1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 /**************************************************************************
23 **************************************************************************
25 - HierarchyEntry::move
26 --> Rewrite to use XNamed ( once this is supported by config db api ).
28 *************************************************************************/
29 #include "hierarchydata.hxx"
32 #include <osl/diagnose.h>
33 #include <rtl/ustrbuf.hxx>
34 #include <com/sun/star/beans/PropertyValue.hpp>
35 #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
36 #include <com/sun/star/container/XNameContainer.hpp>
37 #include <com/sun/star/container/XNameReplace.hpp>
38 #include <com/sun/star/util/XChangesBatch.hpp>
39 #include <com/sun/star/util/XOfficeInstallationDirectories.hpp>
40 #include "hierarchyprovider.hxx"
41 #include "hierarchyuri.hxx"
43 using namespace com::sun::star
;
45 namespace hierarchy_ucp
49 struct HierarchyEntry::iterator_Impl
51 HierarchyEntryData entry
;
52 uno::Reference
< container::XHierarchicalNameAccess
> dir
;
53 uno::Reference
< util::XOfficeInstallationDirectories
> officeDirs
;
54 uno::Sequence
< OUString
> names
;
57 : officeDirs( 0 ), pos( -1 /* before first */ ) {};
61 void makeXMLName( const OUString
& rIn
, OUStringBuffer
& rBuffer
)
63 sal_Int32 nCount
= rIn
.getLength();
64 for ( sal_Int32 n
= 0; n
< nCount
; ++n
)
66 const sal_Unicode c
= rIn
[ n
];
70 rBuffer
.appendAscii( "&" );
74 rBuffer
.appendAscii( """ );
78 rBuffer
.appendAscii( "'" );
82 rBuffer
.appendAscii( "<" );
86 rBuffer
.appendAscii( ">" );
99 // HierarchyEntry Implementation.
104 #define READ_SERVICE_NAME "com.sun.star.ucb.HierarchyDataReadAccess"
105 #define READWRITE_SERVICE_NAME "com.sun.star.ucb.HierarchyDataReadWriteAccess"
107 // describe path of cfg entry
108 #define CFGPROPERTY_NODEPATH "nodepath"
111 HierarchyEntry::HierarchyEntry(
112 const uno::Reference
< uno::XComponentContext
>& rxContext
,
113 HierarchyContentProvider
* pProvider
,
114 const OUString
& rURL
)
115 : m_xContext( rxContext
),
116 m_xOfficeInstDirs( pProvider
->getOfficeInstallationDirectories() ),
117 m_bTriedToGetRootReadAccess( false )
119 HierarchyUri
aUri( rURL
);
120 m_aServiceSpecifier
= aUri
.getService();
123 = pProvider
->getConfigProvider( m_aServiceSpecifier
);
125 = pProvider
->getRootConfigReadNameAccess( m_aServiceSpecifier
);
127 // Note: do not init m_aPath in init list. createPathFromHierarchyURL
128 // needs m_xContext and m_aMutex.
129 m_aPath
= createPathFromHierarchyURL( aUri
);
131 // Extract language independent name from URL.
132 sal_Int32 nPos
= rURL
.lastIndexOf( '/' );
133 if ( nPos
> HIERARCHY_URL_SCHEME_LENGTH
)
134 m_aName
= rURL
.copy( nPos
+ 1 );
136 OSL_FAIL( "HierarchyEntry - Invalid URL!" );
140 bool HierarchyEntry::hasData()
142 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
143 uno::Reference
< container::XHierarchicalNameAccess
> xRootReadAccess
144 = getRootReadAccess();
146 OSL_ENSURE( xRootReadAccess
.is(), "HierarchyEntry::hasData - No root!" );
148 if ( xRootReadAccess
.is() )
149 return xRootReadAccess
->hasByHierarchicalName( m_aPath
);
155 bool HierarchyEntry::getData( HierarchyEntryData
& rData
)
159 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
161 uno::Reference
< container::XHierarchicalNameAccess
> xRootReadAccess
162 = getRootReadAccess();
164 OSL_ENSURE( xRootReadAccess
.is(),
165 "HierarchyEntry::getData - No root!" );
167 if ( xRootReadAccess
.is() )
169 OUString aTitlePath
= m_aPath
;
170 aTitlePath
+= "/Title";
172 // Note: Avoid NoSuchElementExceptions, because exceptions are
173 // relatively 'expensive'. Checking for availability of
174 // title value is sufficient here, because if it is
175 // there, the other values will be available too.
176 if ( !xRootReadAccess
->hasByHierarchicalName( aTitlePath
) )
182 if ( !( xRootReadAccess
->getByHierarchicalName( aTitlePath
)
185 OSL_FAIL( "HierarchyEntry::getData - "
186 "Got no Title value!" );
190 rData
.setTitle( aValue
);
192 // Get TargetURL value.
193 OUString aTargetURLPath
= m_aPath
;
194 aTargetURLPath
+= "/TargetURL";
195 if ( !( xRootReadAccess
->getByHierarchicalName( aTargetURLPath
)
198 OSL_FAIL( "HierarchyEntry::getData - "
199 "Got no TargetURL value!" );
203 // TargetURL property may contain a reference to the Office
204 // installation directory. To ensure a reloctable office
205 // installation, the path to the office installtion directory must
206 // never be stored directly. A placeholder is used instead. Replace
207 // it by actual installation directory.
208 if ( m_xOfficeInstDirs
.is() && !aValue
.isEmpty() )
209 aValue
= m_xOfficeInstDirs
->makeAbsoluteURL( aValue
);
210 rData
.setTargetURL( aValue
);
212 OUString aTypePath
= m_aPath
;
213 aTypePath
+= "/Type";
214 if ( xRootReadAccess
->hasByHierarchicalName( aTypePath
) )
216 // Might not be present since it was introduced long after
217 // Title and TargetURL (#82433#)... So not getting it is
222 if ( xRootReadAccess
->getByHierarchicalName( aTypePath
)
227 rData
.setType( HierarchyEntryData::LINK
);
229 else if ( nType
== 1 )
231 rData
.setType( HierarchyEntryData::FOLDER
);
235 OSL_FAIL( "HierarchyEntry::getData - "
236 "Unknown Type value!" );
242 rData
.setName( m_aName
);
246 catch ( uno::RuntimeException
const & )
250 catch ( container::NoSuchElementException
const & )
252 // getByHierarchicalName
254 OSL_FAIL( "HierarchyEntry::getData - caught NoSuchElementException!" );
260 bool HierarchyEntry::setData(
261 const HierarchyEntryData
& rData
, bool bCreate
)
265 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
267 if ( !m_xConfigProvider
.is() )
268 m_xConfigProvider
= uno::Reference
< lang::XMultiServiceFactory
>(
269 m_xContext
->getServiceManager()->createInstanceWithContext(m_aServiceSpecifier
, m_xContext
),
272 if ( m_xConfigProvider
.is() )
274 // Create parent's key. It must exist!
276 OUString aParentPath
;
279 sal_Int32 nPos
= m_aPath
.lastIndexOf( '/' );
282 // Skip "/Children" segment of the path, too.
283 nPos
= m_aPath
.lastIndexOf( '/', nPos
- 1 );
285 OSL_ENSURE( nPos
!= -1,
286 "HierarchyEntry::setData - Wrong path!" );
288 aParentPath
+= m_aPath
.copy( 0, nPos
);
292 uno::Sequence
< uno::Any
> aArguments( 1 );
293 beans::PropertyValue aProperty
;
295 aProperty
.Name
= CFGPROPERTY_NODEPATH
;
296 aProperty
.Value
<<= aParentPath
;
297 aArguments
[ 0 ] <<= aProperty
;
299 uno::Reference
< util::XChangesBatch
> xBatch(
300 m_xConfigProvider
->createInstanceWithArguments(
301 OUString( READWRITE_SERVICE_NAME
),
305 OSL_ENSURE( xBatch
.is(),
306 "HierarchyEntry::setData - No batch!" );
308 uno::Reference
< container::XNameAccess
> xParentNameAccess(
309 xBatch
, uno::UNO_QUERY
);
311 OSL_ENSURE( xParentNameAccess
.is(),
312 "HierarchyEntry::setData - No name access!" );
314 if ( xBatch
.is() && xParentNameAccess
.is() )
316 // Try to create own key. It must not exist!
323 uno::Reference
< container::XNameAccess
> xNameAccess
;
327 xNameAccess
= xParentNameAccess
;
331 xParentNameAccess
->getByName(
332 OUString("Children") )
336 if ( xNameAccess
->hasByName( m_aName
) )
337 aMyKey
= xNameAccess
->getByName( m_aName
);
341 catch ( container::NoSuchElementException
const & )
346 uno::Reference
< container::XNameReplace
> xNameReplace
;
347 uno::Reference
< container::XNameContainer
> xContainer
;
351 // Key exists. Replace values.
353 aMyKey
>>= xNameReplace
;
355 OSL_ENSURE( xNameReplace
.is(),
356 "HierarchyEntry::setData - No name replace!" );
363 // Key does not exist. Create / fill / insert it.
365 uno::Reference
< lang::XSingleServiceFactory
> xFac
;
369 // Special handling for children of root,
370 // which is not an entry. It's only a set
372 xFac
= uno::Reference
< lang::XSingleServiceFactory
>(
373 xParentNameAccess
, uno::UNO_QUERY
);
377 // Append new entry to parents child list,
378 // which is a set of entries.
379 xParentNameAccess
->getByName(
380 OUString( "Children" ) ) >>= xFac
;
383 OSL_ENSURE( xFac
.is(),
384 "HierarchyEntry::setData - No factory!" );
389 = uno::Reference
< container::XNameReplace
>(
390 xFac
->createInstance(), uno::UNO_QUERY
);
392 OSL_ENSURE( xNameReplace
.is(),
393 "HierarchyEntry::setData - No name replace!" );
395 if ( xNameReplace
.is() )
398 = uno::Reference
< container::XNameContainer
>(
399 xFac
, uno::UNO_QUERY
);
401 OSL_ENSURE( xContainer
.is(),
402 "HierarchyEntry::setData - No container!" );
407 if ( xNameReplace
.is() )
410 xNameReplace
->replaceByName(
412 uno::makeAny( rData
.getTitle() ) );
414 // Set TargetURL value.
416 // TargetURL property may contain a reference to the Office
417 // installation directory. To ensure a reloctable office
418 // installation, the path to the office installtion
419 // directory must never be stored directly. Use a
420 // placeholder instead.
421 OUString
aValue( rData
.getTargetURL() );
422 if ( m_xOfficeInstDirs
.is() && !aValue
.isEmpty() )
424 = m_xOfficeInstDirs
->makeRelocatableURL( aValue
);
426 xNameReplace
->replaceByName(
427 OUString("TargetURL"),
428 uno::makeAny( aValue
) );
432 = rData
.getType() == HierarchyEntryData::LINK
? 0 : 1;
433 xNameReplace
->replaceByName(
435 uno::makeAny( nType
) );
437 if ( xContainer
.is() )
438 xContainer
->insertByName(
439 m_aName
, uno::makeAny( xNameReplace
) );
442 xBatch
->commitChanges();
448 catch ( lang::IllegalArgumentException
const & )
450 // replaceByName, insertByName
453 "HierarchyEntry::setData - caught IllegalArgumentException!" );
455 catch ( uno::RuntimeException
const & )
459 catch ( container::NoSuchElementException
const & )
461 // replaceByName, getByName
464 "HierarchyEntry::setData - caught NoSuchElementException!" );
466 catch ( container::ElementExistException
const & )
471 "HierarchyEntry::setData - caught ElementExistException!" );
473 catch ( lang::WrappedTargetException
const & )
475 // replaceByName, insertByName, getByName, commitChanges
478 "HierarchyEntry::setData - caught WrappedTargetException!" );
480 catch ( uno::Exception
const & )
482 // createInstance, createInstanceWithArguments
485 "HierarchyEntry::setData - caught Exception!" );
492 bool HierarchyEntry::move(
493 const OUString
& rNewURL
, const HierarchyEntryData
& rData
)
495 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
497 OUString aNewPath
= createPathFromHierarchyURL( rNewURL
);
499 if ( aNewPath
== m_aPath
)
502 bool bOldRoot
= true;
503 uno::Reference
< util::XChangesBatch
> xOldParentBatch
;
506 sal_Int32 nURLPos
= rNewURL
.lastIndexOf( '/' );
507 if ( nURLPos
> HIERARCHY_URL_SCHEME_LENGTH
)
508 aNewKey
= rNewURL
.copy( nURLPos
+ 1 );
511 OSL_FAIL( "HierarchyEntry::move - Invalid URL!" );
515 bool bNewRoot
= true;
516 uno::Reference
< util::XChangesBatch
> xNewParentBatch
;
518 bool bDifferentParents
= true;
522 if ( !m_xConfigProvider
.is() )
523 m_xConfigProvider
= uno::Reference
< lang::XMultiServiceFactory
>(
524 m_xContext
->getServiceManager()->createInstanceWithContext(m_aServiceSpecifier
, m_xContext
),
527 if ( !m_xConfigProvider
.is() )
530 OUString aOldParentPath
;
531 sal_Int32 nPos
= m_aPath
.lastIndexOf( '/' );
534 // Skip "/Children" segment of the path, too.
535 nPos
= m_aPath
.lastIndexOf( '/', nPos
- 1 );
537 OSL_ENSURE( nPos
!= -1, "HierarchyEntry::move - Wrong path!" );
539 aOldParentPath
+= m_aPath
.copy( 0, nPos
);
543 OUString aNewParentPath
;
544 nPos
= aNewPath
.lastIndexOf( '/' );
547 // Skip "/Children" segment of the path, too.
548 nPos
= aNewPath
.lastIndexOf( '/', nPos
- 1 );
550 OSL_ENSURE( nPos
!= -1, "HierarchyEntry::move - Wrong path!" );
552 aNewParentPath
+= aNewPath
.copy( 0, nPos
);
556 uno::Sequence
< uno::Any
> aArguments( 1 );
557 beans::PropertyValue aProperty
;
559 aProperty
.Name
= CFGPROPERTY_NODEPATH
;
560 aProperty
.Value
<<= aOldParentPath
;
561 aArguments
[ 0 ] <<= aProperty
;
563 xOldParentBatch
= uno::Reference
< util::XChangesBatch
>(
564 m_xConfigProvider
->createInstanceWithArguments(
565 OUString( READWRITE_SERVICE_NAME
),
569 OSL_ENSURE( xOldParentBatch
.is(), "HierarchyEntry::move - No batch!" );
571 if ( !xOldParentBatch
.is() )
574 if ( aOldParentPath
== aNewParentPath
)
576 bDifferentParents
= false;
577 xNewParentBatch
= xOldParentBatch
;
581 bDifferentParents
= true;
583 aProperty
.Name
= CFGPROPERTY_NODEPATH
;
584 aProperty
.Value
<<= aNewParentPath
;
585 aArguments
[ 0 ] <<= aProperty
;
587 xNewParentBatch
= uno::Reference
< util::XChangesBatch
>(
588 m_xConfigProvider
->createInstanceWithArguments(
589 OUString( READWRITE_SERVICE_NAME
),
594 xNewParentBatch
.is(), "HierarchyEntry::move - No batch!" );
596 if ( !xNewParentBatch
.is() )
600 catch ( uno::RuntimeException
const & )
604 catch ( uno::Exception
const & )
606 // createInstance, createInstanceWithArguments
608 OSL_FAIL( "HierarchyEntry::move - caught Exception!" );
617 uno::Reference
< container::XNameAccess
> xOldParentNameAccess
;
618 uno::Reference
< container::XNameContainer
> xOldNameContainer
;
623 = uno::Reference
< container::XNameAccess
>(
624 xOldParentBatch
, uno::UNO_QUERY
);
626 OSL_ENSURE( xOldParentNameAccess
.is(),
627 "HierarchyEntry::move - No name access!" );
629 if ( !xOldParentNameAccess
.is() )
634 xOldNameContainer
= uno::Reference
< container::XNameContainer
>(
635 xOldParentNameAccess
, uno::UNO_QUERY
);
639 xOldParentNameAccess
->getByName(
640 OUString("Children") )
641 >>= xOldNameContainer
;
644 aEntry
= xOldNameContainer
->getByName( m_aName
);
646 catch ( container::NoSuchElementException
const & )
650 OSL_FAIL( "HierarchyEntry::move - caught NoSuchElementException!" );
653 catch ( lang::WrappedTargetException
const & )
657 OSL_FAIL( "HierarchyEntry::move - caught WrappedTargetException!" );
662 // (2) Remove entry... Note: Insert BEFORE remove does not work!
667 xOldNameContainer
->removeByName( m_aName
);
668 xOldParentBatch
->commitChanges();
670 catch ( container::NoSuchElementException
const & )
672 // getByName, removeByName
674 OSL_FAIL( "HierarchyEntry::move - caught NoSuchElementException!" );
679 // (3) Insert entry at new parent...
684 uno::Reference
< container::XNameReplace
> xNewNameReplace
;
685 aEntry
>>= xNewNameReplace
;
687 OSL_ENSURE( xNewNameReplace
.is(),
688 "HierarchyEntry::move - No name replace!" );
690 if ( !xNewNameReplace
.is() )
693 uno::Reference
< container::XNameAccess
> xNewParentNameAccess
;
694 if ( bDifferentParents
)
696 = uno::Reference
< container::XNameAccess
>(
697 xNewParentBatch
, uno::UNO_QUERY
);
699 xNewParentNameAccess
= xOldParentNameAccess
;
701 OSL_ENSURE( xNewParentNameAccess
.is(),
702 "HierarchyEntry::move - No name access!" );
704 if ( !xNewParentNameAccess
.is() )
707 uno::Reference
< container::XNameContainer
> xNewNameContainer
;
708 if ( bDifferentParents
)
713 = uno::Reference
< container::XNameContainer
>(
714 xNewParentNameAccess
, uno::UNO_QUERY
);
718 xNewParentNameAccess
->getByName(
719 OUString("Children") )
720 >>= xNewNameContainer
;
724 xNewNameContainer
= xOldNameContainer
;
726 if ( !xNewNameContainer
.is() )
729 xNewNameReplace
->replaceByName(
731 uno::makeAny( rData
.getTitle() ) );
733 // TargetURL property may contain a reference to the Office
734 // installation directory. To ensure a reloctable office
735 // installation, the path to the office installtion
736 // directory must never be stored directly. Use a placeholder
738 OUString
aValue( rData
.getTargetURL() );
739 if ( m_xOfficeInstDirs
.is() && !aValue
.isEmpty() )
740 aValue
= m_xOfficeInstDirs
->makeRelocatableURL( aValue
);
741 xNewNameReplace
->replaceByName(
742 OUString("TargetURL"),
743 uno::makeAny( aValue
) );
744 sal_Int32 nType
= rData
.getType() == HierarchyEntryData::LINK
? 0 : 1;
745 xNewNameReplace
->replaceByName(
747 uno::makeAny( nType
) );
749 xNewNameContainer
->insertByName( aNewKey
, aEntry
);
750 xNewParentBatch
->commitChanges();
752 catch ( container::NoSuchElementException
const & )
754 // replaceByName, insertByName, getByName
756 OSL_FAIL( "HierarchyEntry::move - caught NoSuchElementException!" );
759 catch ( lang::IllegalArgumentException
const & )
761 // replaceByName, insertByName
764 "HierarchyEntry::move - caught IllegalArgumentException!" );
767 catch ( container::ElementExistException
const & )
771 OSL_FAIL( "HierarchyEntry::move - caught ElementExistException!" );
774 catch ( lang::WrappedTargetException
const & )
776 // replaceByName, insertByName, getByName
778 OSL_FAIL( "HierarchyEntry::move - caught WrappedTargetException!" );
786 bool HierarchyEntry::remove()
790 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
792 if ( !m_xConfigProvider
.is() )
793 m_xConfigProvider
= uno::Reference
< lang::XMultiServiceFactory
>(
794 m_xContext
->getServiceManager()->createInstanceWithContext(m_aServiceSpecifier
, m_xContext
),
797 if ( m_xConfigProvider
.is() )
799 // Create parent's key. It must exist!
801 OUString aParentPath
;
804 sal_Int32 nPos
= m_aPath
.lastIndexOf( '/' );
807 // Skip "/Children" segment of the path, too.
808 nPos
= m_aPath
.lastIndexOf( '/', nPos
- 1 );
810 OSL_ENSURE( nPos
!= -1,
811 "HierarchyEntry::remove - Wrong path!" );
813 aParentPath
+= m_aPath
.copy( 0, nPos
);
817 uno::Sequence
< uno::Any
> aArguments( 1 );
818 beans::PropertyValue aProperty
;
820 aProperty
.Name
= CFGPROPERTY_NODEPATH
;
821 aProperty
.Value
<<= aParentPath
;
822 aArguments
[ 0 ] <<= aProperty
;
824 uno::Reference
< util::XChangesBatch
> xBatch(
825 m_xConfigProvider
->createInstanceWithArguments(
826 OUString( READWRITE_SERVICE_NAME
),
830 OSL_ENSURE( xBatch
.is(),
831 "HierarchyEntry::remove - No batch!" );
833 uno::Reference
< container::XNameAccess
> xParentNameAccess(
834 xBatch
, uno::UNO_QUERY
);
836 OSL_ENSURE( xParentNameAccess
.is(),
837 "HierarchyEntry::remove - No name access!" );
839 if ( xBatch
.is() && xParentNameAccess
.is() )
841 uno::Reference
< container::XNameContainer
> xContainer
;
845 // Special handling for children of root,
846 // which is not an entry. It's only a set
848 xContainer
= uno::Reference
< container::XNameContainer
>(
849 xParentNameAccess
, uno::UNO_QUERY
);
853 // Append new entry to parents child list,
854 // which is a set of entries.
855 xParentNameAccess
->getByName(
856 OUString("Children") )
860 OSL_ENSURE( xContainer
.is(),
861 "HierarchyEntry::remove - No container!" );
863 if ( xContainer
.is() )
865 xContainer
->removeByName( m_aName
);
866 xBatch
->commitChanges();
872 catch ( uno::RuntimeException
const & )
876 catch ( container::NoSuchElementException
const & )
878 // getByName, removeByName
881 "HierarchyEntry::remove - caught NoSuchElementException!" );
883 catch ( lang::WrappedTargetException
const & )
885 // getByName, commitChanges
888 "HierarchyEntry::remove - caught WrappedTargetException!" );
890 catch ( uno::Exception
const & )
892 // createInstance, createInstanceWithArguments
894 OSL_FAIL( "HierarchyEntry::remove - caught Exception!" );
901 bool HierarchyEntry::first( iterator
& it
)
903 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
905 if ( it
.m_pImpl
->pos
== -1 )
911 uno::Reference
< container::XHierarchicalNameAccess
>
912 xRootHierNameAccess
= getRootReadAccess();
914 if ( xRootHierNameAccess
.is() )
916 uno::Reference
< container::XNameAccess
> xNameAccess
;
918 if ( !m_aPath
.isEmpty() )
920 OUString aPath
= m_aPath
;
921 aPath
+= "/Children";
923 xRootHierNameAccess
->getByHierarchicalName( aPath
)
928 = uno::Reference
< container::XNameAccess
>(
929 xRootHierNameAccess
, uno::UNO_QUERY
);
931 OSL_ENSURE( xNameAccess
.is(),
932 "HierarchyEntry::first - No name access!" );
934 if ( xNameAccess
.is() )
935 it
.m_pImpl
->names
= xNameAccess
->getElementNames();
937 uno::Reference
< container::XHierarchicalNameAccess
>
938 xHierNameAccess( xNameAccess
, uno::UNO_QUERY
);
940 OSL_ENSURE( xHierNameAccess
.is(),
941 "HierarchyEntry::first - No hier. name access!" );
943 it
.m_pImpl
->dir
= xHierNameAccess
;
945 it
.m_pImpl
->officeDirs
= m_xOfficeInstDirs
;
948 catch ( uno::RuntimeException
const & )
952 catch ( container::NoSuchElementException
const& )
954 // getByHierarchicalName
957 "HierarchyEntry::first - caught NoSuchElementException!" );
959 catch ( uno::Exception
const & )
961 OSL_FAIL( "HierarchyEntry::first - caught Exception!" );
965 if ( it
.m_pImpl
->names
.getLength() == 0 )
973 bool HierarchyEntry::next( iterator
& it
)
975 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
977 if ( it
.m_pImpl
->pos
== -1 )
982 return ( it
.m_pImpl
->pos
< it
.m_pImpl
->names
.getLength() );
986 OUString
HierarchyEntry::createPathFromHierarchyURL(
987 const HierarchyUri
& rURI
)
989 // Transform path....
990 // folder/subfolder/subsubfolder
991 // --> ['folder']/Children/['subfolder']/Children/['subsubfolder']
993 const OUString aPath
= rURI
.getPath().copy( 1 ); // skip leading slash.
994 sal_Int32 nLen
= aPath
.getLength();
998 OUStringBuffer aNewPath
;
999 aNewPath
.appendAscii( "['" );
1001 sal_Int32 nStart
= 0;
1002 sal_Int32 nEnd
= aPath
.indexOf( '/' );
1009 OUString aToken
= aPath
.copy( nStart
, nEnd
- nStart
);
1010 makeXMLName( aToken
, aNewPath
);
1014 aNewPath
.appendAscii( "']/Children/['" );
1016 nEnd
= aPath
.indexOf( '/', nStart
);
1019 aNewPath
.appendAscii( "']" );
1021 while ( nEnd
!= nLen
);
1023 return aNewPath
.makeStringAndClear();
1030 uno::Reference
< container::XHierarchicalNameAccess
>
1031 HierarchyEntry::getRootReadAccess()
1033 if ( !m_xRootReadAccess
.is() )
1035 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
1036 if ( !m_xRootReadAccess
.is() )
1038 if ( m_bTriedToGetRootReadAccess
) // #82494#
1040 OSL_FAIL( "HierarchyEntry::getRootReadAccess - "
1041 "Unable to read any config data! -> #82494#" );
1042 return uno::Reference
< container::XHierarchicalNameAccess
>();
1047 if ( !m_xConfigProvider
.is() )
1049 = uno::Reference
< lang::XMultiServiceFactory
>(
1050 m_xContext
->getServiceManager()->createInstanceWithContext(m_aServiceSpecifier
, m_xContext
),
1053 if ( m_xConfigProvider
.is() )
1055 // Create Root object.
1057 uno::Sequence
< uno::Any
> aArguments( 1 );
1058 beans::PropertyValue aProperty
;
1059 aProperty
.Name
= CFGPROPERTY_NODEPATH
;
1060 aProperty
.Value
<<= OUString(); // root path
1061 aArguments
[ 0 ] <<= aProperty
;
1063 m_bTriedToGetRootReadAccess
= true;
1066 = uno::Reference
< container::XHierarchicalNameAccess
>(
1067 m_xConfigProvider
->createInstanceWithArguments(
1068 OUString( READ_SERVICE_NAME
),
1073 catch ( uno::RuntimeException
const & )
1077 catch ( uno::Exception
const & )
1079 // createInstance, createInstanceWithArguments
1081 OSL_FAIL( "HierarchyEntry::getRootReadAccess - "
1082 "caught Exception!" );
1086 return m_xRootReadAccess
;
1092 // HierarchyEntry::iterator Implementation.
1097 HierarchyEntry::iterator::iterator()
1099 m_pImpl
= new iterator_Impl
;
1103 HierarchyEntry::iterator::~iterator()
1109 const HierarchyEntryData
& HierarchyEntry::iterator::operator*() const
1111 if ( ( m_pImpl
->pos
!= -1 )
1112 && ( m_pImpl
->dir
.is() )
1113 && ( m_pImpl
->pos
< m_pImpl
->names
.getLength() ) )
1117 OUStringBuffer aKey
;
1118 aKey
.appendAscii( "['" );
1119 makeXMLName( m_pImpl
->names
.getConstArray()[ m_pImpl
->pos
], aKey
);
1120 aKey
.appendAscii( "']" );
1122 OUString aTitle
= aKey
.makeStringAndClear();
1123 OUString aTargetURL
= aTitle
;
1124 OUString aType
= aTitle
;
1127 aTargetURL
+= "/TargetURL";
1131 m_pImpl
->dir
->getByHierarchicalName( aTitle
) >>= aValue
;
1132 m_pImpl
->entry
.setTitle( aValue
);
1134 m_pImpl
->dir
->getByHierarchicalName( aTargetURL
) >>= aValue
;
1136 // TargetURL property may contain a reference to the Office
1137 // installation directory. To ensure a reloctable office
1138 // installation, the path to the office installtion directory must
1139 // never be stored directly. A placeholder is used instead. Replace
1140 // it by actual installation directory.
1141 if ( m_pImpl
->officeDirs
.is() && !aValue
.isEmpty() )
1142 aValue
= m_pImpl
->officeDirs
->makeAbsoluteURL( aValue
);
1143 m_pImpl
->entry
.setTargetURL( aValue
);
1145 if ( m_pImpl
->dir
->hasByHierarchicalName( aType
) )
1147 // Might not be present since it was introduced long
1148 // after Title and TargetURL (#82433#)... So not getting
1149 // it is not an error.
1152 sal_Int32 nType
= 0;
1153 if ( m_pImpl
->dir
->getByHierarchicalName( aType
) >>= nType
)
1157 m_pImpl
->entry
.setType( HierarchyEntryData::LINK
);
1159 else if ( nType
== 1 )
1161 m_pImpl
->entry
.setType( HierarchyEntryData::FOLDER
);
1165 OSL_FAIL( "HierarchyEntry::getData - "
1166 "Unknown Type value!" );
1171 m_pImpl
->entry
.setName(
1172 m_pImpl
->names
.getConstArray()[ m_pImpl
->pos
] );
1174 catch ( container::NoSuchElementException
const & )
1176 m_pImpl
->entry
= HierarchyEntryData();
1180 return m_pImpl
->entry
;
1183 } // namespace hierarchy_ucp
1185 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */