1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
30 /**************************************************************************
32 **************************************************************************
34 - HierarchyEntry::move
35 --> Rewrite to use XNamed ( once this is supported by config db api ).
37 *************************************************************************/
38 #include "hierarchydata.hxx"
41 #include <osl/diagnose.h>
42 #include <rtl/ustrbuf.hxx>
43 #include <com/sun/star/beans/PropertyValue.hpp>
44 #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
45 #include <com/sun/star/container/XNameContainer.hpp>
46 #include <com/sun/star/container/XNameReplace.hpp>
47 #include <com/sun/star/util/XChangesBatch.hpp>
48 #include <com/sun/star/util/XOfficeInstallationDirectories.hpp>
49 #include "hierarchyprovider.hxx"
50 #include "hierarchyuri.hxx"
52 using namespace com::sun::star
;
54 namespace hierarchy_ucp
57 //=========================================================================
58 struct HierarchyEntry::iterator_Impl
60 HierarchyEntryData entry
;
61 uno::Reference
< container::XHierarchicalNameAccess
> dir
;
62 uno::Reference
< util::XOfficeInstallationDirectories
> officeDirs
;
63 uno::Sequence
< rtl::OUString
> names
;
66 : officeDirs( 0 ), pos( -1 /* before first */ ) {};
69 //=========================================================================
70 void makeXMLName( const rtl::OUString
& rIn
, rtl::OUStringBuffer
& rBuffer
)
72 sal_Int32 nCount
= rIn
.getLength();
73 for ( sal_Int32 n
= 0; n
< nCount
; ++n
)
75 const sal_Unicode c
= rIn
.getStr()[ n
];
79 rBuffer
.appendAscii( "&" );
83 rBuffer
.appendAscii( """ );
87 rBuffer
.appendAscii( "'" );
91 rBuffer
.appendAscii( "<" );
95 rBuffer
.appendAscii( ">" );
105 //=========================================================================
106 //=========================================================================
108 // HierarchyEntry Implementation.
110 //=========================================================================
111 //=========================================================================
113 #define READ_SERVICE_NAME "com.sun.star.ucb.HierarchyDataReadAccess"
114 #define READWRITE_SERVICE_NAME "com.sun.star.ucb.HierarchyDataReadWriteAccess"
116 // describe path of cfg entry
117 #define CFGPROPERTY_NODEPATH "nodepath"
119 //=========================================================================
120 HierarchyEntry::HierarchyEntry(
121 const uno::Reference
< lang::XMultiServiceFactory
>& rSMgr
,
122 HierarchyContentProvider
* pProvider
,
123 const rtl::OUString
& rURL
)
125 m_xOfficeInstDirs( pProvider
->getOfficeInstallationDirectories() ),
126 m_bTriedToGetRootReadAccess( sal_False
)
128 HierarchyUri
aUri( rURL
);
129 m_aServiceSpecifier
= aUri
.getService();
134 = pProvider
->getConfigProvider( m_aServiceSpecifier
);
136 = pProvider
->getRootConfigReadNameAccess( m_aServiceSpecifier
);
139 // Note: do not init m_aPath in init list. createPathFromHierarchyURL
140 // needs m_xSMgr and m_aMutex.
141 m_aPath
= createPathFromHierarchyURL( aUri
);
143 // Extract language independent name from URL.
144 sal_Int32 nPos
= rURL
.lastIndexOf( '/' );
145 if ( nPos
> HIERARCHY_URL_SCHEME_LENGTH
)
146 m_aName
= rURL
.copy( nPos
+ 1 );
148 OSL_FAIL( "HierarchyEntry - Invalid URL!" );
151 //=========================================================================
152 sal_Bool
HierarchyEntry::hasData()
154 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
155 uno::Reference
< container::XHierarchicalNameAccess
> xRootReadAccess
156 = getRootReadAccess();
158 OSL_ENSURE( xRootReadAccess
.is(), "HierarchyEntry::hasData - No root!" );
160 if ( xRootReadAccess
.is() )
161 return xRootReadAccess
->hasByHierarchicalName( m_aPath
);
166 //=========================================================================
167 sal_Bool
HierarchyEntry::getData( HierarchyEntryData
& rData
)
171 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
173 uno::Reference
< container::XHierarchicalNameAccess
> xRootReadAccess
174 = getRootReadAccess();
176 OSL_ENSURE( xRootReadAccess
.is(),
177 "HierarchyEntry::getData - No root!" );
179 if ( xRootReadAccess
.is() )
181 rtl::OUString aTitlePath
= m_aPath
;
182 aTitlePath
+= rtl::OUString("/Title");
184 // Note: Avoid NoSuchElementExceptions, because exceptions are
185 // relatively 'expensive'. Checking for availability of
186 // title value is sufficient here, because if it is
187 // there, the other values will be available too.
188 if ( !xRootReadAccess
->hasByHierarchicalName( aTitlePath
) )
191 rtl::OUString aValue
;
194 if ( !( xRootReadAccess
->getByHierarchicalName( aTitlePath
)
197 OSL_FAIL( "HierarchyEntry::getData - "
198 "Got no Title value!" );
202 rData
.setTitle( aValue
);
204 // Get TargetURL value.
205 rtl::OUString aTargetURLPath
= m_aPath
;
206 aTargetURLPath
+= rtl::OUString("/TargetURL");
207 if ( !( xRootReadAccess
->getByHierarchicalName( aTargetURLPath
)
210 OSL_FAIL( "HierarchyEntry::getData - "
211 "Got no TargetURL value!" );
215 // TargetURL property may contain a reference to the Office
216 // installation directory. To ensure a reloctable office
217 // installation, the path to the office installtion directory must
218 // never be stored directly. A placeholder is used instead. Replace
219 // it by actual installation directory.
220 if ( m_xOfficeInstDirs
.is() && !aValue
.isEmpty() )
221 aValue
= m_xOfficeInstDirs
->makeAbsoluteURL( aValue
);
222 rData
.setTargetURL( aValue
);
224 rtl::OUString aTypePath
= m_aPath
;
225 aTypePath
+= rtl::OUString("/Type");
226 if ( xRootReadAccess
->hasByHierarchicalName( aTypePath
) )
228 // Might not be present since it was introduced long after
229 // Title and TargetURL (#82433#)... So not getting it is
234 if ( xRootReadAccess
->getByHierarchicalName( aTypePath
)
239 rData
.setType( HierarchyEntryData::LINK
);
241 else if ( nType
== 1 )
243 rData
.setType( HierarchyEntryData::FOLDER
);
247 OSL_FAIL( "HierarchyEntry::getData - "
248 "Unknown Type value!" );
254 rData
.setName( m_aName
);
258 catch ( uno::RuntimeException
const & )
262 catch ( container::NoSuchElementException
const & )
264 // getByHierarchicalName
266 OSL_FAIL( "HierarchyEntry::getData - caught NoSuchElementException!" );
271 //=========================================================================
272 sal_Bool
HierarchyEntry::setData(
273 const HierarchyEntryData
& rData
, sal_Bool bCreate
)
277 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
279 if ( !m_xConfigProvider
.is() )
280 m_xConfigProvider
= uno::Reference
< lang::XMultiServiceFactory
>(
281 m_xSMgr
->createInstance( m_aServiceSpecifier
),
284 if ( m_xConfigProvider
.is() )
286 // Create parent's key. It must exist!
288 rtl::OUString aParentPath
;
289 sal_Bool bRoot
= sal_True
;
291 sal_Int32 nPos
= m_aPath
.lastIndexOf( '/' );
294 // Skip "/Children" segment of the path, too.
295 nPos
= m_aPath
.lastIndexOf( '/', nPos
- 1 );
297 OSL_ENSURE( nPos
!= -1,
298 "HierarchyEntry::setData - Wrong path!" );
300 aParentPath
+= m_aPath
.copy( 0, nPos
);
304 uno::Sequence
< uno::Any
> aArguments( 1 );
305 beans::PropertyValue aProperty
;
307 aProperty
.Name
= rtl::OUString( CFGPROPERTY_NODEPATH
);
308 aProperty
.Value
<<= aParentPath
;
309 aArguments
[ 0 ] <<= aProperty
;
311 uno::Reference
< util::XChangesBatch
> xBatch(
312 m_xConfigProvider
->createInstanceWithArguments(
313 rtl::OUString( READWRITE_SERVICE_NAME
),
317 OSL_ENSURE( xBatch
.is(),
318 "HierarchyEntry::setData - No batch!" );
320 uno::Reference
< container::XNameAccess
> xParentNameAccess(
321 xBatch
, uno::UNO_QUERY
);
323 OSL_ENSURE( xParentNameAccess
.is(),
324 "HierarchyEntry::setData - No name access!" );
326 if ( xBatch
.is() && xParentNameAccess
.is() )
328 // Try to create own key. It must not exist!
330 sal_Bool bExists
= sal_True
;
335 uno::Reference
< container::XNameAccess
> xNameAccess
;
339 xNameAccess
= xParentNameAccess
;
343 xParentNameAccess
->getByName(
344 rtl::OUString("Children") )
348 if ( xNameAccess
->hasByName( m_aName
) )
349 aMyKey
= xNameAccess
->getByName( m_aName
);
353 catch ( container::NoSuchElementException
const & )
358 uno::Reference
< container::XNameReplace
> xNameReplace
;
359 uno::Reference
< container::XNameContainer
> xContainer
;
363 // Key exists. Replace values.
365 aMyKey
>>= xNameReplace
;
367 OSL_ENSURE( xNameReplace
.is(),
368 "HierarchyEntry::setData - No name replace!" );
375 // Key does not exist. Create / fill / insert it.
377 uno::Reference
< lang::XSingleServiceFactory
> xFac
;
381 // Special handling for children of root,
382 // which is not an entry. It's only a set
384 xFac
= uno::Reference
< lang::XSingleServiceFactory
>(
385 xParentNameAccess
, uno::UNO_QUERY
);
389 // Append new entry to parents child list,
390 // which is a set of entries.
391 xParentNameAccess
->getByName(
392 rtl::OUString( "Children" ) ) >>= xFac
;
395 OSL_ENSURE( xFac
.is(),
396 "HierarchyEntry::setData - No factory!" );
401 = uno::Reference
< container::XNameReplace
>(
402 xFac
->createInstance(), uno::UNO_QUERY
);
404 OSL_ENSURE( xNameReplace
.is(),
405 "HierarchyEntry::setData - No name replace!" );
407 if ( xNameReplace
.is() )
410 = uno::Reference
< container::XNameContainer
>(
411 xFac
, uno::UNO_QUERY
);
413 OSL_ENSURE( xContainer
.is(),
414 "HierarchyEntry::setData - No container!" );
419 if ( xNameReplace
.is() )
422 xNameReplace
->replaceByName(
423 rtl::OUString("Title"),
424 uno::makeAny( rData
.getTitle() ) );
426 // Set TargetURL value.
428 // TargetURL property may contain a reference to the Office
429 // installation directory. To ensure a reloctable office
430 // installation, the path to the office installtion
431 // directory must never be stored directly. Use a
432 // placeholder instead.
433 rtl::OUString
aValue( rData
.getTargetURL() );
434 if ( m_xOfficeInstDirs
.is() && !aValue
.isEmpty() )
436 = m_xOfficeInstDirs
->makeRelocatableURL( aValue
);
438 xNameReplace
->replaceByName(
439 rtl::OUString("TargetURL"),
440 uno::makeAny( aValue
) );
444 = rData
.getType() == HierarchyEntryData::LINK
? 0 : 1;
445 xNameReplace
->replaceByName(
446 rtl::OUString("Type"),
447 uno::makeAny( nType
) );
449 if ( xContainer
.is() )
450 xContainer
->insertByName(
451 m_aName
, uno::makeAny( xNameReplace
) );
454 xBatch
->commitChanges();
460 catch ( uno::RuntimeException
const & )
464 catch ( lang::IllegalArgumentException
const & )
466 // replaceByName, insertByName
469 "HierarchyEntry::setData - caught IllegalArgumentException!" );
471 catch ( container::NoSuchElementException
const & )
473 // replaceByName, getByName
476 "HierarchyEntry::setData - caught NoSuchElementException!" );
478 catch ( container::ElementExistException
const & )
483 "HierarchyEntry::setData - caught ElementExistException!" );
485 catch ( lang::WrappedTargetException
const & )
487 // replaceByName, insertByName, getByName, commitChanges
490 "HierarchyEntry::setData - caught WrappedTargetException!" );
492 catch ( uno::Exception
const & )
494 // createInstance, createInstanceWithArguments
497 "HierarchyEntry::setData - caught Exception!" );
503 //=========================================================================
504 sal_Bool
HierarchyEntry::move(
505 const rtl::OUString
& rNewURL
, const HierarchyEntryData
& rData
)
507 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
509 rtl::OUString aNewPath
= createPathFromHierarchyURL( rNewURL
);
511 if ( aNewPath
== m_aPath
)
514 sal_Bool bOldRoot
= sal_True
;
515 uno::Reference
< util::XChangesBatch
> xOldParentBatch
;
517 rtl::OUString aNewKey
;
518 sal_Int32 nURLPos
= rNewURL
.lastIndexOf( '/' );
519 if ( nURLPos
> HIERARCHY_URL_SCHEME_LENGTH
)
520 aNewKey
= rNewURL
.copy( nURLPos
+ 1 );
523 OSL_FAIL( "HierarchyEntry::move - Invalid URL!" );
527 sal_Bool bNewRoot
= sal_True
;
528 uno::Reference
< util::XChangesBatch
> xNewParentBatch
;
530 sal_Bool bDifferentParents
= sal_True
;
534 if ( !m_xConfigProvider
.is() )
535 m_xConfigProvider
= uno::Reference
< lang::XMultiServiceFactory
>(
536 m_xSMgr
->createInstance( m_aServiceSpecifier
),
539 if ( !m_xConfigProvider
.is() )
542 rtl::OUString aOldParentPath
;
543 sal_Int32 nPos
= m_aPath
.lastIndexOf( '/' );
546 // Skip "/Children" segment of the path, too.
547 nPos
= m_aPath
.lastIndexOf( '/', nPos
- 1 );
549 OSL_ENSURE( nPos
!= -1, "HierarchyEntry::move - Wrong path!" );
551 aOldParentPath
+= m_aPath
.copy( 0, nPos
);
552 bOldRoot
= sal_False
;
555 rtl::OUString aNewParentPath
;
556 nPos
= aNewPath
.lastIndexOf( '/' );
559 // Skip "/Children" segment of the path, too.
560 nPos
= aNewPath
.lastIndexOf( '/', nPos
- 1 );
562 OSL_ENSURE( nPos
!= -1, "HierarchyEntry::move - Wrong path!" );
564 aNewParentPath
+= aNewPath
.copy( 0, nPos
);
565 bNewRoot
= sal_False
;
568 uno::Sequence
< uno::Any
> aArguments( 1 );
569 beans::PropertyValue aProperty
;
571 aProperty
.Name
= rtl::OUString( CFGPROPERTY_NODEPATH
);
572 aProperty
.Value
<<= aOldParentPath
;
573 aArguments
[ 0 ] <<= aProperty
;
575 xOldParentBatch
= uno::Reference
< util::XChangesBatch
>(
576 m_xConfigProvider
->createInstanceWithArguments(
577 rtl::OUString( READWRITE_SERVICE_NAME
),
581 OSL_ENSURE( xOldParentBatch
.is(), "HierarchyEntry::move - No batch!" );
583 if ( !xOldParentBatch
.is() )
586 if ( aOldParentPath
== aNewParentPath
)
588 bDifferentParents
= sal_False
;
589 xNewParentBatch
= xOldParentBatch
;
593 bDifferentParents
= sal_True
;
595 aProperty
.Name
= rtl::OUString( CFGPROPERTY_NODEPATH
);
596 aProperty
.Value
<<= aNewParentPath
;
597 aArguments
[ 0 ] <<= aProperty
;
599 xNewParentBatch
= uno::Reference
< util::XChangesBatch
>(
600 m_xConfigProvider
->createInstanceWithArguments(
601 rtl::OUString( READWRITE_SERVICE_NAME
),
606 xNewParentBatch
.is(), "HierarchyEntry::move - No batch!" );
608 if ( !xNewParentBatch
.is() )
612 catch ( uno::RuntimeException
const & )
616 catch ( uno::Exception
const & )
618 // createInstance, createInstanceWithArguments
620 OSL_FAIL( "HierarchyEntry::move - caught Exception!" );
624 //////////////////////////////////////////////////////////////////////
626 //////////////////////////////////////////////////////////////////////
629 uno::Reference
< container::XNameAccess
> xOldParentNameAccess
;
630 uno::Reference
< container::XNameContainer
> xOldNameContainer
;
635 = uno::Reference
< container::XNameAccess
>(
636 xOldParentBatch
, uno::UNO_QUERY
);
638 OSL_ENSURE( xOldParentNameAccess
.is(),
639 "HierarchyEntry::move - No name access!" );
641 if ( !xOldParentNameAccess
.is() )
646 xOldNameContainer
= uno::Reference
< container::XNameContainer
>(
647 xOldParentNameAccess
, uno::UNO_QUERY
);
651 xOldParentNameAccess
->getByName(
652 rtl::OUString("Children") )
653 >>= xOldNameContainer
;
656 aEntry
= xOldNameContainer
->getByName( m_aName
);
658 catch ( container::NoSuchElementException
const & )
662 OSL_FAIL( "HierarchyEntry::move - caught NoSuchElementException!" );
665 catch ( lang::WrappedTargetException
const & )
669 OSL_FAIL( "HierarchyEntry::move - caught WrappedTargetException!" );
673 //////////////////////////////////////////////////////////////////////
674 // (2) Remove entry... Note: Insert BEFORE remove does not work!
675 //////////////////////////////////////////////////////////////////////
679 xOldNameContainer
->removeByName( m_aName
);
680 xOldParentBatch
->commitChanges();
682 catch ( container::NoSuchElementException
const & )
684 // getByName, removeByName
686 OSL_FAIL( "HierarchyEntry::move - caught NoSuchElementException!" );
690 //////////////////////////////////////////////////////////////////////
691 // (3) Insert entry at new parent...
692 //////////////////////////////////////////////////////////////////////
696 uno::Reference
< container::XNameReplace
> xNewNameReplace
;
697 aEntry
>>= xNewNameReplace
;
699 OSL_ENSURE( xNewNameReplace
.is(),
700 "HierarchyEntry::move - No name replace!" );
702 if ( !xNewNameReplace
.is() )
705 uno::Reference
< container::XNameAccess
> xNewParentNameAccess
;
706 if ( bDifferentParents
)
708 = uno::Reference
< container::XNameAccess
>(
709 xNewParentBatch
, uno::UNO_QUERY
);
711 xNewParentNameAccess
= xOldParentNameAccess
;
713 OSL_ENSURE( xNewParentNameAccess
.is(),
714 "HierarchyEntry::move - No name access!" );
716 if ( !xNewParentNameAccess
.is() )
719 uno::Reference
< container::XNameContainer
> xNewNameContainer
;
720 if ( bDifferentParents
)
725 = uno::Reference
< container::XNameContainer
>(
726 xNewParentNameAccess
, uno::UNO_QUERY
);
730 xNewParentNameAccess
->getByName(
731 rtl::OUString("Children") )
732 >>= xNewNameContainer
;
736 xNewNameContainer
= xOldNameContainer
;
738 if ( !xNewNameContainer
.is() )
741 xNewNameReplace
->replaceByName(
742 rtl::OUString("Title"),
743 uno::makeAny( rData
.getTitle() ) );
745 // TargetURL property may contain a reference to the Office
746 // installation directory. To ensure a reloctable office
747 // installation, the path to the office installtion
748 // directory must never be stored directly. Use a placeholder
750 rtl::OUString
aValue( rData
.getTargetURL() );
751 if ( m_xOfficeInstDirs
.is() && !aValue
.isEmpty() )
752 aValue
= m_xOfficeInstDirs
->makeRelocatableURL( aValue
);
753 xNewNameReplace
->replaceByName(
754 rtl::OUString("TargetURL"),
755 uno::makeAny( aValue
) );
756 sal_Int32 nType
= rData
.getType() == HierarchyEntryData::LINK
? 0 : 1;
757 xNewNameReplace
->replaceByName(
758 rtl::OUString("Type"),
759 uno::makeAny( nType
) );
761 xNewNameContainer
->insertByName( aNewKey
, aEntry
);
762 xNewParentBatch
->commitChanges();
764 catch ( container::NoSuchElementException
const & )
766 // replaceByName, insertByName, getByName
768 OSL_FAIL( "HierarchyEntry::move - caught NoSuchElementException!" );
771 catch ( lang::IllegalArgumentException
const & )
773 // replaceByName, insertByName
776 "HierarchyEntry::move - caught IllegalArgumentException!" );
779 catch ( container::ElementExistException
const & )
783 OSL_FAIL( "HierarchyEntry::move - caught ElementExistException!" );
786 catch ( lang::WrappedTargetException
const & )
788 // replaceByName, insertByName, getByName
790 OSL_FAIL( "HierarchyEntry::move - caught WrappedTargetException!" );
797 //=========================================================================
798 sal_Bool
HierarchyEntry::remove()
802 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
804 if ( !m_xConfigProvider
.is() )
805 m_xConfigProvider
= uno::Reference
< lang::XMultiServiceFactory
>(
806 m_xSMgr
->createInstance( m_aServiceSpecifier
),
809 if ( m_xConfigProvider
.is() )
811 // Create parent's key. It must exist!
813 rtl::OUString aParentPath
;
814 sal_Bool bRoot
= sal_True
;
816 sal_Int32 nPos
= m_aPath
.lastIndexOf( '/' );
819 // Skip "/Children" segment of the path, too.
820 nPos
= m_aPath
.lastIndexOf( '/', nPos
- 1 );
822 OSL_ENSURE( nPos
!= -1,
823 "HierarchyEntry::remove - Wrong path!" );
825 aParentPath
+= m_aPath
.copy( 0, nPos
);
829 uno::Sequence
< uno::Any
> aArguments( 1 );
830 beans::PropertyValue aProperty
;
832 aProperty
.Name
= rtl::OUString( CFGPROPERTY_NODEPATH
);
833 aProperty
.Value
<<= aParentPath
;
834 aArguments
[ 0 ] <<= aProperty
;
836 uno::Reference
< util::XChangesBatch
> xBatch(
837 m_xConfigProvider
->createInstanceWithArguments(
838 rtl::OUString( READWRITE_SERVICE_NAME
),
842 OSL_ENSURE( xBatch
.is(),
843 "HierarchyEntry::remove - No batch!" );
845 uno::Reference
< container::XNameAccess
> xParentNameAccess(
846 xBatch
, uno::UNO_QUERY
);
848 OSL_ENSURE( xParentNameAccess
.is(),
849 "HierarchyEntry::remove - No name access!" );
851 if ( xBatch
.is() && xParentNameAccess
.is() )
853 uno::Reference
< container::XNameContainer
> xContainer
;
857 // Special handling for children of root,
858 // which is not an entry. It's only a set
860 xContainer
= uno::Reference
< container::XNameContainer
>(
861 xParentNameAccess
, uno::UNO_QUERY
);
865 // Append new entry to parents child list,
866 // which is a set of entries.
867 xParentNameAccess
->getByName(
868 rtl::OUString("Children") )
872 OSL_ENSURE( xContainer
.is(),
873 "HierarchyEntry::remove - No container!" );
875 if ( xContainer
.is() )
877 xContainer
->removeByName( m_aName
);
878 xBatch
->commitChanges();
884 catch ( uno::RuntimeException
const & )
888 catch ( container::NoSuchElementException
const & )
890 // getByName, removeByName
893 "HierarchyEntry::remove - caught NoSuchElementException!" );
895 catch ( lang::WrappedTargetException
const & )
897 // getByName, commitChanges
900 "HierarchyEntry::remove - caught WrappedTargetException!" );
902 catch ( uno::Exception
const & )
904 // createInstance, createInstanceWithArguments
906 OSL_FAIL( "HierarchyEntry::remove - caught Exception!" );
912 //=========================================================================
913 sal_Bool
HierarchyEntry::first( iterator
& it
)
915 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
917 if ( it
.m_pImpl
->pos
== -1 )
923 uno::Reference
< container::XHierarchicalNameAccess
>
924 xRootHierNameAccess
= getRootReadAccess();
926 if ( xRootHierNameAccess
.is() )
928 uno::Reference
< container::XNameAccess
> xNameAccess
;
930 if ( !m_aPath
.isEmpty() )
932 rtl::OUString aPath
= m_aPath
;
933 aPath
+= rtl::OUString("/Children");
935 xRootHierNameAccess
->getByHierarchicalName( aPath
)
940 = uno::Reference
< container::XNameAccess
>(
941 xRootHierNameAccess
, uno::UNO_QUERY
);
943 OSL_ENSURE( xNameAccess
.is(),
944 "HierarchyEntry::first - No name access!" );
946 if ( xNameAccess
.is() )
947 it
.m_pImpl
->names
= xNameAccess
->getElementNames();
949 uno::Reference
< container::XHierarchicalNameAccess
>
950 xHierNameAccess( xNameAccess
, uno::UNO_QUERY
);
952 OSL_ENSURE( xHierNameAccess
.is(),
953 "HierarchyEntry::first - No hier. name access!" );
955 it
.m_pImpl
->dir
= xHierNameAccess
;
957 it
.m_pImpl
->officeDirs
= m_xOfficeInstDirs
;
960 catch ( uno::RuntimeException
const & )
964 catch ( container::NoSuchElementException
const& )
966 // getByHierarchicalName
969 "HierarchyEntry::first - caught NoSuchElementException!" );
971 catch ( uno::Exception
const & )
973 OSL_FAIL( "HierarchyEntry::first - caught Exception!" );
977 if ( it
.m_pImpl
->names
.getLength() == 0 )
984 //=========================================================================
985 sal_Bool
HierarchyEntry::next( iterator
& it
)
987 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
989 if ( it
.m_pImpl
->pos
== -1 )
994 return ( it
.m_pImpl
->pos
< it
.m_pImpl
->names
.getLength() );
997 //=========================================================================
998 rtl::OUString
HierarchyEntry::createPathFromHierarchyURL(
999 const HierarchyUri
& rURI
)
1001 // Transform path....
1002 // folder/subfolder/subsubfolder
1003 // --> ['folder']/Children/['subfolder']/Children/['subsubfolder']
1005 const rtl::OUString aPath
= rURI
.getPath().copy( 1 ); // skip leading slash.
1006 sal_Int32 nLen
= aPath
.getLength();
1010 rtl::OUStringBuffer aNewPath
;
1011 aNewPath
.appendAscii( "['" );
1013 sal_Int32 nStart
= 0;
1014 sal_Int32 nEnd
= aPath
.indexOf( '/' );
1021 rtl::OUString aToken
= aPath
.copy( nStart
, nEnd
- nStart
);
1022 makeXMLName( aToken
, aNewPath
);
1026 aNewPath
.appendAscii( "']/Children/['" );
1028 nEnd
= aPath
.indexOf( '/', nStart
);
1031 aNewPath
.appendAscii( "']" );
1033 while ( nEnd
!= nLen
);
1035 return aNewPath
.makeStringAndClear();
1041 //=========================================================================
1042 uno::Reference
< container::XHierarchicalNameAccess
>
1043 HierarchyEntry::getRootReadAccess()
1045 if ( !m_xRootReadAccess
.is() )
1047 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
1048 if ( !m_xRootReadAccess
.is() )
1050 if ( m_bTriedToGetRootReadAccess
) // #82494#
1052 OSL_FAIL( "HierarchyEntry::getRootReadAccess - "
1053 "Unable to read any config data! -> #82494#" );
1054 return uno::Reference
< container::XHierarchicalNameAccess
>();
1059 if ( !m_xConfigProvider
.is() )
1061 = uno::Reference
< lang::XMultiServiceFactory
>(
1062 m_xSMgr
->createInstance( m_aServiceSpecifier
),
1065 if ( m_xConfigProvider
.is() )
1067 // Create Root object.
1069 uno::Sequence
< uno::Any
> aArguments( 1 );
1070 beans::PropertyValue aProperty
;
1071 aProperty
.Name
= rtl::OUString(
1072 CFGPROPERTY_NODEPATH
);
1073 aProperty
.Value
<<= rtl::OUString(); // root path
1074 aArguments
[ 0 ] <<= aProperty
;
1076 m_bTriedToGetRootReadAccess
= sal_True
;
1079 = uno::Reference
< container::XHierarchicalNameAccess
>(
1080 m_xConfigProvider
->createInstanceWithArguments(
1081 rtl::OUString( READ_SERVICE_NAME
),
1086 catch ( uno::RuntimeException
const & )
1090 catch ( uno::Exception
const & )
1092 // createInstance, createInstanceWithArguments
1094 OSL_FAIL( "HierarchyEntry::getRootReadAccess - "
1095 "caught Exception!" );
1099 return m_xRootReadAccess
;
1102 //=========================================================================
1103 //=========================================================================
1105 // HierarchyEntry::iterator Implementation.
1107 //=========================================================================
1108 //=========================================================================
1110 HierarchyEntry::iterator::iterator()
1112 m_pImpl
= new iterator_Impl
;
1115 //=========================================================================
1116 HierarchyEntry::iterator::~iterator()
1121 //=========================================================================
1122 const HierarchyEntryData
& HierarchyEntry::iterator::operator*() const
1124 if ( ( m_pImpl
->pos
!= -1 )
1125 && ( m_pImpl
->dir
.is() )
1126 && ( m_pImpl
->pos
< m_pImpl
->names
.getLength() ) )
1130 rtl::OUStringBuffer aKey
;
1131 aKey
.appendAscii( "['" );
1132 makeXMLName( m_pImpl
->names
.getConstArray()[ m_pImpl
->pos
], aKey
);
1133 aKey
.appendAscii( "']" );
1135 rtl::OUString aTitle
= aKey
.makeStringAndClear();
1136 rtl::OUString aTargetURL
= aTitle
;
1137 rtl::OUString aType
= aTitle
;
1139 aTitle
+= rtl::OUString("/Title");
1140 aTargetURL
+= rtl::OUString("/TargetURL");
1141 aType
+= rtl::OUString("/Type");
1143 rtl::OUString aValue
;
1144 m_pImpl
->dir
->getByHierarchicalName( aTitle
) >>= aValue
;
1145 m_pImpl
->entry
.setTitle( aValue
);
1147 m_pImpl
->dir
->getByHierarchicalName( aTargetURL
) >>= aValue
;
1149 // TargetURL property may contain a reference to the Office
1150 // installation directory. To ensure a reloctable office
1151 // installation, the path to the office installtion directory must
1152 // never be stored directly. A placeholder is used instead. Replace
1153 // it by actual installation directory.
1154 if ( m_pImpl
->officeDirs
.is() && !aValue
.isEmpty() )
1155 aValue
= m_pImpl
->officeDirs
->makeAbsoluteURL( aValue
);
1156 m_pImpl
->entry
.setTargetURL( aValue
);
1158 if ( m_pImpl
->dir
->hasByHierarchicalName( aType
) )
1160 // Might not be present since it was introduced long
1161 // after Title and TargetURL (#82433#)... So not getting
1162 // it is not an error.
1165 sal_Int32 nType
= 0;
1166 if ( m_pImpl
->dir
->getByHierarchicalName( aType
) >>= nType
)
1170 m_pImpl
->entry
.setType( HierarchyEntryData::LINK
);
1172 else if ( nType
== 1 )
1174 m_pImpl
->entry
.setType( HierarchyEntryData::FOLDER
);
1178 OSL_FAIL( "HierarchyEntry::getData - "
1179 "Unknown Type value!" );
1184 m_pImpl
->entry
.setName(
1185 m_pImpl
->names
.getConstArray()[ m_pImpl
->pos
] );
1187 catch ( container::NoSuchElementException
const & )
1189 m_pImpl
->entry
= HierarchyEntryData();
1193 return m_pImpl
->entry
;
1196 } // namespace hierarchy_ucp
1198 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */