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 36 : ContentProvider::ContentProvider( const uno::Reference< uno::XComponentContext >& rxContext )
50 : : ::ucbhelper::ContentProviderImplHelper( rxContext )
51 : , isInitialized( false )
52 : , m_aScheme(MYUCP_URL_SCHEME)
53 36 : , m_pDatabases( 0 )
54 : {
55 36 : }
56 :
57 : // virtual
58 108 : ContentProvider::~ContentProvider()
59 : {
60 36 : delete m_pDatabases;
61 72 : }
62 :
63 : // XInterface methods.
64 70730 : void SAL_CALL ContentProvider::acquire()
65 : throw()
66 : {
67 70730 : OWeakObject::acquire();
68 70730 : }
69 :
70 70730 : void SAL_CALL ContentProvider::release()
71 : throw()
72 : {
73 70730 : OWeakObject::release();
74 70730 : }
75 :
76 5314 : 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 5314 : );
87 5314 : 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 74 : OUString ContentProvider::getImplementationName_Static()
130 : {
131 74 : 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 36 : ContentProvider_CreateInstance(
150 : const uno::Reference< lang::XMultiServiceFactory> & rSMgr )
151 : throw( uno::Exception )
152 : {
153 : lang::XServiceInfo * pX = static_cast< lang::XServiceInfo * >(
154 36 : new ContentProvider( comphelper::getComponentContext(rSMgr) ) );
155 36 : return uno::Reference< uno::XInterface >::query( pX );
156 : }
157 :
158 : uno::Sequence< OUString >
159 36 : ContentProvider::getSupportedServiceNames_Static()
160 : {
161 36 : uno::Sequence< OUString > aSNS( 2 );
162 72 : aSNS.getArray()[ 0 ] =
163 : OUString(
164 36 : MYUCP_CONTENT_PROVIDER_SERVICE_NAME1 );
165 72 : aSNS.getArray()[ 1 ] =
166 : OUString(
167 36 : MYUCP_CONTENT_PROVIDER_SERVICE_NAME2 );
168 :
169 36 : return aSNS;
170 : }
171 :
172 : // Service factory implementation.
173 :
174 : css::uno::Reference< css::lang::XSingleServiceFactory >
175 36 : 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 36 : ContentProvider::getSupportedServiceNames_Static() ) );
185 : }
186 :
187 : // XContentProvider methods.
188 :
189 : // virtual
190 : uno::Reference< ucb::XContent > SAL_CALL
191 5158 : ContentProvider::queryContent(
192 : const uno::Reference< ucb::XContentIdentifier >& xCanonicId )
193 : throw( ucb::IllegalIdentifierException, uno::RuntimeException, std::exception )
194 : {
195 15474 : if ( !xCanonicId->getContentProviderScheme()
196 15474 : .equalsIgnoreAsciiCase( m_aScheme ) )
197 : { // Wrong URL-scheme
198 0 : throw ucb::IllegalIdentifierException();
199 : }
200 :
201 : {
202 5158 : osl::MutexGuard aGuard( m_aMutex );
203 5158 : if( !isInitialized )
204 36 : init();
205 : }
206 :
207 5158 : 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 5158 : = queryExistingContent( xCanonicId ).get();
213 5158 : if ( xContent.is() )
214 0 : return xContent;
215 :
216 5158 : xContent = new Content( m_xContext, this, xCanonicId, m_pDatabases );
217 :
218 : // register new content
219 5158 : registerNewContent( xContent );
220 :
221 : // Further checks
222 :
223 5158 : if ( !xContent->getIdentifier().is() )
224 0 : throw ucb::IllegalIdentifierException();
225 :
226 5158 : return xContent;
227 : }
228 :
229 : void SAL_CALL
230 36 : ContentProvider::dispose()
231 : throw ( uno::RuntimeException, std::exception)
232 : {
233 36 : if(m_xContainer.is())
234 : {
235 36 : m_xContainer->removeContainerListener(this);
236 36 : m_xContainer.clear();
237 : }
238 36 : }
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.equalsAscii("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 36 : void ContentProvider::init()
263 : {
264 36 : osl::MutexGuard aGuard( m_aMutex );
265 :
266 36 : isInitialized = true;
267 : uno::Reference< lang::XMultiServiceFactory > sProvider(
268 72 : getConfiguration() );
269 : uno::Reference< container::XHierarchicalNameAccess > xHierAccess(
270 : getHierAccess( sProvider,
271 72 : "org.openoffice.Office.Common" ) );
272 :
273 72 : OUString instPath( getKey( xHierAccess,"Path/Current/Help" ) );
274 36 : if( instPath.isEmpty() )
275 : // try to determine path from default
276 0 : instPath = "$(instpath)/" LIBO_SHARE_HELP_FOLDER;
277 : // replace anything like $(instpath);
278 36 : subst( instPath );
279 :
280 72 : 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 36 : xHierAccess, uno::UNO_QUERY );
286 36 : if( xAccess.is() )
287 : {
288 : uno::Any aAny =
289 36 : xAccess->getByName("Help");
290 36 : aAny >>= m_xContainer;
291 36 : if( m_xContainer.is() )
292 36 : m_xContainer->addContainerListener( this );
293 36 : }
294 : }
295 0 : catch( uno::Exception const & )
296 : {
297 : }
298 :
299 36 : xHierAccess = getHierAccess( sProvider, "org.openoffice.Setup" );
300 :
301 : OUString setupversion(
302 72 : getKey( xHierAccess,"Product/ooSetupVersion" ) );
303 72 : OUString setupextension;
304 :
305 : try
306 : {
307 : uno::Reference< lang::XMultiServiceFactory > xConfigProvider =
308 36 : configuration::theDefaultProvider::get( m_xContext );
309 :
310 72 : uno::Sequence < uno::Any > lParams(1);
311 72 : beans::PropertyValue aParam ;
312 36 : aParam.Name = "nodepath";
313 36 : aParam.Value <<= OUString("/org.openoffice.Setup/Product");
314 36 : lParams[0] = uno::makeAny(aParam);
315 :
316 : // open it
317 36 : uno::Reference< uno::XInterface > xCFG( xConfigProvider->createInstanceWithArguments(
318 : OUString("com.sun.star.configuration.ConfigurationAccess"),
319 72 : lParams) );
320 :
321 72 : uno::Reference< container::XNameAccess > xDirectAccess(xCFG, uno::UNO_QUERY);
322 72 : uno::Any aRet = xDirectAccess->getByName("ooSetupExtension");
323 :
324 72 : aRet >>= setupextension;
325 : }
326 0 : catch ( uno::Exception& )
327 : {
328 : }
329 :
330 : OUString productversion(
331 72 : setupversion +
332 144 : OUString( " " ) +
333 72 : setupextension );
334 :
335 72 : uno::Sequence< OUString > aImagesZipPaths( 2 );
336 36 : xHierAccess = getHierAccess( sProvider, "org.openoffice.Office.Common" );
337 :
338 72 : OUString aPath( getKey( xHierAccess, "Path/Current/UserConfig" ) );
339 36 : subst( aPath );
340 36 : aImagesZipPaths[ 0 ] = aPath;
341 :
342 36 : aPath = "$BRAND_BASE_DIR/$BRAND_SHARE_SUBDIR/config";
343 36 : rtl::Bootstrap::expandMacros(aPath);
344 36 : aImagesZipPaths[ 1 ] = aPath;
345 :
346 36 : 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 72 : m_xContext );
354 36 : }
355 :
356 : uno::Reference< lang::XMultiServiceFactory >
357 36 : ContentProvider::getConfiguration() const
358 : {
359 36 : uno::Reference< lang::XMultiServiceFactory > xProvider;
360 36 : if( m_xContext.is() )
361 : {
362 : try
363 : {
364 36 : 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 36 : return xProvider;
373 : }
374 :
375 : uno::Reference< container::XHierarchicalNameAccess >
376 108 : ContentProvider::getHierAccess(
377 : const uno::Reference< lang::XMultiServiceFactory >& sProvider,
378 : const char* file ) const
379 : {
380 108 : uno::Reference< container::XHierarchicalNameAccess > xHierAccess;
381 :
382 108 : if( sProvider.is() )
383 : {
384 108 : uno::Sequence< uno::Any > seq( 1 );
385 : OUString sReaderService(
386 : OUString(
387 216 : "com.sun.star.configuration.ConfigurationAccess" ) );
388 :
389 108 : seq[ 0 ] <<= OUString::createFromAscii( file );
390 :
391 : try
392 : {
393 216 : xHierAccess =
394 : uno::Reference< container::XHierarchicalNameAccess >(
395 108 : sProvider->createInstanceWithArguments(
396 108 : sReaderService, seq ),
397 108 : uno::UNO_QUERY );
398 : }
399 0 : catch( const uno::Exception& )
400 : {
401 108 : }
402 : }
403 108 : return xHierAccess;
404 : }
405 :
406 : OUString
407 144 : ContentProvider::getKey(
408 : const uno::Reference< container::XHierarchicalNameAccess >& xHierAccess,
409 : const char* key ) const
410 : {
411 144 : OUString instPath;
412 144 : if( xHierAccess.is() )
413 : {
414 144 : uno::Any aAny;
415 : try
416 : {
417 288 : aAny =
418 144 : xHierAccess->getByHierarchicalName(
419 288 : OUString::createFromAscii( key ) );
420 : }
421 0 : catch( const container::NoSuchElementException& )
422 : {
423 : }
424 144 : aAny >>= instPath;
425 : }
426 144 : return instPath;
427 : }
428 :
429 : bool
430 36 : ContentProvider::getBooleanKey(
431 : const uno::Reference< container::XHierarchicalNameAccess >& xHierAccess,
432 : const char* key ) const
433 : {
434 36 : bool ret = false;
435 36 : if( xHierAccess.is() )
436 : {
437 36 : uno::Any aAny;
438 : try
439 : {
440 72 : aAny =
441 36 : xHierAccess->getByHierarchicalName(
442 72 : OUString::createFromAscii( key ) );
443 : }
444 0 : catch( const container::NoSuchElementException& )
445 : {
446 : }
447 36 : aAny >>= ret;
448 : }
449 36 : return ret;
450 : }
451 :
452 72 : void ContentProvider::subst( OUString& instpath ) const
453 : {
454 72 : SvtPathOptions aOptions;
455 72 : instpath = aOptions.SubstituteVariable( instpath );
456 72 : }
457 :
458 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|