Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/LibreOffice/ucb/source/ucp/hierarchy/   (Office von Apache Version 25.8.3.2©)  Datei vom 5.10.2025 mit Größe 32 kB image not shown  

Quelle  hierarchydata.cxx   Sprache: C

 
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */



/**************************************************************************
                                TODO
 **************************************************************************

 - HierarchyEntry::move
   --> Rewrite to use XNamed ( once this is supported by config db api ).

 *************************************************************************/

#include "hierarchydata.hxx"

#include <comphelper/diagnose_ex.hxx>
#include <rtl/ustrbuf.hxx>
#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
#include <com/sun/star/container/XNameContainer.hpp>
#include <com/sun/star/container/XNameReplace.hpp>
#include <com/sun/star/util/XChangesBatch.hpp>
#include <com/sun/star/util/XOfficeInstallationDirectories.hpp>
#include <com/sun/star/lang/XSingleServiceFactory.hpp>
#include <comphelper/propertysequence.hxx>
#include <utility>
#include "hierarchyprovider.hxx"
#include "hierarchyuri.hxx"

using namespace com::sun::star;

namespace hierarchy_ucp
{


static void makeXMLName( std::u16string_view rIn, OUStringBuffer & rBuffer  )
{
    size_t nCount = rIn.size();
    for ( size_t n = 0; n < nCount; ++n )
    {
        const sal_Unicode c = rIn[ n ];
        switch ( c )
        {
            case '&':
                rBuffer.append( "&" );
                break;

            case '"':
                rBuffer.append( """ );
                break;

            case '\'':
                rBuffer.append( "'" );
                break;

            case '<':
                rBuffer.append( "<" );
                break;

            case '>':
                rBuffer.append( ">" );
                break;

            default:
                rBuffer.append( c );
                break;
        }
    }
}


// HierarchyEntry Implementation.


constexpr OUStringLiteral READ_SERVICE_NAME = u"com.sun.star.ucb.HierarchyDataReadAccess";
constexpr OUString READWRITE_SERVICE_NAME = u"com.sun.star.ucb.HierarchyDataReadWriteAccess"_ustr;

// describe path of cfg entry
constexpr OUString CFGPROPERTY_NODEPATH = u"nodepath"_ustr;


HierarchyEntry::HierarchyEntry(
                uno::Reference< uno::XComponentContext > xContext,
                HierarchyContentProvider* pProvider,
                const OUString& rURL )
: m_xContext(std::move( xContext )),
  m_xOfficeInstDirs( pProvider->getOfficeInstallationDirectories() ),
  m_bTriedToGetRootReadAccess( false )
{
    HierarchyUri aUri( rURL );
    m_aServiceSpecifier = aUri.getService();

    m_xConfigProvider
        = pProvider->getConfigProvider( m_aServiceSpecifier );
    m_xRootReadAccess
        = pProvider->getRootConfigReadNameAccess( m_aServiceSpecifier );

    // Note: do not init m_aPath in init list. createPathFromHierarchyURL
    //       needs m_xContext and m_aMutex.
    m_aPath = createPathFromHierarchyURL( aUri );

    // Extract language independent name from URL.
    sal_Int32 nPos = rURL.lastIndexOf( '/' );
    if ( nPos > HIERARCHY_URL_SCHEME_LENGTH )
        m_aName = rURL.copy( nPos + 1 );
    else
        OSL_FAIL( "HierarchyEntry - Invalid URL!" );
}


bool HierarchyEntry::hasData()
{
    uno::Reference< container::XHierarchicalNameAccess > xRootReadAccess
        = getRootReadAccess();

    OSL_ENSURE( xRootReadAccess.is(), "HierarchyEntry::hasData - No root!" );

    if ( xRootReadAccess.is() )
        return xRootReadAccess->hasByHierarchicalName( m_aPath );

    return false;
}


bool HierarchyEntry::getData( HierarchyEntryData& rData )
{
    try
    {
        uno::Reference< container::XHierarchicalNameAccess > xRootReadAccess
            = getRootReadAccess();

        OSL_ENSURE( xRootReadAccess.is(),
                    "HierarchyEntry::getData - No root!" );

        if ( xRootReadAccess.is() )
        {
            OUString aTitlePath = m_aPath + "/Title";

            // Note: Avoid NoSuchElementExceptions, because exceptions are
            //       relatively 'expensive'. Checking for availability of
            //       title value is sufficient here, because if it is
            //       there, the other values will be available too.
            if ( !xRootReadAccess->hasByHierarchicalName( aTitlePath ) )
                return false;

            OUString aValue;

            // Get Title value.
            if ( !( xRootReadAccess->getByHierarchicalName( aTitlePath )
                    >>= aValue ) )
            {
                OSL_FAIL( "HierarchyEntry::getData - "
                            "Got no Title value!" );
                return false;
            }

            rData.setTitle( aValue );

            // Get TargetURL value.
            OUString aTargetURLPath = m_aPath + "/TargetURL";
            if ( !( xRootReadAccess->getByHierarchicalName( aTargetURLPath )
                    >>= aValue ) )
            {
                OSL_FAIL( "HierarchyEntry::getData - "
                            "Got no TargetURL value!" );
                return false;
            }

            // TargetURL property may contain a reference to the Office
            // installation directory. To ensure a reloctable office
            // installation, the path to the office installation directory must
            // never be stored directly. A placeholder is used instead. Replace
            // it by actual installation directory.
            if ( m_xOfficeInstDirs.is() &&  !aValue.isEmpty()  )
                aValue = m_xOfficeInstDirs->makeAbsoluteURL( aValue );
            rData.setTargetURL( aValue );

            OUString aTypePath = m_aPath + "/Type";
            if ( xRootReadAccess->hasByHierarchicalName( aTypePath ) )
            {
                // Might not be present since it was introduced long after
                // Title and TargetURL (#82433#)... So not getting it is
                // not an error.

                // Get Type value.
                sal_Int32 nType = 0;
                if ( xRootReadAccess->getByHierarchicalName( aTypePath )
                     >>= nType )
                {
                    if ( nType == 0 )
                    {
                        rData.setType( HierarchyEntryData::LINK );
                    }
                    else if ( nType == 1 )
                    {
                        rData.setType( HierarchyEntryData::FOLDER );
                    }
                    else
                    {
                        OSL_FAIL( "HierarchyEntry::getData - "
                                    "Unknown Type value!" );
                        return false;
                    }
                }
            }

            rData.setName( m_aName );
            return true;
        }
    }
    catch ( uno::RuntimeException const & )
    {
        throw;
    }
    catch ( container::NoSuchElementException const & )
    {
        // getByHierarchicalName

        TOOLS_WARN_EXCEPTION("ucb.ucp""");
    }
    return false;
}


bool HierarchyEntry::setData( const HierarchyEntryData& rData )
{
    try
    {
        std::unique_lock aGuard( m_aMutex );

        if ( !m_xConfigProvider.is() )
            m_xConfigProvider.set(
                m_xContext->getServiceManager()->createInstanceWithContext(m_aServiceSpecifier, m_xContext),
                uno::UNO_QUERY );

        if ( m_xConfigProvider.is() )
        {
            // Create parent's key. It must exist!

            OUString aParentPath;
            bool bRoot = true;

            sal_Int32 nPos = m_aPath.lastIndexOf( '/' );
            if ( nPos != -1 )
            {
                // Skip "/Children" segment of the path, too.
                nPos = m_aPath.lastIndexOf( '/', nPos - 1 );

                OSL_ENSURE( nPos != -1,
                            "HierarchyEntry::setData - Wrong path!" );

                aParentPath += m_aPath.subView( 0, nPos );
                bRoot = false;
            }

            uno::Sequence<uno::Any> aArguments(comphelper::InitAnyPropertySequence(
            {
                {CFGPROPERTY_NODEPATH, uno::Any(aParentPath)}
            }));

            uno::Reference< util::XChangesBatch > xBatch(
                    m_xConfigProvider->createInstanceWithArguments(
                        READWRITE_SERVICE_NAME,
                        aArguments ),
                    uno::UNO_QUERY );

            OSL_ENSURE( xBatch.is(),
                        "HierarchyEntry::setData - No batch!" );

            uno::Reference< container::XNameAccess > xParentNameAccess(
                xBatch, uno::UNO_QUERY );

            OSL_ENSURE( xParentNameAccess.is(),
                        "HierarchyEntry::setData - No name access!" );

            if ( xBatch.is() && xParentNameAccess.is() )
            {
                // Try to create own key. It must not exist!

                bool bExists = true;
                uno::Any aMyKey;

                try
                {
                    uno::Reference< container::XNameAccess > xNameAccess;

                    if ( bRoot )
                    {
                        xNameAccess = xParentNameAccess;
                    }
                    else
                    {
                        xParentNameAccess->getByName(u"Children"_ustr) >>= xNameAccess;
                    }

                    if ( xNameAccess->hasByName( m_aName ) )
                        aMyKey = xNameAccess->getByName( m_aName );
                    else
                        bExists = false;
                }
                catch ( container::NoSuchElementException const & )
                {
                    bExists = false;
                }

                uno::Reference< container::XNameReplace >   xNameReplace;
                uno::Reference< container::XNameContainer > xContainer;

                if ( bExists )
                {
                    // Key exists. Replace values.

                    aMyKey >>= xNameReplace;

                    OSL_ENSURE( xNameReplace.is(),
                                "HierarchyEntry::setData - No name replace!" );
                }
                else
                {
                    // Key does not exist. Create / fill / insert it.

                    uno::Reference< lang::XSingleServiceFactory > xFac;

                    if ( bRoot )
                    {
                        // Special handling for children of root,
                        // which is not an entry. It's only a set
                        // of entries.
                        xFac.set( xParentNameAccess, uno::UNO_QUERY );
                    }
                    else
                    {
                        // Append new entry to parents child list,
                        // which is a set of entries.
                        xParentNameAccess->getByName(u"Children"_ustr) >>= xFac;
                    }

                    OSL_ENSURE( xFac.is(),
                                "HierarchyEntry::setData - No factory!" );

                    if ( xFac.is() )
                    {
                        xNameReplace.set( xFac->createInstance(), uno::UNO_QUERY );

                        OSL_ENSURE( xNameReplace.is(),
                                "HierarchyEntry::setData - No name replace!" );

                        if ( xNameReplace.is() )
                        {
                            xContainer.set( xFac, uno::UNO_QUERY );

                            OSL_ENSURE( xContainer.is(),
                                "HierarchyEntry::setData - No container!" );
                        }
                    }
                }

                if ( xNameReplace.is() )
                {
                    // Set Title value.
                    xNameReplace->replaceByName(
                        u"Title"_ustr,
                        uno::Any( rData.getTitle() ) );

                    // Set TargetURL value.

                    // TargetURL property may contain a reference to the Office
                    // installation directory. To ensure a reloctable office
                    // installation, the path to the office installation
                    // directory must never be stored directly. Use a
                    // placeholder instead.
                    OUString aValue( rData.getTargetURL() );
                    if ( m_xOfficeInstDirs.is() &&  !aValue.isEmpty() )
                        aValue
                            = m_xOfficeInstDirs->makeRelocatableURL( aValue );

                    xNameReplace->replaceByName(
                        u"TargetURL"_ustr,
                        uno::Any( aValue ) );

                    // Set Type value.
                    sal_Int32 nType
                        = rData.getType() == HierarchyEntryData::LINK ? 0 : 1;
                    xNameReplace->replaceByName(
                        u"Type"_ustr,
                        uno::Any( nType ) );

                    if ( xContainer.is() )
                        xContainer->insertByName(
                            m_aName, uno::Any( xNameReplace ) );

                    // Commit changes.
                    xBatch->commitChanges();
                    return true;
                }
            }
        }
    }
    catch ( lang::IllegalArgumentException const & )
    {
        // replaceByName, insertByName

        TOOLS_WARN_EXCEPTION("ucb.ucp""");
    }
    catch ( uno::RuntimeException const & )
    {
        throw;
    }
    catch ( container::NoSuchElementException const & )
    {
        // replaceByName, getByName

        TOOLS_WARN_EXCEPTION("ucb.ucp""");
    }
    catch ( container::ElementExistException const & )
    {
        // insertByName

        TOOLS_WARN_EXCEPTION("ucb.ucp""");
    }
    catch ( lang::WrappedTargetException const & )
    {
        // replaceByName, insertByName, getByName, commitChanges

        TOOLS_WARN_EXCEPTION("ucb.ucp""");
    }
    catch ( uno::Exception const & )
    {
        // createInstance, createInstanceWithArguments

        TOOLS_WARN_EXCEPTION("ucb.ucp""");
    }

    return false;
}


bool HierarchyEntry::move(
    const OUString& rNewURL, const HierarchyEntryData& rData )
{
    OUString aNewPath = createPathFromHierarchyURL( HierarchyUri(rNewURL) );

    std::unique_lock aGuard( m_aMutex );

    if ( aNewPath == m_aPath )
        return true;

    bool bOldRoot = true;
    uno::Reference< util::XChangesBatch > xOldParentBatch;

    OUString aNewKey;
    sal_Int32 nURLPos = rNewURL.lastIndexOf( '/' );
    if ( nURLPos > HIERARCHY_URL_SCHEME_LENGTH )
        aNewKey = rNewURL.copy( nURLPos + 1 );
    else
    {
        OSL_FAIL( "HierarchyEntry::move - Invalid URL!" );
        return false;
    }

    bool bNewRoot = true;
    uno::Reference< util::XChangesBatch > xNewParentBatch;

    bool bDifferentParents = true;

    try
    {
        if ( !m_xConfigProvider.is() )
            m_xConfigProvider.set(
                m_xContext->getServiceManager()->createInstanceWithContext(m_aServiceSpecifier, m_xContext),
                uno::UNO_QUERY );

        if ( !m_xConfigProvider.is() )
            return false;

        OUString aOldParentPath;
        sal_Int32 nPos = m_aPath.lastIndexOf( '/' );
        if ( nPos != -1 )
        {
            // Skip "/Children" segment of the path, too.
            nPos = m_aPath.lastIndexOf( '/', nPos - 1 );

            OSL_ENSURE( nPos != -1, "HierarchyEntry::move - Wrong path!" );

            aOldParentPath += m_aPath.subView( 0, nPos );
            bOldRoot = false;
        }

        OUString aNewParentPath;
        nPos = aNewPath.lastIndexOf( '/' );
        if ( nPos != -1 )
        {
            // Skip "/Children" segment of the path, too.
            nPos = aNewPath.lastIndexOf( '/', nPos - 1 );

            OSL_ENSURE( nPos != -1, "HierarchyEntry::move - Wrong path!" );

            aNewParentPath += aNewPath.subView( 0, nPos );
            bNewRoot = false;
        }

        uno::Sequence<uno::Any> aArguments(comphelper::InitAnyPropertySequence(
        {
            {CFGPROPERTY_NODEPATH, uno::Any(aOldParentPath)}
        }));

        xOldParentBatch.set(
            m_xConfigProvider->createInstanceWithArguments(
                READWRITE_SERVICE_NAME,
                aArguments ),
            uno::UNO_QUERY );

        OSL_ENSURE( xOldParentBatch.is(), "HierarchyEntry::move - No batch!" );

        if ( !xOldParentBatch.is() )
            return false;

        if ( aOldParentPath == aNewParentPath )
        {
            bDifferentParents = false;
            xNewParentBatch = xOldParentBatch;
        }
        else
        {
            uno::Sequence<uno::Any> aArguments2(comphelper::InitAnyPropertySequence(
            {
                {CFGPROPERTY_NODEPATH, uno::Any(aNewParentPath)}
            }));

            xNewParentBatch.set(
                m_xConfigProvider->createInstanceWithArguments(
                    READWRITE_SERVICE_NAME,
                    aArguments2 ),
                uno::UNO_QUERY );

            OSL_ENSURE(
                xNewParentBatch.is(), "HierarchyEntry::move - No batch!" );

            if ( !xNewParentBatch.is() )
                return false;
        }
    }
    catch ( uno::RuntimeException const & )
    {
        throw;
    }
    catch ( uno::Exception const & )
    {
        // createInstance, createInstanceWithArguments

        TOOLS_WARN_EXCEPTION("ucb.ucp""");
        return false;
    }


    // (1) Get entry...


    uno::Any aEntry;
    uno::Reference< container::XNameAccess >    xOldParentNameAccess;
    uno::Reference< container::XNameContainer > xOldNameContainer;

    try
    {
        xOldParentNameAccess.set( xOldParentBatch, uno::UNO_QUERY );

        OSL_ENSURE( xOldParentNameAccess.is(),
                    "HierarchyEntry::move - No name access!" );

        if ( !xOldParentNameAccess.is() )
            return false;

        if ( bOldRoot )
        {
            xOldNameContainer.set( xOldParentNameAccess, uno::UNO_QUERY );
        }
        else
        {
            xOldParentNameAccess->getByName(u"Children"_ustr) >>= xOldNameContainer;
        }

        aEntry = xOldNameContainer->getByName( m_aName );
    }
    catch ( container::NoSuchElementException const & )
    {
        // getByName

        TOOLS_WARN_EXCEPTION("ucb.ucp""");
        return false;
    }
    catch ( lang::WrappedTargetException const & )
    {
        // getByName

        TOOLS_WARN_EXCEPTION("ucb.ucp""");
        return false;
    }


    // (2) Remove entry... Note: Insert BEFORE remove does not work!


    try
    {
        xOldNameContainer->removeByName( m_aName );
        xOldParentBatch->commitChanges();
    }
    catch ( container::NoSuchElementException const & )
    {
        // getByName, removeByName

        TOOLS_WARN_EXCEPTION("ucb.ucp""");
        return false;
    }


    // (3) Insert entry at new parent...


    try
    {
        uno::Reference< container::XNameReplace > xNewNameReplace;
        aEntry >>= xNewNameReplace;

        OSL_ENSURE( xNewNameReplace.is(),
                    "HierarchyEntry::move - No name replace!" );

        if ( !xNewNameReplace.is() )
            return false;

        uno::Reference< container::XNameAccess > xNewParentNameAccess;
        if ( bDifferentParents )
            xNewParentNameAccess.set( xNewParentBatch, uno::UNO_QUERY );
        else
            xNewParentNameAccess = std::move(xOldParentNameAccess);

        OSL_ENSURE( xNewParentNameAccess.is(),
                    "HierarchyEntry::move - No name access!" );

        if ( !xNewParentNameAccess.is() )
            return false;

        uno::Reference< container::XNameContainer > xNewNameContainer;
        if ( bDifferentParents )
        {
            if ( bNewRoot )
            {
                xNewNameContainer.set( xNewParentNameAccess, uno::UNO_QUERY );
            }
            else
            {
                xNewParentNameAccess->getByName(u"Children"_ustr) >>= xNewNameContainer;
            }
        }
        else
            xNewNameContainer = std::move(xOldNameContainer);

        if ( !xNewNameContainer.is() )
            return false;

        xNewNameReplace->replaceByName(
            u"Title"_ustr,
            uno::Any( rData.getTitle() ) );

        // TargetURL property may contain a reference to the Office
        // installation directory. To ensure a reloctable office
        // installation, the path to the office installation
        // directory must never be stored directly. Use a placeholder
        // instead.
        OUString aValue( rData.getTargetURL() );
        if ( m_xOfficeInstDirs.is() &&  !aValue.isEmpty() )
            aValue = m_xOfficeInstDirs->makeRelocatableURL( aValue );
        xNewNameReplace->replaceByName(
            u"TargetURL"_ustr,
            uno::Any( aValue ) );
        sal_Int32 nType = rData.getType() == HierarchyEntryData::LINK ? 0 : 1;
        xNewNameReplace->replaceByName(
            u"Type"_ustr,
            uno::Any( nType ) );

        xNewNameContainer->insertByName( aNewKey, aEntry );
        xNewParentBatch->commitChanges();
    }
    catch ( container::NoSuchElementException const & )
    {
        // replaceByName, insertByName, getByName

        TOOLS_WARN_EXCEPTION("ucb.ucp""");
        return false;
    }
    catch ( lang::IllegalArgumentException const & )
    {
        // replaceByName, insertByName

        TOOLS_WARN_EXCEPTION("ucb.ucp""");
        return false;
    }
    catch ( container::ElementExistException const & )
    {
        // insertByName

        TOOLS_WARN_EXCEPTION("ucb.ucp""");
        return false;
    }
    catch ( lang::WrappedTargetException const & )
    {
        // replaceByName, insertByName, getByName

        TOOLS_WARN_EXCEPTION("ucb.ucp""");
        return false;
    }

    return true;
}


bool HierarchyEntry::remove()
{
    try
    {
        std::unique_lock aGuard( m_aMutex );

        if ( !m_xConfigProvider.is() )
            m_xConfigProvider.set(
                m_xContext->getServiceManager()->createInstanceWithContext(m_aServiceSpecifier, m_xContext),
                uno::UNO_QUERY );

        if ( m_xConfigProvider.is() )
        {
            // Create parent's key. It must exist!

            OUString aParentPath;
            bool bRoot = true;

            sal_Int32 nPos = m_aPath.lastIndexOf( '/' );
            if ( nPos != -1 )
            {
                // Skip "/Children" segment of the path, too.
                nPos = m_aPath.lastIndexOf( '/', nPos - 1 );

                OSL_ENSURE( nPos != -1,
                            "HierarchyEntry::remove - Wrong path!" );

                aParentPath += m_aPath.subView( 0, nPos );
                bRoot = false;
            }

            uno::Sequence<uno::Any> aArguments(comphelper::InitAnyPropertySequence(
            {
                {CFGPROPERTY_NODEPATH, uno::Any(aParentPath)}
            }));

            uno::Reference< util::XChangesBatch > xBatch(
                m_xConfigProvider->createInstanceWithArguments(
                    READWRITE_SERVICE_NAME,
                    aArguments ),
                uno::UNO_QUERY );

            OSL_ENSURE( xBatch.is(),
                        "HierarchyEntry::remove - No batch!" );

            uno::Reference< container::XNameAccess > xParentNameAccess(
                xBatch, uno::UNO_QUERY );

            OSL_ENSURE( xParentNameAccess.is(),
                        "HierarchyEntry::remove - No name access!" );

            if ( xBatch.is() && xParentNameAccess.is() )
            {
                uno::Reference< container::XNameContainer > xContainer;

                if ( bRoot )
                {
                    // Special handling for children of root,
                    // which is not an entry. It's only a set
                    // of entries.
                    xContainer.set( xParentNameAccess, uno::UNO_QUERY );
                }
                else
                {
                    // Append new entry to parents child list,
                    // which is a set of entries.
                     xParentNameAccess->getByName(u"Children"_ustr) >>= xContainer;
                }

                OSL_ENSURE( xContainer.is(),
                            "HierarchyEntry::remove - No container!" );

                if ( xContainer.is() )
                {
                    xContainer->removeByName( m_aName );
                    xBatch->commitChanges();
                    return true;
                }
            }
        }
    }
    catch ( uno::RuntimeException const & )
    {
        throw;
    }
    catch ( container::NoSuchElementException const & )
    {
        // getByName, removeByName

        OSL_FAIL(
            "HierarchyEntry::remove - caught NoSuchElementException!" );
    }
    catch ( lang::WrappedTargetException const & )
    {
        // getByName, commitChanges

        OSL_FAIL(
            "HierarchyEntry::remove - caught WrappedTargetException!" );
    }
    catch ( uno::Exception const & )
    {
        // createInstance, createInstanceWithArguments

        TOOLS_WARN_EXCEPTION("ucb.ucp""");
    }

    return false;
}


bool HierarchyEntry::first( iterator & it )
{
    if ( it.pos == -1 )
    {
        // Init...

        try
        {
            uno::Reference< container::XHierarchicalNameAccess >
                xRootHierNameAccess = getRootReadAccess();

            if ( xRootHierNameAccess.is() )
            {
                uno::Reference< container::XNameAccess > xNameAccess;

                if ( !m_aPath.isEmpty() )
                {
                    OUString aPath = m_aPath + "/Children";

                    xRootHierNameAccess->getByHierarchicalName( aPath )
                        >>= xNameAccess;
                }
                else
                    xNameAccess.set( xRootHierNameAccess, uno::UNO_QUERY );

                OSL_ENSURE( xNameAccess.is(),
                            "HierarchyEntry::first - No name access!" );

                if ( xNameAccess.is() )
                    it.names = xNameAccess->getElementNames();

                uno::Reference< container::XHierarchicalNameAccess >
                    xHierNameAccess( xNameAccess, uno::UNO_QUERY );

                OSL_ENSURE( xHierNameAccess.is(),
                            "HierarchyEntry::first - No hier. name access!" );

                it.dir = std::move(xHierNameAccess);

                it.officeDirs = m_xOfficeInstDirs;
            }
        }
        catch ( uno::RuntimeException const & )
        {
            throw;
        }
        catch ( container::NoSuchElementException const& )
        {
            // getByHierarchicalName

            TOOLS_WARN_EXCEPTION("ucb.ucp""");
        }
        catch ( uno::Exception const & )
        {
            TOOLS_WARN_EXCEPTION("ucb.ucp""");
        }
    }

    if ( !it.names.hasElements() )
        return false;

    it.pos = 0;
    return true;
}


bool HierarchyEntry::next( iterator& it )
{
    if ( it.pos == -1 )
        return first( it );

    ++it.pos;

    return ( it.pos < it.names.getLength() );
}


OUString HierarchyEntry::createPathFromHierarchyURL(
    const HierarchyUri& rURI )
{
    // Transform path...
    // folder/subfolder/subsubfolder
    //      --> ['folder']/Children/['subfolder']/Children/['subsubfolder']

    const OUString aPath = rURI.getPath().copy( 1 ); // skip leading slash.
    sal_Int32 nLen = aPath.getLength();

    if ( nLen )
    {
        OUStringBuffer aNewPath( "['" );

        sal_Int32 nStart = 0;
        sal_Int32 nEnd   = aPath.indexOf( '/' );

        do
        {
            if ( nEnd == -1 )
                nEnd = nLen;

            OUString aToken = aPath.copy( nStart, nEnd - nStart );
            makeXMLName( aToken, aNewPath );

            if ( nEnd != nLen )
            {
                aNewPath.append( "']/Children/['" );
                nStart = nEnd + 1;
                nEnd   = aPath.indexOf( '/', nStart );
            }
            else
                aNewPath.append( "']" );
        }
        while ( nEnd != nLen );

        return aNewPath.makeStringAndClear();
    }

    return aPath;
}


uno::Reference< container::XHierarchicalNameAccess >
HierarchyEntry::getRootReadAccess()
{
    if ( !m_xRootReadAccess.is() )
    {
        std::unique_lock aGuard( m_aMutex );
        if ( !m_xRootReadAccess.is() )
        {
            if ( m_bTriedToGetRootReadAccess )
            {
                OSL_FAIL( "HierarchyEntry::getRootReadAccess - "
                            "Unable to read any config data! -> #82494#" );
                return uno::Reference< container::XHierarchicalNameAccess >();
            }

            try
            {
                if ( !m_xConfigProvider.is() )
                    m_xConfigProvider.set(
                            m_xContext->getServiceManager()->createInstanceWithContext(m_aServiceSpecifier, m_xContext),
                            uno::UNO_QUERY );

                if ( m_xConfigProvider.is() )
                {
                    // Create Root object.

                    uno::Sequence<uno::Any> aArguments(comphelper::InitAnyPropertySequence(
                    {
                        {CFGPROPERTY_NODEPATH, uno::Any(OUString())} // root path
                    }));

                    m_bTriedToGetRootReadAccess = true;

                    m_xRootReadAccess.set(
                            m_xConfigProvider->createInstanceWithArguments(
                                READ_SERVICE_NAME,
                                aArguments ),
                            uno::UNO_QUERY );
                }
            }
            catch ( uno::RuntimeException const & )
            {
                throw;
            }
            catch ( uno::Exception const & )
            {
                // createInstance, createInstanceWithArguments

                TOOLS_WARN_EXCEPTION("ucb.ucp""");
            }
        }
    }
    return m_xRootReadAccess;
}


// HierarchyEntry::iterator Implementation.


const HierarchyEntryData& HierarchyEntry::iterator::operator*()
{
    if ( ( pos != -1 )
         && ( dir.is() )
         && ( pos < names.getLength() ) )
    {
        try
        {
            OUStringBuffer aKey( "['" );
            makeXMLName( names.getConstArray()[ pos ], aKey );
            aKey.append( "']" );

            OUString aTitle     = aKey.makeStringAndClear();
            OUString aTargetURL = aTitle;
            OUString aType      = aTitle;

            aTitle     += "/Title";
            aTargetURL += "/TargetURL";
            aType      += "/Type";

            OUString aValue;
            dir->getByHierarchicalName( aTitle ) >>= aValue;
            entry.setTitle( aValue );

            dir->getByHierarchicalName( aTargetURL ) >>= aValue;

            // TargetURL property may contain a reference to the Office
            // installation directory. To ensure a reloctable office
            // installation, the path to the office installation directory must
            // never be stored directly. A placeholder is used instead. Replace
            // it by actual installation directory.
            if ( officeDirs.is() && !aValue.isEmpty() )
                aValue = officeDirs->makeAbsoluteURL( aValue );
            entry.setTargetURL( aValue );

            if ( dir->hasByHierarchicalName( aType ) )
            {
                // Might not be present since it was introduced long
                // after Title and TargetURL (#82433#)... So not getting
                // it is not an error.

                // Get Type value.
                sal_Int32 nType = 0;
                if ( dir->getByHierarchicalName( aType ) >>= nType )
                {
                    if ( nType == 0 )
                    {
                        entry.setType( HierarchyEntryData::LINK );
                    }
                    else if ( nType == 1 )
                    {
                        entry.setType( HierarchyEntryData::FOLDER );
                    }
                    else
                    {
                        OSL_FAIL( "HierarchyEntry::getData - "
                                    "Unknown Type value!" );
                    }
                }
            }

            entry.setName(
                names.getConstArray()[ pos ] );
        }
        catch ( container::NoSuchElementException const & )
        {
            entry = HierarchyEntryData();
        }
    }

    return entry;
}

// namespace hierarchy_ucp

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Messung V0.5
C=95 H=97 G=95

¤ Dauer der Verarbeitung: 0.9 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.