LCOV - code coverage report
Current view: top level - libreoffice/xmlhelp/source/treeview - tvread.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 599 0.0 %
Date: 2012-12-27 Functions: 0 61 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             : #include <string.h>
      21             : #include <rtl/ustrbuf.hxx>
      22             : #include <osl/diagnose.h>
      23             : #include "tvread.hxx"
      24             : #include <expat.h>
      25             : #include <osl/file.hxx>
      26             : #include <unotools/configmgr.hxx>
      27             : #include <com/sun/star/configuration/theDefaultProvider.hpp>
      28             : #include <com/sun/star/ucb/SimpleFileAccess.hpp>
      29             : #include <com/sun/star/frame/XConfigManager.hpp>
      30             : #include <com/sun/star/beans/PropertyValue.hpp>
      31             : 
      32             : #include <comphelper/processfactory.hxx>
      33             : #include "com/sun/star/deployment/thePackageManagerFactory.hpp"
      34             : #include <com/sun/star/util/XMacroExpander.hpp>
      35             : #include <com/sun/star/uri/UriReferenceFactory.hpp>
      36             : #include <com/sun/star/uri/XVndSunStarExpandUrl.hpp>
      37             : #include <comphelper/locale.hxx>
      38             : #include <comphelper/string.hxx>
      39             : 
      40             : namespace treeview {
      41             : 
      42             : 
      43             :     class TVDom
      44             :     {
      45             :         friend class TVChildTarget;
      46             :         friend class TVRead;
      47             : 
      48             :     public:
      49             : 
      50           0 :         TVDom( TVDom* arent = 0 )
      51             :             : kind( other ),
      52             :               parent( arent ),
      53           0 :               children( 0 )
      54             :         {
      55           0 :         }
      56             : 
      57           0 :         ~TVDom()
      58           0 :         {
      59           0 :             for( unsigned i = 0; i < children.size(); ++i )
      60           0 :                 delete children[i];
      61           0 :         }
      62             : 
      63             : 
      64           0 :         TVDom* newChild()
      65             :         {
      66           0 :             children.push_back( new TVDom( this ) );
      67           0 :             return children.back();
      68             :         }
      69             : 
      70           0 :         TVDom* newChild(TVDom* p)
      71             :         {
      72           0 :             children.push_back( p );
      73           0 :             p->parent = this;
      74           0 :             return children.back();
      75             :         }
      76             : 
      77             : 
      78           0 :         TVDom* getParent() const
      79             :         {
      80           0 :             if( parent )
      81           0 :                 return parent;
      82             :             else
      83           0 :                 return const_cast<TVDom*>(this);    // I am my own parent, if I am the root
      84             :         }
      85             : 
      86             :         enum Kind {
      87             :             tree_view,
      88             :             tree_node,
      89             :             tree_leaf,
      90             :             other
      91             :         };
      92             : 
      93           0 :         bool isLeaf() const { return kind == TVDom::tree_leaf; }
      94           0 :         void setKind( Kind ind ) { kind = ind; }
      95             :         Kind getKind( ) const { return kind; }
      96             : 
      97             : 
      98           0 :         void setApplication( const char* appl )
      99             :         {
     100             :             application = rtl::OUString( (sal_Char*)(appl),
     101           0 :                                          strlen( appl ),
     102           0 :                                          RTL_TEXTENCODING_UTF8 );
     103           0 :         }
     104             : 
     105           0 :         void setTitle( const char* itle )
     106             :         {
     107             :             title += rtl::OUString( (sal_Char*)(itle),
     108           0 :                                     strlen( itle ),
     109           0 :                                     RTL_TEXTENCODING_UTF8 );
     110           0 :         }
     111             : 
     112           0 :         void setTitle( const XML_Char* itle,int len )
     113             :         {
     114             :             title += rtl::OUString( (sal_Char*)(itle),
     115             :                                     len,
     116           0 :                                     RTL_TEXTENCODING_UTF8 );
     117           0 :         }
     118             : 
     119           0 :         void setId( const char* d )
     120             :         {
     121             :             id = rtl::OUString( (sal_Char*)(d),
     122           0 :                                 strlen( d ),
     123           0 :                                 RTL_TEXTENCODING_UTF8 );
     124           0 :         }
     125             : 
     126           0 :         void setAnchor( const char* nchor )
     127             :         {
     128             :             anchor = rtl::OUString( (sal_Char*)(nchor),
     129           0 :                                     strlen( nchor ),
     130           0 :                                     RTL_TEXTENCODING_UTF8 );
     131           0 :         }
     132             : 
     133           0 :         rtl::OUString getTargetURL()
     134             :         {
     135           0 :             if( targetURL.isEmpty() )
     136             :             {
     137             :                 sal_Int32 len;
     138           0 :                 for ( const TVDom* p = this;; p = p->parent )
     139             :                 {
     140           0 :                     len = p->application.getLength();
     141           0 :                     if ( len != 0 )
     142           0 :                         break;
     143             :                 }
     144             : 
     145           0 :                 rtl::OUStringBuffer strBuff( 22 + len + id.getLength() );
     146             :                 strBuff.appendAscii(
     147             :                                     "vnd.sun.star.help://"
     148           0 :                                     ).append(id);
     149             : 
     150           0 :                 targetURL = strBuff.makeStringAndClear();
     151             :             }
     152             : 
     153           0 :             return targetURL;
     154             :         }
     155             : 
     156             :     private:
     157             : 
     158             :         Kind   kind;
     159             :         rtl::OUString  application;
     160             :         rtl::OUString  title;
     161             :         rtl::OUString  id;
     162             :         rtl::OUString  anchor;
     163             :         rtl::OUString  targetURL;
     164             : 
     165             :         TVDom *parent;
     166             :         std::vector< TVDom* > children;
     167             :     };
     168             : 
     169             : }
     170             : 
     171             : 
     172             : 
     173             : using namespace treeview;
     174             : using namespace com::sun::star;
     175             : using namespace com::sun::star::uno;
     176             : using namespace com::sun::star::beans;
     177             : using namespace com::sun::star::configuration;
     178             : using namespace com::sun::star::lang;
     179             : using namespace com::sun::star::util;
     180             : using namespace com::sun::star::frame;
     181             : using namespace com::sun::star::container;
     182             : using namespace com::sun::star::deployment;
     183             : 
     184             : 
     185           0 : ConfigData::ConfigData()
     186             :     : prodName("%PRODUCTNAME"),
     187             :       prodVersion("%PRODUCTVERSION"),
     188             :       vendName("%VENDORNAME"),
     189             :       vendVersion("%VENDORVERSION"),
     190           0 :       vendShort("%VENDORSHORT")
     191             : {
     192           0 : }
     193             : 
     194           0 : void SAL_CALL ConfigData::replaceName( rtl::OUString& oustring ) const
     195             : {
     196           0 :     sal_Int32 idx = -1,k = 0,off;
     197           0 :     bool cap = false;
     198           0 :     rtl::OUStringBuffer aStrBuf( 0 );
     199             : 
     200           0 :     while( ( idx = oustring.indexOf( sal_Unicode('%'),++idx ) ) != -1 )
     201             :     {
     202           0 :         if( oustring.indexOf( prodName,idx ) == idx )
     203           0 :             off = PRODUCTNAME;
     204           0 :         else if( oustring.indexOf( prodVersion,idx ) == idx )
     205           0 :             off = PRODUCTVERSION;
     206           0 :         else if( oustring.indexOf( vendName,idx ) == idx )
     207           0 :             off = VENDORNAME;
     208           0 :         else if( oustring.indexOf( vendVersion,idx ) == idx )
     209           0 :             off = VENDORVERSION;
     210           0 :         else if( oustring.indexOf( vendShort,idx ) == idx )
     211           0 :             off = VENDORSHORT;
     212             :         else
     213           0 :             off = -1;
     214             : 
     215           0 :         if( off != -1 )
     216             :         {
     217           0 :             if( ! cap )
     218             :             {
     219           0 :                 cap = true;
     220           0 :                 aStrBuf.ensureCapacity( 256 );
     221             :             }
     222             : 
     223           0 :             aStrBuf.append( &oustring.getStr()[k],idx - k );
     224           0 :             aStrBuf.append( m_vReplacement[off] );
     225           0 :             k = idx + m_vAdd[off];
     226             :         }
     227             :     }
     228             : 
     229           0 :     if( cap )
     230             :     {
     231           0 :         if( k < oustring.getLength() )
     232           0 :             aStrBuf.append( &oustring.getStr()[k],oustring.getLength()-k );
     233           0 :         oustring = aStrBuf.makeStringAndClear();
     234           0 :     }
     235           0 : }
     236             : 
     237             : 
     238             : 
     239             : 
     240             : //////////////////////////////////////////////////////////////////////////
     241             : // XInterface
     242             : //////////////////////////////////////////////////////////////////////////
     243             : 
     244             : 
     245             : void SAL_CALL
     246           0 : TVBase::acquire(
     247             :     void )
     248             :     throw()
     249             : {
     250           0 :   OWeakObject::acquire();
     251           0 : }
     252             : 
     253             : 
     254             : void SAL_CALL
     255           0 : TVBase::release(
     256             :               void )
     257             :   throw()
     258             : {
     259           0 :   OWeakObject::release();
     260           0 : }
     261             : 
     262             : 
     263             : Any SAL_CALL
     264           0 : TVBase::queryInterface(
     265             :     const Type& rType )
     266             :     throw( RuntimeException )
     267             : {
     268             :     Any aRet = cppu::queryInterface( rType,
     269             :                                      (static_cast< XTypeProvider* >(this)),
     270             :                                      (static_cast< XNameAccess* >(this)),
     271             :                                      (static_cast< XHierarchicalNameAccess* >(this)),
     272             :                                      (static_cast< XChangesNotifier* >(this)),
     273           0 :                                      (static_cast< XComponent* >(this)) );
     274             : 
     275           0 :     return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType );
     276             : }
     277             : 
     278             : 
     279             : ////////////////////////////////////////////////////////////////////////////////
     280             : //
     281             : // XTypeProvider methods.
     282             : 
     283           0 : XTYPEPROVIDER_IMPL_5( TVBase,
     284             :                          XTypeProvider,
     285             :                       XNameAccess,
     286             :                       XHierarchicalNameAccess,
     287             :                       XChangesNotifier,
     288             :                       XComponent );
     289             : 
     290             : 
     291             : 
     292             : 
     293             : 
     294             : 
     295             : // TVRead
     296             : 
     297             : 
     298           0 : TVRead::TVRead( const ConfigData& configData,TVDom* tvDom )
     299             : {
     300           0 :     if( ! tvDom )
     301           0 :         return;
     302             : 
     303           0 :     Title = tvDom->title;
     304           0 :     configData.replaceName( Title );
     305           0 :     if( tvDom->isLeaf() )
     306             :     {
     307           0 :         TargetURL = ( tvDom->getTargetURL() + configData.appendix );
     308           0 :         if( !tvDom->anchor.isEmpty() )
     309             :             TargetURL += ( rtl::OUString( "#" ) +
     310           0 :                            tvDom->anchor );
     311             :     }
     312             :     else
     313           0 :         Children = new TVChildTarget( configData,tvDom );
     314             : }
     315             : 
     316             : 
     317             : 
     318           0 : TVRead::~TVRead()
     319             : {
     320           0 : }
     321             : 
     322             : 
     323             : 
     324             : 
     325             : 
     326             : 
     327             : // XNameAccess
     328             : 
     329             : Any SAL_CALL
     330           0 : TVRead::getByName( const rtl::OUString& aName )
     331             :     throw( NoSuchElementException,
     332             :            WrappedTargetException,
     333             :            RuntimeException )
     334             : {
     335           0 :     bool found( true );
     336           0 :     Any aAny;
     337           0 :     if( aName.compareToAscii( "Title" ) == 0 )
     338           0 :         aAny <<= Title;
     339           0 :     else if( aName.compareToAscii( "TargetURL" ) == 0 )
     340           0 :         aAny <<= TargetURL;
     341           0 :     else if( aName.compareToAscii( "Children" ) == 0 )
     342             :     {
     343           0 :         cppu::OWeakObject* p = Children.get();
     344           0 :         aAny <<= Reference< XInterface >( p );
     345             :     }
     346             :     else
     347           0 :         found = false;
     348             : 
     349           0 :     if( found )
     350           0 :         return aAny;
     351             : 
     352           0 :     throw NoSuchElementException();
     353             : }
     354             : 
     355             : 
     356             : 
     357             : 
     358             : Sequence< rtl::OUString > SAL_CALL
     359           0 : TVRead::getElementNames( )
     360             :     throw( RuntimeException )
     361             : {
     362           0 :     Sequence< rtl::OUString > seq( 3 );
     363             : 
     364           0 :     seq[0] = rtl::OUString( "Title" );
     365           0 :     seq[1] = rtl::OUString( "TargetURL" );
     366           0 :     seq[2] = rtl::OUString( "Children" );
     367             : 
     368           0 :     return seq;
     369             : }
     370             : 
     371             : 
     372             : 
     373             : sal_Bool SAL_CALL
     374           0 : TVRead::hasByName( const rtl::OUString& aName )
     375             :     throw( RuntimeException )
     376             : {
     377           0 :     if( aName.compareToAscii( "Title" ) == 0        ||
     378           0 :         aName.compareToAscii( "TargetURL" ) == 0    ||
     379           0 :         aName.compareToAscii( "Children" ) == 0 )
     380           0 :         return true;
     381             : 
     382           0 :     return false;
     383             : }
     384             : 
     385             : 
     386             : // XHierarchicalNameAccess
     387             : 
     388             : Any SAL_CALL
     389           0 : TVRead::getByHierarchicalName( const rtl::OUString& aName )
     390             :     throw( NoSuchElementException,
     391             :            RuntimeException )
     392             : {
     393             :     sal_Int32 idx;
     394           0 :     rtl::OUString name( aName );
     395             : 
     396           0 :     if( ( idx = name.indexOf( sal_Unicode( '/' ) ) ) != -1  &&
     397           0 :         name.copy( 0,idx ).compareToAscii( "Children" ) == 0 )
     398           0 :         return Children->getByHierarchicalName( name.copy( 1 + idx ) );
     399             : 
     400           0 :     return getByName( name );
     401             : }
     402             : 
     403             : 
     404             : 
     405             : 
     406             : sal_Bool SAL_CALL
     407           0 : TVRead::hasByHierarchicalName( const rtl::OUString& aName )
     408             :     throw( RuntimeException )
     409             : {
     410             :     sal_Int32 idx;
     411           0 :     rtl::OUString name( aName );
     412             : 
     413           0 :        if( ( idx = name.indexOf( sal_Unicode( '/' ) ) ) != -1  &&
     414           0 :         name.copy( 0,idx ).compareToAscii( "Children" ) == 0 )
     415           0 :         return Children->hasByHierarchicalName( name.copy( 1 + idx ) );
     416             : 
     417           0 :     return hasByName( name );
     418             : }
     419             : 
     420             : 
     421             : 
     422             : /**************************************************************************/
     423             : /*                                                                        */
     424             : /*                      TVChildTarget                                     */
     425             : /*                                                                        */
     426             : /**************************************************************************/
     427             : 
     428             : 
     429             : 
     430             : 
     431           0 : extern "C" void start_handler(void *userData,
     432             :                    const XML_Char *name,
     433             :                    const XML_Char **atts)
     434             : {
     435             :     TVDom::Kind kind;
     436             : 
     437           0 :     if( strcmp( name,"help_section" ) == 0  ||
     438           0 :         strcmp( name,"node" ) == 0 )
     439           0 :         kind = TVDom::tree_node;
     440           0 :     else if( strcmp( name,"topic" ) == 0 )
     441           0 :         kind = TVDom::tree_leaf;
     442             :     else
     443           0 :         return;
     444             : 
     445           0 :     TVDom **tvDom = static_cast< TVDom** >( userData );
     446             :     TVDom  *p;
     447           0 :     p = *tvDom;
     448             : 
     449           0 :     *tvDom = p->newChild();
     450           0 :     p = *tvDom;
     451             : 
     452           0 :     p->setKind( kind );
     453           0 :     while( *atts )
     454             :     {
     455           0 :         if( strcmp( *atts,"application" ) == 0 )
     456           0 :             p->setApplication( *(atts+1) );
     457           0 :         else if( strcmp( *atts,"title" ) == 0 )
     458           0 :             p->setTitle( *(atts+1) );
     459           0 :         else if( strcmp( *atts,"id" ) == 0 )
     460           0 :             p->setId( *(atts+1) );
     461           0 :         else if( strcmp( *atts,"anchor" ) == 0 )
     462           0 :             p->setAnchor( *(atts+1) );
     463             : 
     464           0 :         atts+=2;
     465             :     }
     466             : }
     467             : 
     468             : 
     469           0 : extern "C" void end_handler(void *userData,
     470             :                  const XML_Char *name )
     471             : {
     472             :     (void)name;
     473             : 
     474           0 :     TVDom **tvDom = static_cast< TVDom** >( userData );
     475           0 :     *tvDom = (*tvDom)->getParent();
     476           0 : }
     477             : 
     478             : 
     479           0 : extern "C" void data_handler( void *userData,
     480             :                    const XML_Char *s,
     481             :                    int len)
     482             : {
     483           0 :     TVDom **tvDom = static_cast< TVDom** >( userData );
     484           0 :     if( (*tvDom)->isLeaf() )
     485           0 :         (*tvDom)->setTitle( s,len );
     486           0 : }
     487             : 
     488           0 : TVChildTarget::TVChildTarget( const ConfigData& configData,TVDom* tvDom )
     489             : {
     490           0 :     Elements.resize( tvDom->children.size() );
     491           0 :     for( unsigned i = 0; i < Elements.size(); ++i )
     492           0 :         Elements[i] = new TVRead( configData,tvDom->children[i] );
     493           0 : }
     494             : 
     495           0 : TVChildTarget::TVChildTarget( const Reference< XMultiServiceFactory >& xMSF )
     496             : {
     497           0 :     ConfigData configData = init( xMSF );
     498             : 
     499           0 :     if( configData.locale.isEmpty() || configData.system.isEmpty() )
     500           0 :         return;
     501             : 
     502           0 :     sal_uInt64  ret,len = 0;
     503           0 :     int j = configData.vFileURL.size();
     504             : 
     505           0 :     TVDom tvDom;
     506           0 :     TVDom* pTVDom = &tvDom;
     507             : 
     508           0 :     while( j )
     509             :     {
     510           0 :         len = configData.vFileLen[--j];
     511           0 :         char* s = new char[ int(len) ];  // the buffer to hold the installed files
     512           0 :         osl::File aFile( configData.vFileURL[j] );
     513           0 :         aFile.open( osl_File_OpenFlag_Read );
     514           0 :         aFile.read( s,len,ret );
     515           0 :         aFile.close();
     516             : 
     517           0 :         XML_Parser parser = XML_ParserCreate( 0 );
     518             :         XML_SetElementHandler( parser,
     519             :                                start_handler,
     520           0 :                                end_handler );
     521             :         XML_SetCharacterDataHandler( parser,
     522           0 :                                      data_handler);
     523           0 :         XML_SetUserData( parser,&pTVDom ); // does not return this
     524             : 
     525           0 :         XML_Status const parsed = XML_Parse(parser, s, int(len), j==0);
     526             :         SAL_WARN_IF(XML_STATUS_ERROR == parsed, "xmlhelp",
     527             :                 "TVChildTarget::TVChildTarget(): Tree file parsing failed");
     528             : 
     529           0 :         XML_ParserFree( parser );
     530           0 :         delete[] s;
     531             : 
     532           0 :         Check(pTVDom);
     533           0 :     }
     534             :     // now TVDom holds the relevant information
     535             : 
     536           0 :     Elements.resize( tvDom.children.size() );
     537           0 :     for( unsigned i = 0; i < Elements.size(); ++i )
     538           0 :         Elements[i] = new TVRead( configData,tvDom.children[i] );
     539             : }
     540             : 
     541             : 
     542           0 : TVChildTarget::~TVChildTarget()
     543             : {
     544           0 : }
     545             : 
     546           0 : void TVChildTarget::Check(TVDom* tvDom)
     547             : {
     548           0 :         unsigned i = 0;
     549           0 :         bool h = false;
     550             : 
     551           0 :         while((i<tvDom->children.size()-1) && (!h))
     552             :         {
     553           0 :             if (((tvDom->children[i])->application == (tvDom->children[tvDom->children.size()-1])->application) &&
     554           0 :                 ((tvDom->children[i])->id == (tvDom->children[tvDom->children.size()-1])->id))
     555             :             {
     556           0 :                 TVDom* p = tvDom->children[tvDom->children.size()-1];
     557             : 
     558           0 :                 for(unsigned k=0; k<p->children.size(); ++k)
     559           0 :                     if (!SearchAndInsert(p->children[k], tvDom->children[i]))       tvDom->children[i]->newChild(p->children[k]);
     560             : 
     561           0 :                 tvDom->children.pop_back();
     562           0 :                 h = true;
     563             :             }
     564           0 :             ++i;
     565             :         }
     566           0 : }
     567             : 
     568           0 : bool TVChildTarget::SearchAndInsert(TVDom* p, TVDom* tvDom)
     569             : {
     570           0 :     if (p->isLeaf()) return false;
     571             : 
     572           0 :     bool h = false;
     573           0 :     sal_Int32 max = 0;
     574             : 
     575           0 :     std::vector< TVDom* >::iterator max_It, i;
     576           0 :     max_It = tvDom->children.begin();
     577             : 
     578             :     sal_Int32 c_int;
     579           0 :     sal_Int32 p_int = p->id.toInt32();
     580             : 
     581             : ////////////////////////////////check this level in the tree
     582           0 :     for(i = tvDom->children.begin(); i!=tvDom->children.end(); ++i)
     583           0 :         if (!((*i)->isLeaf()) &&
     584           0 :             ((*i)->id.getLength() == p->id.getLength()) &&
     585           0 :             (p->id.replaceAt((*i)->parent->id.getLength(), p->id.getLength()-(*i)->parent->id.getLength(), OUString("")) == (*i)->parent->id))      //prefix check
     586             :         {
     587           0 :             h = true;
     588           0 :             c_int = (*i)->id.toInt32();
     589             : 
     590           0 :             if (p_int==c_int)
     591             :             {
     592           0 :                 (*(tvDom->children.insert(i+1, p)))->parent = tvDom;
     593           0 :                 return true;
     594             :             }
     595           0 :             else if(c_int>max && c_int < p_int)
     596             :             {
     597           0 :                 max = c_int;
     598           0 :                 max_It = i+1;
     599             :             }
     600             :         }
     601             : ////////////////////////////////recursive call if necessary
     602           0 :     if (h) (*(tvDom->children.insert(max_It, p)))->parent = tvDom;
     603             :     else
     604             :     {
     605           0 :         i = tvDom->children.begin();
     606           0 :         while ((i!=tvDom->children.end()) && (!h))
     607             :         {
     608           0 :             h = SearchAndInsert(p, *i);
     609           0 :             ++i;
     610             :         }
     611             :     }
     612           0 :     return h;
     613             : }
     614             : 
     615             : Any SAL_CALL
     616           0 : TVChildTarget::getByName( const rtl::OUString& aName )
     617             :     throw( NoSuchElementException,
     618             :            WrappedTargetException,
     619             :            RuntimeException )
     620             : {
     621           0 :     rtl::OUString num( aName.getStr()+2,aName.getLength()-4 );
     622           0 :     sal_Int32 idx = num.toInt32() - 1;
     623           0 :     if( idx < 0 || Elements.size() <= sal_uInt32( idx ) )
     624           0 :         throw NoSuchElementException();
     625             : 
     626           0 :     Any aAny;
     627           0 :     cppu::OWeakObject* p = Elements[idx].get();
     628           0 :     aAny <<= Reference< XInterface >( p );
     629           0 :     return aAny;
     630             : }
     631             : 
     632             : 
     633             : 
     634             : 
     635             : Sequence< rtl::OUString > SAL_CALL
     636           0 : TVChildTarget::getElementNames( )
     637             :     throw( RuntimeException )
     638             : {
     639           0 :     Sequence< rtl::OUString > seq( Elements.size() );
     640           0 :     for( unsigned i = 0; i < Elements.size(); ++i )
     641           0 :         seq[i] = rtl::OUString::valueOf( sal_Int32( 1+i ) );
     642             : 
     643           0 :     return seq;
     644             : }
     645             : 
     646             : 
     647             : 
     648             : sal_Bool SAL_CALL
     649           0 : TVChildTarget::hasByName( const rtl::OUString& aName )
     650             :     throw( RuntimeException )
     651             : {
     652           0 :     rtl::OUString num( aName.getStr()+2,aName.getLength()-4 );
     653           0 :     sal_Int32 idx = num.toInt32() - 1;
     654           0 :     if( idx < 0 || Elements.size() <= sal_uInt32( idx ) )
     655           0 :         return false;
     656             : 
     657           0 :     return true;
     658             : }
     659             : 
     660             : 
     661             : 
     662             : // XHierarchicalNameAccess
     663             : 
     664             : Any SAL_CALL
     665           0 : TVChildTarget::getByHierarchicalName( const rtl::OUString& aName )
     666             :     throw( NoSuchElementException,
     667             :            RuntimeException )
     668             : {
     669             :     sal_Int32 idx;
     670           0 :     rtl::OUString name( aName );
     671             : 
     672           0 :     if( ( idx = name.indexOf( sal_Unicode( '/' ) ) ) != -1 )
     673             :     {
     674           0 :         rtl::OUString num( name.getStr()+2,idx-4 );
     675           0 :         sal_Int32 pref = num.toInt32() - 1;
     676             : 
     677           0 :         if( pref < 0 || Elements.size() <= sal_uInt32( pref ) )
     678           0 :             throw NoSuchElementException();
     679             : 
     680           0 :         return Elements[pref]->getByHierarchicalName( name.copy( 1 + idx ) );
     681             :     }
     682             :     else
     683           0 :         return getByName( name );
     684             : }
     685             : 
     686             : 
     687             : 
     688             : sal_Bool SAL_CALL
     689           0 : TVChildTarget::hasByHierarchicalName( const rtl::OUString& aName )
     690             :     throw( RuntimeException )
     691             : {
     692             :     sal_Int32 idx;
     693           0 :     rtl::OUString name( aName );
     694             : 
     695           0 :        if( ( idx = name.indexOf( sal_Unicode( '/' ) ) ) != -1 )
     696             :     {
     697           0 :         rtl::OUString num( name.getStr()+2,idx-4 );
     698           0 :         sal_Int32 pref = num.toInt32() - 1;
     699           0 :         if( pref < 0 || Elements.size() <= sal_uInt32( pref ) )
     700           0 :             return false;
     701             : 
     702           0 :         return Elements[pref]->hasByHierarchicalName( name.copy( 1 + idx ) );
     703             :     }
     704             :     else
     705           0 :         return hasByName( name );
     706             : }
     707             : 
     708             : 
     709             : 
     710             : 
     711             : 
     712             : 
     713           0 : ConfigData TVChildTarget::init( const Reference< XMultiServiceFactory >& xSMgr )
     714             : {
     715           0 :     ConfigData configData;
     716           0 :     Reference< XMultiServiceFactory > sProvider( getConfiguration(comphelper::getComponentContext(xSMgr)) );
     717             : 
     718             :     /**********************************************************************/
     719             :     /*                       reading Office.Common                        */
     720             :     /**********************************************************************/
     721             : 
     722             :     Reference< XHierarchicalNameAccess > xHierAccess( getHierAccess( sProvider,
     723           0 :                                                                      "org.openoffice.Office.Common" ) );
     724           0 :     rtl::OUString system( getKey( xHierAccess,"Help/System" ) );
     725           0 :     sal_Bool showBasic( getBooleanKey(xHierAccess,"Help/ShowBasic") );
     726           0 :     rtl::OUString instPath( getKey( xHierAccess,"Path/Current/Help" ) );
     727           0 :     if( instPath.isEmpty() )
     728             :       // try to determine path from default
     729           0 :       instPath = rtl::OUString( "$(instpath)/help" );
     730             : 
     731             :     // replace anything like $(instpath);
     732           0 :     subst( xSMgr,instPath );
     733             : 
     734             :     /**********************************************************************/
     735             :     /*                       reading setup                                */
     736             :     /**********************************************************************/
     737             : 
     738             :     xHierAccess = getHierAccess( sProvider,
     739           0 :                                  "org.openoffice.Setup" );
     740             : 
     741           0 :     rtl::OUString setupversion( getKey( xHierAccess,"Product/ooSetupVersion" ) );
     742           0 :     rtl::OUString setupextension;
     743             : 
     744             :     try
     745             :     {
     746           0 :         Reference< lang::XMultiServiceFactory > xConfigProvider = theDefaultProvider::get( comphelper::getComponentContext(xSMgr) );
     747             : 
     748           0 :         uno::Sequence < uno::Any > lParams(1);
     749           0 :         beans::PropertyValue                       aParam ;
     750           0 :         aParam.Name    = ::rtl::OUString("nodepath");
     751           0 :         aParam.Value <<= ::rtl::OUString("/org.openoffice.Setup/Product");
     752           0 :         lParams[0] = uno::makeAny(aParam);
     753             : 
     754             :         // open it
     755           0 :         uno::Reference< uno::XInterface > xCFG( xConfigProvider->createInstanceWithArguments(
     756             :                     ::rtl::OUString("com.sun.star.configuration.ConfigurationAccess"),
     757           0 :                     lParams) );
     758             : 
     759           0 :         uno::Reference< container::XNameAccess > xDirectAccess(xCFG, uno::UNO_QUERY);
     760           0 :         uno::Any aRet = xDirectAccess->getByName(::rtl::OUString("ooSetupExtension"));
     761             : 
     762           0 :         aRet >>= setupextension;
     763             :     }
     764           0 :     catch ( uno::Exception& )
     765             :     {
     766             :     }
     767             : 
     768             :     rtl::OUString productVersion( setupversion +
     769           0 :                                   rtl::OUString( " " ) +
     770           0 :                                   setupextension );
     771           0 :     rtl::OUString locale( getKey( xHierAccess,"L10N/ooLocale" ) );
     772             : 
     773             : 
     774             :     // Determine fileurl from url and locale
     775           0 :     rtl::OUString url;
     776           0 :     osl::FileBase::RC errFile = osl::FileBase::getFileURLFromSystemPath( instPath,url );
     777           0 :     if( errFile != osl::FileBase::E_None ) return configData;
     778           0 :     if( url.lastIndexOf( sal_Unicode( '/' ) ) != url.getLength() - 1 )
     779           0 :         url += rtl::OUString( "/" );
     780           0 :     rtl::OUString ret;
     781             :     sal_Int32 idx;
     782           0 :     osl::DirectoryItem aDirItem;
     783           0 :     if( osl::FileBase::E_None == osl::DirectoryItem::get( url + locale,aDirItem ) )
     784           0 :         ret = locale;
     785           0 :     else if( ( ( idx = locale.indexOf( '-' ) ) != -1 ||
     786             :                ( idx = locale.indexOf( '_' ) ) != -1 ) &&
     787           0 :              osl::FileBase::E_None == osl::DirectoryItem::get( url + locale.copy( 0,idx ),
     788           0 :                                                                aDirItem ) )
     789           0 :         ret = locale.copy( 0,idx );
     790             :     else
     791             :         {
     792           0 :         locale = rtl::OUString( "en-US" );
     793           0 :         ret = rtl::OUString("en");
     794             :         }
     795           0 :     url = url + ret;
     796             : 
     797             :     // first of all, try do determine whether there are any *.tree files present
     798             : 
     799             :     // Start with extensions to set them at the end of the list
     800           0 :     TreeFileIterator aTreeIt( locale );
     801           0 :     rtl::OUString aTreeFile;
     802             :     sal_Int32 nFileSize;
     803           0 :     while( !(aTreeFile = aTreeIt.nextTreeFile( nFileSize ) ).isEmpty() )
     804             :     {
     805           0 :         configData.vFileLen.push_back( nFileSize );
     806           0 :         configData.vFileURL.push_back( aTreeFile );
     807             :     }
     808             : 
     809           0 :     osl::Directory aDirectory( url );
     810           0 :     osl::FileStatus aFileStatus( osl_FileStatus_Mask_FileName | osl_FileStatus_Mask_FileSize | osl_FileStatus_Mask_FileURL );
     811           0 :     if( osl::Directory::E_None == aDirectory.open() )
     812             :     {
     813           0 :         int idx_ = 0;
     814           0 :         rtl::OUString aFileUrl, aFileName;
     815           0 :         while( aDirectory.getNextItem( aDirItem ) == osl::FileBase::E_None &&
     816           0 :                aDirItem.getFileStatus( aFileStatus ) == osl::FileBase::E_None &&
     817           0 :                aFileStatus.isValid( osl_FileStatus_Mask_FileURL ) &&
     818           0 :                aFileStatus.isValid( osl_FileStatus_Mask_FileName ) )
     819             :           {
     820           0 :             aFileUrl = aFileStatus.getFileURL();
     821           0 :             aFileName = aFileStatus.getFileName();
     822           0 :             idx_ = aFileName.lastIndexOf( sal_Unicode( '.' ) );
     823           0 :             if( idx_ == -1 )
     824           0 :               continue;
     825             : 
     826           0 :             const sal_Unicode* str = aFileName.getStr();
     827             : 
     828           0 :             if( aFileName.getLength() == idx_ + 5                   &&
     829           0 :                 ( str[idx_ + 1] == 't' || str[idx_ + 1] == 'T' )    &&
     830           0 :                 ( str[idx_ + 2] == 'r' || str[idx_ + 2] == 'R' )    &&
     831           0 :                 ( str[idx_ + 3] == 'e' || str[idx_ + 3] == 'E' )    &&
     832           0 :                 ( str[idx_ + 4] == 'e' || str[idx_ + 4] == 'E' ) )
     833             :               {
     834             :                 OSL_ENSURE( aFileStatus.isValid( osl_FileStatus_Mask_FileSize ),
     835             :                             "invalid file size" );
     836             : 
     837           0 :                 rtl::OUString baseName = aFileName.copy(0,idx_).toAsciiLowerCase();
     838           0 :                 if(! showBasic && baseName.compareToAscii("sbasic") == 0 )
     839           0 :                   continue;
     840           0 :                 osl::File aFile( aFileUrl );
     841           0 :                 if( osl::FileBase::E_None == aFile.open( osl_File_OpenFlag_Read ) )
     842             :                 {
     843             :                     sal_uInt64 nSize;
     844           0 :                     aFile.getSize( nSize );
     845           0 :                     configData.vFileLen.push_back( aFileStatus.getFileSize() );
     846           0 :                     configData.vFileURL.push_back( aFileUrl );
     847           0 :                     aFile.close();
     848           0 :                 }
     849             :               }
     850             :           }
     851           0 :         aDirectory.close();
     852             :     }
     853             : 
     854           0 :     configData.m_vAdd[0] = 12;
     855           0 :     configData.m_vAdd[1] = 15;
     856           0 :     configData.m_vAdd[2] = 11;
     857           0 :     configData.m_vAdd[3] = 14;
     858           0 :     configData.m_vAdd[4] = 12;
     859           0 :     configData.m_vReplacement[0] = utl::ConfigManager::getProductName();
     860           0 :     configData.m_vReplacement[1] = productVersion;
     861             :     // m_vReplacement[2...4] (vendorName/-Version/-Short) are empty strings
     862             : 
     863           0 :        configData.system = system;
     864           0 :     configData.locale = locale;
     865             :     configData.appendix =
     866             :         rtl::OUString( "?Language=" ) +
     867           0 :         configData.locale +
     868           0 :         rtl::OUString( "&System=" ) +
     869           0 :         configData.system +
     870           0 :         rtl::OUString( "&UseDB=no" ) ;
     871             : 
     872           0 :     return configData;
     873             : }
     874             : 
     875             : 
     876             : 
     877             : 
     878             : 
     879             : 
     880             : 
     881             : 
     882             : 
     883             : Reference< XMultiServiceFactory >
     884           0 : TVChildTarget::getConfiguration(const Reference< XComponentContext >& rxContext) const
     885             : {
     886           0 :     Reference< XMultiServiceFactory > xProvider;
     887           0 :     if( rxContext.is() )
     888             :     {
     889             :         try
     890             :         {
     891           0 :             xProvider = theDefaultProvider::get( rxContext );
     892             :         }
     893           0 :         catch( const com::sun::star::uno::Exception& )
     894             :         {
     895             :             OSL_ENSURE( xProvider.is(),"cant instantiate configuration" );
     896             :         }
     897             :     }
     898             : 
     899           0 :     return xProvider;
     900             : }
     901             : 
     902             : 
     903             : 
     904             : Reference< XHierarchicalNameAccess >
     905           0 : TVChildTarget::getHierAccess( const Reference< XMultiServiceFactory >& sProvider,
     906             :                               const char* file ) const
     907             : {
     908           0 :     Reference< XHierarchicalNameAccess > xHierAccess;
     909             : 
     910           0 :     if( sProvider.is() )
     911             :     {
     912           0 :         Sequence< Any > seq(1);
     913             :         rtl::OUString sReaderService =
     914           0 :             rtl::OUString( "com.sun.star.configuration.ConfigurationAccess" );
     915             : 
     916           0 :         seq[0] <<= rtl::OUString::createFromAscii( file );
     917             : 
     918             :         try
     919             :         {
     920             :             xHierAccess =
     921             :                 Reference< XHierarchicalNameAccess >
     922           0 :                 ( sProvider->createInstanceWithArguments( sReaderService,seq ),
     923           0 :                   UNO_QUERY );
     924             :         }
     925           0 :         catch( const com::sun::star::uno::Exception& )
     926             :         {
     927           0 :         }
     928             :     }
     929             : 
     930           0 :     return xHierAccess;
     931             : }
     932             : 
     933             : 
     934             : 
     935             : rtl::OUString
     936           0 : TVChildTarget::getKey( const Reference< XHierarchicalNameAccess >& xHierAccess,
     937             :                        const char* key ) const
     938             : {
     939           0 :     rtl::OUString instPath;
     940           0 :     if( xHierAccess.is() )
     941             :     {
     942           0 :         Any aAny;
     943             :         try
     944             :         {
     945             :             aAny =
     946           0 :                 xHierAccess->getByHierarchicalName( rtl::OUString::createFromAscii( key ) );
     947             :         }
     948           0 :         catch( const com::sun::star::container::NoSuchElementException& )
     949             :         {
     950             :         }
     951           0 :         aAny >>= instPath;
     952             :     }
     953           0 :     return instPath;
     954             : }
     955             : 
     956             : 
     957             : sal_Bool
     958           0 : TVChildTarget::getBooleanKey(const Reference<
     959             :                              XHierarchicalNameAccess >& xHierAccess,
     960             :                              const char* key) const
     961             : {
     962           0 :   sal_Bool ret = sal_False;
     963           0 :   if( xHierAccess.is() )
     964             :     {
     965           0 :       Any aAny;
     966             :       try
     967             :         {
     968             :           aAny =
     969           0 :             xHierAccess->getByHierarchicalName(
     970           0 :                                                rtl::OUString::createFromAscii(key));
     971             :         }
     972           0 :       catch( const com::sun::star::container::NoSuchElementException& )
     973             :         {
     974             :         }
     975           0 :       aAny >>= ret;
     976             :     }
     977           0 :   return ret;
     978             : }
     979             : 
     980             : 
     981           0 : void TVChildTarget::subst( const Reference< XMultiServiceFactory >& m_xSMgr,
     982             :                            rtl::OUString& instpath ) const
     983             : {
     984           0 :     Reference< XConfigManager >  xCfgMgr;
     985           0 :     if( m_xSMgr.is() )
     986             :     {
     987             :         try
     988             :         {
     989             :             xCfgMgr =
     990             :                 Reference< XConfigManager >(
     991           0 :                     m_xSMgr->createInstance( rtl::OUString( "com.sun.star.config.SpecialConfigManager" ) ),
     992           0 :                     UNO_QUERY );
     993             :         }
     994           0 :         catch( const com::sun::star::uno::Exception& )
     995             :         {
     996             :             OSL_ENSURE( xCfgMgr.is()," cant instantiate the special config manager " );
     997             :         }
     998             :     }
     999             : 
    1000             :     OSL_ENSURE( xCfgMgr.is(), "specialconfigmanager not found\n" );
    1001             : 
    1002           0 :     if( xCfgMgr.is() )
    1003           0 :         instpath = xCfgMgr->substituteVariables( instpath );
    1004           0 : }
    1005             : 
    1006             : 
    1007             : //===================================================================
    1008             : // class ExtensionIteratorBase
    1009             : 
    1010           0 : static rtl::OUString aSlash("/");
    1011           0 : static rtl::OUString aHelpFilesBaseName("help");
    1012           0 : static rtl::OUString aHelpMediaType("application/vnd.sun.star.help");
    1013             : 
    1014           0 : ExtensionIteratorBase::ExtensionIteratorBase( const rtl::OUString& aLanguage )
    1015             :         : m_eState( USER_EXTENSIONS )
    1016           0 :         , m_aLanguage( aLanguage )
    1017             : {
    1018           0 :     init();
    1019           0 : }
    1020             : 
    1021           0 : void ExtensionIteratorBase::init()
    1022             : {
    1023           0 :     m_xContext = ::comphelper::getProcessComponentContext();
    1024           0 :     if( !m_xContext.is() )
    1025             :     {
    1026             :         throw RuntimeException(
    1027             :             ::rtl::OUString( "ExtensionIteratorBase::init(), no XComponentContext" ),
    1028           0 :             Reference< XInterface >() );
    1029             :     }
    1030             : 
    1031           0 :     m_xSFA = ucb::SimpleFileAccess::create(m_xContext);
    1032             : 
    1033           0 :     m_bUserPackagesLoaded = false;
    1034           0 :     m_bSharedPackagesLoaded = false;
    1035           0 :     m_bBundledPackagesLoaded = false;
    1036           0 :     m_iUserPackage = 0;
    1037           0 :     m_iSharedPackage = 0;
    1038           0 :     m_iBundledPackage = 0;
    1039           0 : }
    1040             : 
    1041           0 : Reference< deployment::XPackage > ExtensionIteratorBase::implGetHelpPackageFromPackage
    1042             :     ( Reference< deployment::XPackage > xPackage, Reference< deployment::XPackage >& o_xParentPackageBundle )
    1043             : {
    1044           0 :     o_xParentPackageBundle.clear();
    1045             : 
    1046           0 :     Reference< deployment::XPackage > xHelpPackage;
    1047           0 :     if( !xPackage.is() )
    1048             :         return xHelpPackage;
    1049             : 
    1050             :     // Check if parent package is registered
    1051           0 :     beans::Optional< beans::Ambiguous<sal_Bool> > option( xPackage->isRegistered
    1052           0 :         ( Reference<task::XAbortChannel>(), Reference<ucb::XCommandEnvironment>() ) );
    1053           0 :     bool bRegistered = false;
    1054           0 :     if( option.IsPresent )
    1055             :     {
    1056           0 :         beans::Ambiguous<sal_Bool> const & reg = option.Value;
    1057           0 :         if( !reg.IsAmbiguous && reg.Value )
    1058           0 :             bRegistered = true;
    1059             :     }
    1060           0 :     if( !bRegistered )
    1061             :         return xHelpPackage;
    1062             : 
    1063           0 :     if( xPackage->isBundle() )
    1064             :     {
    1065           0 :         Sequence< Reference< deployment::XPackage > > aPkgSeq = xPackage->getBundle
    1066           0 :             ( Reference<task::XAbortChannel>(), Reference<ucb::XCommandEnvironment>() );
    1067           0 :         sal_Int32 nPkgCount = aPkgSeq.getLength();
    1068           0 :         const Reference< deployment::XPackage >* pSeq = aPkgSeq.getConstArray();
    1069           0 :         for( sal_Int32 iPkg = 0 ; iPkg < nPkgCount ; ++iPkg )
    1070             :         {
    1071           0 :             const Reference< deployment::XPackage > xSubPkg = pSeq[ iPkg ];
    1072           0 :             const Reference< deployment::XPackageTypeInfo > xPackageTypeInfo = xSubPkg->getPackageType();
    1073           0 :             rtl::OUString aMediaType = xPackageTypeInfo->getMediaType();
    1074           0 :             if( aMediaType.equals( aHelpMediaType ) )
    1075             :             {
    1076           0 :                 xHelpPackage = xSubPkg;
    1077           0 :                 o_xParentPackageBundle = xPackage;
    1078             :                 break;
    1079             :             }
    1080           0 :         }
    1081             :     }
    1082             :     else
    1083             :     {
    1084           0 :         const Reference< deployment::XPackageTypeInfo > xPackageTypeInfo = xPackage->getPackageType();
    1085           0 :         rtl::OUString aMediaType = xPackageTypeInfo->getMediaType();
    1086           0 :         if( aMediaType.equals( aHelpMediaType ) )
    1087           0 :             xHelpPackage = xPackage;
    1088             :     }
    1089             : 
    1090           0 :     return xHelpPackage;
    1091             : }
    1092             : 
    1093           0 : Reference< deployment::XPackage > ExtensionIteratorBase::implGetNextUserHelpPackage
    1094             :     ( Reference< deployment::XPackage >& o_xParentPackageBundle )
    1095             : {
    1096           0 :     Reference< deployment::XPackage > xHelpPackage;
    1097             : 
    1098           0 :     if( !m_bUserPackagesLoaded )
    1099             :     {
    1100             :         Reference< XPackageManager > xUserManager =
    1101           0 :             thePackageManagerFactory::get( m_xContext )->getPackageManager( rtl::OUString("user") );
    1102           0 :         m_aUserPackagesSeq = xUserManager->getDeployedPackages
    1103           0 :             ( Reference< task::XAbortChannel >(), Reference< ucb::XCommandEnvironment >() );
    1104             : 
    1105           0 :         m_bUserPackagesLoaded = true;
    1106             :     }
    1107             : 
    1108           0 :     if( m_iUserPackage == m_aUserPackagesSeq.getLength() )
    1109             :     {
    1110           0 :         m_eState = SHARED_EXTENSIONS;       // Later: SHARED_MODULE
    1111             :     }
    1112             :     else
    1113             :     {
    1114           0 :         const Reference< deployment::XPackage >* pUserPackages = m_aUserPackagesSeq.getConstArray();
    1115           0 :         Reference< deployment::XPackage > xPackage = pUserPackages[ m_iUserPackage++ ];
    1116             :         OSL_ENSURE( xPackage.is(), "ExtensionIteratorBase::implGetNextUserHelpPackage(): Invalid package" );
    1117           0 :         xHelpPackage = implGetHelpPackageFromPackage( xPackage, o_xParentPackageBundle );
    1118             :     }
    1119             : 
    1120           0 :     return xHelpPackage;
    1121             : }
    1122             : 
    1123           0 : Reference< deployment::XPackage > ExtensionIteratorBase::implGetNextSharedHelpPackage
    1124             :     ( Reference< deployment::XPackage >& o_xParentPackageBundle )
    1125             : {
    1126           0 :     Reference< deployment::XPackage > xHelpPackage;
    1127             : 
    1128           0 :     if( !m_bSharedPackagesLoaded )
    1129             :     {
    1130             :         Reference< XPackageManager > xSharedManager =
    1131           0 :             thePackageManagerFactory::get( m_xContext )->getPackageManager( rtl::OUString("shared") );
    1132           0 :         m_aSharedPackagesSeq = xSharedManager->getDeployedPackages
    1133           0 :             ( Reference< task::XAbortChannel >(), Reference< ucb::XCommandEnvironment >() );
    1134             : 
    1135           0 :         m_bSharedPackagesLoaded = true;
    1136             :     }
    1137             : 
    1138           0 :     if( m_iSharedPackage == m_aSharedPackagesSeq.getLength() )
    1139             :     {
    1140           0 :         m_eState = BUNDLED_EXTENSIONS;
    1141             :     }
    1142             :     else
    1143             :     {
    1144           0 :         const Reference< deployment::XPackage >* pSharedPackages = m_aSharedPackagesSeq.getConstArray();
    1145           0 :         Reference< deployment::XPackage > xPackage = pSharedPackages[ m_iSharedPackage++ ];
    1146             :         OSL_ENSURE( xPackage.is(), "ExtensionIteratorBase::implGetNextSharedHelpPackage(): Invalid package" );
    1147           0 :         xHelpPackage = implGetHelpPackageFromPackage( xPackage, o_xParentPackageBundle );
    1148             :     }
    1149             : 
    1150           0 :     return xHelpPackage;
    1151             : }
    1152             : 
    1153           0 : Reference< deployment::XPackage > ExtensionIteratorBase::implGetNextBundledHelpPackage
    1154             :     ( Reference< deployment::XPackage >& o_xParentPackageBundle )
    1155             : {
    1156           0 :     Reference< deployment::XPackage > xHelpPackage;
    1157             : 
    1158           0 :     if( !m_bBundledPackagesLoaded )
    1159             :     {
    1160             :         Reference< XPackageManager > xBundledManager =
    1161           0 :             thePackageManagerFactory::get( m_xContext )->getPackageManager( rtl::OUString("bundled") );
    1162           0 :         m_aBundledPackagesSeq = xBundledManager->getDeployedPackages
    1163           0 :             ( Reference< task::XAbortChannel >(), Reference< ucb::XCommandEnvironment >() );
    1164             : 
    1165           0 :         m_bBundledPackagesLoaded = true;
    1166             :     }
    1167             : 
    1168           0 :     if( m_iBundledPackage == m_aBundledPackagesSeq.getLength() )
    1169             :     {
    1170           0 :         m_eState = END_REACHED;
    1171             :     }
    1172             :     else
    1173             :     {
    1174           0 :         const Reference< deployment::XPackage >* pBundledPackages = m_aBundledPackagesSeq.getConstArray();
    1175           0 :         Reference< deployment::XPackage > xPackage = pBundledPackages[ m_iBundledPackage++ ];
    1176             :         OSL_ENSURE( xPackage.is(), "ExtensionIteratorBase::implGetNextBundledHelpPackage(): Invalid package" );
    1177           0 :         xHelpPackage = implGetHelpPackageFromPackage( xPackage, o_xParentPackageBundle );
    1178             :     }
    1179             : 
    1180           0 :     return xHelpPackage;
    1181             : }
    1182             : 
    1183           0 : inline bool isLetter( sal_Unicode c )
    1184             : {
    1185           0 :     return comphelper::string::isalphaAscii(c);
    1186             : }
    1187             : 
    1188           0 : void ExtensionIteratorBase::implGetLanguageVectorFromPackage( ::std::vector< ::rtl::OUString > &rv,
    1189             :     com::sun::star::uno::Reference< com::sun::star::deployment::XPackage > xPackage )
    1190             : {
    1191           0 :     rv.clear();
    1192           0 :     rtl::OUString aExtensionPath = xPackage->getURL();
    1193           0 :     Sequence< rtl::OUString > aEntrySeq = m_xSFA->getFolderContents( aExtensionPath, true );
    1194             : 
    1195           0 :     const rtl::OUString* pSeq = aEntrySeq.getConstArray();
    1196           0 :     sal_Int32 nCount = aEntrySeq.getLength();
    1197           0 :     for( sal_Int32 i = 0 ; i < nCount ; ++i )
    1198             :     {
    1199           0 :         rtl::OUString aEntry = pSeq[i];
    1200           0 :         if( m_xSFA->isFolder( aEntry ) )
    1201             :         {
    1202           0 :             sal_Int32 nLastSlash = aEntry.lastIndexOf( '/' );
    1203           0 :             if( nLastSlash != -1 )
    1204             :             {
    1205           0 :                 rtl::OUString aPureEntry = aEntry.copy( nLastSlash + 1 );
    1206             : 
    1207             :                 // Check language sceme
    1208           0 :                 int nLen = aPureEntry.getLength();
    1209           0 :                 const sal_Unicode* pc = aPureEntry.getStr();
    1210           0 :                 bool bStartCanBeLanguage = ( nLen >= 2 && isLetter( pc[0] ) && isLetter( pc[1] ) );
    1211             :                 bool bIsLanguage = bStartCanBeLanguage &&
    1212           0 :                     ( nLen == 2 || (nLen == 5 && pc[2] == '-' && isLetter( pc[3] ) && isLetter( pc[4] )) );
    1213           0 :                 if( bIsLanguage )
    1214           0 :                     rv.push_back( aPureEntry );
    1215             :             }
    1216             :         }
    1217           0 :     }
    1218           0 : }
    1219             : 
    1220             : 
    1221             : //===================================================================
    1222             : // class TreeFileIterator
    1223             : 
    1224           0 : rtl::OUString TreeFileIterator::nextTreeFile( sal_Int32& rnFileSize )
    1225             : {
    1226           0 :     rtl::OUString aRetFile;
    1227             : 
    1228           0 :     while( aRetFile.isEmpty() && m_eState != END_REACHED )
    1229             :     {
    1230           0 :         switch( m_eState )
    1231             :         {
    1232             :             case USER_EXTENSIONS:
    1233             :             {
    1234           0 :                 Reference< deployment::XPackage > xParentPackageBundle;
    1235           0 :                 Reference< deployment::XPackage > xHelpPackage = implGetNextUserHelpPackage( xParentPackageBundle );
    1236           0 :                 if( !xHelpPackage.is() )
    1237             :                     break;
    1238             : 
    1239           0 :                 aRetFile = implGetTreeFileFromPackage( rnFileSize, xHelpPackage );
    1240           0 :                 break;
    1241             :             }
    1242             : 
    1243             :             case SHARED_EXTENSIONS:
    1244             :             {
    1245           0 :                 Reference< deployment::XPackage > xParentPackageBundle;
    1246           0 :                 Reference< deployment::XPackage > xHelpPackage = implGetNextSharedHelpPackage( xParentPackageBundle );
    1247           0 :                 if( !xHelpPackage.is() )
    1248             :                     break;
    1249             : 
    1250           0 :                 aRetFile = implGetTreeFileFromPackage( rnFileSize, xHelpPackage );
    1251           0 :                 break;
    1252             :             }
    1253             :             case BUNDLED_EXTENSIONS:
    1254             :             {
    1255           0 :                 Reference< deployment::XPackage > xParentPackageBundle;
    1256           0 :                 Reference< deployment::XPackage > xHelpPackage = implGetNextBundledHelpPackage( xParentPackageBundle );
    1257           0 :                 if( !xHelpPackage.is() )
    1258             :                     break;
    1259             : 
    1260           0 :                 aRetFile = implGetTreeFileFromPackage( rnFileSize, xHelpPackage );
    1261           0 :                 break;
    1262             :             }
    1263             : 
    1264             :         case END_REACHED:
    1265             :                 OSL_FAIL( "DataBaseIterator::nextTreeFile(): Invalid case END_REACHED" );
    1266           0 :                 break;
    1267             :         }
    1268             :     }
    1269             : 
    1270           0 :     return aRetFile;
    1271             : }
    1272             : 
    1273           0 : rtl::OUString TreeFileIterator::expandURL( const rtl::OUString& aURL )
    1274             : {
    1275           0 :     static Reference< util::XMacroExpander > xMacroExpander;
    1276           0 :     static Reference< uri::XUriReferenceFactory > xFac;
    1277             : 
    1278           0 :     osl::MutexGuard aGuard( m_aMutex );
    1279             : 
    1280           0 :     if( !xMacroExpander.is() || !xFac.is() )
    1281             :     {
    1282           0 :         xFac = uri::UriReferenceFactory::create( m_xContext );
    1283             : 
    1284             :         xMacroExpander = Reference< util::XMacroExpander >(
    1285           0 :             m_xContext->getValueByName(
    1286           0 :             ::rtl::OUString( "/singletons/com.sun.star.util.theMacroExpander" ) ),
    1287           0 :             UNO_QUERY_THROW );
    1288             :      }
    1289             : 
    1290           0 :     rtl::OUString aRetURL = aURL;
    1291           0 :     if( xMacroExpander.is() )
    1292             :     {
    1293           0 :         Reference< uri::XUriReference > uriRef;
    1294           0 :         for (;;)
    1295             :         {
    1296           0 :             uriRef = Reference< uri::XUriReference >( xFac->parse( aRetURL ), UNO_QUERY );
    1297           0 :             if ( uriRef.is() )
    1298             :             {
    1299           0 :                 Reference < uri::XVndSunStarExpandUrl > sxUri( uriRef, UNO_QUERY );
    1300           0 :                 if( !sxUri.is() )
    1301             :                     break;
    1302             : 
    1303           0 :                 aRetURL = sxUri->expand( xMacroExpander );
    1304             :             }
    1305           0 :         }
    1306             :      }
    1307           0 :     return aRetURL;
    1308             : }
    1309             : 
    1310           0 : rtl::OUString TreeFileIterator::implGetTreeFileFromPackage
    1311             :     ( sal_Int32& rnFileSize, Reference< deployment::XPackage > xPackage )
    1312             : {
    1313           0 :     rtl::OUString aRetFile;
    1314           0 :     rtl::OUString aLanguage = m_aLanguage;
    1315           0 :     for( sal_Int32 iPass = 0 ; iPass < 2 ; ++iPass )
    1316             :     {
    1317           0 :         rtl::OUStringBuffer aStrBuf;
    1318           0 :         aStrBuf.append( xPackage->getURL() );
    1319           0 :         aStrBuf.append( aSlash );
    1320           0 :         aStrBuf.append( aLanguage );
    1321           0 :         aStrBuf.append( aSlash );
    1322           0 :         aStrBuf.append( aHelpFilesBaseName );
    1323           0 :         aStrBuf.appendAscii( ".tree" );
    1324             : 
    1325           0 :         aRetFile = expandURL( aStrBuf.makeStringAndClear() );
    1326           0 :         if( iPass == 0 )
    1327             :         {
    1328           0 :             if( m_xSFA->exists( aRetFile ) )
    1329             :                 break;
    1330             : 
    1331           0 :             ::std::vector< ::rtl::OUString > av;
    1332           0 :             implGetLanguageVectorFromPackage( av, xPackage );
    1333           0 :             ::std::vector< ::rtl::OUString >::const_iterator pFound = av.end();
    1334             :             try
    1335             :             {
    1336           0 :                 pFound = ::comphelper::Locale::getFallback( av, m_aLanguage );
    1337             :             }
    1338           0 :             catch( ::comphelper::Locale::MalFormedLocaleException& )
    1339             :             {}
    1340           0 :             if( pFound != av.end() )
    1341           0 :                 aLanguage = *pFound;
    1342             :         }
    1343           0 :     }
    1344             : 
    1345           0 :     rnFileSize = 0;
    1346           0 :     if( m_xSFA->exists( aRetFile ) )
    1347           0 :         rnFileSize = m_xSFA->getSize( aRetFile );
    1348             :     else
    1349           0 :         aRetFile = rtl::OUString();
    1350             : 
    1351           0 :     return aRetFile;
    1352           0 : }
    1353             : 
    1354             : 
    1355             : 
    1356             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10