diff options
Diffstat (limited to 'configmgr/source/localbe/localhierarchybrowsersvc.cxx')
-rw-r--r-- | configmgr/source/localbe/localhierarchybrowsersvc.cxx | 536 |
1 files changed, 536 insertions, 0 deletions
diff --git a/configmgr/source/localbe/localhierarchybrowsersvc.cxx b/configmgr/source/localbe/localhierarchybrowsersvc.cxx new file mode 100644 index 000000000000..2a6196e87fd5 --- /dev/null +++ b/configmgr/source/localbe/localhierarchybrowsersvc.cxx @@ -0,0 +1,536 @@ +/************************************************************************* + * + * 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: localhierarchybrowsersvc.cxx,v $ + * $Revision: 1.12 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_configmgr.hxx" + +#include "localhierarchybrowsersvc.hxx" +#include "localsinglebackend.hxx" + +#ifndef CONFIGMGR_API_FACTORY_HXX_ +#include "confapifactory.hxx" +#endif +#include <com/sun/star/lang/NullPointerException.hpp> +#include <rtl/ustrbuf.hxx> + +#include <algorithm> +// ----------------------------------------------------------------------------- + +#define OUSTRING( constascii ) rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(constascii)) +// ----------------------------------------------------------------------------- + +namespace configmgr +{ +// ----------------------------------------------------------------------------- + namespace localbe + { +// ----------------------------------------------------------------------------- + +sal_Char const * const aLocalHierarchyBrowserServices[] = +{ + "com.sun.star.configuration.backend.LocalHierarchyBrowser", + 0, + "com.sun.star.configuration.backend.HierarchyBrowser", + 0 +}; +const ServiceImplementationInfo aLocalHierarchyBrowserSI = +{ + "com.sun.star.comp.configuration.backend.LocalHierarchyBrowser", + aLocalHierarchyBrowserServices, + aLocalHierarchyBrowserServices + 3 +}; +// ----------------------------------------------------------------------------- + +const ServiceRegistrationInfo* getLocalHierarchyBrowserServiceInfo() +{ return getRegistrationInfo(& aLocalHierarchyBrowserSI); } +// ----------------------------------------------------------------------------- + +inline +ServiceInfoHelper LocalHierarchyBrowserService::getServiceInfo() +{ + return & aLocalHierarchyBrowserSI; +} +// ----------------------------------------------------------------------------- + +uno::Reference< uno::XInterface > SAL_CALL instantiateLocalHierarchyBrowser +( uno::Reference< uno::XComponentContext > const& rServiceManager ) +{ + return * new LocalHierarchyBrowserService( rServiceManager ); +} +// ----------------------------------------------------------------------------- + +LocalHierarchyBrowserService::LocalHierarchyBrowserService(uno::Reference< uno::XComponentContext > const & _xContext) +: m_xServiceFactory(_xContext->getServiceManager(), uno::UNO_QUERY) +{ + if (!m_xServiceFactory.is()) + { + rtl::OUString sMessage( RTL_CONSTASCII_USTRINGPARAM("Configuration Importer: Unexpected NULL context")); + throw lang::NullPointerException(sMessage,NULL); + } +} +// ----------------------------------------------------------------------------- + +LocalHierarchyBrowserService::~LocalHierarchyBrowserService() +{} +// ----------------------------------------------------------------------------- + +namespace +{ + struct JobDesc + { + explicit JobDesc(task::XJob * pJob, const uno::Sequence< beans::NamedValue >& aArguments); + + enum Mode { findNone, findSchemas, findLayers }; + enum Result { getDefault,getUrls, getNames }; + + rtl::OUString aBaseDataUrl; + uno::Sequence< rtl::OUString > aExcludeList; + Mode mode; + Result result_type; + }; + + JobDesc::JobDesc(task::XJob * pJob, const uno::Sequence< beans::NamedValue >& aArguments) + : aBaseDataUrl() + , aExcludeList() + , mode(findNone) + , result_type(getDefault) + { + sal_Int16 const nCount = static_cast<sal_Int16>(aArguments.getLength()); + + if (sal_Int32(nCount) != aArguments.getLength()) + { + rtl::OUString sMessage = OUSTRING("Too many arguments for LocalHierarchyBrowser Job"); + throw lang::IllegalArgumentException(sMessage,pJob,0); + } + + for (sal_Int16 i=0; i < nCount; ++i) + { + sal_Bool bKnown = false; + sal_Bool bGood = false; + + if (aArguments[i].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("SchemaDataUrl"))) + { + bKnown = true; + bGood = (aArguments[i].Value >>= aBaseDataUrl); + mode = (bGood && aBaseDataUrl.getLength()) ? findSchemas : findNone; + } + else if (aArguments[i].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("LayerDataUrl"))) + { + bKnown = true; + + rtl::OUString aLayerBaseUrl; + bGood = (aArguments[i].Value >>= aLayerBaseUrl); + + if (aLayerBaseUrl.getLength()) + { + rtl::OUString aLocalizedSubDir; + LocalSingleBackend::getLayerSubDirectories(aLayerBaseUrl,this->aBaseDataUrl,aLocalizedSubDir); + + mode = findLayers; + } + else + { + mode = findNone; + } + } + else if (aArguments[i].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("ExcludeComponents"))) + { + bKnown = true; + + sal_Int32 const nNextIndex = aExcludeList.getLength(); + + switch (aArguments[i].Value.getValueTypeClass()) + { + case uno::TypeClass_STRING: + { + rtl::OUString aComponent; + bGood = (aArguments[i].Value >>= aComponent); + + OSL_ASSERT(bGood); + + aExcludeList.realloc(nNextIndex + 1); + aExcludeList[nNextIndex] = aComponent; + } + break; + + case uno::TypeClass_SEQUENCE: + { + uno::Sequence<rtl::OUString> aComponentList; + bGood = (aArguments[i].Value >>= aComponentList); + + if (bGood) + { + sal_Int32 const nCompListCount = aComponentList.getLength(); + aExcludeList.realloc(nNextIndex + nCompListCount); + + rtl::OUString const * pSrc = aComponentList.getConstArray(); + std::copy(pSrc,pSrc+nCompListCount,aExcludeList.getArray()); + } + } + break; + + default: + OSL_ASSERT(!bGood); + break; + } + } + else if (aArguments[i].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("FetchComponentNames"))) + { + sal_Bool bComponents = sal_False; + + bKnown = true; + if (aArguments[i].Value.hasValue()) + { + bGood = (aArguments[i].Value >>= bComponents); + if (bGood) result_type = bComponents ? getNames : getUrls; + } + else + { + bGood = true; + result_type = getDefault; + } + } + + if (!bGood) + { + rtl::OUStringBuffer sMsg; + sMsg.appendAscii("LocalHierarchyBrowser - Illegal argument: "); + if (bKnown) + sMsg.appendAscii("Wrong value type for argument '"); + else + sMsg.appendAscii("Unknown argument '"); + + sMsg.append(aArguments[i].Name).appendAscii("'."); + + throw lang::IllegalArgumentException(sMsg.makeStringAndClear(),pJob,i+1); + } + } + if (findNone == mode) + { + rtl::OUStringBuffer sMsg; + sMsg.appendAscii("LocalHierarchyBrowser - Missing argument: "); + sMsg.appendAscii("No data URL available"); + throw lang::IllegalArgumentException(sMsg.makeStringAndClear(),pJob,0); + } + if (getDefault == result_type) + result_type = (mode == findSchemas) ? getNames : getUrls; + + } + + static + inline + rtl::OUString getDataFileExtension(JobDesc::Mode mode) + { + switch (mode) + { + case JobDesc::findSchemas: return OUSTRING(".xcs"); + case JobDesc::findLayers: return OUSTRING(".xcu"); + default: OSL_ASSERT(false); return rtl::OUString(); + } + } +} +// ----------------------------------------------------------------------------- + +// XJob + +uno::Any SAL_CALL + LocalHierarchyBrowserService::execute( const uno::Sequence< beans::NamedValue >& Arguments ) + throw (lang::IllegalArgumentException, uno::Exception, uno::RuntimeException) +{ + JobDesc const aJob(this,Arguments); + + OSL_ASSERT(JobDesc::getUrls == aJob.result_type || JobDesc::getNames == aJob.result_type); + + uno::Sequence< rtl::OUString > (LocalHierarchyBrowserService::* const find)( rtl::OUString const & _aBaseDirectory, rtl::OUString const & _aComponentFileExtension, uno::Sequence< rtl::OUString > const & aExcludeList) = (JobDesc::getUrls == aJob.result_type) ? + &LocalHierarchyBrowserService::findLocalComponentUrls : + &LocalHierarchyBrowserService::findLocalComponentNames; + + uno::Sequence< rtl::OUString > aComponents = (this->*find)(aJob.aBaseDataUrl,getDataFileExtension(aJob.mode), aJob.aExcludeList); + + return uno::makeAny(aComponents); +} +// ----------------------------------------------------------------------------- + +// XServiceInfo + +rtl::OUString SAL_CALL + LocalHierarchyBrowserService::getImplementationName( ) + throw (uno::RuntimeException) +{ + return getServiceInfo().getImplementationName( ); +} +// ----------------------------------------------------------------------------- + +sal_Bool SAL_CALL + LocalHierarchyBrowserService::supportsService( const rtl::OUString& ServiceName ) + throw (uno::RuntimeException) +{ + return getServiceInfo().supportsService( ServiceName ); +} +// ----------------------------------------------------------------------------- + + +uno::Sequence< ::rtl::OUString > SAL_CALL + LocalHierarchyBrowserService::getSupportedServiceNames( ) + throw (uno::RuntimeException) +{ + return getServiceInfo().getSupportedServiceNames( ); +} +// ----------------------------------------------------------------------------- +// ----------------------------------------------------------------------------- + } // namespace + +// ----------------------------------------------------------------------------- +} // namespace + +// ----------------------------------------------------------------------------- +// ----------------------------------------------------------------------------- + +#include "filehelper.hxx" +#include <osl/file.hxx> +#include "tools/getprocessworkingdir.hxx" +#include <vector> +// ----------------------------------------------------------------------------- + + namespace uno = com::sun::star::uno; + // ----------------------------------------------------------------------------- + + #define OSL_VERIFY_RC( expr ) OSL_VERIFY( (expr) == osl::FileBase::E_None ) + //------------------------------------------------------------------------------ + static + inline + bool matchesExtension( rtl::OUString const & aFileName, rtl::OUString const & aExt ) + { + sal_Int32 const nExtStart = aFileName.getLength() - aExt.getLength(); + return nExtStart > 0 && !!aFileName.copy(nExtStart).equalsIgnoreAsciiCase(aExt); + } + //------------------------------------------------------------------------------ + static + inline + rtl::OUString stripExtension( rtl::OUString const & aFileName, rtl::OUString const & aExt ) + { + OSL_PRECOND( matchesExtension(aFileName,aExt), "File name doesn't have expected extension"); + + sal_Int32 const nExtStart = aFileName.getLength() - aExt.getLength(); + return aFileName.copy(0,nExtStart); + } +//------------------------------------------------------------------------------ + static + inline + bool matchesExtension( osl::FileStatus const & aFileDescriptor, rtl::OUString const & aExt ) + { + OSL_PRECOND( aFileDescriptor.isValid(FileStatusMask_Type | FileStatusMask_FileName), + "Not all required file-status fields available for filter" ); + + if (aFileDescriptor.getFileType() != osl::FileStatus::Regular) + return false; + + return matchesExtension(aFileDescriptor.getFileName(),aExt); + } +//------------------------------------------------------------------------------ + + static + bool makeAbsoluteURL(rtl::OUString & rURL ) + { + rtl::OUString aBaseDir; tools::getProcessWorkingDir(&aBaseDir); + + osl::File::RC errcode = osl::File::getAbsoluteFileURL(aBaseDir,rURL,rURL); + + return osl::File::E_None == errcode; + } +//------------------------------------------------------------------------------ + static + inline + bool getNextDirectoryItem(osl::Directory & aDirectory, osl::DirectoryItem & aItem, osl::Directory::RC & errcode) + { + switch (errcode = aDirectory.getNextItem(aItem)) + { + case osl::Directory::E_None: + return true; + + case osl::Directory::E_NOENT: + errcode = osl::Directory::E_None; + return false; + + default: + return false; + } + } +//------------------------------------------------------------------------------ + static inline bool isExcluded(rtl::OUString const & aName, uno::Sequence< rtl::OUString > const & aExcludeList) + { + for (sal_Int32 i = 0; i<aExcludeList.getLength(); ++i) + { + if (aExcludeList[i].equals(aName)) return true; + } + return false; + } +//------------------------------------------------------------------------------ + static + osl::FileBase::RC findComponents( std::vector<rtl::OUString> * componentNames, std::vector<rtl::OUString> * componentUrls, + rtl::OUString const& aDirectoryPath, rtl::OUString const& aComponentExtension, + rtl::OUString const& aPackagePrefix, rtl::OUString const & aComponentSeparator, + uno::Sequence< rtl::OUString > const & aExcludeList) + { + static sal_Unicode const chDirSep = '/'; + static rtl::OUString const sDirectorySeparator(&chDirSep,1); + + osl::Directory aDirectory(aDirectoryPath); + + osl::Directory::RC errcode = aDirectory.open(); + + if (errcode == osl::Directory::E_None) + { + sal_uInt32 n_STATUS_FIELDS = FileStatusMask_Type | FileStatusMask_FileName; + if (componentUrls) n_STATUS_FIELDS |= FileStatusMask_FileURL; + + osl::DirectoryItem aItem; + while( getNextDirectoryItem(aDirectory,aItem,errcode) ) + { + + osl::FileStatus aItemDescriptor( n_STATUS_FIELDS ); + errcode = aItem.getFileStatus(aItemDescriptor); + + if ( errcode != osl::DirectoryItem::E_None ) + { + OSL_TRACE("Locating Configuration Components - Error (%u) getting status of directory item - skipping\n", unsigned(errcode)); + continue; + } + + OSL_ENSURE( aItemDescriptor.isValid(FileStatusMask_Type), "Could not get type of directory item"); + + if (aItemDescriptor.getFileType() == osl::FileStatus::Directory) + { + OSL_ENSURE( aItemDescriptor.isValid(FileStatusMask_FileName), "Could not get name of subdirectory"); + + rtl::OUString const aSubdirName = aItemDescriptor.getFileName(); + rtl::OUString const aSubdirPath = aDirectoryPath + sDirectorySeparator + aSubdirName; + rtl::OUString const aSubpackagePrefix = aPackagePrefix + aSubdirName + aComponentSeparator; + // recurse + if (!isExcluded(aSubpackagePrefix,aExcludeList)) + OSL_VERIFY_RC( findComponents( componentNames, componentUrls, + aSubdirPath, aComponentExtension, + aSubpackagePrefix, aComponentSeparator, + aExcludeList) ); + } + else if (matchesExtension(aItemDescriptor,aComponentExtension)) + { + OSL_ENSURE( aItemDescriptor.isValid(FileStatusMask_FileName), "Could not get name of component found"); + + rtl::OUString const aComponentName = stripExtension( aItemDescriptor.getFileName(), aComponentExtension ); + rtl::OUString const aFullComponentName = aPackagePrefix + aComponentName; + + if (!isExcluded(aFullComponentName,aExcludeList)) + { + if (componentNames) + { + componentNames->push_back(aFullComponentName); + } + + if (componentUrls) + { + OSL_ENSURE( aItemDescriptor.isValid(FileStatusMask_FileURL), "Could not get URL of component found"); + + componentUrls->push_back(aItemDescriptor.getFileURL()); + } + } + } + } + aDirectory.close(); + } + return errcode; + } +// ----------------------------------------------------------------------------- + + uno::Sequence< rtl::OUString > configmgr::localbe::LocalHierarchyBrowserService::findLocalComponentNames( rtl::OUString const & _aBaseDirectory, rtl::OUString const & _aComponentFileExtension, uno::Sequence< rtl::OUString > const & aExcludeList) + { + rtl::OUString aBaseDirectory(_aBaseDirectory); + OSL_VERIFY( makeAbsoluteURL(aBaseDirectory) ); + + static const sal_Unicode chPkgSep = '.'; + + std::vector< rtl::OUString > components; + + osl::Directory::RC errcode = findComponents(&components, NULL, + aBaseDirectory, _aComponentFileExtension, + rtl::OUString(), rtl::OUString(&chPkgSep,1), + aExcludeList ); + + if (errcode != osl::Directory::E_None) + { + OSL_TRACE("Locating Configuration Components failed - Error (%u) trying to locate files\n", unsigned(errcode)); + + if (errcode != osl::Directory::E_NOENT) + { + rtl::OUString sMsg = OUSTRING("LocalHierarchyBrowser - IO Error while scanning for components: ") + + FileHelper::createOSLErrorString(errcode); + + throw com::sun::star::io::IOException(sMsg,*this); + } + } + + return uno::Sequence< rtl::OUString >(&components.front(),components.size()); + } +// ----------------------------------------------------------------------------- + + uno::Sequence< rtl::OUString > configmgr::localbe::LocalHierarchyBrowserService::findLocalComponentUrls( rtl::OUString const & _aBaseDirectory, rtl::OUString const & _aComponentFileExtension, uno::Sequence< rtl::OUString > const & aExcludeList) + { + rtl::OUString aBaseDirectory(_aBaseDirectory); + OSL_VERIFY( makeAbsoluteURL(aBaseDirectory) ); + + static const sal_Unicode chPkgSep = '.'; + + std::vector< rtl::OUString > components; + + osl::Directory::RC errcode = findComponents(NULL, &components, + aBaseDirectory, _aComponentFileExtension, + rtl::OUString(), rtl::OUString(&chPkgSep,1), + aExcludeList ); + + if (errcode != osl::Directory::E_None) + { + OSL_TRACE("Locating Configuration Components failed - Error (%u) trying to locate files\n", unsigned(errcode)); + + if (errcode != osl::Directory::E_NOENT) + { + rtl::OUString sMsg = OUSTRING("LocalHierarchyBrowser - IO Error while scanning for component files: ") + + FileHelper::createOSLErrorString(errcode); + + throw com::sun::star::io::IOException(sMsg,*this); + } + } + + return uno::Sequence< rtl::OUString >(&components.front(),components.size()); + } +//------------------------------------------------------------------------------ + +// ----------------------------------------------------------------------------- +// ----------------------------------------------------------------------------- + |