merge the formfield patch from ooo-build
[ooovba.git] / configmgr / source / localbe / localsinglebackend.cxx
blobca424fce8d82cfb04f52fd16878dc5adb053e066
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: localsinglebackend.cxx,v $
10 * $Revision: 1.23 $
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>
50 #include <memory>
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")),
89 *this, 0) ;
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) ;
106 else
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]);
119 if (!bOptional)
120 validateFileURL(aSchemas[j],*this);
122 else if (!isValidFileURL(aSchemas[j]))
123 continue;
125 OSL_ASSERT(isValidFileURL(aSchemas[j]));
127 //NormalizeURL
128 implEnsureAbsoluteURL(aSchemas[j]);
129 if (!normalizeURL(aSchemas[j],*this,bOptional))
130 continue;
132 // now we have a correct file URL, which we will use
133 mSchemaDataUrls[nSchemaLocations++] = aSchemas[j];
135 // check existence
136 if (!bOptional)
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) ;
164 else
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)
175 // skip invalid URLs
176 if (!isValidFileURL(aDefaults[ix]))
177 continue;
179 //NormalizeURL
180 implEnsureAbsoluteURL(aDefaults[ix]);
181 if (!normalizeURL(aDefaults[ix],*this,true))
182 continue;
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;
198 if (bAdminMode)
200 // find given entity
201 if ( (context->getValueByName(kEntity) >>= mUserDataUrl) && mUserDataUrl.getLength() )
203 //Validate UserDataUrl
204 validateFileURL(mUserDataUrl,*this);
205 //NormalizeURL
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);
227 else
229 OSL_ENSURE(false, "Cannot find target entity for admin mode - fallback to local mode");
230 bAdminMode = false;
234 if (!bAdminMode)
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)
267 OSL_ASSERT(0 <= 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)
286 @return layer id
288 static
289 rtl::OUString urlToLayerId(const rtl::OUString& aFileUrl,sal_Int32 aIndex)
291 rtl::OUStringBuffer id ;
293 OSL_ASSERT(isValidEntity(aIndex));
294 if (aIndex)
295 id.append(aIndex).appendAscii(" ",1); // non-user layers
296 else
297 id.appendAscii("U ",2); // user layer
299 id.append(aFileUrl) ;
300 return id.makeStringAndClear() ;
303 static
304 inline
305 bool layerIdToUrl( const rtl::OUString& aLayerId,
306 rtl::OUString& aFileUrl,
307 sal_Int32& aIndex)
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;
317 aIndex = 0;
319 else
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);
329 return true;
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));
345 return 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))
372 // found it
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;
388 // not found
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) ;
428 return aLayerIds;
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();
531 return xResult;
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) ;
547 return retCode ;
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")),
562 *this, 0) ;
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]) ;
570 return retCode ;
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();
611 break;
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));
644 else
645 throw backend::BackendAccessException(sMsg.makeStringAndClear(),*this,uno::makeAny(ioe));
647 // simply not found
648 return NULL;
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),
657 uno::UNO_QUERY) ;
659 if (!schema.is())
661 throw uno::RuntimeException(
662 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
663 "Cannot instantiate Schema Parser for ")) + aComponent,
664 *this) ;
666 return schema ;
668 //------------------------------------------------------------------------------
670 static
671 inline
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 ;
680 return true;
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);
708 return pLayer;
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))
719 return NULL;
721 SimpleLocalFileLayer * pLayer = new SimpleLocalFileLayer(xFactory, aLayerUrl, componentToPath(aComponent) + kDataSuffix);
722 return pLayer;
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