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 : :
30 : : /**************************************************************************
31 : : TODO
32 : : **************************************************************************
33 : :
34 : : *************************************************************************/
35 : :
36 : : #include <stdio.h>
37 : : #include <osl/file.hxx>
38 : : #include <osl/diagnose.h>
39 : : #include <ucbhelper/contentidentifier.hxx>
40 : : #include <com/sun/star/frame/XConfigManager.hpp>
41 : : #include <com/sun/star/beans/PropertyAttribute.hpp>
42 : : #include <com/sun/star/beans/PropertyValue.hpp>
43 : : #include <com/sun/star/container/XContainer.hpp>
44 : : #include <com/sun/star/container/XNameAccess.hpp>
45 : : #include <com/sun/star/container/XNameReplace.hpp>
46 : : #include <com/sun/star/uno/XComponentContext.hpp>
47 : : #include <com/sun/star/beans/XPropertySet.hpp>
48 : : #include <unotools/configmgr.hxx>
49 : : #include <rtl/bootstrap.hxx>
50 : :
51 : : #include "databases.hxx"
52 : : #include "provider.hxx"
53 : : #include "content.hxx"
54 : :
55 : : using namespace com::sun::star;
56 : : using namespace chelp;
57 : :
58 : : //=========================================================================
59 : : //=========================================================================
60 : : //
61 : : // ContentProvider Implementation.
62 : : //
63 : : //=========================================================================
64 : : //=========================================================================
65 : :
66 : 21 : ContentProvider::ContentProvider(
67 : : const uno::Reference< lang::XMultiServiceFactory >& rSMgr )
68 : : : ::ucbhelper::ContentProviderImplHelper( rSMgr ),
69 : : isInitialized( false ),
70 : : m_aScheme(MYUCP_URL_SCHEME),
71 [ + - ]: 21 : m_pDatabases( 0 )
72 : : {
73 : 21 : }
74 : :
75 : : //=========================================================================
76 : : // virtual
77 [ + - ]: 21 : ContentProvider::~ContentProvider()
78 : : {
79 [ + - ][ + - ]: 21 : delete m_pDatabases;
80 [ - + ]: 42 : }
81 : :
82 : : //=========================================================================
83 : : //
84 : : // XInterface methods.
85 : : //
86 : : //=========================================================================
87 : :
88 [ + - ][ + + ]: 19967 : XINTERFACE_IMPL_6( ContentProvider,
[ + - ]
89 : : lang::XTypeProvider,
90 : : lang::XServiceInfo,
91 : : ucb::XContentProvider,
92 : : lang::XComponent,
93 : : lang::XEventListener, /* base of XContainerListener */
94 : : container::XContainerListener);
95 : :
96 : : //=========================================================================
97 : : //
98 : : // XTypeProvider methods.
99 : : //
100 : : //=========================================================================
101 : :
102 [ # # ][ # # ]: 0 : XTYPEPROVIDER_IMPL_5( ContentProvider,
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
103 : : lang::XTypeProvider,
104 : : lang::XServiceInfo,
105 : : ucb::XContentProvider,
106 : : lang::XComponent,
107 : : container::XContainerListener);
108 : :
109 : : //=========================================================================
110 : : //
111 : : // XServiceInfo methods.
112 : : //
113 : : //=========================================================================
114 : :
115 : 2 : rtl::OUString SAL_CALL ContentProvider::getImplementationName()
116 : : throw( uno::RuntimeException )
117 : : {
118 : 2 : return getImplementationName_Static();
119 : : }
120 : :
121 : 44 : rtl::OUString ContentProvider::getImplementationName_Static()
122 : : {
123 : 44 : return rtl::OUString("CHelpContentProvider" );
124 : : }
125 : :
126 : : sal_Bool SAL_CALL
127 : 0 : ContentProvider::supportsService(const rtl::OUString& ServiceName )
128 : : throw( uno::RuntimeException )
129 : : {
130 [ # # ]: 0 : uno::Sequence< rtl::OUString > aSNL = getSupportedServiceNames();
131 [ # # ]: 0 : const rtl::OUString* pArray = aSNL.getArray();
132 [ # # ]: 0 : for( sal_Int32 i = 0; i < aSNL.getLength(); i++ )
133 : : {
134 [ # # ]: 0 : if( pArray[ i ] == ServiceName )
135 : 0 : return sal_True;
136 : : }
137 : :
138 [ # # ]: 0 : return sal_False;
139 : : }
140 : :
141 : : uno::Sequence< rtl::OUString > SAL_CALL
142 : 0 : ContentProvider::getSupportedServiceNames()
143 : : throw( uno::RuntimeException )
144 : : {
145 : 0 : return getSupportedServiceNames_Static();
146 : : }
147 : :
148 : : static uno::Reference< uno::XInterface > SAL_CALL
149 : 21 : ContentProvider_CreateInstance(
150 : : const uno::Reference< lang::XMultiServiceFactory> & rSMgr )
151 : : throw( uno::Exception )
152 : : {
153 : : lang::XServiceInfo * pX = static_cast< lang::XServiceInfo * >(
154 [ + - ][ + - ]: 21 : new ContentProvider( rSMgr ) );
155 : 21 : return uno::Reference< uno::XInterface >::query( pX );
156 : : }
157 : :
158 : : uno::Sequence< rtl::OUString >
159 : 21 : ContentProvider::getSupportedServiceNames_Static()
160 : : {
161 : 21 : uno::Sequence< rtl::OUString > aSNS( 2 );
162 : : aSNS.getArray()[ 0 ] =
163 : : rtl::OUString(
164 [ + - ]: 21 : MYUCP_CONTENT_PROVIDER_SERVICE_NAME1 );
165 [ + - ]: 21 : aSNS.getArray()[ 1 ] =
166 : : rtl::OUString(
167 : 42 : MYUCP_CONTENT_PROVIDER_SERVICE_NAME2 );
168 : :
169 : 21 : return aSNS;
170 : : }
171 : :
172 : : //=========================================================================
173 : : //
174 : : // Service factory implementation.
175 : : //
176 : : //=========================================================================
177 : :
178 [ + - ][ + - ]: 21 : ONE_INSTANCE_SERVICE_FACTORY_IMPL( ContentProvider );
179 : :
180 : : //=========================================================================
181 : : //
182 : : // XContentProvider methods.
183 : : //
184 : : //=========================================================================
185 : :
186 : : // virtual
187 : : uno::Reference< ucb::XContent > SAL_CALL
188 : 593 : ContentProvider::queryContent(
189 : : const uno::Reference< ucb::XContentIdentifier >& xCanonicId )
190 : : throw( ucb::IllegalIdentifierException, uno::RuntimeException )
191 : : {
192 [ + - - + ]: 1186 : if ( !xCanonicId->getContentProviderScheme()
193 [ + - ]: 593 : .equalsIgnoreAsciiCase( m_aScheme ) )
194 : : { // Wrong URL-scheme
195 [ # # ]: 0 : throw ucb::IllegalIdentifierException();
196 : : }
197 : :
198 : : {
199 [ + - ]: 593 : osl::MutexGuard aGuard( m_aMutex );
200 [ + + ]: 593 : if( !isInitialized )
201 [ + - ][ + - ]: 593 : init();
202 : : }
203 : :
204 [ - + ]: 593 : if( !m_pDatabases )
205 [ # # ]: 0 : throw uno::RuntimeException();
206 : :
207 [ + - ]: 593 : rtl::OUString aOUString( m_pDatabases->getInstallPathAsURL() );
208 : : rtl::OString aOString( aOUString.getStr(),
209 : : aOUString.getLength(),
210 [ + - ]: 593 : RTL_TEXTENCODING_UTF8 );
211 : :
212 : : // Check, if a content with given id already exists...
213 : : uno::Reference< ucb::XContent > xContent
214 [ + - ][ - + ]: 593 : = queryExistingContent( xCanonicId ).get();
[ + - ]
215 [ + - ]: 593 : if ( xContent.is() )
216 : : return xContent;
217 : :
218 [ + + ][ + - ]: 593 : xContent = new Content( m_xSMgr, this, xCanonicId, m_pDatabases );
[ + - ]
219 : :
220 : : // register new content
221 [ + - ]: 590 : registerNewContent( xContent );
222 : :
223 : : // Further checks
224 : :
225 [ + - ][ + - ]: 590 : if ( !xContent->getIdentifier().is() )
[ - + ]
226 [ # # ]: 0 : throw ucb::IllegalIdentifierException();
227 : :
228 : 593 : return xContent;
229 : : }
230 : :
231 : : void SAL_CALL
232 : 21 : ContentProvider::dispose()
233 : : throw ( uno::RuntimeException)
234 : : {
235 [ + - ]: 21 : if(m_xContainer.is())
236 : : {
237 [ + - ]: 21 : m_xContainer->removeContainerListener(this);
238 : 21 : m_xContainer.clear();
239 : : }
240 : 21 : }
241 : :
242 : : void SAL_CALL
243 : 0 : ContentProvider::elementReplaced(const container::ContainerEvent& Event)
244 : : throw (uno::RuntimeException)
245 : : {
246 [ # # ]: 0 : if(!m_pDatabases)
247 : : return;
248 : :
249 : 0 : rtl::OUString accessor;
250 : 0 : Event.Accessor >>= accessor;
251 [ # # ]: 0 : if(accessor.compareToAscii("HelpStyleSheet"))
252 : : return;
253 : :
254 : 0 : rtl::OUString replacedElement,element;
255 : 0 : Event.ReplacedElement >>= replacedElement;
256 : 0 : Event.Element >>= element;
257 : :
258 [ # # ]: 0 : if(replacedElement == element)
259 : : return;
260 : :
261 [ # # ][ # # ]: 0 : m_pDatabases->changeCSS(element);
[ # # ][ # # ]
262 : : }
263 : :
264 : 21 : void ContentProvider::init()
265 : : {
266 [ + - ]: 21 : osl::MutexGuard aGuard( m_aMutex );
267 : :
268 : 21 : isInitialized = true;
269 : : uno::Reference< lang::XMultiServiceFactory > sProvider(
270 [ + - ]: 21 : getConfiguration() );
271 : : uno::Reference< container::XHierarchicalNameAccess > xHierAccess(
272 : : getHierAccess( sProvider,
273 [ + - ]: 21 : "org.openoffice.Office.Common" ) );
274 : :
275 [ + - ]: 21 : rtl::OUString instPath( getKey( xHierAccess,"Path/Current/Help" ) );
276 [ - + ]: 21 : if( instPath.isEmpty() )
277 : : // try to determine path from default
278 : 0 : instPath = rtl::OUString( "$(instpath)/help" );
279 : : // replace anything like $(instpath);
280 [ + - ]: 21 : subst( instPath );
281 : :
282 [ + - ]: 21 : rtl::OUString stylesheet( getKey( xHierAccess,"Help/HelpStyleSheet" ) );
283 : : try
284 : : {
285 : : // now adding as configuration change listener for the stylesheet
286 : : uno::Reference< container::XNameAccess> xAccess(
287 [ + - ]: 21 : xHierAccess, uno::UNO_QUERY );
288 [ + - ]: 21 : if( xAccess.is() )
289 : : {
290 : : uno::Any aAny =
291 [ + - ][ + - ]: 21 : xAccess->getByName( rtl::OUString( "Help" ) );
292 [ + - ]: 21 : aAny >>= m_xContainer;
293 [ + - ]: 21 : if( m_xContainer.is() )
294 [ + - ][ + - ]: 21 : m_xContainer->addContainerListener( this );
[ + - ]
295 [ # # ]: 21 : }
296 : : }
297 [ # # ]: 0 : catch( uno::Exception const & )
298 : : {
299 : : }
300 : :
301 [ + - ][ + - ]: 21 : xHierAccess = getHierAccess( sProvider, "org.openoffice.Setup" );
302 : :
303 : : rtl::OUString setupversion(
304 [ + - ]: 21 : getKey( xHierAccess,"Product/ooSetupVersion" ) );
305 : 21 : rtl::OUString setupextension;
306 : :
307 : : try
308 : : {
309 : : uno::Reference< lang::XMultiServiceFactory > xConfigProvider(
310 [ + - ][ + - ]: 21 : m_xSMgr ->createInstance(::rtl::OUString("com.sun.star.configuration.ConfigurationProvider")), uno::UNO_QUERY_THROW);
[ + - ]
311 : :
312 [ + - ]: 21 : uno::Sequence < uno::Any > lParams(1);
313 : 21 : beans::PropertyValue aParam ;
314 : 21 : aParam.Name = ::rtl::OUString("nodepath");
315 [ + - ]: 21 : aParam.Value <<= ::rtl::OUString("/org.openoffice.Setup/Product");
316 [ + - ][ + - ]: 21 : lParams[0] = uno::makeAny(aParam);
317 : :
318 : : // open it
319 [ + - ]: 21 : uno::Reference< uno::XInterface > xCFG( xConfigProvider->createInstanceWithArguments(
320 : : ::rtl::OUString("com.sun.star.configuration.ConfigurationAccess"),
321 [ + - ]: 21 : lParams) );
322 : :
323 [ + - ]: 21 : uno::Reference< container::XNameAccess > xDirectAccess(xCFG, uno::UNO_QUERY);
324 [ + - ][ + - ]: 21 : uno::Any aRet = xDirectAccess->getByName(::rtl::OUString("ooSetupExtension"));
325 : :
326 [ # # ][ + - ]: 21 : aRet >>= setupextension;
327 : : }
328 [ # # ]: 0 : catch ( uno::Exception& )
329 : : {
330 : : }
331 : :
332 : : rtl::OUString productversion(
333 : : setupversion +
334 : : rtl::OUString( " " ) +
335 : 21 : setupextension );
336 : :
337 [ + - ]: 21 : uno::Sequence< rtl::OUString > aImagesZipPaths( 2 );
338 [ + - ][ + - ]: 21 : xHierAccess = getHierAccess( sProvider, "org.openoffice.Office.Common" );
339 : :
340 [ + - ]: 21 : rtl::OUString aPath( getKey( xHierAccess, "Path/Current/UserConfig" ) );
341 [ + - ]: 21 : subst( aPath );
342 [ + - ]: 21 : aImagesZipPaths[ 0 ] = aPath;
343 : :
344 : 21 : aPath = rtl::OUString("$BRAND_BASE_DIR/share/config");
345 : 21 : rtl::Bootstrap::expandMacros(aPath);
346 [ + - ]: 21 : aImagesZipPaths[ 1 ] = aPath;
347 : :
348 : 21 : uno::Reference< uno::XComponentContext > xContext;
349 [ + - ]: 21 : uno::Reference< beans::XPropertySet > xProps( m_xSMgr, uno::UNO_QUERY );
350 : : OSL_ASSERT( xProps.is() );
351 [ + - ]: 21 : if (xProps.is())
352 : : {
353 [ + - ]: 21 : xProps->getPropertyValue(
354 [ + - ][ + - ]: 21 : ::rtl::OUString( "DefaultContext" ) ) >>= xContext;
355 : : OSL_ASSERT( xContext.is() );
356 : : }
357 : :
358 [ + - ]: 21 : sal_Bool showBasic = getBooleanKey(xHierAccess,"Help/ShowBasic");
359 : : m_pDatabases = new Databases( showBasic,
360 : : instPath,
361 : : aImagesZipPaths,
362 : : utl::ConfigManager::getProductName(),
363 : : productversion,
364 : : stylesheet,
365 [ + - ][ + - ]: 21 : xContext );
[ + - ][ + - ]
[ + - ]
366 : 21 : }
367 : :
368 : : uno::Reference< lang::XMultiServiceFactory >
369 : 21 : ContentProvider::getConfiguration() const
370 : : {
371 : 21 : uno::Reference< lang::XMultiServiceFactory > sProvider;
372 [ + - ]: 21 : if( m_xSMgr.is() )
373 : : {
374 : : try
375 : : {
376 : : rtl::OUString sProviderService =
377 : : rtl::OUString(
378 : 21 : "com.sun.star.configuration.ConfigurationProvider" );
379 : : sProvider =
380 : : uno::Reference< lang::XMultiServiceFactory >(
381 [ + - ]: 21 : m_xSMgr->createInstance( sProviderService ),
382 [ + - ][ + - ]: 21 : uno::UNO_QUERY );
[ + - ][ # # ]
383 : : }
384 [ # # ]: 0 : catch( const uno::Exception& )
385 : : {
386 : : OSL_ENSURE( sProvider.is(), "cant instantiate configuration" );
387 : : }
388 : : }
389 : :
390 : 21 : return sProvider;
391 : : }
392 : :
393 : : uno::Reference< container::XHierarchicalNameAccess >
394 : 63 : ContentProvider::getHierAccess(
395 : : const uno::Reference< lang::XMultiServiceFactory >& sProvider,
396 : : const char* file ) const
397 : : {
398 : 63 : uno::Reference< container::XHierarchicalNameAccess > xHierAccess;
399 : :
400 [ + - ]: 63 : if( sProvider.is() )
401 : : {
402 [ + - ]: 63 : uno::Sequence< uno::Any > seq( 1 );
403 : : rtl::OUString sReaderService(
404 : : rtl::OUString(
405 : 63 : "com.sun.star.configuration.ConfigurationAccess" ) );
406 : :
407 [ + - ][ + - ]: 63 : seq[ 0 ] <<= rtl::OUString::createFromAscii( file );
408 : :
409 : : try
410 : : {
411 : : xHierAccess =
412 : : uno::Reference< container::XHierarchicalNameAccess >(
413 [ + - ]: 63 : sProvider->createInstanceWithArguments(
414 : 63 : sReaderService, seq ),
415 [ + - ][ + - ]: 63 : uno::UNO_QUERY );
[ + - ][ # # ]
416 : : }
417 [ # # ]: 0 : catch( const uno::Exception& )
418 : : {
419 [ + - ]: 63 : }
420 : : }
421 : 63 : return xHierAccess;
422 : : }
423 : :
424 : :
425 : :
426 : : rtl::OUString
427 : 84 : ContentProvider::getKey(
428 : : const uno::Reference< container::XHierarchicalNameAccess >& xHierAccess,
429 : : const char* key ) const
430 : : {
431 : 84 : rtl::OUString instPath;
432 [ + - ]: 84 : if( xHierAccess.is() )
433 : : {
434 : 84 : uno::Any aAny;
435 : : try
436 : : {
437 : : aAny =
438 [ + - ]: 84 : xHierAccess->getByHierarchicalName(
439 [ + - ][ # # ]: 84 : rtl::OUString::createFromAscii( key ) );
440 : : }
441 [ # # ]: 0 : catch( const container::NoSuchElementException& )
442 : : {
443 : : }
444 : 84 : aAny >>= instPath;
445 : : }
446 : 84 : return instPath;
447 : : }
448 : :
449 : : sal_Bool
450 : 21 : ContentProvider::getBooleanKey(
451 : : const uno::Reference< container::XHierarchicalNameAccess >& xHierAccess,
452 : : const char* key ) const
453 : : {
454 : 21 : sal_Bool ret = sal_False;
455 [ + - ]: 21 : if( xHierAccess.is() )
456 : : {
457 : 21 : uno::Any aAny;
458 : : try
459 : : {
460 : : aAny =
461 [ + - ]: 21 : xHierAccess->getByHierarchicalName(
462 [ + - ][ # # ]: 21 : rtl::OUString::createFromAscii( key ) );
463 : : }
464 [ # # ]: 0 : catch( const container::NoSuchElementException& )
465 : : {
466 : : }
467 : 21 : aAny >>= ret;
468 : : }
469 : 21 : return ret;
470 : : }
471 : :
472 : 42 : void ContentProvider::subst( rtl::OUString& instpath ) const
473 : : {
474 : 42 : uno::Reference< frame::XConfigManager > xCfgMgr;
475 [ + - ]: 42 : if( m_xSMgr.is() )
476 : : {
477 : : try
478 : : {
479 : : xCfgMgr =
480 : : uno::Reference< frame::XConfigManager >(
481 [ + - ]: 42 : m_xSMgr->createInstance(
482 : : rtl::OUString(
483 : 42 : "com.sun.star.config.SpecialConfigManager" ) ),
484 [ + - ][ + - ]: 42 : uno::UNO_QUERY );
[ + - ][ # # ]
485 : : }
486 [ # # ]: 0 : catch( const uno::Exception&)
487 : : {
488 : : OSL_ENSURE( xCfgMgr.is(),
489 : : "cant instantiate the special config manager " );
490 : : }
491 : : }
492 : :
493 : : OSL_ENSURE( xCfgMgr.is(), "specialconfigmanager not found\n" );
494 : :
495 [ + + ]: 42 : if( xCfgMgr.is() )
496 [ + - ][ + - ]: 42 : instpath = xCfgMgr->substituteVariables( instpath );
497 : 42 : }
498 : :
499 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|