/************************************************************************* * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * Copyright 2008 by Sun Microsystems, Inc. * * OpenOffice.org - a multi-platform office productivity suite * * $RCSfile: localsinglebackend.cxx,v $ * $Revision: 1.23 $ * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 * only, as published by the Free Software Foundation. * * OpenOffice.org is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License version 3 for more details * (a copy is included in the LICENSE file that accompanied this code). * * You should have received a copy of the GNU Lesser General Public License * version 3 along with OpenOffice.org. If not, see * * for a copy of the LGPLv3 License. * ************************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_configmgr.hxx" #include "localsinglebackend.hxx" #include "localfilehelper.hxx" #include "localfilelayer.hxx" #include "oslstream.hxx" #ifndef CONFIGMGR_API_FACTORY_HXX_ #include "confapifactory.hxx" #endif // CONFIGMGR_API_FACTORY_HXX_ #include "serviceinfohelper.hxx" #include "bootstrap.hxx" #include "filehelper.hxx" #include #include #include #include #include #include namespace configmgr { namespace localbe { //============================================================================== //------------------------------------------------------------------------------ LocalSingleBackend::LocalSingleBackend( const uno::Reference& xContext) : cppu::WeakComponentImplHelper5(mMutex), mFactory(xContext->getServiceManager(),uno::UNO_QUERY) { } //------------------------------------------------------------------------------ LocalSingleBackend::~LocalSingleBackend(void) {} //------------------------------------------------------------------------------ static const rtl::OUString kSchemaDataUrl( RTL_CONSTASCII_USTRINGPARAM(CONTEXT_ITEM_PREFIX_"SchemaDataUrl")) ; static const rtl::OUString kDefaultDataUrl( RTL_CONSTASCII_USTRINGPARAM(CONTEXT_ITEM_PREFIX_"DefaultLayerUrls")) ; static const rtl::OUString kUserDataUrl( RTL_CONSTASCII_USTRINGPARAM(CONTEXT_ITEM_PREFIX_"UserLayerUrl")) ; static const rtl::OUString kEntity( RTL_CONSTASCII_USTRINGPARAM(CONTEXT_ITEM_PREFIX_"EntityLayer")) ; static const rtl::OUString kAdminModeFlag( RTL_CONSTASCII_USTRINGPARAM(CONTEXT_ITEM_ADMINFLAG)) ; void SAL_CALL LocalSingleBackend::initialize( const uno::Sequence& aParameters) throw (uno::RuntimeException, uno::Exception, css::configuration::InvalidBootstrapFileException, backend::CannotConnectException, backend::BackendSetupException) { if (aParameters.getLength() == 0) { throw lang::IllegalArgumentException( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "No parameters provided to SingleBackend")), *this, 0) ; } uno::Reference context ; for (sal_Int32 i = 0 ; i < aParameters.getLength() ; ++ i) { if (aParameters [i] >>= context) { break ; } } // Setting: schema diretory(ies) uno::Any const aSchemaDataSetting = context->getValueByName(kSchemaDataUrl); uno::Sequence< rtl::OUString > aSchemas; rtl::OUString schemas; if (aSchemaDataSetting >>= schemas) { fillFromBlankSeparated(schemas, aSchemas) ; } else { aSchemaDataSetting >>= aSchemas; } //validate SchemaDataUrls mSchemaDataUrls.realloc(aSchemas.getLength()); sal_Int32 nSchemaLocations = 0; sal_Int32 nExistingSchemaLocations = 0; for (sal_Int32 j = 0; j < aSchemas.getLength(); ++j) { bool bOptional = checkOptionalArg(aSchemas[j]); if (!bOptional) validateFileURL(aSchemas[j],*this); else if (!isValidFileURL(aSchemas[j])) continue; OSL_ASSERT(isValidFileURL(aSchemas[j])); //NormalizeURL implEnsureAbsoluteURL(aSchemas[j]); if (!normalizeURL(aSchemas[j],*this,bOptional)) continue; // now we have a correct file URL, which we will use mSchemaDataUrls[nSchemaLocations++] = aSchemas[j]; // check existence if (!bOptional) checkFileExists(aSchemas[j], *this); else if(!FileHelper::fileExists(aSchemas[j])) continue; // skip the directory check checkIfDirectory(aSchemas[j],*this); ++nExistingSchemaLocations; } mSchemaDataUrls.realloc(nSchemaLocations); if (0 == nExistingSchemaLocations) { rtl::OUString sMsg = rtl::OUString::createFromAscii("LocalBackend: No schema directories found"); throw backend::BackendSetupException(sMsg,*this, uno::Any()) ; } // Setting: default layer(s) uno::Any const aDefaultDataSetting = context->getValueByName(kDefaultDataUrl); uno::Sequence< rtl::OUString > aDefaults; rtl::OUString defaults; if (aDefaultDataSetting >>= defaults) { fillFromBlankSeparated(defaults, aDefaults) ; } else { aDefaultDataSetting >>= aDefaults ; } //validate DefaultDataUrls mDefaultDataUrls.realloc(aDefaults.getLength()); sal_Int32 nDefaultLayers = 0; for (sal_Int32 ix = 0; ix < aDefaults.getLength(); ++ix) { // skip invalid URLs if (!isValidFileURL(aDefaults[ix])) continue; //NormalizeURL implEnsureAbsoluteURL(aDefaults[ix]); if (!normalizeURL(aDefaults[ix],*this,true)) continue; if(FileHelper::fileExists(aDefaults[ix])) { checkIfDirectory(aDefaults[ix],*this); } // good URL -> use it mDefaultDataUrls[nDefaultLayers++] = aDefaults[ix]; } mDefaultDataUrls.realloc(nDefaultLayers); // Setting: admin mode tag sal_Bool bAdminMode = false; context->getValueByName(kAdminModeFlag) >>= bAdminMode; if (bAdminMode) { // find given entity if ( (context->getValueByName(kEntity) >>= mUserDataUrl) && mUserDataUrl.getLength() ) { //Validate UserDataUrl validateFileURL(mUserDataUrl,*this); //NormalizeURL implEnsureAbsoluteURL(mUserDataUrl); normalizeURL(mUserDataUrl,*this); if(FileHelper::fileExists(mUserDataUrl)) { checkIfDirectory(mUserDataUrl,*this); } for (sal_Int32 ix = 0; ix < mDefaultDataUrls.getLength(); ++ix) { if (mDefaultDataUrls.getConstArray()[ix].equals(mUserDataUrl)) { mDefaultDataUrls.realloc(ix); // this is the last round through the loop } } } else if (aDefaults.getLength()) // administrate first default layer { mUserDataUrl = aDefaults[0]; mDefaultDataUrls.realloc(0); } else { OSL_ENSURE(false, "Cannot find target entity for admin mode - fallback to local mode"); bAdminMode = false; } } if (!bAdminMode) { context->getValueByName(kUserDataUrl) >>= mUserDataUrl ; //Validate UserDataUrl if (isValidFileURL(mUserDataUrl)) { implEnsureAbsoluteURL(mUserDataUrl); normalizeURL(mUserDataUrl,*this); if(FileHelper::fileExists(mUserDataUrl)) { checkIfDirectory(mUserDataUrl,*this); } } } if (mUserDataUrl.getLength() == 0) { mUserDataUrl = rtl::OUString::createFromAscii("*"); OSL_ASSERT(!isValidFileURL(mUserDataUrl)); } } //------------------------------------------------------------------------------ const sal_Int32 k_UserLayerEntity = 0; const sal_Int32 k_InvalidEntity = k_UserLayerEntity - 1; const sal_Int32 k_DefaultEntityOffset = k_UserLayerEntity + 1; //------------------------------------------------------------------------------ static inline bool isValidEntity(sal_Int32 ent) { return ent > k_InvalidEntity; } //------------------------------------------------------------------------------ static inline sal_Int32 indexToEntity(sal_Int32 ix) { OSL_ASSERT(0 <= ix); return ix + k_DefaultEntityOffset; } static inline sal_Int32 entityToIndex(sal_Int32 ent) { OSL_ASSERT(k_DefaultEntityOffset <= ent); return ent - k_DefaultEntityOffset; } //------------------------------------------------------------------------------ /** Transforms a file url into a layer id. The layer id will contain the URL passed plus an integer indicating which layer the URL points to. If the integer is 0, the URL is a user layer, otherwise it is one of the default layers. @param aFileUrl URL to encode @param aIndex index of the layer concerned (0 = user, other = default) @return layer id */ static rtl::OUString urlToLayerId(const rtl::OUString& aFileUrl,sal_Int32 aIndex) { rtl::OUStringBuffer id ; OSL_ASSERT(isValidEntity(aIndex)); if (aIndex) id.append(aIndex).appendAscii(" ",1); // non-user layers else id.appendAscii("U ",2); // user layer id.append(aFileUrl) ; return id.makeStringAndClear() ; } static inline bool layerIdToUrl( const rtl::OUString& aLayerId, rtl::OUString& aFileUrl, sal_Int32& aIndex) { sal_Int32 const sep = aLayerId.indexOf(sal_Unicode(' ')) ; if (sep < 0) return false; // detect user layer id if (aLayerId[0] == sal_Unicode('U')) { if (sep != 1) return false; aIndex = 0; } else { aIndex = aLayerId.copy(0, sep).toInt32() ; if (0 == aIndex || !isValidEntity(aIndex)) return false; OSL_ENSURE( aLayerId.copy(0, sep).equals(rtl::OUString::valueOf(aIndex)), "Invalid layer id was not detected"); } aFileUrl = aLayerId.copy(sep + 1); return true; } //------------------------------------------------------------------------------ sal_Int32 LocalSingleBackend::resolveLayerId(const rtl::OUString& aLayerId, rtl::OUString& aFileUrl) { sal_Int32 nIndex = k_InvalidEntity; if (!layerIdToUrl(aLayerId,aFileUrl,nIndex)) { rtl::OUString const sMsg(RTL_CONSTASCII_USTRINGPARAM( "LocalSingleBackend - Invalid layer id: ")); // layer id is always the second parameter throw lang::IllegalArgumentException(sMsg.concat(aLayerId), *this, 2); } OSL_ASSERT(isValidEntity(nIndex)); return nIndex; } //------------------------------------------------------------------------------ sal_Int32 LocalSingleBackend::findEntity(const rtl::OUString& aEntity) { if (aEntity.getLength() == 0) { return k_InvalidEntity; } // quick check for OwnerEntity first if (aEntity.equals(mUserDataUrl)) { return k_UserLayerEntity; } rtl::OUString sNormalizedEntityUrl(aEntity); normalizeURL(sNormalizedEntityUrl,*this); for (sal_Int32 ix = 0; ix < mDefaultDataUrls.getLength(); ++ix) { rtl::OUString sNormalizedDefaultUrl(mDefaultDataUrls[ix]); OSL_VERIFY(normalizeURL(sNormalizedDefaultUrl,*this,true)); if (sNormalizedEntityUrl.equals(sNormalizedDefaultUrl)) { // found it return indexToEntity(ix); } } //Try normalized version of mUserDataUrl rtl::OUString sNormalizedUserUrl(mUserDataUrl); if (normalizeURL(sNormalizedUserUrl,*this,true)) { if (sNormalizedEntityUrl.equals(sNormalizedUserUrl)) { return k_UserLayerEntity; } } // not found return k_InvalidEntity; } //------------------------------------------------------------------------------ static const rtl::OUString kDataSuffix(RTL_CONSTASCII_USTRINGPARAM(".xcu")) ; uno::Sequence SAL_CALL LocalSingleBackend::listLayerIds( const rtl::OUString& aComponent, const rtl::OUString& aEntity) throw (backend::BackendAccessException, lang::IllegalArgumentException, uno::RuntimeException) { sal_Int32 nEntity = findEntity(aEntity); if ( !isValidEntity(nEntity) ) { rtl::OUString const sMsg(RTL_CONSTASCII_USTRINGPARAM( "LocalSingleBackend - Unknown entity: ")); throw lang::IllegalArgumentException(sMsg.concat(aEntity), *this, 2); } sal_Int32 nDefLayers = (k_UserLayerEntity == nEntity) ? mDefaultDataUrls.getLength() : entityToIndex(nEntity); OSL_ASSERT(0 <= nDefLayers && nDefLayers <= mDefaultDataUrls.getLength()); rtl::OUString const componentSubPath = componentToPath(aComponent) + kDataSuffix ; uno::Sequence aLayerIds(nDefLayers + 1) ; OSL_ASSERT(0 < aLayerIds.getLength()); // First, the defaults... for (sal_Int32 ix = 0; ix < nDefLayers ; ++ ix) { aLayerIds[ix] = urlToLayerId(componentSubPath, indexToEntity(ix)) ; } // Then the entity data. aLayerIds [nDefLayers] = urlToLayerId(componentSubPath, nEntity) ; return aLayerIds; } //------------------------------------------------------------------------------ rtl::OUString SAL_CALL LocalSingleBackend::getUpdateLayerId( const rtl::OUString& aComponent, const rtl::OUString& aEntity) throw (backend::BackendAccessException, lang::IllegalArgumentException, uno::RuntimeException) { sal_Int32 nEntity = findEntity(aEntity); if ( !isValidEntity(nEntity) ) { rtl::OUString const sMsg(RTL_CONSTASCII_USTRINGPARAM( "LocalSingleBackend - Unknown entity for update: ")); throw lang::IllegalArgumentException(sMsg.concat(aEntity), *this, 2); } return urlToLayerId(componentToPath(aComponent) + kDataSuffix, nEntity) ; } //------------------------------------------------------------------------------ rtl::OUString SAL_CALL LocalSingleBackend::getOwnerEntity() throw (uno::RuntimeException) { return mUserDataUrl ; } //------------------------------------------------------------------------------ rtl::OUString SAL_CALL LocalSingleBackend::getAdminEntity() throw (uno::RuntimeException) { return mDefaultDataUrls.getLength() > 0 ? mDefaultDataUrls[0] : mUserDataUrl; } //------------------------------------------------------------------------------ sal_Bool SAL_CALL LocalSingleBackend::supportsEntity( const rtl::OUString& aEntity ) throw (backend::BackendAccessException, uno::RuntimeException) { return isValidEntity(findEntity(aEntity)) ; } //------------------------------------------------------------------------------ sal_Bool SAL_CALL LocalSingleBackend::isEqualEntity(const rtl::OUString& aEntity, const rtl::OUString& aOtherEntity) throw (backend::BackendAccessException, lang::IllegalArgumentException, uno::RuntimeException) { if (aEntity.getLength() == 0) { rtl::OUString const sMsg(RTL_CONSTASCII_USTRINGPARAM( "LocalSingleBackend - Invalid empty entity.")); throw lang::IllegalArgumentException(sMsg, *this, 1); } if (aOtherEntity.getLength() == 0) { rtl::OUString const sMsg(RTL_CONSTASCII_USTRINGPARAM( "LocalSingleBackend - Invalid empty entity.")); throw lang::IllegalArgumentException(sMsg, *this, 2); } rtl::OUString aNormalizedEntity(aEntity); normalizeURL(aNormalizedEntity,*this); rtl::OUString aNormalizedOther(aOtherEntity); normalizeURL(aNormalizedOther,*this); return aNormalizedEntity == aNormalizedOther; } //------------------------------------------------------------------------------ sal_Bool LocalSingleBackend::isMoreRecent(const rtl::OUString& aFileUrl, sal_Int32 aLayerIndex, const rtl::OUString& aTimestamp) { rtl::OUString layerUrl ; rtl::OUString subLayerUrl ; // if we don't find a layer, but have a non-empty timestamp -> modified if (!getLayerDirectories(aLayerIndex,layerUrl, subLayerUrl)) return aTimestamp.getLength() != 0; return layerUrl.getLength() == 0 || BasicLocalFileLayer::getTimestamp(layerUrl + aFileUrl).compareTo( aTimestamp) != 0; } //------------------------------------------------------------------------------ static const rtl::OUString kDataSubPath( RTL_CONSTASCII_USTRINGPARAM("/data")) ; static const rtl::OUString kLocalisedDataSubPath( RTL_CONSTASCII_USTRINGPARAM("/res")) ; uno::Reference SAL_CALL LocalSingleBackend::getLayer( const rtl::OUString& aLayerId, const rtl::OUString& aTimestamp) throw (backend::BackendAccessException, lang::IllegalArgumentException, uno::RuntimeException) { rtl::OUString fileUrl ; sal_Int32 defaultIndex = resolveLayerId(aLayerId, fileUrl) ; if (!isMoreRecent(fileUrl, defaultIndex, aTimestamp)) { return NULL ; } uno::Reference xLayer = getFileLayer(fileUrl,defaultIndex); uno::Reference xResult = xLayer.get(); return xResult; } //------------------------------------------------------------------------------ uno::Sequence > SAL_CALL LocalSingleBackend::getLayers(const uno::Sequence& aLayerIds, const rtl::OUString& aTimestamp) throw (backend::BackendAccessException, lang::IllegalArgumentException, uno::RuntimeException) { uno::Sequence > retCode(aLayerIds.getLength()) ; for (sal_Int32 i = 0 ; i < aLayerIds.getLength() ; ++ i) { retCode [i] = getLayer(aLayerIds [i], aTimestamp) ; } return retCode ; } //------------------------------------------------------------------------------ uno::Sequence > SAL_CALL LocalSingleBackend::getMultipleLayers( const uno::Sequence& aLayerIds, const uno::Sequence& aTimestamps) throw (backend::BackendAccessException, lang::IllegalArgumentException, uno::RuntimeException) { if (aLayerIds.getLength() != aTimestamps.getLength()) { throw lang::IllegalArgumentException( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "Not enough or too many timestamps")), *this, 0) ; } uno::Sequence > retCode(aLayerIds.getLength()) ; for (sal_Int32 i = 0 ; i < aLayerIds.getLength() ; ++ i) { retCode [i] = getLayer(aLayerIds [i], aTimestamps [i]) ; } return retCode ; } //------------------------------------------------------------------------------ uno::Reference SAL_CALL LocalSingleBackend::getUpdatableLayer(const rtl::OUString& aLayerId) throw (backend::BackendAccessException, lang::IllegalArgumentException, uno::RuntimeException) { return getFileLayer(aLayerId) ; } //------------------------------------------------------------------------------ static const rtl::OUString kSchemaSuffix(RTL_CONSTASCII_USTRINGPARAM(".xcs")) ; static const rtl::OUString kXMLSchemaParser(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.configuration.backend.xml.SchemaParser")) ; uno::Reference SAL_CALL LocalSingleBackend::getComponentSchema(const rtl::OUString& aComponent) throw (backend::BackendAccessException, lang::IllegalArgumentException, uno::RuntimeException) { rtl::OUString subPath = componentToPath(aComponent) ; osl::File * schemaFile = NULL; rtl::OUString errorMessage; bool bInsufficientAccess = false; for (sal_Int32 ix = 0; ix < mSchemaDataUrls.getLength(); ++ix) { rtl::OUStringBuffer schemaUrl(mSchemaDataUrls[ix]) ; schemaUrl.append(subPath).append(kSchemaSuffix) ; rtl::OUString const aFileUrl = schemaUrl.makeStringAndClear(); std::auto_ptr checkFile( new osl::File(aFileUrl) ); osl::File::RC rc = checkFile->open(OpenFlag_Read) ; if (rc == osl::File::E_None) { schemaFile = checkFile.release(); break; } else if (rc != osl::File::E_NOENT) { if (rc == osl::File::E_ACCES) bInsufficientAccess =true; // accumulate error messages rtl::OUStringBuffer sMsg(errorMessage); if (errorMessage.getLength()) sMsg.appendAscii("LocalFile SchemaSupplier - Error accessing schema: "); sMsg.appendAscii("\n- Cannot open input file \""); sMsg.append(aFileUrl); sMsg.appendAscii("\" : "); sMsg.append(FileHelper::createOSLErrorString(rc)); errorMessage = sMsg.makeStringAndClear(); } } if (NULL == schemaFile) { if (errorMessage.getLength() != 0) { // a real error occured io::IOException ioe(errorMessage,*this); rtl::OUStringBuffer sMsg; sMsg.appendAscii("LocalFileLayer - Cannot readData: ").append(errorMessage); if (bInsufficientAccess) throw backend::InsufficientAccessRightsException(sMsg.makeStringAndClear(),*this,uno::makeAny(ioe)); else throw backend::BackendAccessException(sMsg.makeStringAndClear(),*this,uno::makeAny(ioe)); } // simply not found return NULL; } uno::Sequence arguments(1) ; uno::Reference stream( new OSLInputStreamWrapper(schemaFile, true) ); arguments [0] <<= stream ; uno::Reference schema( mFactory->createInstanceWithArguments(kXMLSchemaParser, arguments), uno::UNO_QUERY) ; if (!schema.is()) { throw uno::RuntimeException( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "Cannot instantiate Schema Parser for ")) + aComponent, *this) ; } return schema ; } //------------------------------------------------------------------------------ static inline bool impl_getLayerSubDirectories(rtl::OUString const & aLayerBaseUrl, rtl::OUString& aMainLayerUrl, rtl::OUString& aSubLayerUrl) { if (!isValidFileURL(aLayerBaseUrl)) return false; aMainLayerUrl = aLayerBaseUrl + kDataSubPath ; aSubLayerUrl = aLayerBaseUrl + kLocalisedDataSubPath ; return true; } //------------------------------------------------------------------------------ bool LocalSingleBackend::getLayerSubDirectories(rtl::OUString const & aLayerBaseUrl, rtl::OUString& aMainLayerUrl, rtl::OUString& aSubLayerUrl) { return impl_getLayerSubDirectories(aLayerBaseUrl,aMainLayerUrl,aSubLayerUrl); } //------------------------------------------------------------------------------ bool LocalSingleBackend::getLayerDirectories(sal_Int32 aLayerIndex, rtl::OUString& aLayerUrl, rtl::OUString& aSubLayerUrl) { OSL_ASSERT(isValidEntity(aLayerIndex)); rtl::OUString aLayerBaseUrl = (aLayerIndex == k_UserLayerEntity) ? mUserDataUrl : mDefaultDataUrls [entityToIndex(aLayerIndex)] ; return impl_getLayerSubDirectories(aLayerBaseUrl,aLayerUrl,aSubLayerUrl); } //------------------------------------------------------------------------------ uno::Reference LocalSingleBackend::createSimpleLayer( const uno::Reference& xFactory, rtl::OUString const & aComponentUrl) { SimpleLocalFileLayer * pLayer = new SimpleLocalFileLayer(xFactory, aComponentUrl); return pLayer; } //------------------------------------------------------------------------------ uno::Reference LocalSingleBackend::createSimpleLayer( const uno::Reference& xFactory, rtl::OUString const & aLayerBaseUrl, rtl::OUString const & aComponent) { rtl::OUString aLayerUrl, aSubLayerUrl; if (!impl_getLayerSubDirectories(aLayerBaseUrl,aLayerUrl,aSubLayerUrl)) return NULL; SimpleLocalFileLayer * pLayer = new SimpleLocalFileLayer(xFactory, aLayerUrl, componentToPath(aComponent) + kDataSuffix); return pLayer; } //------------------------------------------------------------------------------ uno::Reference LocalSingleBackend::getFileLayer(const rtl::OUString& aLayerId) throw (lang::IllegalArgumentException) { rtl::OUString fileUrl ; sal_Int32 defaultIndex = resolveLayerId(aLayerId, fileUrl) ; return getFileLayer(fileUrl, defaultIndex) ; } //------------------------------------------------------------------------------ uno::Reference LocalSingleBackend::getFileLayer( const rtl::OUString& aComponent, sal_Int32 aLayerIndex) { rtl::OUString layerPath ; rtl::OUString subLayerPath ; if (!getLayerDirectories(aLayerIndex, layerPath, subLayerPath)) { OSL_ENSURE(aLayerIndex == k_UserLayerEntity, "Unexpected: Invalid non-user layer url"); rtl::OUStringBuffer sMsg; sMsg.appendAscii("LocalSingleBackend: Cannot create file layer - Layer URL '"); sMsg.append(mUserDataUrl).appendAscii("' is invalid."); throw lang::IllegalArgumentException(sMsg.makeStringAndClear(),*this,1); } return createUpdatableLocalFileLayer(mFactory, layerPath, aComponent, subLayerPath) ; } //------------------------------------------------------------------------------ static const sal_Char * const kImplementation = "com.sun.star.comp.configuration.backend.LocalSingleBackend" ; static const sal_Char * const kBackendService = "com.sun.star.configuration.backend.SingleBackend" ; static const sal_Char * const kLocalService = "com.sun.star.configuration.backend.LocalSingleBackend" ; static sal_Char const * kServiceNames [] = { kLocalService, 0, kBackendService, 0 } ; static const ServiceImplementationInfo kServiceInfo = { kImplementation, kServiceNames, kServiceNames + 2 } ; const ServiceRegistrationInfo *getLocalBackendServiceInfo() { return getRegistrationInfo(&kServiceInfo) ; } uno::Reference SAL_CALL instantiateLocalBackend(const uno::Reference< uno::XComponentContext >& xContext) { return *new LocalSingleBackend(xContext) ; } //------------------------------------------------------------------------------ rtl::OUString SAL_CALL LocalSingleBackend::getImplementationName(void) throw (uno::RuntimeException) { return ServiceInfoHelper(&kServiceInfo).getImplementationName() ; } //------------------------------------------------------------------------------ sal_Bool SAL_CALL LocalSingleBackend::supportsService( const rtl::OUString& aServiceName) throw (uno::RuntimeException) { return ServiceInfoHelper(&kServiceInfo).supportsService(aServiceName); } //------------------------------------------------------------------------------ uno::Sequence SAL_CALL LocalSingleBackend::getSupportedServiceNames(void) throw (uno::RuntimeException) { return ServiceInfoHelper(&kServiceInfo).getSupportedServiceNames() ; } // --------------------------------------------------------------------------------------- } } // configmgr.localbe