1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: localhierarchybrowsersvc.cxx,v $
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"
40 #include <com/sun/star/lang/NullPointerException.hpp>
41 #include <rtl/ustrbuf.hxx>
44 // -----------------------------------------------------------------------------
46 #define OUSTRING( constascii ) rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(constascii))
47 // -----------------------------------------------------------------------------
51 // -----------------------------------------------------------------------------
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 // -----------------------------------------------------------------------------
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 // -----------------------------------------------------------------------------
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
;
119 JobDesc::JobDesc(task::XJob
* pJob
, const uno::Sequence
< beans::NamedValue
>& aArguments
)
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")))
141 bGood
= (aArguments
[i
].Value
>>= aBaseDataUrl
);
142 mode
= (bGood
&& aBaseDataUrl
.getLength()) ? findSchemas
: findNone
;
144 else if (aArguments
[i
].Name
.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("LayerDataUrl")))
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
);
163 else if (aArguments
[i
].Name
.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("ExcludeComponents")))
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
);
178 aExcludeList
.realloc(nNextIndex
+ 1);
179 aExcludeList
[nNextIndex
] = aComponent
;
183 case uno::TypeClass_SEQUENCE
:
185 uno::Sequence
<rtl::OUString
> aComponentList
;
186 bGood
= (aArguments
[i
].Value
>>= aComponentList
);
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());
204 else if (aArguments
[i
].Name
.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("FetchComponentNames")))
206 sal_Bool bComponents
= sal_False
;
209 if (aArguments
[i
].Value
.hasValue())
211 bGood
= (aArguments
[i
].Value
>>= bComponents
);
212 if (bGood
) result_type
= bComponents
? getNames
: getUrls
;
217 result_type
= getDefault
;
223 rtl::OUStringBuffer sMsg
;
224 sMsg
.appendAscii("LocalHierarchyBrowser - Illegal argument: ");
226 sMsg
.appendAscii("Wrong value type for argument '");
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
;
249 rtl::OUString
getDataFileExtension(JobDesc::Mode mode
)
253 case JobDesc::findSchemas
: return OUSTRING(".xcs");
254 case JobDesc::findLayers
: return OUSTRING(".xcu");
255 default: OSL_ASSERT(false); return rtl::OUString();
259 // -----------------------------------------------------------------------------
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 // -----------------------------------------------------------------------------
283 rtl::OUString SAL_CALL
284 LocalHierarchyBrowserService::getImplementationName( )
285 throw (uno::RuntimeException
)
287 return getServiceInfo().getImplementationName( );
289 // -----------------------------------------------------------------------------
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 // -----------------------------------------------------------------------------
310 // -----------------------------------------------------------------------------
313 // -----------------------------------------------------------------------------
314 // -----------------------------------------------------------------------------
316 #include "filehelper.hxx"
317 #include <osl/file.hxx>
318 #include "tools/getprocessworkingdir.hxx"
320 // -----------------------------------------------------------------------------
322 namespace uno
= com::sun::star::uno
;
323 // -----------------------------------------------------------------------------
325 #define OSL_VERIFY_RC( expr ) OSL_VERIFY( (expr) == osl::FileBase::E_None )
326 //------------------------------------------------------------------------------
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 //------------------------------------------------------------------------------
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 //------------------------------------------------------------------------------
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
)
355 return matchesExtension(aFileDescriptor
.getFileName(),aExt
);
357 //------------------------------------------------------------------------------
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 //------------------------------------------------------------------------------
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
:
378 case osl::Directory::E_NOENT
:
379 errcode
= osl::Directory::E_None
;
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;
395 //------------------------------------------------------------------------------
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
));
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
;
437 if (!isExcluded(aSubpackagePrefix
,aExcludeList
))
438 OSL_VERIFY_RC( findComponents( componentNames
, componentUrls
,
439 aSubdirPath
, aComponentExtension
,
440 aSubpackagePrefix
, aComponentSeparator
,
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
))
454 componentNames
->push_back(aFullComponentName
);
459 OSL_ENSURE( aItemDescriptor
.isValid(FileStatusMask_FileURL
), "Could not get URL of component found");
461 componentUrls
->push_back(aItemDescriptor
.getFileURL());
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),
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),
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 // -----------------------------------------------------------------------------