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