Update ooo320-m1
[ooovba.git] / configmgr / source / localbe / localhierarchybrowsersvc.cxx
blob65e9bf8bef368429b823346fa80e6f6eba4738ae
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: localhierarchybrowsersvc.cxx,v $
10 * $Revision: 1.12 $
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 "localhierarchybrowsersvc.hxx"
35 #include "localsinglebackend.hxx"
37 #ifndef CONFIGMGR_API_FACTORY_HXX_
38 #include "confapifactory.hxx"
39 #endif
40 #include <com/sun/star/lang/NullPointerException.hpp>
41 #include <rtl/ustrbuf.hxx>
43 #include <algorithm>
44 // -----------------------------------------------------------------------------
46 #define OUSTRING( constascii ) rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(constascii))
47 // -----------------------------------------------------------------------------
49 namespace configmgr
51 // -----------------------------------------------------------------------------
52 namespace localbe
54 // -----------------------------------------------------------------------------
56 sal_Char const * const aLocalHierarchyBrowserServices[] =
58 "com.sun.star.configuration.backend.LocalHierarchyBrowser",
60 "com.sun.star.configuration.backend.HierarchyBrowser",
63 const ServiceImplementationInfo aLocalHierarchyBrowserSI =
65 "com.sun.star.comp.configuration.backend.LocalHierarchyBrowser",
66 aLocalHierarchyBrowserServices,
67 aLocalHierarchyBrowserServices + 3
69 // -----------------------------------------------------------------------------
71 const ServiceRegistrationInfo* getLocalHierarchyBrowserServiceInfo()
72 { return getRegistrationInfo(& aLocalHierarchyBrowserSI); }
73 // -----------------------------------------------------------------------------
75 inline
76 ServiceInfoHelper LocalHierarchyBrowserService::getServiceInfo()
78 return & aLocalHierarchyBrowserSI;
80 // -----------------------------------------------------------------------------
82 uno::Reference< uno::XInterface > SAL_CALL instantiateLocalHierarchyBrowser
83 ( uno::Reference< uno::XComponentContext > const& rServiceManager )
85 return * new LocalHierarchyBrowserService( rServiceManager );
87 // -----------------------------------------------------------------------------
89 LocalHierarchyBrowserService::LocalHierarchyBrowserService(uno::Reference< uno::XComponentContext > const & _xContext)
90 : m_xServiceFactory(_xContext->getServiceManager(), uno::UNO_QUERY)
92 if (!m_xServiceFactory.is())
94 rtl::OUString sMessage( RTL_CONSTASCII_USTRINGPARAM("Configuration Importer: Unexpected NULL context"));
95 throw lang::NullPointerException(sMessage,NULL);
98 // -----------------------------------------------------------------------------
100 LocalHierarchyBrowserService::~LocalHierarchyBrowserService()
102 // -----------------------------------------------------------------------------
104 namespace
106 struct JobDesc
108 explicit JobDesc(task::XJob * pJob, const uno::Sequence< beans::NamedValue >& aArguments);
110 enum Mode { findNone, findSchemas, findLayers };
111 enum Result { getDefault,getUrls, getNames };
113 rtl::OUString aBaseDataUrl;
114 uno::Sequence< rtl::OUString > aExcludeList;
115 Mode mode;
116 Result result_type;
119 JobDesc::JobDesc(task::XJob * pJob, const uno::Sequence< beans::NamedValue >& aArguments)
120 : aBaseDataUrl()
121 , aExcludeList()
122 , mode(findNone)
123 , result_type(getDefault)
125 sal_Int16 const nCount = static_cast<sal_Int16>(aArguments.getLength());
127 if (sal_Int32(nCount) != aArguments.getLength())
129 rtl::OUString sMessage = OUSTRING("Too many arguments for LocalHierarchyBrowser Job");
130 throw lang::IllegalArgumentException(sMessage,pJob,0);
133 for (sal_Int16 i=0; i < nCount; ++i)
135 sal_Bool bKnown = false;
136 sal_Bool bGood = false;
138 if (aArguments[i].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("SchemaDataUrl")))
140 bKnown = true;
141 bGood = (aArguments[i].Value >>= aBaseDataUrl);
142 mode = (bGood && aBaseDataUrl.getLength()) ? findSchemas : findNone;
144 else if (aArguments[i].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("LayerDataUrl")))
146 bKnown = true;
148 rtl::OUString aLayerBaseUrl;
149 bGood = (aArguments[i].Value >>= aLayerBaseUrl);
151 if (aLayerBaseUrl.getLength())
153 rtl::OUString aLocalizedSubDir;
154 LocalSingleBackend::getLayerSubDirectories(aLayerBaseUrl,this->aBaseDataUrl,aLocalizedSubDir);
156 mode = findLayers;
158 else
160 mode = findNone;
163 else if (aArguments[i].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("ExcludeComponents")))
165 bKnown = true;
167 sal_Int32 const nNextIndex = aExcludeList.getLength();
169 switch (aArguments[i].Value.getValueTypeClass())
171 case uno::TypeClass_STRING:
173 rtl::OUString aComponent;
174 bGood = (aArguments[i].Value >>= aComponent);
176 OSL_ASSERT(bGood);
178 aExcludeList.realloc(nNextIndex + 1);
179 aExcludeList[nNextIndex] = aComponent;
181 break;
183 case uno::TypeClass_SEQUENCE:
185 uno::Sequence<rtl::OUString> aComponentList;
186 bGood = (aArguments[i].Value >>= aComponentList);
188 if (bGood)
190 sal_Int32 const nCompListCount = aComponentList.getLength();
191 aExcludeList.realloc(nNextIndex + nCompListCount);
193 rtl::OUString const * pSrc = aComponentList.getConstArray();
194 std::copy(pSrc,pSrc+nCompListCount,aExcludeList.getArray());
197 break;
199 default:
200 OSL_ASSERT(!bGood);
201 break;
204 else if (aArguments[i].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("FetchComponentNames")))
206 sal_Bool bComponents = sal_False;
208 bKnown = true;
209 if (aArguments[i].Value.hasValue())
211 bGood = (aArguments[i].Value >>= bComponents);
212 if (bGood) result_type = bComponents ? getNames : getUrls;
214 else
216 bGood = true;
217 result_type = getDefault;
221 if (!bGood)
223 rtl::OUStringBuffer sMsg;
224 sMsg.appendAscii("LocalHierarchyBrowser - Illegal argument: ");
225 if (bKnown)
226 sMsg.appendAscii("Wrong value type for argument '");
227 else
228 sMsg.appendAscii("Unknown argument '");
230 sMsg.append(aArguments[i].Name).appendAscii("'.");
232 throw lang::IllegalArgumentException(sMsg.makeStringAndClear(),pJob,i+1);
235 if (findNone == mode)
237 rtl::OUStringBuffer sMsg;
238 sMsg.appendAscii("LocalHierarchyBrowser - Missing argument: ");
239 sMsg.appendAscii("No data URL available");
240 throw lang::IllegalArgumentException(sMsg.makeStringAndClear(),pJob,0);
242 if (getDefault == result_type)
243 result_type = (mode == findSchemas) ? getNames : getUrls;
247 static
248 inline
249 rtl::OUString getDataFileExtension(JobDesc::Mode mode)
251 switch (mode)
253 case JobDesc::findSchemas: return OUSTRING(".xcs");
254 case JobDesc::findLayers: return OUSTRING(".xcu");
255 default: OSL_ASSERT(false); return rtl::OUString();
259 // -----------------------------------------------------------------------------
261 // XJob
263 uno::Any SAL_CALL
264 LocalHierarchyBrowserService::execute( const uno::Sequence< beans::NamedValue >& Arguments )
265 throw (lang::IllegalArgumentException, uno::Exception, uno::RuntimeException)
267 JobDesc const aJob(this,Arguments);
269 OSL_ASSERT(JobDesc::getUrls == aJob.result_type || JobDesc::getNames == aJob.result_type);
271 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) ?
272 &LocalHierarchyBrowserService::findLocalComponentUrls :
273 &LocalHierarchyBrowserService::findLocalComponentNames;
275 uno::Sequence< rtl::OUString > aComponents = (this->*find)(aJob.aBaseDataUrl,getDataFileExtension(aJob.mode), aJob.aExcludeList);
277 return uno::makeAny(aComponents);
279 // -----------------------------------------------------------------------------
281 // XServiceInfo
283 rtl::OUString SAL_CALL
284 LocalHierarchyBrowserService::getImplementationName( )
285 throw (uno::RuntimeException)
287 return getServiceInfo().getImplementationName( );
289 // -----------------------------------------------------------------------------
291 sal_Bool SAL_CALL
292 LocalHierarchyBrowserService::supportsService( const rtl::OUString& ServiceName )
293 throw (uno::RuntimeException)
295 return getServiceInfo().supportsService( ServiceName );
297 // -----------------------------------------------------------------------------
300 uno::Sequence< ::rtl::OUString > SAL_CALL
301 LocalHierarchyBrowserService::getSupportedServiceNames( )
302 throw (uno::RuntimeException)
304 return getServiceInfo().getSupportedServiceNames( );
306 // -----------------------------------------------------------------------------
307 // -----------------------------------------------------------------------------
308 } // namespace
310 // -----------------------------------------------------------------------------
311 } // namespace
313 // -----------------------------------------------------------------------------
314 // -----------------------------------------------------------------------------
316 #include "filehelper.hxx"
317 #include <osl/file.hxx>
318 #include "tools/getprocessworkingdir.hxx"
319 #include <vector>
320 // -----------------------------------------------------------------------------
322 namespace uno = com::sun::star::uno;
323 // -----------------------------------------------------------------------------
325 #define OSL_VERIFY_RC( expr ) OSL_VERIFY( (expr) == osl::FileBase::E_None )
326 //------------------------------------------------------------------------------
327 static
328 inline
329 bool matchesExtension( rtl::OUString const & aFileName, rtl::OUString const & aExt )
331 sal_Int32 const nExtStart = aFileName.getLength() - aExt.getLength();
332 return nExtStart > 0 && !!aFileName.copy(nExtStart).equalsIgnoreAsciiCase(aExt);
334 //------------------------------------------------------------------------------
335 static
336 inline
337 rtl::OUString stripExtension( rtl::OUString const & aFileName, rtl::OUString const & aExt )
339 OSL_PRECOND( matchesExtension(aFileName,aExt), "File name doesn't have expected extension");
341 sal_Int32 const nExtStart = aFileName.getLength() - aExt.getLength();
342 return aFileName.copy(0,nExtStart);
344 //------------------------------------------------------------------------------
345 static
346 inline
347 bool matchesExtension( osl::FileStatus const & aFileDescriptor, rtl::OUString const & aExt )
349 OSL_PRECOND( aFileDescriptor.isValid(FileStatusMask_Type | FileStatusMask_FileName),
350 "Not all required file-status fields available for filter" );
352 if (aFileDescriptor.getFileType() != osl::FileStatus::Regular)
353 return false;
355 return matchesExtension(aFileDescriptor.getFileName(),aExt);
357 //------------------------------------------------------------------------------
359 static
360 bool makeAbsoluteURL(rtl::OUString & rURL )
362 rtl::OUString aBaseDir; tools::getProcessWorkingDir(&aBaseDir);
364 osl::File::RC errcode = osl::File::getAbsoluteFileURL(aBaseDir,rURL,rURL);
366 return osl::File::E_None == errcode;
368 //------------------------------------------------------------------------------
369 static
370 inline
371 bool getNextDirectoryItem(osl::Directory & aDirectory, osl::DirectoryItem & aItem, osl::Directory::RC & errcode)
373 switch (errcode = aDirectory.getNextItem(aItem))
375 case osl::Directory::E_None:
376 return true;
378 case osl::Directory::E_NOENT:
379 errcode = osl::Directory::E_None;
380 return false;
382 default:
383 return false;
386 //------------------------------------------------------------------------------
387 static inline bool isExcluded(rtl::OUString const & aName, uno::Sequence< rtl::OUString > const & aExcludeList)
389 for (sal_Int32 i = 0; i<aExcludeList.getLength(); ++i)
391 if (aExcludeList[i].equals(aName)) return true;
393 return false;
395 //------------------------------------------------------------------------------
396 static
397 osl::FileBase::RC findComponents( std::vector<rtl::OUString> * componentNames, std::vector<rtl::OUString> * componentUrls,
398 rtl::OUString const& aDirectoryPath, rtl::OUString const& aComponentExtension,
399 rtl::OUString const& aPackagePrefix, rtl::OUString const & aComponentSeparator,
400 uno::Sequence< rtl::OUString > const & aExcludeList)
402 static sal_Unicode const chDirSep = '/';
403 static rtl::OUString const sDirectorySeparator(&chDirSep,1);
405 osl::Directory aDirectory(aDirectoryPath);
407 osl::Directory::RC errcode = aDirectory.open();
409 if (errcode == osl::Directory::E_None)
411 sal_uInt32 n_STATUS_FIELDS = FileStatusMask_Type | FileStatusMask_FileName;
412 if (componentUrls) n_STATUS_FIELDS |= FileStatusMask_FileURL;
414 osl::DirectoryItem aItem;
415 while( getNextDirectoryItem(aDirectory,aItem,errcode) )
418 osl::FileStatus aItemDescriptor( n_STATUS_FIELDS );
419 errcode = aItem.getFileStatus(aItemDescriptor);
421 if ( errcode != osl::DirectoryItem::E_None )
423 OSL_TRACE("Locating Configuration Components - Error (%u) getting status of directory item - skipping\n", unsigned(errcode));
424 continue;
427 OSL_ENSURE( aItemDescriptor.isValid(FileStatusMask_Type), "Could not get type of directory item");
429 if (aItemDescriptor.getFileType() == osl::FileStatus::Directory)
431 OSL_ENSURE( aItemDescriptor.isValid(FileStatusMask_FileName), "Could not get name of subdirectory");
433 rtl::OUString const aSubdirName = aItemDescriptor.getFileName();
434 rtl::OUString const aSubdirPath = aDirectoryPath + sDirectorySeparator + aSubdirName;
435 rtl::OUString const aSubpackagePrefix = aPackagePrefix + aSubdirName + aComponentSeparator;
436 // recurse
437 if (!isExcluded(aSubpackagePrefix,aExcludeList))
438 OSL_VERIFY_RC( findComponents( componentNames, componentUrls,
439 aSubdirPath, aComponentExtension,
440 aSubpackagePrefix, aComponentSeparator,
441 aExcludeList) );
443 else if (matchesExtension(aItemDescriptor,aComponentExtension))
445 OSL_ENSURE( aItemDescriptor.isValid(FileStatusMask_FileName), "Could not get name of component found");
447 rtl::OUString const aComponentName = stripExtension( aItemDescriptor.getFileName(), aComponentExtension );
448 rtl::OUString const aFullComponentName = aPackagePrefix + aComponentName;
450 if (!isExcluded(aFullComponentName,aExcludeList))
452 if (componentNames)
454 componentNames->push_back(aFullComponentName);
457 if (componentUrls)
459 OSL_ENSURE( aItemDescriptor.isValid(FileStatusMask_FileURL), "Could not get URL of component found");
461 componentUrls->push_back(aItemDescriptor.getFileURL());
466 aDirectory.close();
468 return errcode;
470 // -----------------------------------------------------------------------------
472 uno::Sequence< rtl::OUString > configmgr::localbe::LocalHierarchyBrowserService::findLocalComponentNames( rtl::OUString const & _aBaseDirectory, rtl::OUString const & _aComponentFileExtension, uno::Sequence< rtl::OUString > const & aExcludeList)
474 rtl::OUString aBaseDirectory(_aBaseDirectory);
475 OSL_VERIFY( makeAbsoluteURL(aBaseDirectory) );
477 static const sal_Unicode chPkgSep = '.';
479 std::vector< rtl::OUString > components;
481 osl::Directory::RC errcode = findComponents(&components, NULL,
482 aBaseDirectory, _aComponentFileExtension,
483 rtl::OUString(), rtl::OUString(&chPkgSep,1),
484 aExcludeList );
486 if (errcode != osl::Directory::E_None)
488 OSL_TRACE("Locating Configuration Components failed - Error (%u) trying to locate files\n", unsigned(errcode));
490 if (errcode != osl::Directory::E_NOENT)
492 rtl::OUString sMsg = OUSTRING("LocalHierarchyBrowser - IO Error while scanning for components: ") +
493 FileHelper::createOSLErrorString(errcode);
495 throw com::sun::star::io::IOException(sMsg,*this);
499 return uno::Sequence< rtl::OUString >(&components.front(),components.size());
501 // -----------------------------------------------------------------------------
503 uno::Sequence< rtl::OUString > configmgr::localbe::LocalHierarchyBrowserService::findLocalComponentUrls( rtl::OUString const & _aBaseDirectory, rtl::OUString const & _aComponentFileExtension, uno::Sequence< rtl::OUString > const & aExcludeList)
505 rtl::OUString aBaseDirectory(_aBaseDirectory);
506 OSL_VERIFY( makeAbsoluteURL(aBaseDirectory) );
508 static const sal_Unicode chPkgSep = '.';
510 std::vector< rtl::OUString > components;
512 osl::Directory::RC errcode = findComponents(NULL, &components,
513 aBaseDirectory, _aComponentFileExtension,
514 rtl::OUString(), rtl::OUString(&chPkgSep,1),
515 aExcludeList );
517 if (errcode != osl::Directory::E_None)
519 OSL_TRACE("Locating Configuration Components failed - Error (%u) trying to locate files\n", unsigned(errcode));
521 if (errcode != osl::Directory::E_NOENT)
523 rtl::OUString sMsg = OUSTRING("LocalHierarchyBrowser - IO Error while scanning for component files: ") +
524 FileHelper::createOSLErrorString(errcode);
526 throw com::sun::star::io::IOException(sMsg,*this);
530 return uno::Sequence< rtl::OUString >(&components.front(),components.size());
532 //------------------------------------------------------------------------------
534 // -----------------------------------------------------------------------------
535 // -----------------------------------------------------------------------------