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