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