536 lines
21 KiB
C++
536 lines
21 KiB
C++
/*************************************************************************
|
|
*
|
|
* 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());
|
|
}
|
|
//------------------------------------------------------------------------------
|
|
|
|
// -----------------------------------------------------------------------------
|
|
// -----------------------------------------------------------------------------
|
|
|