1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: localsinglebackend.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_configmgr.hxx"
34 #include "localsinglebackend.hxx"
35 #include "localfilehelper.hxx"
36 #include "localfilelayer.hxx"
37 #include "oslstream.hxx"
39 #ifndef CONFIGMGR_API_FACTORY_HXX_
40 #include "confapifactory.hxx"
41 #endif // CONFIGMGR_API_FACTORY_HXX_
42 #include "serviceinfohelper.hxx"
43 #include "bootstrap.hxx"
44 #include "filehelper.hxx"
45 #include <rtl/ustrbuf.hxx>
46 #include <com/sun/star/uno/XComponentContext.hpp>
47 #include <com/sun/star/configuration/backend/InsufficientAccessRightsException.hpp>
48 #include <osl/file.hxx>
49 #include <osl/process.h>
52 namespace configmgr
{ namespace localbe
{
54 //==============================================================================
56 //------------------------------------------------------------------------------
58 LocalSingleBackend::LocalSingleBackend(
59 const uno::Reference
<uno::XComponentContext
>& xContext
)
60 : cppu::WeakComponentImplHelper5
<backend::XSchemaSupplier
, backend::XMultiLayerStratum
, backend::XBackendEntities
, lang::XInitialization
, lang::XServiceInfo
>(mMutex
), mFactory(xContext
->getServiceManager(),uno::UNO_QUERY
) {
62 //------------------------------------------------------------------------------
64 LocalSingleBackend::~LocalSingleBackend(void) {}
65 //------------------------------------------------------------------------------
66 static const rtl::OUString
kSchemaDataUrl(
67 RTL_CONSTASCII_USTRINGPARAM(CONTEXT_ITEM_PREFIX_
"SchemaDataUrl")) ;
68 static const rtl::OUString
kDefaultDataUrl(
69 RTL_CONSTASCII_USTRINGPARAM(CONTEXT_ITEM_PREFIX_
"DefaultLayerUrls")) ;
70 static const rtl::OUString
kUserDataUrl(
71 RTL_CONSTASCII_USTRINGPARAM(CONTEXT_ITEM_PREFIX_
"UserLayerUrl")) ;
72 static const rtl::OUString
kEntity(
73 RTL_CONSTASCII_USTRINGPARAM(CONTEXT_ITEM_PREFIX_
"EntityLayer")) ;
75 static const rtl::OUString
kAdminModeFlag(
76 RTL_CONSTASCII_USTRINGPARAM(CONTEXT_ITEM_ADMINFLAG
)) ;
78 void SAL_CALL
LocalSingleBackend::initialize(
79 const uno::Sequence
<uno::Any
>& aParameters
)
80 throw (uno::RuntimeException
, uno::Exception
,
81 css::configuration::InvalidBootstrapFileException
,
82 backend::CannotConnectException
,
83 backend::BackendSetupException
)
85 if (aParameters
.getLength() == 0) {
86 throw lang::IllegalArgumentException(
87 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
88 "No parameters provided to SingleBackend")),
91 uno::Reference
<uno::XComponentContext
> context
;
93 for (sal_Int32 i
= 0 ; i
< aParameters
.getLength() ; ++ i
) {
94 if (aParameters
[i
] >>= context
) { break ; }
97 // Setting: schema diretory(ies)
98 uno::Any
const aSchemaDataSetting
= context
->getValueByName(kSchemaDataUrl
);
99 uno::Sequence
< rtl::OUString
> aSchemas
;
100 rtl::OUString schemas
;
102 if (aSchemaDataSetting
>>= schemas
)
104 fillFromBlankSeparated(schemas
, aSchemas
) ;
108 aSchemaDataSetting
>>= aSchemas
;
110 //validate SchemaDataUrls
111 mSchemaDataUrls
.realloc(aSchemas
.getLength());
113 sal_Int32 nSchemaLocations
= 0;
114 sal_Int32 nExistingSchemaLocations
= 0;
115 for (sal_Int32 j
= 0; j
< aSchemas
.getLength(); ++j
)
117 bool bOptional
= checkOptionalArg(aSchemas
[j
]);
120 validateFileURL(aSchemas
[j
],*this);
122 else if (!isValidFileURL(aSchemas
[j
]))
125 OSL_ASSERT(isValidFileURL(aSchemas
[j
]));
128 implEnsureAbsoluteURL(aSchemas
[j
]);
129 if (!normalizeURL(aSchemas
[j
],*this,bOptional
))
132 // now we have a correct file URL, which we will use
133 mSchemaDataUrls
[nSchemaLocations
++] = aSchemas
[j
];
137 checkFileExists(aSchemas
[j
], *this);
139 else if(!FileHelper::fileExists(aSchemas
[j
]))
140 continue; // skip the directory check
143 checkIfDirectory(aSchemas
[j
],*this);
145 ++nExistingSchemaLocations
;
147 mSchemaDataUrls
.realloc(nSchemaLocations
);
149 if (0 == nExistingSchemaLocations
)
151 rtl::OUString sMsg
= rtl::OUString::createFromAscii("LocalBackend: No schema directories found");
152 throw backend::BackendSetupException(sMsg
,*this, uno::Any()) ;
155 // Setting: default layer(s)
156 uno::Any
const aDefaultDataSetting
= context
->getValueByName(kDefaultDataUrl
);
157 uno::Sequence
< rtl::OUString
> aDefaults
;
158 rtl::OUString defaults
;
160 if (aDefaultDataSetting
>>= defaults
)
162 fillFromBlankSeparated(defaults
, aDefaults
) ;
166 aDefaultDataSetting
>>= aDefaults
;
169 //validate DefaultDataUrls
170 mDefaultDataUrls
.realloc(aDefaults
.getLength());
171 sal_Int32 nDefaultLayers
= 0;
173 for (sal_Int32 ix
= 0; ix
< aDefaults
.getLength(); ++ix
)
176 if (!isValidFileURL(aDefaults
[ix
]))
180 implEnsureAbsoluteURL(aDefaults
[ix
]);
181 if (!normalizeURL(aDefaults
[ix
],*this,true))
184 if(FileHelper::fileExists(aDefaults
[ix
]))
186 checkIfDirectory(aDefaults
[ix
],*this);
189 // good URL -> use it
190 mDefaultDataUrls
[nDefaultLayers
++] = aDefaults
[ix
];
192 mDefaultDataUrls
.realloc(nDefaultLayers
);
194 // Setting: admin mode tag
195 sal_Bool bAdminMode
= false;
196 context
->getValueByName(kAdminModeFlag
) >>= bAdminMode
;
201 if ( (context
->getValueByName(kEntity
) >>= mUserDataUrl
) && mUserDataUrl
.getLength() )
203 //Validate UserDataUrl
204 validateFileURL(mUserDataUrl
,*this);
206 implEnsureAbsoluteURL(mUserDataUrl
);
207 normalizeURL(mUserDataUrl
,*this);
208 if(FileHelper::fileExists(mUserDataUrl
))
210 checkIfDirectory(mUserDataUrl
,*this);
213 for (sal_Int32 ix
= 0; ix
< mDefaultDataUrls
.getLength(); ++ix
)
215 if (mDefaultDataUrls
.getConstArray()[ix
].equals(mUserDataUrl
))
217 mDefaultDataUrls
.realloc(ix
);
218 // this is the last round through the loop
222 else if (aDefaults
.getLength()) // administrate first default layer
224 mUserDataUrl
= aDefaults
[0];
225 mDefaultDataUrls
.realloc(0);
229 OSL_ENSURE(false, "Cannot find target entity for admin mode - fallback to local mode");
236 context
->getValueByName(kUserDataUrl
) >>= mUserDataUrl
;
237 //Validate UserDataUrl
238 if (isValidFileURL(mUserDataUrl
))
240 implEnsureAbsoluteURL(mUserDataUrl
);
241 normalizeURL(mUserDataUrl
,*this);
242 if(FileHelper::fileExists(mUserDataUrl
))
244 checkIfDirectory(mUserDataUrl
,*this);
249 if (mUserDataUrl
.getLength() == 0)
251 mUserDataUrl
= rtl::OUString::createFromAscii("*");
252 OSL_ASSERT(!isValidFileURL(mUserDataUrl
));
255 //------------------------------------------------------------------------------
256 const sal_Int32 k_UserLayerEntity
= 0;
257 const sal_Int32 k_InvalidEntity
= k_UserLayerEntity
- 1;
258 const sal_Int32 k_DefaultEntityOffset
= k_UserLayerEntity
+ 1;
259 //------------------------------------------------------------------------------
260 static inline bool isValidEntity(sal_Int32 ent
)
262 return ent
> k_InvalidEntity
;
264 //------------------------------------------------------------------------------
265 static inline sal_Int32
indexToEntity(sal_Int32 ix
)
268 return ix
+ k_DefaultEntityOffset
;
270 static inline sal_Int32
entityToIndex(sal_Int32 ent
)
272 OSL_ASSERT(k_DefaultEntityOffset
<= ent
);
273 return ent
- k_DefaultEntityOffset
;
275 //------------------------------------------------------------------------------
279 Transforms a file url into a layer id. The layer id will
280 contain the URL passed plus an integer indicating which
281 layer the URL points to. If the integer is 0, the URL
282 is a user layer, otherwise it is one of the default layers.
284 @param aFileUrl URL to encode
285 @param aIndex index of the layer concerned (0 = user, other = default)
289 rtl::OUString
urlToLayerId(const rtl::OUString
& aFileUrl
,sal_Int32 aIndex
)
291 rtl::OUStringBuffer id
;
293 OSL_ASSERT(isValidEntity(aIndex
));
295 id
.append(aIndex
).appendAscii(" ",1); // non-user layers
297 id
.appendAscii("U ",2); // user layer
299 id
.append(aFileUrl
) ;
300 return id
.makeStringAndClear() ;
305 bool layerIdToUrl( const rtl::OUString
& aLayerId
,
306 rtl::OUString
& aFileUrl
,
309 sal_Int32
const sep
= aLayerId
.indexOf(sal_Unicode(' ')) ;
311 if (sep
< 0) return false;
313 // detect user layer id
314 if (aLayerId
[0] == sal_Unicode('U'))
316 if (sep
!= 1) return false;
321 aIndex
= aLayerId
.copy(0, sep
).toInt32() ;
322 if (0 == aIndex
|| !isValidEntity(aIndex
)) return false;
324 OSL_ENSURE( aLayerId
.copy(0, sep
).equals(rtl::OUString::valueOf(aIndex
)),
325 "Invalid layer id was not detected");
327 aFileUrl
= aLayerId
.copy(sep
+ 1);
331 //------------------------------------------------------------------------------
332 sal_Int32
LocalSingleBackend::resolveLayerId(const rtl::OUString
& aLayerId
,
333 rtl::OUString
& aFileUrl
)
335 sal_Int32 nIndex
= k_InvalidEntity
;
336 if (!layerIdToUrl(aLayerId
,aFileUrl
,nIndex
))
338 rtl::OUString
const sMsg(RTL_CONSTASCII_USTRINGPARAM(
339 "LocalSingleBackend - Invalid layer id: "));
341 // layer id is always the second parameter
342 throw lang::IllegalArgumentException(sMsg
.concat(aLayerId
), *this, 2);
344 OSL_ASSERT(isValidEntity(nIndex
));
347 //------------------------------------------------------------------------------
349 sal_Int32
LocalSingleBackend::findEntity(const rtl::OUString
& aEntity
)
351 if (aEntity
.getLength() == 0)
353 return k_InvalidEntity
;
356 // quick check for OwnerEntity first
357 if (aEntity
.equals(mUserDataUrl
))
359 return k_UserLayerEntity
;
362 rtl::OUString
sNormalizedEntityUrl(aEntity
);
363 normalizeURL(sNormalizedEntityUrl
,*this);
365 for (sal_Int32 ix
= 0; ix
< mDefaultDataUrls
.getLength(); ++ix
)
367 rtl::OUString
sNormalizedDefaultUrl(mDefaultDataUrls
[ix
]);
368 OSL_VERIFY(normalizeURL(sNormalizedDefaultUrl
,*this,true));
370 if (sNormalizedEntityUrl
.equals(sNormalizedDefaultUrl
))
373 return indexToEntity(ix
);
377 //Try normalized version of mUserDataUrl
378 rtl::OUString
sNormalizedUserUrl(mUserDataUrl
);
380 if (normalizeURL(sNormalizedUserUrl
,*this,true))
382 if (sNormalizedEntityUrl
.equals(sNormalizedUserUrl
))
384 return k_UserLayerEntity
;
389 return k_InvalidEntity
;
391 //------------------------------------------------------------------------------
393 static const rtl::OUString
kDataSuffix(RTL_CONSTASCII_USTRINGPARAM(".xcu")) ;
395 uno::Sequence
<rtl::OUString
> SAL_CALL
LocalSingleBackend::listLayerIds(
396 const rtl::OUString
& aComponent
, const rtl::OUString
& aEntity
)
397 throw (backend::BackendAccessException
, lang::IllegalArgumentException
,
398 uno::RuntimeException
)
400 sal_Int32 nEntity
= findEntity(aEntity
);
401 if ( !isValidEntity(nEntity
) )
403 rtl::OUString
const sMsg(RTL_CONSTASCII_USTRINGPARAM(
404 "LocalSingleBackend - Unknown entity: "));
406 throw lang::IllegalArgumentException(sMsg
.concat(aEntity
), *this, 2);
409 sal_Int32 nDefLayers
= (k_UserLayerEntity
== nEntity
)
410 ? mDefaultDataUrls
.getLength()
411 : entityToIndex(nEntity
);
413 OSL_ASSERT(0 <= nDefLayers
&& nDefLayers
<= mDefaultDataUrls
.getLength());
415 rtl::OUString
const componentSubPath
= componentToPath(aComponent
) + kDataSuffix
;
417 uno::Sequence
<rtl::OUString
> aLayerIds(nDefLayers
+ 1) ;
418 OSL_ASSERT(0 < aLayerIds
.getLength());
420 // First, the defaults...
421 for (sal_Int32 ix
= 0; ix
< nDefLayers
; ++ ix
)
423 aLayerIds
[ix
] = urlToLayerId(componentSubPath
, indexToEntity(ix
)) ;
425 // Then the entity data.
426 aLayerIds
[nDefLayers
] = urlToLayerId(componentSubPath
, nEntity
) ;
430 //------------------------------------------------------------------------------
432 rtl::OUString SAL_CALL
LocalSingleBackend::getUpdateLayerId(
433 const rtl::OUString
& aComponent
, const rtl::OUString
& aEntity
)
434 throw (backend::BackendAccessException
, lang::IllegalArgumentException
,
435 uno::RuntimeException
)
437 sal_Int32 nEntity
= findEntity(aEntity
);
438 if ( !isValidEntity(nEntity
) )
440 rtl::OUString
const sMsg(RTL_CONSTASCII_USTRINGPARAM(
441 "LocalSingleBackend - Unknown entity for update: "));
443 throw lang::IllegalArgumentException(sMsg
.concat(aEntity
), *this, 2);
446 return urlToLayerId(componentToPath(aComponent
) + kDataSuffix
, nEntity
) ;
448 //------------------------------------------------------------------------------
450 rtl::OUString SAL_CALL
LocalSingleBackend::getOwnerEntity()
451 throw (uno::RuntimeException
)
453 return mUserDataUrl
;
455 //------------------------------------------------------------------------------
457 rtl::OUString SAL_CALL
LocalSingleBackend::getAdminEntity()
458 throw (uno::RuntimeException
)
460 return mDefaultDataUrls
.getLength() > 0 ? mDefaultDataUrls
[0] : mUserDataUrl
;
462 //------------------------------------------------------------------------------
464 sal_Bool SAL_CALL
LocalSingleBackend::supportsEntity( const rtl::OUString
& aEntity
)
465 throw (backend::BackendAccessException
, uno::RuntimeException
)
467 return isValidEntity(findEntity(aEntity
)) ;
469 //------------------------------------------------------------------------------
471 sal_Bool SAL_CALL
LocalSingleBackend::isEqualEntity(const rtl::OUString
& aEntity
, const rtl::OUString
& aOtherEntity
)
472 throw (backend::BackendAccessException
, lang::IllegalArgumentException
, uno::RuntimeException
)
474 if (aEntity
.getLength() == 0)
476 rtl::OUString
const sMsg(RTL_CONSTASCII_USTRINGPARAM(
477 "LocalSingleBackend - Invalid empty entity."));
479 throw lang::IllegalArgumentException(sMsg
, *this, 1);
481 if (aOtherEntity
.getLength() == 0)
483 rtl::OUString
const sMsg(RTL_CONSTASCII_USTRINGPARAM(
484 "LocalSingleBackend - Invalid empty entity."));
486 throw lang::IllegalArgumentException(sMsg
, *this, 2);
488 rtl::OUString
aNormalizedEntity(aEntity
);
489 normalizeURL(aNormalizedEntity
,*this);
491 rtl::OUString
aNormalizedOther(aOtherEntity
);
492 normalizeURL(aNormalizedOther
,*this);
494 return aNormalizedEntity
== aNormalizedOther
;
496 //------------------------------------------------------------------------------
498 sal_Bool
LocalSingleBackend::isMoreRecent(const rtl::OUString
& aFileUrl
,
499 sal_Int32 aLayerIndex
,
500 const rtl::OUString
& aTimestamp
) {
501 rtl::OUString layerUrl
;
502 rtl::OUString subLayerUrl
;
504 // if we don't find a layer, but have a non-empty timestamp -> modified
505 if (!getLayerDirectories(aLayerIndex
,layerUrl
, subLayerUrl
))
506 return aTimestamp
.getLength() != 0;
508 return layerUrl
.getLength() == 0 ||
509 BasicLocalFileLayer::getTimestamp(layerUrl
+ aFileUrl
).compareTo( aTimestamp
) != 0;
511 //------------------------------------------------------------------------------
513 static const rtl::OUString
kDataSubPath(
514 RTL_CONSTASCII_USTRINGPARAM("/data")) ;
515 static const rtl::OUString
kLocalisedDataSubPath(
516 RTL_CONSTASCII_USTRINGPARAM("/res")) ;
518 uno::Reference
<backend::XLayer
> SAL_CALL
LocalSingleBackend::getLayer(
519 const rtl::OUString
& aLayerId
, const rtl::OUString
& aTimestamp
)
520 throw (backend::BackendAccessException
, lang::IllegalArgumentException
,
521 uno::RuntimeException
)
523 rtl::OUString fileUrl
;
525 sal_Int32 defaultIndex
= resolveLayerId(aLayerId
, fileUrl
) ;
527 if (!isMoreRecent(fileUrl
, defaultIndex
, aTimestamp
)) { return NULL
; }
529 uno::Reference
<backend::XUpdatableLayer
> xLayer
= getFileLayer(fileUrl
,defaultIndex
);
530 uno::Reference
<backend::XLayer
> xResult
= xLayer
.get();
533 //------------------------------------------------------------------------------
535 uno::Sequence
<uno::Reference
<backend::XLayer
> > SAL_CALL
536 LocalSingleBackend::getLayers(const uno::Sequence
<rtl::OUString
>& aLayerIds
,
537 const rtl::OUString
& aTimestamp
)
538 throw (backend::BackendAccessException
, lang::IllegalArgumentException
,
539 uno::RuntimeException
)
541 uno::Sequence
<uno::Reference
<backend::XLayer
> >
542 retCode(aLayerIds
.getLength()) ;
544 for (sal_Int32 i
= 0 ; i
< aLayerIds
.getLength() ; ++ i
) {
545 retCode
[i
] = getLayer(aLayerIds
[i
], aTimestamp
) ;
549 //------------------------------------------------------------------------------
551 uno::Sequence
<uno::Reference
<backend::XLayer
> > SAL_CALL
552 LocalSingleBackend::getMultipleLayers(
553 const uno::Sequence
<rtl::OUString
>& aLayerIds
,
554 const uno::Sequence
<rtl::OUString
>& aTimestamps
)
555 throw (backend::BackendAccessException
, lang::IllegalArgumentException
,
556 uno::RuntimeException
)
558 if (aLayerIds
.getLength() != aTimestamps
.getLength()) {
559 throw lang::IllegalArgumentException(
560 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
561 "Not enough or too many timestamps")),
564 uno::Sequence
<uno::Reference
<backend::XLayer
> >
565 retCode(aLayerIds
.getLength()) ;
567 for (sal_Int32 i
= 0 ; i
< aLayerIds
.getLength() ; ++ i
) {
568 retCode
[i
] = getLayer(aLayerIds
[i
], aTimestamps
[i
]) ;
572 //------------------------------------------------------------------------------
574 uno::Reference
<backend::XUpdatableLayer
> SAL_CALL
575 LocalSingleBackend::getUpdatableLayer(const rtl::OUString
& aLayerId
)
576 throw (backend::BackendAccessException
, lang::IllegalArgumentException
,
577 uno::RuntimeException
)
579 return getFileLayer(aLayerId
) ;
581 //------------------------------------------------------------------------------
583 static const rtl::OUString
kSchemaSuffix(RTL_CONSTASCII_USTRINGPARAM(".xcs")) ;
584 static const rtl::OUString
kXMLSchemaParser(RTL_CONSTASCII_USTRINGPARAM(
585 "com.sun.star.configuration.backend.xml.SchemaParser")) ;
587 uno::Reference
<backend::XSchema
> SAL_CALL
588 LocalSingleBackend::getComponentSchema(const rtl::OUString
& aComponent
)
589 throw (backend::BackendAccessException
, lang::IllegalArgumentException
,
590 uno::RuntimeException
)
592 rtl::OUString subPath
= componentToPath(aComponent
) ;
594 osl::File
* schemaFile
= NULL
;
595 rtl::OUString errorMessage
;
596 bool bInsufficientAccess
= false;
597 for (sal_Int32 ix
= 0; ix
< mSchemaDataUrls
.getLength(); ++ix
)
599 rtl::OUStringBuffer
schemaUrl(mSchemaDataUrls
[ix
]) ;
601 schemaUrl
.append(subPath
).append(kSchemaSuffix
) ;
603 rtl::OUString
const aFileUrl
= schemaUrl
.makeStringAndClear();
605 std::auto_ptr
<osl::File
> checkFile( new osl::File(aFileUrl
) );
606 osl::File::RC rc
= checkFile
->open(OpenFlag_Read
) ;
608 if (rc
== osl::File::E_None
)
610 schemaFile
= checkFile
.release();
613 else if (rc
!= osl::File::E_NOENT
)
615 if (rc
== osl::File::E_ACCES
)
616 bInsufficientAccess
=true;
618 // accumulate error messages
619 rtl::OUStringBuffer
sMsg(errorMessage
);
620 if (errorMessage
.getLength())
621 sMsg
.appendAscii("LocalFile SchemaSupplier - Error accessing schema: ");
623 sMsg
.appendAscii("\n- Cannot open input file \"");
624 sMsg
.append(aFileUrl
);
625 sMsg
.appendAscii("\" : ");
626 sMsg
.append(FileHelper::createOSLErrorString(rc
));
628 errorMessage
= sMsg
.makeStringAndClear();
632 if (NULL
== schemaFile
)
634 if (errorMessage
.getLength() != 0)
636 // a real error occured
637 io::IOException
ioe(errorMessage
,*this);
639 rtl::OUStringBuffer sMsg
;
640 sMsg
.appendAscii("LocalFileLayer - Cannot readData: ").append(errorMessage
);
642 if (bInsufficientAccess
)
643 throw backend::InsufficientAccessRightsException(sMsg
.makeStringAndClear(),*this,uno::makeAny(ioe
));
645 throw backend::BackendAccessException(sMsg
.makeStringAndClear(),*this,uno::makeAny(ioe
));
651 uno::Sequence
<uno::Any
> arguments(1) ;
652 uno::Reference
<io::XInputStream
> stream( new OSLInputStreamWrapper(schemaFile
, true) );
654 arguments
[0] <<= stream
;
655 uno::Reference
<backend::XSchema
> schema(
656 mFactory
->createInstanceWithArguments(kXMLSchemaParser
, arguments
),
661 throw uno::RuntimeException(
662 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
663 "Cannot instantiate Schema Parser for ")) + aComponent
,
668 //------------------------------------------------------------------------------
672 bool impl_getLayerSubDirectories(rtl::OUString
const & aLayerBaseUrl
,
673 rtl::OUString
& aMainLayerUrl
,
674 rtl::OUString
& aSubLayerUrl
)
676 if (!isValidFileURL(aLayerBaseUrl
)) return false;
678 aMainLayerUrl
= aLayerBaseUrl
+ kDataSubPath
;
679 aSubLayerUrl
= aLayerBaseUrl
+ kLocalisedDataSubPath
;
682 //------------------------------------------------------------------------------
684 bool LocalSingleBackend::getLayerSubDirectories(rtl::OUString
const & aLayerBaseUrl
,
685 rtl::OUString
& aMainLayerUrl
,
686 rtl::OUString
& aSubLayerUrl
)
688 return impl_getLayerSubDirectories(aLayerBaseUrl
,aMainLayerUrl
,aSubLayerUrl
);
690 //------------------------------------------------------------------------------
692 bool LocalSingleBackend::getLayerDirectories(sal_Int32 aLayerIndex
,
693 rtl::OUString
& aLayerUrl
,
694 rtl::OUString
& aSubLayerUrl
)
696 OSL_ASSERT(isValidEntity(aLayerIndex
));
697 rtl::OUString aLayerBaseUrl
= (aLayerIndex
== k_UserLayerEntity
) ? mUserDataUrl
: mDefaultDataUrls
[entityToIndex(aLayerIndex
)] ;
699 return impl_getLayerSubDirectories(aLayerBaseUrl
,aLayerUrl
,aSubLayerUrl
);
701 //------------------------------------------------------------------------------
703 uno::Reference
<backend::XLayer
> LocalSingleBackend::createSimpleLayer(
704 const uno::Reference
<lang::XMultiServiceFactory
>& xFactory
,
705 rtl::OUString
const & aComponentUrl
)
707 SimpleLocalFileLayer
* pLayer
= new SimpleLocalFileLayer(xFactory
, aComponentUrl
);
710 //------------------------------------------------------------------------------
712 uno::Reference
<backend::XLayer
> LocalSingleBackend::createSimpleLayer(
713 const uno::Reference
<lang::XMultiServiceFactory
>& xFactory
,
714 rtl::OUString
const & aLayerBaseUrl
,
715 rtl::OUString
const & aComponent
)
717 rtl::OUString aLayerUrl
, aSubLayerUrl
;
718 if (!impl_getLayerSubDirectories(aLayerBaseUrl
,aLayerUrl
,aSubLayerUrl
))
721 SimpleLocalFileLayer
* pLayer
= new SimpleLocalFileLayer(xFactory
, aLayerUrl
, componentToPath(aComponent
) + kDataSuffix
);
724 //------------------------------------------------------------------------------
727 uno::Reference
<backend::XUpdatableLayer
> LocalSingleBackend::getFileLayer(const rtl::OUString
& aLayerId
)
728 throw (lang::IllegalArgumentException
)
730 rtl::OUString fileUrl
;
731 sal_Int32 defaultIndex
= resolveLayerId(aLayerId
, fileUrl
) ;
733 return getFileLayer(fileUrl
, defaultIndex
) ;
735 //------------------------------------------------------------------------------
737 uno::Reference
<backend::XUpdatableLayer
> LocalSingleBackend::getFileLayer(
738 const rtl::OUString
& aComponent
, sal_Int32 aLayerIndex
) {
739 rtl::OUString layerPath
;
740 rtl::OUString subLayerPath
;
742 if (!getLayerDirectories(aLayerIndex
, layerPath
, subLayerPath
))
744 OSL_ENSURE(aLayerIndex
== k_UserLayerEntity
, "Unexpected: Invalid non-user layer url");
746 rtl::OUStringBuffer sMsg
;
747 sMsg
.appendAscii("LocalSingleBackend: Cannot create file layer - Layer URL '");
748 sMsg
.append(mUserDataUrl
).appendAscii("' is invalid.");
750 throw lang::IllegalArgumentException(sMsg
.makeStringAndClear(),*this,1);
753 return createUpdatableLocalFileLayer(mFactory
, layerPath
, aComponent
, subLayerPath
) ;
755 //------------------------------------------------------------------------------
757 static const sal_Char
* const kImplementation
=
758 "com.sun.star.comp.configuration.backend.LocalSingleBackend" ;
759 static const sal_Char
* const kBackendService
=
760 "com.sun.star.configuration.backend.SingleBackend" ;
761 static const sal_Char
* const kLocalService
=
762 "com.sun.star.configuration.backend.LocalSingleBackend" ;
764 static sal_Char
const * kServiceNames
[] = { kLocalService
, 0, kBackendService
, 0 } ;
765 static const ServiceImplementationInfo kServiceInfo
= { kImplementation
, kServiceNames
, kServiceNames
+ 2 } ;
767 const ServiceRegistrationInfo
*getLocalBackendServiceInfo()
768 { return getRegistrationInfo(&kServiceInfo
) ; }
770 uno::Reference
<uno::XInterface
> SAL_CALL
771 instantiateLocalBackend(const uno::Reference
< uno::XComponentContext
>& xContext
) {
772 return *new LocalSingleBackend(xContext
) ;
775 //------------------------------------------------------------------------------
777 rtl::OUString SAL_CALL
LocalSingleBackend::getImplementationName(void)
778 throw (uno::RuntimeException
)
780 return ServiceInfoHelper(&kServiceInfo
).getImplementationName() ;
782 //------------------------------------------------------------------------------
784 sal_Bool SAL_CALL
LocalSingleBackend::supportsService(
785 const rtl::OUString
& aServiceName
)
786 throw (uno::RuntimeException
)
788 return ServiceInfoHelper(&kServiceInfo
).supportsService(aServiceName
);
790 //------------------------------------------------------------------------------
792 uno::Sequence
<rtl::OUString
>
793 SAL_CALL
LocalSingleBackend::getSupportedServiceNames(void)
794 throw (uno::RuntimeException
)
796 return ServiceInfoHelper(&kServiceInfo
).getSupportedServiceNames() ;
799 // ---------------------------------------------------------------------------------------
801 } } // configmgr.localbe