LCOV - code coverage report
Current view: top level - ucb/source/ucp/hierarchy - hierarchydata.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 0 449 0.0 %
Date: 2015-06-13 12:38:46 Functions: 0 16 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       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/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      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 .
      18             :  */
      19             : 
      20             : 
      21             : /**************************************************************************
      22             :                                 TODO
      23             :  **************************************************************************
      24             : 
      25             :  - HierarchyEntry::move
      26             :    --> Rewrite to use XNamed ( once this is supported by config db api ).
      27             : 
      28             :  *************************************************************************/
      29             : #include "hierarchydata.hxx"
      30             : 
      31             : #include <vector>
      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"
      42             : 
      43             : using namespace com::sun::star;
      44             : 
      45             : namespace hierarchy_ucp
      46             : {
      47             : 
      48             : 
      49           0 : struct HierarchyEntry::iterator_Impl
      50             : {
      51             :     HierarchyEntryData                                     entry;
      52             :     uno::Reference< container::XHierarchicalNameAccess >   dir;
      53             :     uno::Reference< util::XOfficeInstallationDirectories > officeDirs;
      54             :     uno::Sequence< OUString>                          names;
      55             :     sal_Int32                                              pos;
      56           0 :     iterator_Impl()
      57           0 :     : officeDirs( 0 ), pos( -1 /* before first */ ) {};
      58             : };
      59             : 
      60             : 
      61           0 : void makeXMLName( const OUString & rIn, OUStringBuffer & rBuffer  )
      62             : {
      63           0 :     sal_Int32 nCount = rIn.getLength();
      64           0 :     for ( sal_Int32 n = 0; n < nCount; ++n )
      65             :     {
      66           0 :         const sal_Unicode c = rIn[ n ];
      67           0 :         switch ( c )
      68             :         {
      69             :             case '&':
      70           0 :                 rBuffer.appendAscii( "&amp;" );
      71           0 :                 break;
      72             : 
      73             :             case '"':
      74           0 :                 rBuffer.appendAscii( "&quot;" );
      75           0 :                 break;
      76             : 
      77             :             case '\'':
      78           0 :                 rBuffer.appendAscii( "&apos;" );
      79           0 :                 break;
      80             : 
      81             :             case '<':
      82           0 :                 rBuffer.appendAscii( "&lt;" );
      83           0 :                 break;
      84             : 
      85             :             case '>':
      86           0 :                 rBuffer.appendAscii( "&gt;" );
      87           0 :                 break;
      88             : 
      89             :             default:
      90           0 :                 rBuffer.append( c );
      91           0 :                 break;
      92             :         }
      93             :     }
      94           0 : }
      95             : 
      96             : 
      97             : 
      98             : 
      99             : // HierarchyEntry Implementation.
     100             : 
     101             : 
     102             : 
     103             : 
     104             : #define READ_SERVICE_NAME      "com.sun.star.ucb.HierarchyDataReadAccess"
     105             : #define READWRITE_SERVICE_NAME "com.sun.star.ucb.HierarchyDataReadWriteAccess"
     106             : 
     107             : // describe path of cfg entry
     108             : #define CFGPROPERTY_NODEPATH    "nodepath"
     109             : 
     110             : 
     111           0 : 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           0 :   m_bTriedToGetRootReadAccess( false )
     118             : {
     119           0 :     HierarchyUri aUri( rURL );
     120           0 :     m_aServiceSpecifier = aUri.getService();
     121             : 
     122             :     m_xConfigProvider
     123           0 :         = pProvider->getConfigProvider( m_aServiceSpecifier );
     124             :     m_xRootReadAccess
     125           0 :         = pProvider->getRootConfigReadNameAccess( m_aServiceSpecifier );
     126             : 
     127             :     // Note: do not init m_aPath in init list. createPathFromHierarchyURL
     128             :     //       needs m_xContext and m_aMutex.
     129           0 :     m_aPath = createPathFromHierarchyURL( aUri );
     130             : 
     131             :     // Extract language independent name from URL.
     132           0 :     sal_Int32 nPos = rURL.lastIndexOf( '/' );
     133           0 :     if ( nPos > HIERARCHY_URL_SCHEME_LENGTH )
     134           0 :         m_aName = rURL.copy( nPos + 1 );
     135             :     else
     136           0 :         OSL_FAIL( "HierarchyEntry - Invalid URL!" );
     137           0 : }
     138             : 
     139             : 
     140           0 : bool HierarchyEntry::hasData()
     141             : {
     142           0 :     osl::Guard< osl::Mutex > aGuard( m_aMutex );
     143             :     uno::Reference< container::XHierarchicalNameAccess > xRootReadAccess
     144           0 :         = getRootReadAccess();
     145             : 
     146             :     OSL_ENSURE( xRootReadAccess.is(), "HierarchyEntry::hasData - No root!" );
     147             : 
     148           0 :     if ( xRootReadAccess.is() )
     149           0 :         return xRootReadAccess->hasByHierarchicalName( m_aPath );
     150             : 
     151           0 :     return false;
     152             : }
     153             : 
     154             : 
     155           0 : bool HierarchyEntry::getData( HierarchyEntryData& rData )
     156             : {
     157             :     try
     158             :     {
     159           0 :         osl::Guard< osl::Mutex > aGuard( m_aMutex );
     160             : 
     161             :         uno::Reference< container::XHierarchicalNameAccess > xRootReadAccess
     162           0 :             = getRootReadAccess();
     163             : 
     164             :         OSL_ENSURE( xRootReadAccess.is(),
     165             :                     "HierarchyEntry::getData - No root!" );
     166             : 
     167           0 :         if ( xRootReadAccess.is() )
     168             :         {
     169           0 :             OUString aTitlePath = m_aPath;
     170           0 :             aTitlePath += "/Title";
     171             : 
     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           0 :             if ( !xRootReadAccess->hasByHierarchicalName( aTitlePath ) )
     177           0 :                 return false;
     178             : 
     179           0 :             OUString aValue;
     180             : 
     181             :             // Get Title value.
     182           0 :             if ( !( xRootReadAccess->getByHierarchicalName( aTitlePath )
     183           0 :                     >>= aValue ) )
     184             :             {
     185             :                 OSL_FAIL( "HierarchyEntry::getData - "
     186             :                             "Got no Title value!" );
     187           0 :                 return false;
     188             :             }
     189             : 
     190           0 :             rData.setTitle( aValue );
     191             : 
     192             :             // Get TargetURL value.
     193           0 :             OUString aTargetURLPath = m_aPath;
     194           0 :             aTargetURLPath += "/TargetURL";
     195           0 :             if ( !( xRootReadAccess->getByHierarchicalName( aTargetURLPath )
     196           0 :                     >>= aValue ) )
     197             :             {
     198             :                 OSL_FAIL( "HierarchyEntry::getData - "
     199             :                             "Got no TargetURL value!" );
     200           0 :                 return false;
     201             :             }
     202             : 
     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           0 :             if ( m_xOfficeInstDirs.is() &&  !aValue.isEmpty()  )
     209           0 :                 aValue = m_xOfficeInstDirs->makeAbsoluteURL( aValue );
     210           0 :             rData.setTargetURL( aValue );
     211             : 
     212           0 :             OUString aTypePath = m_aPath;
     213           0 :             aTypePath += "/Type";
     214           0 :             if ( xRootReadAccess->hasByHierarchicalName( aTypePath ) )
     215             :             {
     216             :                 // Might not be present since it was introduced long after
     217             :                 // Title and TargetURL (#82433#)... So not getting it is
     218             :                 // not an error.
     219             : 
     220             :                 // Get Type value.
     221           0 :                 sal_Int32 nType = 0;
     222           0 :                 if ( xRootReadAccess->getByHierarchicalName( aTypePath )
     223           0 :                      >>= nType )
     224             :                 {
     225           0 :                     if ( nType == 0 )
     226             :                     {
     227           0 :                         rData.setType( HierarchyEntryData::LINK );
     228             :                     }
     229           0 :                     else if ( nType == 1 )
     230             :                     {
     231           0 :                         rData.setType( HierarchyEntryData::FOLDER );
     232             :                     }
     233             :                     else
     234             :                     {
     235             :                         OSL_FAIL( "HierarchyEntry::getData - "
     236             :                                     "Unknown Type value!" );
     237           0 :                         return false;
     238             :                     }
     239             :                 }
     240             :             }
     241             : 
     242           0 :             rData.setName( m_aName );
     243           0 :             return true;
     244           0 :         }
     245             :     }
     246           0 :     catch ( uno::RuntimeException const & )
     247             :     {
     248           0 :         throw;
     249             :     }
     250           0 :     catch ( container::NoSuchElementException const & )
     251             :     {
     252             :         // getByHierarchicalName
     253             : 
     254             :         OSL_FAIL( "HierarchyEntry::getData - caught NoSuchElementException!" );
     255             :     }
     256           0 :     return false;
     257             : }
     258             : 
     259             : 
     260           0 : bool HierarchyEntry::setData(
     261             :                     const HierarchyEntryData& rData, bool bCreate )
     262             : {
     263             :     try
     264             :     {
     265           0 :         osl::Guard< osl::Mutex > aGuard( m_aMutex );
     266             : 
     267           0 :         if ( !m_xConfigProvider.is() )
     268           0 :             m_xConfigProvider = uno::Reference< lang::XMultiServiceFactory >(
     269           0 :                 m_xContext->getServiceManager()->createInstanceWithContext(m_aServiceSpecifier, m_xContext),
     270           0 :                 uno::UNO_QUERY );
     271             : 
     272           0 :         if ( m_xConfigProvider.is() )
     273             :         {
     274             :             // Create parent's key. It must exist!
     275             : 
     276           0 :             OUString aParentPath;
     277           0 :             bool bRoot = true;
     278             : 
     279           0 :             sal_Int32 nPos = m_aPath.lastIndexOf( '/' );
     280           0 :             if ( nPos != -1 )
     281             :             {
     282             :                 // Skip "/Children" segment of the path, too.
     283           0 :                 nPos = m_aPath.lastIndexOf( '/', nPos - 1 );
     284             : 
     285             :                 OSL_ENSURE( nPos != -1,
     286             :                             "HierarchyEntry::setData - Wrong path!" );
     287             : 
     288           0 :                 aParentPath += m_aPath.copy( 0, nPos );
     289           0 :                 bRoot = false;
     290             :             }
     291             : 
     292           0 :             uno::Sequence< uno::Any > aArguments( 1 );
     293           0 :             beans::PropertyValue      aProperty;
     294             : 
     295           0 :             aProperty.Name    = CFGPROPERTY_NODEPATH;
     296           0 :             aProperty.Value <<= aParentPath;
     297           0 :             aArguments[ 0 ] <<= aProperty;
     298             : 
     299             :             uno::Reference< util::XChangesBatch > xBatch(
     300           0 :                     m_xConfigProvider->createInstanceWithArguments(
     301             :                         OUString( READWRITE_SERVICE_NAME  ),
     302           0 :                         aArguments ),
     303           0 :                     uno::UNO_QUERY );
     304             : 
     305             :             OSL_ENSURE( xBatch.is(),
     306             :                         "HierarchyEntry::setData - No batch!" );
     307             : 
     308             :             uno::Reference< container::XNameAccess > xParentNameAccess(
     309           0 :                 xBatch, uno::UNO_QUERY );
     310             : 
     311             :             OSL_ENSURE( xParentNameAccess.is(),
     312             :                         "HierarchyEntry::setData - No name access!" );
     313             : 
     314           0 :             if ( xBatch.is() && xParentNameAccess.is() )
     315             :             {
     316             :                 // Try to create own key. It must not exist!
     317             : 
     318           0 :                 bool bExists = true;
     319           0 :                 uno::Any aMyKey;
     320             : 
     321             :                 try
     322             :                 {
     323           0 :                     uno::Reference< container::XNameAccess > xNameAccess;
     324             : 
     325           0 :                     if ( bRoot )
     326             :                     {
     327           0 :                         xNameAccess = xParentNameAccess;
     328             :                     }
     329             :                     else
     330             :                     {
     331           0 :                         xParentNameAccess->getByName(
     332           0 :                             OUString("Children") )
     333           0 :                                 >>= xNameAccess;
     334             :                     }
     335             : 
     336           0 :                     if ( xNameAccess->hasByName( m_aName ) )
     337           0 :                         aMyKey = xNameAccess->getByName( m_aName );
     338             :                     else
     339           0 :                         bExists = false;
     340             :                 }
     341           0 :                 catch ( container::NoSuchElementException const & )
     342             :                 {
     343           0 :                     bExists = false;
     344             :                 }
     345             : 
     346           0 :                 uno::Reference< container::XNameReplace >   xNameReplace;
     347           0 :                 uno::Reference< container::XNameContainer > xContainer;
     348             : 
     349           0 :                 if ( bExists )
     350             :                 {
     351             :                     // Key exists. Replace values.
     352             : 
     353           0 :                     aMyKey >>= xNameReplace;
     354             : 
     355             :                     OSL_ENSURE( xNameReplace.is(),
     356             :                                 "HierarchyEntry::setData - No name replace!" );
     357             :                 }
     358             :                 else
     359             :                 {
     360           0 :                     if ( !bCreate )
     361           0 :                         return true;
     362             : 
     363             :                     // Key does not exist. Create / fill / insert it.
     364             : 
     365           0 :                     uno::Reference< lang::XSingleServiceFactory > xFac;
     366             : 
     367           0 :                     if ( bRoot )
     368             :                     {
     369             :                         // Special handling for children of root,
     370             :                         // which is not an entry. It's only a set
     371             :                         // of entries.
     372           0 :                         xFac = uno::Reference< lang::XSingleServiceFactory >(
     373           0 :                             xParentNameAccess, uno::UNO_QUERY );
     374             :                     }
     375             :                     else
     376             :                     {
     377             :                         // Append new entry to parents child list,
     378             :                         // which is a set of entries.
     379           0 :                         xParentNameAccess->getByName(
     380           0 :                                         OUString( "Children" ) ) >>= xFac;
     381             :                     }
     382             : 
     383             :                     OSL_ENSURE( xFac.is(),
     384             :                                 "HierarchyEntry::setData - No factory!" );
     385             : 
     386           0 :                     if ( xFac.is() )
     387             :                     {
     388             :                         xNameReplace
     389           0 :                             = uno::Reference< container::XNameReplace >(
     390           0 :                                 xFac->createInstance(), uno::UNO_QUERY );
     391             : 
     392             :                         OSL_ENSURE( xNameReplace.is(),
     393             :                                 "HierarchyEntry::setData - No name replace!" );
     394             : 
     395           0 :                         if ( xNameReplace.is() )
     396             :                         {
     397             :                             xContainer
     398           0 :                                 = uno::Reference< container::XNameContainer >(
     399           0 :                                     xFac, uno::UNO_QUERY );
     400             : 
     401             :                             OSL_ENSURE( xContainer.is(),
     402             :                                 "HierarchyEntry::setData - No container!" );
     403             :                         }
     404           0 :                     }
     405             :                 }
     406             : 
     407           0 :                 if ( xNameReplace.is() )
     408             :                 {
     409             :                     // Set Title value.
     410           0 :                     xNameReplace->replaceByName(
     411             :                         OUString("Title"),
     412           0 :                         uno::makeAny( rData.getTitle() ) );
     413             : 
     414             :                     // Set TargetURL value.
     415             : 
     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           0 :                     OUString aValue( rData.getTargetURL() );
     422           0 :                     if ( m_xOfficeInstDirs.is() &&  !aValue.isEmpty() )
     423             :                         aValue
     424           0 :                             = m_xOfficeInstDirs->makeRelocatableURL( aValue );
     425             : 
     426           0 :                     xNameReplace->replaceByName(
     427             :                         OUString("TargetURL"),
     428           0 :                         uno::makeAny( aValue ) );
     429             : 
     430             :                     // Set Type value.
     431             :                     sal_Int32 nType
     432           0 :                         = rData.getType() == HierarchyEntryData::LINK ? 0 : 1;
     433           0 :                     xNameReplace->replaceByName(
     434             :                         OUString("Type"),
     435           0 :                         uno::makeAny( nType ) );
     436             : 
     437           0 :                     if ( xContainer.is() )
     438           0 :                         xContainer->insertByName(
     439           0 :                             m_aName, uno::makeAny( xNameReplace ) );
     440             : 
     441             :                     // Commit changes.
     442           0 :                     xBatch->commitChanges();
     443           0 :                     return true;
     444           0 :                 }
     445           0 :             }
     446           0 :         }
     447             :     }
     448           0 :     catch ( lang::IllegalArgumentException const & )
     449             :     {
     450             :         // replaceByName, insertByName
     451             : 
     452             :         OSL_FAIL(
     453             :             "HierarchyEntry::setData - caught IllegalArgumentException!" );
     454             :     }
     455           0 :     catch ( uno::RuntimeException const & )
     456             :     {
     457           0 :         throw;
     458             :     }
     459           0 :     catch ( container::NoSuchElementException const & )
     460             :     {
     461             :         // replaceByName, getByName
     462             : 
     463             :         OSL_FAIL(
     464             :             "HierarchyEntry::setData - caught NoSuchElementException!" );
     465             :     }
     466           0 :     catch ( container::ElementExistException const & )
     467             :     {
     468             :         // insertByName
     469             : 
     470             :         OSL_FAIL(
     471             :             "HierarchyEntry::setData - caught ElementExistException!" );
     472             :     }
     473           0 :     catch ( lang::WrappedTargetException const & )
     474             :     {
     475             :         // replaceByName, insertByName, getByName, commitChanges
     476             : 
     477             :         OSL_FAIL(
     478             :             "HierarchyEntry::setData - caught WrappedTargetException!" );
     479             :     }
     480           0 :     catch ( uno::Exception const & )
     481             :     {
     482             :         // createInstance, createInstanceWithArguments
     483             : 
     484             :         OSL_FAIL(
     485             :             "HierarchyEntry::setData - caught Exception!" );
     486             :     }
     487             : 
     488           0 :     return false;
     489             : }
     490             : 
     491             : 
     492           0 : bool HierarchyEntry::move(
     493             :     const OUString& rNewURL, const HierarchyEntryData& rData )
     494             : {
     495           0 :     osl::Guard< osl::Mutex > aGuard( m_aMutex );
     496             : 
     497           0 :     OUString aNewPath = createPathFromHierarchyURL( rNewURL );
     498             : 
     499           0 :     if ( aNewPath == m_aPath )
     500           0 :         return true;
     501             : 
     502           0 :     bool bOldRoot = true;
     503           0 :     uno::Reference< util::XChangesBatch > xOldParentBatch;
     504             : 
     505           0 :     OUString aNewKey;
     506           0 :     sal_Int32 nURLPos = rNewURL.lastIndexOf( '/' );
     507           0 :     if ( nURLPos > HIERARCHY_URL_SCHEME_LENGTH )
     508           0 :         aNewKey = rNewURL.copy( nURLPos + 1 );
     509             :     else
     510             :     {
     511             :         OSL_FAIL( "HierarchyEntry::move - Invalid URL!" );
     512           0 :         return false;
     513             :     }
     514             : 
     515           0 :     bool bNewRoot = true;
     516           0 :     uno::Reference< util::XChangesBatch > xNewParentBatch;
     517             : 
     518           0 :     bool bDifferentParents = true;
     519             : 
     520             :     try
     521             :     {
     522           0 :         if ( !m_xConfigProvider.is() )
     523           0 :             m_xConfigProvider = uno::Reference< lang::XMultiServiceFactory >(
     524           0 :                 m_xContext->getServiceManager()->createInstanceWithContext(m_aServiceSpecifier, m_xContext),
     525           0 :                 uno::UNO_QUERY );
     526             : 
     527           0 :         if ( !m_xConfigProvider.is() )
     528           0 :             return false;
     529             : 
     530           0 :         OUString aOldParentPath;
     531           0 :         sal_Int32 nPos = m_aPath.lastIndexOf( '/' );
     532           0 :         if ( nPos != -1 )
     533             :         {
     534             :             // Skip "/Children" segment of the path, too.
     535           0 :             nPos = m_aPath.lastIndexOf( '/', nPos - 1 );
     536             : 
     537             :             OSL_ENSURE( nPos != -1, "HierarchyEntry::move - Wrong path!" );
     538             : 
     539           0 :             aOldParentPath += m_aPath.copy( 0, nPos );
     540           0 :             bOldRoot = false;
     541             :         }
     542             : 
     543           0 :         OUString aNewParentPath;
     544           0 :         nPos = aNewPath.lastIndexOf( '/' );
     545           0 :         if ( nPos != -1 )
     546             :         {
     547             :             // Skip "/Children" segment of the path, too.
     548           0 :             nPos = aNewPath.lastIndexOf( '/', nPos - 1 );
     549             : 
     550             :             OSL_ENSURE( nPos != -1, "HierarchyEntry::move - Wrong path!" );
     551             : 
     552           0 :             aNewParentPath += aNewPath.copy( 0, nPos );
     553           0 :             bNewRoot = false;
     554             :         }
     555             : 
     556           0 :         uno::Sequence< uno::Any > aArguments( 1 );
     557           0 :         beans::PropertyValue      aProperty;
     558             : 
     559           0 :         aProperty.Name  = CFGPROPERTY_NODEPATH;
     560           0 :         aProperty.Value <<= aOldParentPath;
     561           0 :         aArguments[ 0 ] <<= aProperty;
     562             : 
     563           0 :         xOldParentBatch = uno::Reference< util::XChangesBatch >(
     564           0 :             m_xConfigProvider->createInstanceWithArguments(
     565             :                 OUString( READWRITE_SERVICE_NAME  ),
     566           0 :                 aArguments ),
     567           0 :             uno::UNO_QUERY );
     568             : 
     569             :         OSL_ENSURE( xOldParentBatch.is(), "HierarchyEntry::move - No batch!" );
     570             : 
     571           0 :         if ( !xOldParentBatch.is() )
     572           0 :             return false;
     573             : 
     574           0 :         if ( aOldParentPath == aNewParentPath )
     575             :         {
     576           0 :             bDifferentParents = false;
     577           0 :             xNewParentBatch = xOldParentBatch;
     578             :         }
     579             :         else
     580             :         {
     581           0 :             bDifferentParents = true;
     582             : 
     583           0 :             aProperty.Name    = CFGPROPERTY_NODEPATH;
     584           0 :             aProperty.Value <<= aNewParentPath;
     585           0 :             aArguments[ 0 ] <<= aProperty;
     586             : 
     587           0 :             xNewParentBatch = uno::Reference< util::XChangesBatch >(
     588           0 :                 m_xConfigProvider->createInstanceWithArguments(
     589             :                     OUString( READWRITE_SERVICE_NAME  ),
     590           0 :                     aArguments ),
     591           0 :                 uno::UNO_QUERY );
     592             : 
     593             :             OSL_ENSURE(
     594             :                 xNewParentBatch.is(), "HierarchyEntry::move - No batch!" );
     595             : 
     596           0 :             if ( !xNewParentBatch.is() )
     597           0 :                 return false;
     598           0 :         }
     599             :     }
     600           0 :     catch ( uno::RuntimeException const & )
     601             :     {
     602           0 :         throw;
     603             :     }
     604           0 :     catch ( uno::Exception const & )
     605             :     {
     606             :         // createInstance, createInstanceWithArguments
     607             : 
     608             :         OSL_FAIL( "HierarchyEntry::move - caught Exception!" );
     609           0 :         return false;
     610             :     }
     611             : 
     612             : 
     613             :     // (1) Get entry...
     614             : 
     615             : 
     616           0 :     uno::Any aEntry;
     617           0 :     uno::Reference< container::XNameAccess >    xOldParentNameAccess;
     618           0 :     uno::Reference< container::XNameContainer > xOldNameContainer;
     619             : 
     620             :     try
     621             :     {
     622             :         xOldParentNameAccess
     623           0 :             = uno::Reference< container::XNameAccess >(
     624           0 :                 xOldParentBatch, uno::UNO_QUERY );
     625             : 
     626             :         OSL_ENSURE( xOldParentNameAccess.is(),
     627             :                     "HierarchyEntry::move - No name access!" );
     628             : 
     629           0 :         if ( !xOldParentNameAccess.is() )
     630           0 :             return false;
     631             : 
     632           0 :         if ( bOldRoot )
     633             :         {
     634           0 :             xOldNameContainer = uno::Reference< container::XNameContainer >(
     635           0 :                                         xOldParentNameAccess, uno::UNO_QUERY );
     636             :         }
     637             :         else
     638             :         {
     639           0 :             xOldParentNameAccess->getByName(
     640           0 :                  OUString("Children") )
     641           0 :                     >>= xOldNameContainer;
     642             :         }
     643             : 
     644           0 :         aEntry = xOldNameContainer->getByName( m_aName );
     645             :     }
     646           0 :     catch ( container::NoSuchElementException const & )
     647             :     {
     648             :         // getByName
     649             : 
     650             :         OSL_FAIL( "HierarchyEntry::move - caught NoSuchElementException!" );
     651           0 :         return false;
     652             :     }
     653           0 :     catch ( lang::WrappedTargetException const & )
     654             :     {
     655             :         // getByName
     656             : 
     657             :         OSL_FAIL( "HierarchyEntry::move - caught WrappedTargetException!" );
     658           0 :         return false;
     659             :     }
     660             : 
     661             : 
     662             :     // (2) Remove entry... Note: Insert BEFORE remove does not work!
     663             : 
     664             : 
     665             :     try
     666             :     {
     667           0 :         xOldNameContainer->removeByName( m_aName );
     668           0 :         xOldParentBatch->commitChanges();
     669             :     }
     670           0 :     catch ( container::NoSuchElementException const & )
     671             :     {
     672             :         // getByName, removeByName
     673             : 
     674             :         OSL_FAIL( "HierarchyEntry::move - caught NoSuchElementException!" );
     675           0 :         return false;
     676             :     }
     677             : 
     678             : 
     679             :     // (3) Insert entry at new parent...
     680             : 
     681             : 
     682             :     try
     683             :     {
     684           0 :         uno::Reference< container::XNameReplace > xNewNameReplace;
     685           0 :         aEntry >>= xNewNameReplace;
     686             : 
     687             :         OSL_ENSURE( xNewNameReplace.is(),
     688             :                     "HierarchyEntry::move - No name replace!" );
     689             : 
     690           0 :         if ( !xNewNameReplace.is() )
     691           0 :             return false;
     692             : 
     693           0 :         uno::Reference< container::XNameAccess > xNewParentNameAccess;
     694           0 :         if ( bDifferentParents )
     695             :             xNewParentNameAccess
     696           0 :                 = uno::Reference< container::XNameAccess >(
     697           0 :                     xNewParentBatch, uno::UNO_QUERY );
     698             :         else
     699           0 :             xNewParentNameAccess = xOldParentNameAccess;
     700             : 
     701             :         OSL_ENSURE( xNewParentNameAccess.is(),
     702             :                     "HierarchyEntry::move - No name access!" );
     703             : 
     704           0 :         if ( !xNewParentNameAccess.is() )
     705           0 :             return false;
     706             : 
     707           0 :         uno::Reference< container::XNameContainer > xNewNameContainer;
     708           0 :         if ( bDifferentParents )
     709             :         {
     710           0 :             if ( bNewRoot )
     711             :             {
     712             :                 xNewNameContainer
     713           0 :                     = uno::Reference< container::XNameContainer >(
     714           0 :                         xNewParentNameAccess, uno::UNO_QUERY );
     715             :             }
     716             :             else
     717             :             {
     718           0 :                 xNewParentNameAccess->getByName(
     719           0 :                      OUString("Children") )
     720           0 :                         >>= xNewNameContainer;
     721             :             }
     722             :         }
     723             :         else
     724           0 :             xNewNameContainer = xOldNameContainer;
     725             : 
     726           0 :         if ( !xNewNameContainer.is() )
     727           0 :             return false;
     728             : 
     729           0 :         xNewNameReplace->replaceByName(
     730             :             OUString("Title"),
     731           0 :             uno::makeAny( rData.getTitle() ) );
     732             : 
     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
     737             :         // instead.
     738           0 :         OUString aValue( rData.getTargetURL() );
     739           0 :         if ( m_xOfficeInstDirs.is() &&  !aValue.isEmpty() )
     740           0 :             aValue = m_xOfficeInstDirs->makeRelocatableURL( aValue );
     741           0 :         xNewNameReplace->replaceByName(
     742             :             OUString("TargetURL"),
     743           0 :             uno::makeAny( aValue ) );
     744           0 :         sal_Int32 nType = rData.getType() == HierarchyEntryData::LINK ? 0 : 1;
     745           0 :         xNewNameReplace->replaceByName(
     746             :             OUString("Type"),
     747           0 :             uno::makeAny( nType ) );
     748             : 
     749           0 :         xNewNameContainer->insertByName( aNewKey, aEntry );
     750           0 :         xNewParentBatch->commitChanges();
     751             :     }
     752           0 :     catch ( container::NoSuchElementException const & )
     753             :     {
     754             :         // replaceByName, insertByName, getByName
     755             : 
     756             :         OSL_FAIL( "HierarchyEntry::move - caught NoSuchElementException!" );
     757           0 :         return false;
     758             :     }
     759           0 :     catch ( lang::IllegalArgumentException const & )
     760             :     {
     761             :         // replaceByName, insertByName
     762             : 
     763             :         OSL_FAIL(
     764             :             "HierarchyEntry::move - caught IllegalArgumentException!" );
     765           0 :         return false;
     766             :     }
     767           0 :     catch ( container::ElementExistException const & )
     768             :     {
     769             :         // insertByName
     770             : 
     771             :         OSL_FAIL( "HierarchyEntry::move - caught ElementExistException!" );
     772           0 :         return false;
     773             :     }
     774           0 :     catch ( lang::WrappedTargetException const & )
     775             :     {
     776             :         // replaceByName, insertByName, getByName
     777             : 
     778             :         OSL_FAIL( "HierarchyEntry::move - caught WrappedTargetException!" );
     779           0 :         return false;
     780             :     }
     781             : 
     782           0 :     return true;
     783             : }
     784             : 
     785             : 
     786           0 : bool HierarchyEntry::remove()
     787             : {
     788             :     try
     789             :     {
     790           0 :         osl::Guard< osl::Mutex > aGuard( m_aMutex );
     791             : 
     792           0 :         if ( !m_xConfigProvider.is() )
     793           0 :             m_xConfigProvider = uno::Reference< lang::XMultiServiceFactory >(
     794           0 :                 m_xContext->getServiceManager()->createInstanceWithContext(m_aServiceSpecifier, m_xContext),
     795           0 :                 uno::UNO_QUERY );
     796             : 
     797           0 :         if ( m_xConfigProvider.is() )
     798             :         {
     799             :             // Create parent's key. It must exist!
     800             : 
     801           0 :             OUString aParentPath;
     802           0 :             bool bRoot = true;
     803             : 
     804           0 :             sal_Int32 nPos = m_aPath.lastIndexOf( '/' );
     805           0 :             if ( nPos != -1 )
     806             :             {
     807             :                 // Skip "/Children" segment of the path, too.
     808           0 :                 nPos = m_aPath.lastIndexOf( '/', nPos - 1 );
     809             : 
     810             :                 OSL_ENSURE( nPos != -1,
     811             :                             "HierarchyEntry::remove - Wrong path!" );
     812             : 
     813           0 :                 aParentPath += m_aPath.copy( 0, nPos );
     814           0 :                 bRoot = false;
     815             :             }
     816             : 
     817           0 :             uno::Sequence< uno::Any > aArguments( 1 );
     818           0 :             beans::PropertyValue      aProperty;
     819             : 
     820           0 :             aProperty.Name    = CFGPROPERTY_NODEPATH;
     821           0 :             aProperty.Value <<= aParentPath;
     822           0 :             aArguments[ 0 ] <<= aProperty;
     823             : 
     824             :             uno::Reference< util::XChangesBatch > xBatch(
     825           0 :                 m_xConfigProvider->createInstanceWithArguments(
     826             :                     OUString( READWRITE_SERVICE_NAME  ),
     827           0 :                     aArguments ),
     828           0 :                 uno::UNO_QUERY );
     829             : 
     830             :             OSL_ENSURE( xBatch.is(),
     831             :                         "HierarchyEntry::remove - No batch!" );
     832             : 
     833             :             uno::Reference< container::XNameAccess > xParentNameAccess(
     834           0 :                 xBatch, uno::UNO_QUERY );
     835             : 
     836             :             OSL_ENSURE( xParentNameAccess.is(),
     837             :                         "HierarchyEntry::remove - No name access!" );
     838             : 
     839           0 :             if ( xBatch.is() && xParentNameAccess.is() )
     840             :             {
     841           0 :                 uno::Reference< container::XNameContainer > xContainer;
     842             : 
     843           0 :                 if ( bRoot )
     844             :                 {
     845             :                     // Special handling for children of root,
     846             :                     // which is not an entry. It's only a set
     847             :                     // of entries.
     848           0 :                     xContainer = uno::Reference< container::XNameContainer >(
     849           0 :                         xParentNameAccess, uno::UNO_QUERY );
     850             :                 }
     851             :                 else
     852             :                 {
     853             :                     // Append new entry to parents child list,
     854             :                     // which is a set of entries.
     855           0 :                      xParentNameAccess->getByName(
     856           0 :                         OUString("Children") )
     857           0 :                             >>= xContainer;
     858             :                 }
     859             : 
     860             :                 OSL_ENSURE( xContainer.is(),
     861             :                             "HierarchyEntry::remove - No container!" );
     862             : 
     863           0 :                 if ( xContainer.is() )
     864             :                 {
     865           0 :                     xContainer->removeByName( m_aName );
     866           0 :                     xBatch->commitChanges();
     867           0 :                     return true;
     868           0 :                 }
     869           0 :             }
     870           0 :         }
     871             :     }
     872           0 :     catch ( uno::RuntimeException const & )
     873             :     {
     874           0 :         throw;
     875             :     }
     876           0 :     catch ( container::NoSuchElementException const & )
     877             :     {
     878             :         // getByName, removeByName
     879             : 
     880             :         OSL_FAIL(
     881             :             "HierarchyEntry::remove - caught NoSuchElementException!" );
     882             :     }
     883           0 :     catch ( lang::WrappedTargetException const & )
     884             :     {
     885             :         // getByName, commitChanges
     886             : 
     887             :         OSL_FAIL(
     888             :             "HierarchyEntry::remove - caught WrappedTargetException!" );
     889             :     }
     890           0 :     catch ( uno::Exception const & )
     891             :     {
     892             :         // createInstance, createInstanceWithArguments
     893             : 
     894             :         OSL_FAIL( "HierarchyEntry::remove - caught Exception!" );
     895             :     }
     896             : 
     897           0 :     return false;
     898             : }
     899             : 
     900             : 
     901           0 : bool HierarchyEntry::first( iterator& it )
     902             : {
     903           0 :     osl::Guard< osl::Mutex > aGuard( m_aMutex );
     904             : 
     905           0 :     if ( it.m_pImpl->pos == -1 )
     906             :     {
     907             :         // Init...
     908             : 
     909             :         try
     910             :         {
     911             :             uno::Reference< container::XHierarchicalNameAccess >
     912           0 :                 xRootHierNameAccess = getRootReadAccess();
     913             : 
     914           0 :             if ( xRootHierNameAccess.is() )
     915             :             {
     916           0 :                 uno::Reference< container::XNameAccess > xNameAccess;
     917             : 
     918           0 :                 if ( !m_aPath.isEmpty() )
     919             :                 {
     920           0 :                     OUString aPath = m_aPath;
     921           0 :                     aPath += "/Children";
     922             : 
     923           0 :                     xRootHierNameAccess->getByHierarchicalName( aPath )
     924           0 :                         >>= xNameAccess;
     925             :                 }
     926             :                 else
     927             :                     xNameAccess
     928           0 :                         = uno::Reference< container::XNameAccess >(
     929           0 :                                 xRootHierNameAccess, uno::UNO_QUERY );
     930             : 
     931             :                 OSL_ENSURE( xNameAccess.is(),
     932             :                             "HierarchyEntry::first - No name access!" );
     933             : 
     934           0 :                 if ( xNameAccess.is() )
     935           0 :                     it.m_pImpl->names = xNameAccess->getElementNames();
     936             : 
     937             :                 uno::Reference< container::XHierarchicalNameAccess >
     938           0 :                     xHierNameAccess( xNameAccess, uno::UNO_QUERY );
     939             : 
     940             :                 OSL_ENSURE( xHierNameAccess.is(),
     941             :                             "HierarchyEntry::first - No hier. name access!" );
     942             : 
     943           0 :                 it.m_pImpl->dir = xHierNameAccess;
     944             : 
     945           0 :                 it.m_pImpl->officeDirs = m_xOfficeInstDirs;
     946           0 :             }
     947             :         }
     948           0 :         catch ( uno::RuntimeException const & )
     949             :         {
     950           0 :             throw;
     951             :         }
     952           0 :         catch ( container::NoSuchElementException const& )
     953             :         {
     954             :             // getByHierarchicalName
     955             : 
     956             :             OSL_FAIL(
     957             :                 "HierarchyEntry::first - caught NoSuchElementException!" );
     958             :         }
     959           0 :         catch ( uno::Exception const & )
     960             :         {
     961             :             OSL_FAIL( "HierarchyEntry::first - caught Exception!" );
     962             :         }
     963             :     }
     964             : 
     965           0 :     if ( it.m_pImpl->names.getLength() == 0 )
     966           0 :         return false;
     967             : 
     968           0 :     it.m_pImpl->pos = 0;
     969           0 :     return true;
     970             : }
     971             : 
     972             : 
     973           0 : bool HierarchyEntry::next( iterator& it )
     974             : {
     975           0 :     osl::Guard< osl::Mutex > aGuard( m_aMutex );
     976             : 
     977           0 :     if ( it.m_pImpl->pos == -1 )
     978           0 :         return first( it );
     979             : 
     980           0 :     ++(it.m_pImpl->pos);
     981             : 
     982           0 :     return ( it.m_pImpl->pos < it.m_pImpl->names.getLength() );
     983             : }
     984             : 
     985             : 
     986           0 : OUString HierarchyEntry::createPathFromHierarchyURL(
     987             :     const HierarchyUri& rURI )
     988             : {
     989             :     // Transform path....
     990             :     // folder/subfolder/subsubfolder
     991             :     //      --> ['folder']/Children/['subfolder']/Children/['subsubfolder']
     992             : 
     993           0 :     const OUString aPath = rURI.getPath().copy( 1 ); // skip leading slash.
     994           0 :     sal_Int32 nLen = aPath.getLength();
     995             : 
     996           0 :     if ( nLen )
     997             :     {
     998           0 :         OUStringBuffer aNewPath;
     999           0 :         aNewPath.appendAscii( "['" );
    1000             : 
    1001           0 :         sal_Int32 nStart = 0;
    1002           0 :         sal_Int32 nEnd   = aPath.indexOf( '/' );
    1003             : 
    1004           0 :         do
    1005             :         {
    1006           0 :             if ( nEnd == -1 )
    1007           0 :                 nEnd = nLen;
    1008             : 
    1009           0 :             OUString aToken = aPath.copy( nStart, nEnd - nStart );
    1010           0 :             makeXMLName( aToken, aNewPath );
    1011             : 
    1012           0 :             if ( nEnd != nLen )
    1013             :             {
    1014           0 :                 aNewPath.appendAscii( "']/Children/['" );
    1015           0 :                 nStart = nEnd + 1;
    1016           0 :                 nEnd   = aPath.indexOf( '/', nStart );
    1017             :             }
    1018             :             else
    1019           0 :                 aNewPath.appendAscii( "']" );
    1020             :         }
    1021             :         while ( nEnd != nLen );
    1022             : 
    1023           0 :         return aNewPath.makeStringAndClear();
    1024             :     }
    1025             : 
    1026           0 :     return aPath;
    1027             : }
    1028             : 
    1029             : 
    1030             : uno::Reference< container::XHierarchicalNameAccess >
    1031           0 : HierarchyEntry::getRootReadAccess()
    1032             : {
    1033           0 :     if ( !m_xRootReadAccess.is() )
    1034             :     {
    1035           0 :         osl::Guard< osl::Mutex > aGuard( m_aMutex );
    1036           0 :         if ( !m_xRootReadAccess.is() )
    1037             :         {
    1038           0 :             if ( m_bTriedToGetRootReadAccess ) // #82494#
    1039             :             {
    1040             :                 OSL_FAIL( "HierarchyEntry::getRootReadAccess - "
    1041             :                             "Unable to read any config data! -> #82494#" );
    1042           0 :                 return uno::Reference< container::XHierarchicalNameAccess >();
    1043             :             }
    1044             : 
    1045             :             try
    1046             :             {
    1047           0 :                 if ( !m_xConfigProvider.is() )
    1048             :                     m_xConfigProvider
    1049           0 :                         = uno::Reference< lang::XMultiServiceFactory >(
    1050           0 :                             m_xContext->getServiceManager()->createInstanceWithContext(m_aServiceSpecifier, m_xContext),
    1051           0 :                             uno::UNO_QUERY );
    1052             : 
    1053           0 :                 if ( m_xConfigProvider.is() )
    1054             :                 {
    1055             :                     // Create Root object.
    1056             : 
    1057           0 :                     uno::Sequence< uno::Any > aArguments( 1 );
    1058           0 :                     beans::PropertyValue      aProperty;
    1059           0 :                     aProperty.Name = CFGPROPERTY_NODEPATH;
    1060           0 :                     aProperty.Value <<= OUString(); // root path
    1061           0 :                     aArguments[ 0 ] <<= aProperty;
    1062             : 
    1063           0 :                     m_bTriedToGetRootReadAccess = true;
    1064             : 
    1065             :                     m_xRootReadAccess
    1066           0 :                         = uno::Reference< container::XHierarchicalNameAccess >(
    1067           0 :                             m_xConfigProvider->createInstanceWithArguments(
    1068             :                                 OUString( READ_SERVICE_NAME  ),
    1069           0 :                                 aArguments ),
    1070           0 :                             uno::UNO_QUERY );
    1071             :                 }
    1072             :             }
    1073           0 :             catch ( uno::RuntimeException const & )
    1074             :             {
    1075           0 :                 throw;
    1076             :             }
    1077           0 :             catch ( uno::Exception const & )
    1078             :             {
    1079             :                 // createInstance, createInstanceWithArguments
    1080             : 
    1081             :                 OSL_FAIL( "HierarchyEntry::getRootReadAccess - "
    1082             :                             "caught Exception!" );
    1083             :             }
    1084           0 :         }
    1085             :     }
    1086           0 :     return m_xRootReadAccess;
    1087             : }
    1088             : 
    1089             : 
    1090             : 
    1091             : 
    1092             : // HierarchyEntry::iterator Implementation.
    1093             : 
    1094             : 
    1095             : 
    1096             : 
    1097           0 : HierarchyEntry::iterator::iterator()
    1098             : {
    1099           0 :     m_pImpl = new iterator_Impl;
    1100           0 : }
    1101             : 
    1102             : 
    1103           0 : HierarchyEntry::iterator::~iterator()
    1104             : {
    1105           0 :     delete m_pImpl;
    1106           0 : }
    1107             : 
    1108             : 
    1109           0 : const HierarchyEntryData& HierarchyEntry::iterator::operator*() const
    1110             : {
    1111           0 :     if ( ( m_pImpl->pos != -1 )
    1112           0 :          && ( m_pImpl->dir.is() )
    1113           0 :          && ( m_pImpl->pos < m_pImpl->names.getLength() ) )
    1114             :     {
    1115             :         try
    1116             :         {
    1117           0 :             OUStringBuffer aKey;
    1118           0 :             aKey.appendAscii( "['" );
    1119           0 :             makeXMLName( m_pImpl->names.getConstArray()[ m_pImpl->pos ], aKey );
    1120           0 :             aKey.appendAscii( "']" );
    1121             : 
    1122           0 :             OUString aTitle     = aKey.makeStringAndClear();
    1123           0 :             OUString aTargetURL = aTitle;
    1124           0 :             OUString aType      = aTitle;
    1125             : 
    1126           0 :             aTitle     += "/Title";
    1127           0 :             aTargetURL += "/TargetURL";
    1128           0 :             aType      += "/Type";
    1129             : 
    1130           0 :             OUString aValue;
    1131           0 :             m_pImpl->dir->getByHierarchicalName( aTitle ) >>= aValue;
    1132           0 :             m_pImpl->entry.setTitle( aValue );
    1133             : 
    1134           0 :             m_pImpl->dir->getByHierarchicalName( aTargetURL ) >>= aValue;
    1135             : 
    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           0 :             if ( m_pImpl->officeDirs.is() && !aValue.isEmpty() )
    1142           0 :                 aValue = m_pImpl->officeDirs->makeAbsoluteURL( aValue );
    1143           0 :             m_pImpl->entry.setTargetURL( aValue );
    1144             : 
    1145           0 :             if ( m_pImpl->dir->hasByHierarchicalName( aType ) )
    1146             :             {
    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.
    1150             : 
    1151             :                 // Get Type value.
    1152           0 :                 sal_Int32 nType = 0;
    1153           0 :                 if ( m_pImpl->dir->getByHierarchicalName( aType ) >>= nType )
    1154             :                 {
    1155           0 :                     if ( nType == 0 )
    1156             :                     {
    1157           0 :                         m_pImpl->entry.setType( HierarchyEntryData::LINK );
    1158             :                     }
    1159           0 :                     else if ( nType == 1 )
    1160             :                     {
    1161           0 :                         m_pImpl->entry.setType( HierarchyEntryData::FOLDER );
    1162             :                     }
    1163             :                     else
    1164             :                     {
    1165             :                         OSL_FAIL( "HierarchyEntry::getData - "
    1166             :                                     "Unknown Type value!" );
    1167             :                     }
    1168             :                 }
    1169             :             }
    1170             : 
    1171             :             m_pImpl->entry.setName(
    1172           0 :                 m_pImpl->names.getConstArray()[ m_pImpl->pos ] );
    1173             :         }
    1174           0 :         catch ( container::NoSuchElementException const & )
    1175             :         {
    1176           0 :             m_pImpl->entry = HierarchyEntryData();
    1177             :         }
    1178             :     }
    1179             : 
    1180           0 :     return m_pImpl->entry;
    1181             : }
    1182             : 
    1183             : } // namespace hierarchy_ucp
    1184             : 
    1185             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11