1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_desktop.hxx"
26
27 #include "dp_component.hrc"
28 #include "dp_backend.h"
29 #include "dp_platform.hxx"
30 #include "dp_ucb.h"
31 #include "rtl/string.hxx"
32 #include "rtl/strbuf.hxx"
33 #include "rtl/ustrbuf.hxx"
34 #include "rtl/uri.hxx"
35 #include "cppuhelper/exc_hlp.hxx"
36 #include "ucbhelper/content.hxx"
37 #include "comphelper/anytostring.hxx"
38 #include "comphelper/servicedecl.hxx"
39 #include "comphelper/sequence.hxx"
40 #include "xmlscript/xml_helper.hxx"
41 #include "svl/inettype.hxx"
42 #include "com/sun/star/lang/WrappedTargetRuntimeException.hpp"
43 #include "com/sun/star/container/XNameContainer.hpp"
44 #include "com/sun/star/container/XHierarchicalNameAccess.hpp"
45 #include "com/sun/star/container/XSet.hpp"
46 #include "com/sun/star/registry/XSimpleRegistry.hpp"
47 #include "com/sun/star/registry/XImplementationRegistration.hpp"
48 #include "com/sun/star/loader/XImplementationLoader.hpp"
49 #include "com/sun/star/io/XInputStream.hpp"
50 #include "com/sun/star/ucb/NameClash.hpp"
51 #include "com/sun/star/util/XMacroExpander.hpp"
52 #include <list>
53 #include <hash_map>
54 #include <vector>
55 #include <memory>
56 #include <algorithm>
57 #include "dp_compbackenddb.hxx"
58
59 using namespace ::dp_misc;
60 using namespace ::com::sun::star;
61 using namespace ::com::sun::star::uno;
62 using namespace ::com::sun::star::ucb;
63 using ::rtl::OUString;
64 namespace css = com::sun::star;
65
66 namespace dp_registry {
67 namespace backend {
68 namespace component {
69 namespace {
70
71 typedef ::std::list<OUString> t_stringlist;
72 typedef ::std::vector< ::std::pair<OUString, OUString> > t_stringpairvec;
73
74 #define IMPLEMENTATION_NAME "com.sun.star.comp.deployment.component.PackageRegistryBackend"
75
76 /** return a vector of bootstrap variables which have been provided
77 as command arguments.
78 */
getCmdBootstrapVariables()79 ::std::vector<OUString> getCmdBootstrapVariables()
80 {
81 ::std::vector<OUString> ret;
82 sal_uInt32 count = osl_getCommandArgCount();
83 for (sal_uInt32 i = 0; i < count; i++)
84 {
85 OUString arg;
86 osl_getCommandArg(i, &arg.pData);
87 if (arg.matchAsciiL("-env:", 5))
88 ret.push_back(arg);
89 }
90 return ret;
91 }
92
jarManifestHeaderPresent(OUString const & url,OUString const & name,Reference<XCommandEnvironment> const & xCmdEnv)93 bool jarManifestHeaderPresent(
94 OUString const & url, OUString const & name,
95 Reference<XCommandEnvironment> const & xCmdEnv )
96 {
97 ::rtl::OUStringBuffer buf;
98 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("vnd.sun.star.zip://") );
99 buf.append(
100 ::rtl::Uri::encode(
101 url, rtl_UriCharClassRegName, rtl_UriEncodeIgnoreEscapes,
102 RTL_TEXTENCODING_UTF8 ) );
103 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("/META-INF/MANIFEST.MF") );
104 ::ucbhelper::Content manifestContent;
105 OUString line;
106 return
107 create_ucb_content(
108 &manifestContent, buf.makeStringAndClear(), xCmdEnv,
109 false /* no throw */ )
110 && readLine( &line, name, manifestContent, RTL_TEXTENCODING_ASCII_US );
111 }
112
113 //==============================================================================
114 class BackendImpl : public ::dp_registry::backend::PackageRegistryBackend
115 {
116 class ComponentPackageImpl : public ::dp_registry::backend::Package
117 {
118 BackendImpl * getMyBackend() const;
119
120 const OUString m_loader;
121
122 enum reg {
123 REG_UNINIT, REG_VOID, REG_REGISTERED, REG_NOT_REGISTERED, REG_MAYBE_REGISTERED
124 } m_registered;
125
126 void getComponentInfo(
127 ComponentBackendDb::Data * data,
128 std::vector< css::uno::Reference< css::uno::XInterface > > *
129 factories,
130 Reference<XComponentContext> const & xContext );
131
132 virtual void SAL_CALL disposing();
133
134 // Package
135 virtual beans::Optional< beans::Ambiguous<sal_Bool> > isRegistered_(
136 ::osl::ResettableMutexGuard & guard,
137 ::rtl::Reference<AbortChannel> const & abortChannel,
138 Reference<XCommandEnvironment> const & xCmdEnv );
139 virtual void processPackage_(
140 ::osl::ResettableMutexGuard & guard,
141 bool registerPackage,
142 bool startup,
143 ::rtl::Reference<AbortChannel> const & abortChannel,
144 Reference<XCommandEnvironment> const & xCmdEnv );
145
146 const Reference<registry::XSimpleRegistry> getRDB() const;
147
148 //Provides the read-only registry (e.g. not the one based on the duplicated
149 //rdb files
150 const Reference<registry::XSimpleRegistry> getRDB_RO() const;
151
152 public:
153 ComponentPackageImpl(
154 ::rtl::Reference<PackageRegistryBackend> const & myBackend,
155 OUString const & url, OUString const & name,
156 Reference<deployment::XPackageTypeInfo> const & xPackageType,
157 OUString const & loader, bool bRemoved,
158 OUString const & identifier);
159 };
160 friend class ComponentPackageImpl;
161
162 class ComponentsPackageImpl : public ::dp_registry::backend::Package
163 {
164 BackendImpl * getMyBackend() const;
165
166 // Package
167 virtual beans::Optional< beans::Ambiguous<sal_Bool> > isRegistered_(
168 ::osl::ResettableMutexGuard & guard,
169 ::rtl::Reference<AbortChannel> const & abortChannel,
170 Reference<XCommandEnvironment> const & xCmdEnv );
171 virtual void processPackage_(
172 ::osl::ResettableMutexGuard & guard,
173 bool registerPackage,
174 bool startup,
175 ::rtl::Reference<AbortChannel> const & abortChannel,
176 Reference<XCommandEnvironment> const & xCmdEnv );
177 public:
178 ComponentsPackageImpl(
179 ::rtl::Reference<PackageRegistryBackend> const & myBackend,
180 OUString const & url, OUString const & name,
181 Reference<deployment::XPackageTypeInfo> const & xPackageType,
182 bool bRemoved, OUString const & identifier);
183 };
184 friend class ComponentsPackageImpl;
185
186 class TypelibraryPackageImpl : public ::dp_registry::backend::Package
187 {
188 BackendImpl * getMyBackend() const;
189
190 const bool m_jarFile;
191 Reference<container::XHierarchicalNameAccess> m_xTDprov;
192
193 virtual void SAL_CALL disposing();
194
195 // Package
196 virtual beans::Optional< beans::Ambiguous<sal_Bool> > isRegistered_(
197 ::osl::ResettableMutexGuard & guard,
198 ::rtl::Reference<AbortChannel> const & abortChannel,
199 Reference<XCommandEnvironment> const & xCmdEnv );
200 virtual void processPackage_(
201 ::osl::ResettableMutexGuard & guard,
202 bool registerPackage,
203 bool startup,
204 ::rtl::Reference<AbortChannel> const & abortChannel,
205 Reference<XCommandEnvironment> const & xCmdEnv );
206
207 public:
208 TypelibraryPackageImpl(
209 ::rtl::Reference<PackageRegistryBackend> const & myBackend,
210 OUString const & url, OUString const & name,
211 Reference<deployment::XPackageTypeInfo> const & xPackageType,
212 bool jarFile, bool bRemoved,
213 OUString const & identifier);
214 };
215 friend class TypelibraryPackageImpl;
216
217 t_stringlist m_jar_typelibs;
218 t_stringlist m_rdb_typelibs;
219 t_stringlist m_components;
220
221 enum RcItem { RCITEM_JAR_TYPELIB, RCITEM_RDB_TYPELIB, RCITEM_COMPONENTS };
222
getRcItemList(RcItem kind)223 t_stringlist & getRcItemList( RcItem kind ) {
224 switch (kind)
225 {
226 case RCITEM_JAR_TYPELIB:
227 return m_jar_typelibs;
228 case RCITEM_RDB_TYPELIB:
229 return m_rdb_typelibs;
230 default: // case RCITEM_COMPONENTS
231 return m_components;
232 }
233 }
234
235 bool m_unorc_inited;
236 bool m_unorc_modified;
237 bool bSwitchedRdbFiles;
238
239 typedef ::std::hash_map< OUString, Reference<XInterface>,
240 ::rtl::OUStringHash > t_string2object;
241 t_string2object m_backendObjects;
242
243 // PackageRegistryBackend
244 virtual Reference<deployment::XPackage> bindPackage_(
245 OUString const & url, OUString const & mediaType,
246 sal_Bool bRemoved, OUString const & identifier,
247 Reference<XCommandEnvironment> const & xCmdEnv );
248
249 virtual void SAL_CALL disposing();
250
251 const Reference<deployment::XPackageTypeInfo> m_xDynComponentTypeInfo;
252 const Reference<deployment::XPackageTypeInfo> m_xJavaComponentTypeInfo;
253 const Reference<deployment::XPackageTypeInfo> m_xPythonComponentTypeInfo;
254 const Reference<deployment::XPackageTypeInfo> m_xComponentsTypeInfo;
255 const Reference<deployment::XPackageTypeInfo> m_xRDBTypelibTypeInfo;
256 const Reference<deployment::XPackageTypeInfo> m_xJavaTypelibTypeInfo;
257 Sequence< Reference<deployment::XPackageTypeInfo> > m_typeInfos;
258
259 OUString m_commonRDB;
260 OUString m_nativeRDB;
261
262 //URLs of the read-only rdbs (e.g. not the ones of the duplicated files)
263 OUString m_commonRDB_RO;
264 OUString m_nativeRDB_RO;
265
266 std::auto_ptr<ComponentBackendDb> m_backendDb;
267
268 void addDataToDb(OUString const & url, ComponentBackendDb::Data const & data);
269 ComponentBackendDb::Data readDataFromDb(OUString const & url);
270 void revokeEntryFromDb(OUString const & url);
271
272
273 //These rdbs are for writing new service entries. The rdb files are copies
274 //which are created when services are added or removed.
275 Reference<registry::XSimpleRegistry> m_xCommonRDB;
276 Reference<registry::XSimpleRegistry> m_xNativeRDB;
277
278 //These rdbs are created on the read-only rdbs which are already used
279 //by UNO since the startup of the current session.
280 Reference<registry::XSimpleRegistry> m_xCommonRDB_RO;
281 Reference<registry::XSimpleRegistry> m_xNativeRDB_RO;
282
283
284 void unorc_verify_init( Reference<XCommandEnvironment> const & xCmdEnv );
285 void unorc_flush( Reference<XCommandEnvironment> const & xCmdEnv );
286
287 Reference<XInterface> getObject( OUString const & id );
288 Reference<XInterface> insertObject(
289 OUString const & id, Reference<XInterface> const & xObject );
290 void releaseObject( OUString const & id );
291
292 bool addToUnoRc( RcItem kind, OUString const & url,
293 Reference<XCommandEnvironment> const & xCmdEnv );
294 bool removeFromUnoRc( RcItem kind, OUString const & url,
295 Reference<XCommandEnvironment> const & xCmdEnv );
296 bool hasInUnoRc( RcItem kind, OUString const & url );
297
298 css::uno::Reference< css::registry::XRegistryKey > openRegistryKey(
299 css::uno::Reference< css::registry::XRegistryKey > const & base,
300 rtl::OUString const & path);
301
302 void extractComponentData(
303 css::uno::Reference< css::uno::XComponentContext > const & context,
304 css::uno::Reference< css::registry::XRegistryKey > const & registry,
305 ComponentBackendDb::Data * data,
306 std::vector< css::uno::Reference< css::uno::XInterface > > * factories,
307 css::uno::Reference< css::loader::XImplementationLoader > const *
308 componentLoader,
309 rtl::OUString const * componentUrl);
310
311 void componentLiveInsertion(
312 ComponentBackendDb::Data const & data,
313 std::vector< css::uno::Reference< css::uno::XInterface > > const &
314 factories);
315
316 void componentLiveRemoval(ComponentBackendDb::Data const & data);
317
318 public:
319 BackendImpl( Sequence<Any> const & args,
320 Reference<XComponentContext> const & xComponentContext );
321
322 // XPackageRegistry
323 virtual Sequence< Reference<deployment::XPackageTypeInfo> > SAL_CALL
324 getSupportedPackageTypes() throw (RuntimeException);
325
326 virtual void SAL_CALL packageRemoved(OUString const & url, OUString const & mediaType)
327 throw (deployment::DeploymentException,
328 uno::RuntimeException);
329
330 using PackageRegistryBackend::disposing;
331
332 //Will be called from ComponentPackageImpl
333 void initServiceRdbFiles();
334
335 //Creates the READ ONLY registries (m_xCommonRDB_RO,m_xNativeRDB_RO)
336 void initServiceRdbFiles_RO();
337 };
338
339 //______________________________________________________________________________
340
ComponentPackageImpl(::rtl::Reference<PackageRegistryBackend> const & myBackend,OUString const & url,OUString const & name,Reference<deployment::XPackageTypeInfo> const & xPackageType,OUString const & loader,bool bRemoved,OUString const & identifier)341 BackendImpl::ComponentPackageImpl::ComponentPackageImpl(
342 ::rtl::Reference<PackageRegistryBackend> const & myBackend,
343 OUString const & url, OUString const & name,
344 Reference<deployment::XPackageTypeInfo> const & xPackageType,
345 OUString const & loader, bool bRemoved,
346 OUString const & identifier)
347 : Package( myBackend, url, name, name /* display-name */,
348 xPackageType, bRemoved, identifier),
349 m_loader( loader ),
350 m_registered( REG_UNINIT )
351 {}
352
353 const Reference<registry::XSimpleRegistry>
getRDB() const354 BackendImpl::ComponentPackageImpl::getRDB() const
355 {
356 BackendImpl * that = getMyBackend();
357
358 //Late "initialization" of the services rdb files
359 //This is to prevent problems when running several
360 //instances of OOo with root rights in parallel. This
361 //would otherwise cause problems when copying the rdbs.
362 //See http://qa.openoffice.org/issues/show_bug.cgi?id=99257
363 {
364 const ::osl::MutexGuard guard( getMutex() );
365 if (!that->bSwitchedRdbFiles)
366 {
367 that->bSwitchedRdbFiles = true;
368 that->initServiceRdbFiles();
369 }
370 }
371 if (m_loader.equalsAsciiL(
372 RTL_CONSTASCII_STRINGPARAM("com.sun.star.loader.SharedLibrary") ))
373 return that->m_xNativeRDB;
374 else
375 return that->m_xCommonRDB;
376 }
377
378 //Returns the read only RDB.
379 const Reference<registry::XSimpleRegistry>
getRDB_RO() const380 BackendImpl::ComponentPackageImpl::getRDB_RO() const
381 {
382 BackendImpl * that = getMyBackend();
383
384 if (m_loader.equalsAsciiL(
385 RTL_CONSTASCII_STRINGPARAM("com.sun.star.loader.SharedLibrary") ))
386 return that->m_xNativeRDB_RO;
387 else
388 return that->m_xCommonRDB_RO;
389 }
390
getMyBackend() const391 BackendImpl * BackendImpl::ComponentPackageImpl::getMyBackend() const
392 {
393 BackendImpl * pBackend = static_cast<BackendImpl *>(m_myBackend.get());
394 if (NULL == pBackend)
395 {
396 //Throws a DisposedException
397 check();
398 //We should never get here...
399 throw RuntimeException(
400 OUSTR("Failed to get the BackendImpl"),
401 static_cast<OWeakObject*>(const_cast<ComponentPackageImpl *>(this)));
402 }
403 return pBackend;
404 }
405
406
407 //______________________________________________________________________________
disposing()408 void BackendImpl::ComponentPackageImpl::disposing()
409 {
410 // m_xRemoteContext.clear();
411 Package::disposing();
412 }
413
414 //______________________________________________________________________________
disposing()415 void BackendImpl::TypelibraryPackageImpl::disposing()
416 {
417 m_xTDprov.clear();
418 Package::disposing();
419 }
420
421 //______________________________________________________________________________
disposing()422 void BackendImpl::disposing()
423 {
424 try {
425 m_backendObjects = t_string2object();
426 if (m_xNativeRDB.is()) {
427 m_xNativeRDB->close();
428 m_xNativeRDB.clear();
429 }
430 if (m_xCommonRDB.is()) {
431 m_xCommonRDB->close();
432 m_xCommonRDB.clear();
433 }
434 unorc_flush( Reference<XCommandEnvironment>() );
435
436 PackageRegistryBackend::disposing();
437 }
438 catch (RuntimeException &) {
439 throw;
440 }
441 catch (Exception &) {
442 Any exc( ::cppu::getCaughtException() );
443 throw lang::WrappedTargetRuntimeException(
444 OUSTR("caught unexpected exception while disposing..."),
445 static_cast<OWeakObject *>(this), exc );
446 }
447 }
448
449
initServiceRdbFiles()450 void BackendImpl::initServiceRdbFiles()
451 {
452 const Reference<XCommandEnvironment> xCmdEnv;
453
454 ::ucbhelper::Content cacheDir( getCachePath(), xCmdEnv );
455 ::ucbhelper::Content oldRDB;
456 // switch common rdb:
457 if (m_commonRDB_RO.getLength() > 0)
458 {
459 create_ucb_content(
460 &oldRDB, makeURL( getCachePath(), m_commonRDB_RO),
461 xCmdEnv, false /* no throw */ );
462 }
463 m_commonRDB = m_commonRDB_RO.equalsAsciiL(
464 RTL_CONSTASCII_STRINGPARAM("common.rdb") )
465 ? OUSTR("common_.rdb") : OUSTR("common.rdb");
466 if (oldRDB.get().is())
467 {
468 if (! cacheDir.transferContent(
469 oldRDB, ::ucbhelper::InsertOperation_COPY,
470 m_commonRDB, NameClash::OVERWRITE ))
471 {
472
473 throw RuntimeException(
474 OUSTR("UCB transferContent() failed!"), 0 );
475 }
476 oldRDB = ::ucbhelper::Content();
477 }
478 // switch native rdb:
479 if (m_nativeRDB_RO.getLength() > 0)
480 {
481 create_ucb_content(
482 &oldRDB, makeURL(getCachePath(), m_nativeRDB_RO),
483 xCmdEnv, false /* no throw */ );
484 }
485 const OUString plt_rdb( getPlatformString() + OUSTR(".rdb") );
486 const OUString plt_rdb_( getPlatformString() + OUSTR("_.rdb") );
487 m_nativeRDB = m_nativeRDB_RO.equals( plt_rdb ) ? plt_rdb_ : plt_rdb;
488 if (oldRDB.get().is())
489 {
490 if (! cacheDir.transferContent(
491 oldRDB, ::ucbhelper::InsertOperation_COPY,
492 m_nativeRDB, NameClash::OVERWRITE ))
493 throw RuntimeException(
494 OUSTR("UCB transferContent() failed!"), 0 );
495 }
496
497 // UNO is bootstrapped, flush for next process start:
498 m_unorc_modified = true;
499 unorc_flush( Reference<XCommandEnvironment>() );
500
501
502 // common rdb for java, native rdb for shared lib components
503 if (m_commonRDB.getLength() > 0) {
504 m_xCommonRDB.set(
505 m_xComponentContext->getServiceManager()
506 ->createInstanceWithContext(
507 OUSTR("com.sun.star.registry.SimpleRegistry"),
508 m_xComponentContext ), UNO_QUERY_THROW );
509 m_xCommonRDB->open(
510 makeURL( expandUnoRcUrl(getCachePath()), m_commonRDB ),
511 // m_readOnly, !m_readOnly );
512 false, true);
513 }
514 if (m_nativeRDB.getLength() > 0) {
515 m_xNativeRDB.set(
516 m_xComponentContext->getServiceManager()
517 ->createInstanceWithContext(
518 OUSTR("com.sun.star.registry.SimpleRegistry"),
519 m_xComponentContext ), UNO_QUERY_THROW );
520 m_xNativeRDB->open(
521 makeURL( expandUnoRcUrl(getCachePath()), m_nativeRDB ),
522 // m_readOnly, !m_readOnly );
523 false, true);
524 }
525 }
526
initServiceRdbFiles_RO()527 void BackendImpl::initServiceRdbFiles_RO()
528 {
529 const Reference<XCommandEnvironment> xCmdEnv;
530
531 // common rdb for java, native rdb for shared lib components
532 if (m_commonRDB_RO.getLength() > 0)
533 {
534 m_xCommonRDB_RO.set(
535 m_xComponentContext->getServiceManager()
536 ->createInstanceWithContext(
537 OUSTR("com.sun.star.registry.SimpleRegistry"),
538 m_xComponentContext), UNO_QUERY_THROW);
539 m_xCommonRDB_RO->open(
540 makeURL(expandUnoRcUrl(getCachePath()), m_commonRDB_RO),
541 sal_True, //read-only
542 sal_True); // create data source if necessary
543 }
544 if (m_nativeRDB_RO.getLength() > 0)
545 {
546 m_xNativeRDB_RO.set(
547 m_xComponentContext->getServiceManager()
548 ->createInstanceWithContext(
549 OUSTR("com.sun.star.registry.SimpleRegistry"),
550 m_xComponentContext), UNO_QUERY_THROW);
551 m_xNativeRDB_RO->open(
552 makeURL(expandUnoRcUrl(getCachePath()), m_nativeRDB_RO),
553 sal_True, //read-only
554 sal_True); // create data source if necessary
555 }
556 }
557
558 //______________________________________________________________________________
BackendImpl(Sequence<Any> const & args,Reference<XComponentContext> const & xComponentContext)559 BackendImpl::BackendImpl(
560 Sequence<Any> const & args,
561 Reference<XComponentContext> const & xComponentContext )
562 : PackageRegistryBackend( args, xComponentContext ),
563 m_unorc_inited( false ),
564 m_unorc_modified( false ),
565 bSwitchedRdbFiles(false),
566 m_xDynComponentTypeInfo( new Package::TypeInfo(
567 OUSTR("application/"
568 "vnd.sun.star.uno-component;"
569 "type=native;platform=") +
570 getPlatformString(),
571 OUSTR("*" SAL_DLLEXTENSION),
572 getResourceString(RID_STR_DYN_COMPONENT),
573 RID_IMG_COMPONENT,
574 RID_IMG_COMPONENT_HC ) ),
575 m_xJavaComponentTypeInfo( new Package::TypeInfo(
576 OUSTR("application/"
577 "vnd.sun.star.uno-component;"
578 "type=Java"),
579 OUSTR("*.jar"),
580 getResourceString(RID_STR_JAVA_COMPONENT),
581 RID_IMG_JAVA_COMPONENT,
582 RID_IMG_JAVA_COMPONENT_HC ) ),
583 m_xPythonComponentTypeInfo( new Package::TypeInfo(
584 OUSTR("application/"
585 "vnd.sun.star.uno-component;"
586 "type=Python"),
587 OUSTR("*.py"),
588 getResourceString(
589 RID_STR_PYTHON_COMPONENT),
590 RID_IMG_COMPONENT,
591 RID_IMG_COMPONENT_HC ) ),
592 m_xComponentsTypeInfo( new Package::TypeInfo(
593 OUSTR("application/"
594 "vnd.sun.star.uno-components"),
595 OUSTR("*.components"),
596 getResourceString(RID_STR_COMPONENTS),
597 RID_IMG_COMPONENT,
598 RID_IMG_COMPONENT_HC ) ),
599 m_xRDBTypelibTypeInfo( new Package::TypeInfo(
600 OUSTR("application/"
601 "vnd.sun.star.uno-typelibrary;"
602 "type=RDB"),
603 OUSTR("*.rdb"),
604 getResourceString(RID_STR_RDB_TYPELIB),
605 RID_IMG_TYPELIB, RID_IMG_TYPELIB_HC ) ),
606 m_xJavaTypelibTypeInfo( new Package::TypeInfo(
607 OUSTR("application/"
608 "vnd.sun.star.uno-typelibrary;"
609 "type=Java"),
610 OUSTR("*.jar"),
611 getResourceString(RID_STR_JAVA_TYPELIB),
612 RID_IMG_JAVA_TYPELIB,
613 RID_IMG_JAVA_TYPELIB_HC ) ),
614 m_typeInfos( 6 )
615 {
616 m_typeInfos[ 0 ] = m_xDynComponentTypeInfo;
617 m_typeInfos[ 1 ] = m_xJavaComponentTypeInfo;
618 m_typeInfos[ 2 ] = m_xPythonComponentTypeInfo;
619 m_typeInfos[ 3 ] = m_xComponentsTypeInfo;
620 m_typeInfos[ 4 ] = m_xRDBTypelibTypeInfo;
621 m_typeInfos[ 5 ] = m_xJavaTypelibTypeInfo;
622
623 const Reference<XCommandEnvironment> xCmdEnv;
624
625 if (transientMode())
626 {
627 // in-mem rdbs:
628 // common rdb for java, native rdb for shared lib components
629 m_xCommonRDB.set(
630 xComponentContext->getServiceManager()->createInstanceWithContext(
631 OUSTR("com.sun.star.registry.SimpleRegistry"),
632 xComponentContext ), UNO_QUERY_THROW );
633 m_xCommonRDB->open( OUString() /* in-mem */,
634 false /* ! read-only */, true /* create */ );
635 m_xNativeRDB.set(
636 xComponentContext->getServiceManager()->createInstanceWithContext(
637 OUSTR("com.sun.star.registry.SimpleRegistry"),
638 xComponentContext ), UNO_QUERY_THROW );
639 m_xNativeRDB->open( OUString() /* in-mem */,
640 false /* ! read-only */, true /* create */ );
641 }
642 else
643 {
644 //do this before initServiceRdbFiles_RO, because it determines
645 //m_commonRDB and m_nativeRDB
646 unorc_verify_init( xCmdEnv );
647
648 initServiceRdbFiles_RO();
649
650 OUString dbFile = makeURL(getCachePath(), OUSTR("backenddb.xml"));
651 m_backendDb.reset(
652 new ComponentBackendDb(getComponentContext(), dbFile));
653 }
654 }
655
addDataToDb(OUString const & url,ComponentBackendDb::Data const & data)656 void BackendImpl::addDataToDb(
657 OUString const & url, ComponentBackendDb::Data const & data)
658 {
659 if (m_backendDb.get())
660 m_backendDb->addEntry(url, data);
661 }
662
readDataFromDb(OUString const & url)663 ComponentBackendDb::Data BackendImpl::readDataFromDb(OUString const & url)
664 {
665 ComponentBackendDb::Data data;
666 if (m_backendDb.get())
667 data = m_backendDb->getEntry(url);
668 return data;
669 }
670
revokeEntryFromDb(OUString const & url)671 void BackendImpl::revokeEntryFromDb(OUString const & url)
672 {
673 if (m_backendDb.get())
674 m_backendDb->revokeEntry(url);
675 }
676
677 // XPackageRegistry
678 //______________________________________________________________________________
679 Sequence< Reference<deployment::XPackageTypeInfo> >
getSupportedPackageTypes()680 BackendImpl::getSupportedPackageTypes() throw (RuntimeException)
681 {
682 return m_typeInfos;
683 }
684
packageRemoved(OUString const & url,OUString const &)685 void BackendImpl::packageRemoved(OUString const & url, OUString const & /*mediaType*/)
686 throw (deployment::DeploymentException,
687 uno::RuntimeException)
688 {
689 if (m_backendDb.get())
690 m_backendDb->removeEntry(url);
691 }
692
693 // PackageRegistryBackend
694 //______________________________________________________________________________
bindPackage_(OUString const & url,OUString const & mediaType_,sal_Bool bRemoved,OUString const & identifier,Reference<XCommandEnvironment> const & xCmdEnv)695 Reference<deployment::XPackage> BackendImpl::bindPackage_(
696 OUString const & url, OUString const & mediaType_,
697 sal_Bool bRemoved, OUString const & identifier,
698 Reference<XCommandEnvironment> const & xCmdEnv )
699 {
700 OUString mediaType(mediaType_);
701 if (mediaType.getLength() == 0 ||
702 mediaType.equalsAsciiL(
703 RTL_CONSTASCII_STRINGPARAM(
704 "application/vnd.sun.star.uno-component") ) ||
705 mediaType.equalsAsciiL(
706 RTL_CONSTASCII_STRINGPARAM(
707 "application/vnd.sun.star.uno-typelibrary") ))
708 {
709 // detect exact media-type:
710 ::ucbhelper::Content ucbContent;
711 if (create_ucb_content( &ucbContent, url, xCmdEnv )) {
712 const OUString title( ucbContent.getPropertyValue(
713 StrTitle::get() ).get<OUString>() );
714 if (title.endsWithIgnoreAsciiCaseAsciiL(
715 RTL_CONSTASCII_STRINGPARAM(SAL_DLLEXTENSION) ))
716 {
717 mediaType = OUSTR("application/vnd.sun.star.uno-component;"
718 "type=native;platform=") +
719 getPlatformString();
720 }
721 else if (title.endsWithIgnoreAsciiCaseAsciiL(
722 RTL_CONSTASCII_STRINGPARAM(".jar") ))
723 {
724 if (jarManifestHeaderPresent(
725 url, OUSTR("RegistrationClassName"), xCmdEnv ))
726 mediaType = OUSTR(
727 "application/vnd.sun.star.uno-component;type=Java");
728 if (mediaType.getLength() == 0)
729 mediaType = OUSTR(
730 "application/vnd.sun.star.uno-typelibrary;type=Java");
731 }
732 else if (title.endsWithIgnoreAsciiCaseAsciiL(
733 RTL_CONSTASCII_STRINGPARAM(".py") ))
734 mediaType =
735 OUSTR("application/vnd.sun.star.uno-component;type=Python");
736 else if (title.endsWithIgnoreAsciiCaseAsciiL(
737 RTL_CONSTASCII_STRINGPARAM(".rdb") ))
738 mediaType =
739 OUSTR("application/vnd.sun.star.uno-typelibrary;type=RDB");
740 }
741 if (mediaType.getLength() == 0)
742 throw lang::IllegalArgumentException(
743 StrCannotDetectMediaType::get() + url,
744 static_cast<OWeakObject *>(this), static_cast<sal_Int16>(-1) );
745 }
746
747 String type, subType;
748 INetContentTypeParameterList params;
749 if (INetContentTypes::parse( mediaType, type, subType, ¶ms ))
750 {
751 if (type.EqualsIgnoreCaseAscii("application"))
752 {
753 OUString name;
754 if (!bRemoved)
755 {
756 ::ucbhelper::Content ucbContent( url, xCmdEnv );
757 name = ucbContent.getPropertyValue(
758 StrTitle::get() ).get<OUString>();
759 }
760
761 if (subType.EqualsIgnoreCaseAscii("vnd.sun.star.uno-component"))
762 {
763 // xxx todo: probe and evaluate component xml description
764
765 INetContentTypeParameter const * param = params.find(
766 ByteString("platform") );
767 if (param == 0 || platform_fits( param->m_sValue )) {
768 param = params.find( ByteString("type") );
769 if (param != 0)
770 {
771 String const & value = param->m_sValue;
772 if (value.EqualsIgnoreCaseAscii("native")) {
773 return new BackendImpl::ComponentPackageImpl(
774 this, url, name, m_xDynComponentTypeInfo,
775 OUSTR("com.sun.star.loader.SharedLibrary"),
776 bRemoved, identifier);
777 }
778 if (value.EqualsIgnoreCaseAscii("Java")) {
779 return new BackendImpl::ComponentPackageImpl(
780 this, url, name, m_xJavaComponentTypeInfo,
781 OUSTR("com.sun.star.loader.Java2"),
782 bRemoved, identifier);
783 }
784 if (value.EqualsIgnoreCaseAscii("Python")) {
785 return new BackendImpl::ComponentPackageImpl(
786 this, url, name, m_xPythonComponentTypeInfo,
787 OUSTR("com.sun.star.loader.Python"),
788 bRemoved, identifier);
789 }
790 }
791 }
792 }
793 else if (subType.EqualsIgnoreCaseAscii(
794 "vnd.sun.star.uno-components"))
795 {
796 INetContentTypeParameter const * param = params.find(
797 ByteString("platform") );
798 if (param == 0 || platform_fits( param->m_sValue )) {
799 return new BackendImpl::ComponentsPackageImpl(
800 this, url, name, m_xComponentsTypeInfo, bRemoved,
801 identifier);
802 }
803 }
804 else if (subType.EqualsIgnoreCaseAscii(
805 "vnd.sun.star.uno-typelibrary"))
806 {
807 INetContentTypeParameter const * param = params.find(
808 ByteString("type") );
809 if (param != 0) {
810 String const & value = param->m_sValue;
811 if (value.EqualsIgnoreCaseAscii("RDB"))
812 {
813 return new BackendImpl::TypelibraryPackageImpl(
814 this, url, name, m_xRDBTypelibTypeInfo,
815 false /* rdb */, bRemoved, identifier);
816 }
817 if (value.EqualsIgnoreCaseAscii("Java")) {
818 return new BackendImpl::TypelibraryPackageImpl(
819 this, url, name, m_xJavaTypelibTypeInfo,
820 true /* jar */, bRemoved, identifier);
821 }
822 }
823 }
824 }
825 }
826 throw lang::IllegalArgumentException(
827 StrUnsupportedMediaType::get() + mediaType,
828 static_cast<OWeakObject *>(this),
829 static_cast<sal_Int16>(-1) );
830 }
831
832 //##############################################################################
833
834 //______________________________________________________________________________
unorc_verify_init(Reference<XCommandEnvironment> const & xCmdEnv)835 void BackendImpl::unorc_verify_init(
836 Reference<XCommandEnvironment> const & xCmdEnv )
837 {
838 if (transientMode())
839 return;
840 const ::osl::MutexGuard guard( getMutex() );
841 if (! m_unorc_inited)
842 {
843 // common rc:
844 ::ucbhelper::Content ucb_content;
845 if (create_ucb_content(
846 &ucb_content,
847 makeURL( getCachePath(), OUSTR("unorc") ),
848 xCmdEnv, false /* no throw */ ))
849 {
850 OUString line;
851 if (readLine( &line, OUSTR("UNO_JAVA_CLASSPATH="), ucb_content,
852 RTL_TEXTENCODING_UTF8 ))
853 {
854 sal_Int32 index = sizeof ("UNO_JAVA_CLASSPATH=") - 1;
855 do {
856 OUString token( line.getToken( 0, ' ', index ).trim() );
857 if (token.getLength() > 0)
858 {
859 if (create_ucb_content(
860 0, expandUnoRcTerm(token), xCmdEnv,
861 false /* no throw */ ))
862 {
863 //The jar file may not exist anymore if a shared or bundled
864 //extension was removed, but it can still be in the unorc
865 //After running XExtensionManager::synchronize, the unorc is
866 //cleaned up
867 m_jar_typelibs.push_back( token );
868 }
869 }
870 }
871 while (index >= 0);
872 }
873 if (readLine( &line, OUSTR("UNO_TYPES="), ucb_content,
874 RTL_TEXTENCODING_UTF8 )) {
875 sal_Int32 index = sizeof ("UNO_TYPES=") - 1;
876 do {
877 OUString token( line.getToken( 0, ' ', index ).trim() );
878 if (token.getLength() > 0)
879 {
880 if (token[ 0 ] == '?')
881 token = token.copy( 1 );
882 if (create_ucb_content(
883 0, expandUnoRcTerm(token), xCmdEnv,
884 false /* no throw */ ))
885 {
886 //The RDB file may not exist anymore if a shared or bundled
887 //extension was removed, but it can still be in the unorc.
888 //After running XExtensionManager::synchronize, the unorc is
889 //cleaned up
890 m_rdb_typelibs.push_back( token );
891 }
892 }
893 }
894 while (index >= 0);
895 }
896 if (readLine( &line, OUSTR("UNO_SERVICES="), ucb_content,
897 RTL_TEXTENCODING_UTF8 ))
898 {
899 // The UNO_SERVICES line always has the BNF form
900 // "UNO_SERVICES="
901 // ("?$ORIGIN/" <common-rdb>)? -- first
902 // "${$ORIGIN/${_OS}_${_ARCH}rc:UNO_SERVICES}"? -- second
903 // ("?" ("BUNDLED_EXTENSIONS" | -- third
904 // "UNO_SHARED_PACKAGES_CACHE" | "UNO_USER_PACKAGES_CACHE")
905 // ...)*
906 // so can unambiguously be split into its thre parts:
907 int state = 1;
908 for (sal_Int32 i = RTL_CONSTASCII_LENGTH("UNO_SERVICES=");
909 i >= 0;)
910 {
911 rtl::OUString token(line.getToken(0, ' ', i));
912 if (token.getLength() != 0)
913 {
914 if (state == 1 &&
915 token.matchAsciiL(
916 RTL_CONSTASCII_STRINGPARAM("?$ORIGIN/")))
917 {
918 m_commonRDB_RO = token.copy(
919 RTL_CONSTASCII_LENGTH("?$ORIGIN/"));
920 state = 2;
921 }
922 else if (state <= 2 &&
923 token.equalsAsciiL(
924 RTL_CONSTASCII_STRINGPARAM(
925 "${$ORIGIN/${_OS}_${_ARCH}rc:"
926 "UNO_SERVICES}")))
927 {
928 state = 3;
929 }
930 else
931 {
932 if (token[0] == '?')
933 {
934 token = token.copy(1);
935 }
936 m_components.push_back(token);
937 state = 3;
938 }
939 }
940 }
941 }
942
943 // native rc:
944 if (create_ucb_content(
945 &ucb_content,
946 makeURL( getCachePath(), getPlatformString() + OUSTR("rc")),
947 xCmdEnv, false /* no throw */ )) {
948 if (readLine( &line, OUSTR("UNO_SERVICES="), ucb_content,
949 RTL_TEXTENCODING_UTF8 )) {
950 m_nativeRDB_RO = line.copy(
951 sizeof ("UNO_SERVICES=?$ORIGIN/") - 1 );
952 }
953 }
954 }
955 m_unorc_modified = false;
956 m_unorc_inited = true;
957 }
958 }
959
960 //______________________________________________________________________________
unorc_flush(Reference<XCommandEnvironment> const & xCmdEnv)961 void BackendImpl::unorc_flush( Reference<XCommandEnvironment> const & xCmdEnv )
962 {
963 if (transientMode())
964 return;
965 if (!m_unorc_inited || !m_unorc_modified)
966 return;
967
968 ::rtl::OStringBuffer buf;
969
970 buf.append(RTL_CONSTASCII_STRINGPARAM("ORIGIN="));
971 OUString sOrigin = dp_misc::makeRcTerm(m_cachePath);
972 ::rtl::OString osOrigin = ::rtl::OUStringToOString(sOrigin, RTL_TEXTENCODING_UTF8);
973 buf.append(osOrigin);
974 buf.append(LF);
975
976 if (! m_jar_typelibs.empty())
977 {
978 t_stringlist::const_iterator iPos( m_jar_typelibs.begin() );
979 t_stringlist::const_iterator const iEnd( m_jar_typelibs.end() );
980 buf.append( RTL_CONSTASCII_STRINGPARAM("UNO_JAVA_CLASSPATH=") );
981 while (iPos != iEnd) {
982 // encoded ASCII file-urls:
983 const ::rtl::OString item(
984 ::rtl::OUStringToOString( *iPos, RTL_TEXTENCODING_ASCII_US ) );
985 buf.append( item );
986 ++iPos;
987 if (iPos != iEnd)
988 buf.append( ' ' );
989 }
990 buf.append(LF);
991 }
992 if (! m_rdb_typelibs.empty())
993 {
994 t_stringlist::const_iterator iPos( m_rdb_typelibs.begin() );
995 t_stringlist::const_iterator const iEnd( m_rdb_typelibs.end() );
996 buf.append( RTL_CONSTASCII_STRINGPARAM("UNO_TYPES=") );
997 while (iPos != iEnd) {
998 buf.append( '?' );
999 // encoded ASCII file-urls:
1000 const ::rtl::OString item(
1001 ::rtl::OUStringToOString( *iPos, RTL_TEXTENCODING_ASCII_US ) );
1002 buf.append( item );
1003 ++iPos;
1004 if (iPos != iEnd)
1005 buf.append( ' ' );
1006 }
1007 buf.append(LF);
1008 }
1009
1010 // If we duplicated the common or native rdb then we must use those urls
1011 //otherwise we use those of the original files. That is, m_commonRDB_RO and
1012 //m_nativeRDB_RO;
1013 OUString sCommonRDB(m_commonRDB.getLength() > 0 ? m_commonRDB : m_commonRDB_RO);
1014 OUString sNativeRDB(m_nativeRDB.getLength() > 0 ? m_nativeRDB : m_nativeRDB_RO);
1015
1016 if (sCommonRDB.getLength() > 0 || sNativeRDB.getLength() > 0 ||
1017 !m_components.empty())
1018 {
1019 buf.append( RTL_CONSTASCII_STRINGPARAM("UNO_SERVICES=") );
1020 bool space = false;
1021 if (sCommonRDB.getLength() > 0)
1022 {
1023 buf.append( RTL_CONSTASCII_STRINGPARAM("?$ORIGIN/") );
1024 buf.append( ::rtl::OUStringToOString(
1025 sCommonRDB, RTL_TEXTENCODING_ASCII_US ) );
1026 space = true;
1027 }
1028 if (sNativeRDB.getLength() > 0)
1029 {
1030 if (space)
1031 {
1032 buf.append(' ');
1033 }
1034 buf.append( RTL_CONSTASCII_STRINGPARAM(
1035 "${$ORIGIN/${_OS}_${_ARCH}rc:UNO_SERVICES}") );
1036 space = true;
1037
1038 // write native rc:
1039 ::rtl::OStringBuffer buf2;
1040 buf2.append(RTL_CONSTASCII_STRINGPARAM("ORIGIN="));
1041 buf2.append(osOrigin);
1042 buf2.append(LF);
1043 buf2.append( RTL_CONSTASCII_STRINGPARAM("UNO_SERVICES=?$ORIGIN/") );
1044 buf2.append( ::rtl::OUStringToOString(
1045 sNativeRDB, RTL_TEXTENCODING_ASCII_US ) );
1046 buf2.append(LF);
1047
1048 const Reference<io::XInputStream> xData(
1049 ::xmlscript::createInputStream(
1050 ::rtl::ByteSequence(
1051 reinterpret_cast<sal_Int8 const *>(buf2.getStr()),
1052 buf2.getLength() ) ) );
1053 ::ucbhelper::Content ucb_content(
1054 makeURL( getCachePath(), getPlatformString() + OUSTR("rc") ),
1055 xCmdEnv );
1056 ucb_content.writeStream( xData, true /* replace existing */ );
1057 }
1058 for (t_stringlist::iterator i(m_components.begin());
1059 i != m_components.end(); ++i)
1060 {
1061 if (space)
1062 {
1063 buf.append(' ');
1064 }
1065 buf.append('?');
1066 buf.append(rtl::OUStringToOString(*i, RTL_TEXTENCODING_UTF8));
1067 space = true;
1068 }
1069 buf.append(LF);
1070 }
1071
1072 // write unorc:
1073 const Reference<io::XInputStream> xData(
1074 ::xmlscript::createInputStream(
1075 ::rtl::ByteSequence(
1076 reinterpret_cast<sal_Int8 const *>(buf.getStr()),
1077 buf.getLength() ) ) );
1078 ::ucbhelper::Content ucb_content(
1079 makeURL( getCachePath(), OUSTR("unorc") ), xCmdEnv );
1080 ucb_content.writeStream( xData, true /* replace existing */ );
1081
1082 m_unorc_modified = false;
1083 }
1084
1085 //______________________________________________________________________________
addToUnoRc(RcItem kind,OUString const & url_,Reference<XCommandEnvironment> const & xCmdEnv)1086 bool BackendImpl::addToUnoRc( RcItem kind, OUString const & url_,
1087 Reference<XCommandEnvironment> const & xCmdEnv )
1088 {
1089 const OUString rcterm( dp_misc::makeRcTerm(url_) );
1090 const ::osl::MutexGuard guard( getMutex() );
1091 unorc_verify_init( xCmdEnv );
1092 t_stringlist & rSet = getRcItemList(kind);
1093 if (::std::find( rSet.begin(), rSet.end(), rcterm ) == rSet.end()) {
1094 rSet.push_front( rcterm ); // prepend to list, thus overriding
1095 // write immediately:
1096 m_unorc_modified = true;
1097 unorc_flush( xCmdEnv );
1098 return true;
1099 }
1100 else
1101 return false;
1102 }
1103
1104 //______________________________________________________________________________
removeFromUnoRc(RcItem kind,OUString const & url_,Reference<XCommandEnvironment> const & xCmdEnv)1105 bool BackendImpl::removeFromUnoRc(
1106 RcItem kind, OUString const & url_,
1107 Reference<XCommandEnvironment> const & xCmdEnv )
1108 {
1109 const OUString rcterm( dp_misc::makeRcTerm(url_) );
1110 const ::osl::MutexGuard guard( getMutex() );
1111 unorc_verify_init( xCmdEnv );
1112 getRcItemList(kind).remove( rcterm );
1113 // write immediately:
1114 m_unorc_modified = true;
1115 unorc_flush( xCmdEnv );
1116 return true;
1117 }
1118
1119 //______________________________________________________________________________
hasInUnoRc(RcItem kind,OUString const & url_)1120 bool BackendImpl::hasInUnoRc(
1121 RcItem kind, OUString const & url_ )
1122 {
1123 const OUString rcterm( dp_misc::makeRcTerm(url_) );
1124 const ::osl::MutexGuard guard( getMutex() );
1125 t_stringlist const & rSet = getRcItemList(kind);
1126 return ::std::find( rSet.begin(), rSet.end(), rcterm ) != rSet.end();
1127 }
1128
openRegistryKey(css::uno::Reference<css::registry::XRegistryKey> const & base,rtl::OUString const & path)1129 css::uno::Reference< css::registry::XRegistryKey > BackendImpl::openRegistryKey(
1130 css::uno::Reference< css::registry::XRegistryKey > const & base,
1131 rtl::OUString const & path)
1132 {
1133 OSL_ASSERT(base.is());
1134 css::uno::Reference< css::registry::XRegistryKey > key(base->openKey(path));
1135 if (!key.is()) {
1136 throw css::deployment::DeploymentException(
1137 (rtl::OUString(
1138 RTL_CONSTASCII_USTRINGPARAM("missing registry entry ")) +
1139 path + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" under ")) +
1140 base->getKeyName()),
1141 static_cast< OWeakObject * >(this), Any());
1142 }
1143 return key;
1144 }
1145
extractComponentData(css::uno::Reference<css::uno::XComponentContext> const & context,css::uno::Reference<css::registry::XRegistryKey> const & registry,ComponentBackendDb::Data * data,std::vector<css::uno::Reference<css::uno::XInterface>> * factories,css::uno::Reference<css::loader::XImplementationLoader> const * componentLoader,rtl::OUString const * componentUrl)1146 void BackendImpl::extractComponentData(
1147 css::uno::Reference< css::uno::XComponentContext > const & context,
1148 css::uno::Reference< css::registry::XRegistryKey > const & registry,
1149 ComponentBackendDb::Data * data,
1150 std::vector< css::uno::Reference< css::uno::XInterface > > * factories,
1151 css::uno::Reference< css::loader::XImplementationLoader > const *
1152 componentLoader,
1153 rtl::OUString const * componentUrl)
1154 {
1155 OSL_ASSERT(context.is() && registry.is() && data != 0 && factories != 0);
1156 rtl::OUString registryName(registry->getKeyName());
1157 sal_Int32 prefix = registryName.getLength();
1158 if (!registryName.endsWithAsciiL(RTL_CONSTASCII_STRINGPARAM("/"))) {
1159 prefix += RTL_CONSTASCII_LENGTH("/");
1160 }
1161 css::uno::Sequence< css::uno::Reference< css::registry::XRegistryKey > >
1162 keys(registry->openKeys());
1163 css::uno::Reference< css::lang::XMultiComponentFactory > smgr(
1164 context->getServiceManager(), css::uno::UNO_QUERY_THROW);
1165 for (sal_Int32 i = 0; i < keys.getLength(); ++i) {
1166 rtl::OUString name(keys[i]->getKeyName().copy(prefix));
1167 data->implementationNames.push_back(name);
1168 css::uno::Reference< css::registry::XRegistryKey > singletons(
1169 keys[i]->openKey(
1170 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("UNO/SINGLETONS"))));
1171 if (singletons.is()) {
1172 sal_Int32 prefix2 = keys[i]->getKeyName().getLength() +
1173 RTL_CONSTASCII_LENGTH("/UNO/SINGLETONS/");
1174 css::uno::Sequence<
1175 css::uno::Reference< css::registry::XRegistryKey > >
1176 singletonKeys(singletons->openKeys());
1177 for (sal_Int32 j = 0; j < singletonKeys.getLength(); ++j) {
1178 data->singletons.push_back(
1179 std::pair< rtl::OUString, rtl::OUString >(
1180 singletonKeys[j]->getKeyName().copy(prefix2), name));
1181 }
1182 }
1183 css::uno::Reference< css::loader::XImplementationLoader > loader;
1184 if (componentLoader == 0) {
1185 rtl::OUString activator(
1186 openRegistryKey(
1187 keys[i],
1188 rtl::OUString(
1189 RTL_CONSTASCII_USTRINGPARAM("UNO/ACTIVATOR")))->
1190 getAsciiValue());
1191 loader.set(
1192 smgr->createInstanceWithContext(activator, context),
1193 css::uno::UNO_QUERY);
1194 if (!loader.is()) {
1195 throw css::deployment::DeploymentException(
1196 (rtl::OUString(
1197 RTL_CONSTASCII_USTRINGPARAM(
1198 "cannot instantiate loader ")) +
1199 activator),
1200 static_cast< OWeakObject * >(this), Any());
1201 }
1202 } else {
1203 OSL_ASSERT(componentLoader->is());
1204 loader = *componentLoader;
1205 }
1206 factories->push_back(
1207 loader->activate(
1208 name, rtl::OUString(),
1209 (componentUrl == 0
1210 ? (openRegistryKey(
1211 keys[i],
1212 rtl::OUString(
1213 RTL_CONSTASCII_USTRINGPARAM("UNO/LOCATION")))->
1214 getAsciiValue())
1215 : *componentUrl),
1216 keys[i]));
1217 }
1218 }
1219
componentLiveInsertion(ComponentBackendDb::Data const & data,std::vector<css::uno::Reference<css::uno::XInterface>> const & factories)1220 void BackendImpl::componentLiveInsertion(
1221 ComponentBackendDb::Data const & data,
1222 std::vector< css::uno::Reference< css::uno::XInterface > > const &
1223 factories)
1224 {
1225 css::uno::Reference< css::container::XSet > set(
1226 getComponentContext()->getServiceManager(), css::uno::UNO_QUERY_THROW);
1227 std::vector< css::uno::Reference< css::uno::XInterface > >::const_iterator
1228 factory(factories.begin());
1229 for (t_stringlist::const_iterator i(data.implementationNames.begin());
1230 i != data.implementationNames.end(); ++i)
1231 {
1232 try {
1233 set->insert(css::uno::Any(*factory++));
1234 } catch (container::ElementExistException &) {
1235 OSL_TRACE(
1236 "implementation %s already registered",
1237 rtl::OUStringToOString(*i, RTL_TEXTENCODING_UTF8).getStr());
1238 }
1239 }
1240 if (!data.singletons.empty()) {
1241 css::uno::Reference< css::container::XNameContainer >
1242 rootContext(
1243 getComponentContext()->getValueByName(
1244 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("_root"))),
1245 css::uno::UNO_QUERY);
1246 if (rootContext.is()) {
1247 for (t_stringpairvec::const_iterator i(data.singletons.begin());
1248 i != data.singletons.end(); ++i)
1249 {
1250 rtl::OUString name(
1251 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/singletons/")) +
1252 i->first);
1253 try {
1254 rootContext->removeByName(
1255 name +
1256 rtl::OUString(
1257 RTL_CONSTASCII_USTRINGPARAM("/arguments")));
1258 } catch (container::NoSuchElementException &) {}
1259 try {
1260 rootContext->insertByName(
1261 (name +
1262 rtl::OUString(
1263 RTL_CONSTASCII_USTRINGPARAM("/service"))),
1264 css::uno::Any(i->second));
1265 } catch (container::ElementExistException &) {
1266 rootContext->replaceByName(
1267 (name +
1268 rtl::OUString(
1269 RTL_CONSTASCII_USTRINGPARAM("/service"))),
1270 css::uno::Any(i->second));
1271 }
1272 try {
1273 rootContext->insertByName(name, css::uno::Any());
1274 } catch (container::ElementExistException &) {
1275 OSL_TRACE(
1276 "singleton %s already registered",
1277 rtl::OUStringToOString(
1278 i->first, RTL_TEXTENCODING_UTF8).getStr());
1279 rootContext->replaceByName(name, css::uno::Any());
1280 }
1281 }
1282 }
1283 }
1284 }
1285
componentLiveRemoval(ComponentBackendDb::Data const & data)1286 void BackendImpl::componentLiveRemoval(ComponentBackendDb::Data const & data) {
1287 css::uno::Reference< css::container::XSet > set(
1288 getComponentContext()->getServiceManager(), css::uno::UNO_QUERY_THROW);
1289 for (t_stringlist::const_iterator i(data.implementationNames.begin());
1290 i != data.implementationNames.end(); ++i)
1291 {
1292 try {
1293 set->remove(css::uno::Any(*i));
1294 } catch (css::container::NoSuchElementException &) {
1295 // ignore if factory has not been live deployed
1296 }
1297 }
1298 if (!data.singletons.empty()) {
1299 css::uno::Reference< css::container::XNameContainer > rootContext(
1300 getComponentContext()->getValueByName(
1301 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("_root"))),
1302 css::uno::UNO_QUERY);
1303 if (rootContext.is()) {
1304 for (t_stringpairvec::const_iterator i(data.singletons.begin());
1305 i != data.singletons.end(); ++i)
1306 {
1307 rtl::OUString name(
1308 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/singletons/")) +
1309 i->first);
1310 try {
1311 rootContext->removeByName(
1312 name +
1313 rtl::OUString(
1314 RTL_CONSTASCII_USTRINGPARAM("/arguments")));
1315 rootContext->removeByName(
1316 name +
1317 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/service")));
1318 rootContext->removeByName(name);
1319 } catch (container::NoSuchElementException &) {}
1320 }
1321 }
1322 }
1323 }
1324
1325 //______________________________________________________________________________
releaseObject(OUString const & id)1326 void BackendImpl::releaseObject( OUString const & id )
1327 {
1328 const ::osl::MutexGuard guard( getMutex() );
1329 m_backendObjects.erase( id );
1330 }
1331
1332 //______________________________________________________________________________
getObject(OUString const & id)1333 Reference<XInterface> BackendImpl::getObject( OUString const & id )
1334 {
1335 const ::osl::MutexGuard guard( getMutex() );
1336 const t_string2object::const_iterator iFind( m_backendObjects.find( id ) );
1337 if (iFind == m_backendObjects.end())
1338 return Reference<XInterface>();
1339 else
1340 return iFind->second;
1341 }
1342
1343 //______________________________________________________________________________
insertObject(OUString const & id,Reference<XInterface> const & xObject)1344 Reference<XInterface> BackendImpl::insertObject(
1345 OUString const & id, Reference<XInterface> const & xObject )
1346 {
1347 const ::osl::MutexGuard guard( getMutex() );
1348 const ::std::pair<t_string2object::iterator, bool> insertion(
1349 m_backendObjects.insert( t_string2object::value_type(
1350 id, xObject ) ) );
1351 return insertion.first->second;
1352 }
1353
1354 //------------------------------------------------------------------------------
raise_uno_process(Reference<XComponentContext> const & xContext,::rtl::Reference<AbortChannel> const & abortChannel)1355 Reference<XComponentContext> raise_uno_process(
1356 Reference<XComponentContext> const & xContext,
1357 ::rtl::Reference<AbortChannel> const & abortChannel )
1358 {
1359 OSL_ASSERT( xContext.is() );
1360
1361 ::rtl::OUString url(
1362 Reference<util::XMacroExpander>(
1363 xContext->getValueByName(
1364 OUSTR("/singletons/com.sun.star.util.theMacroExpander") ),
1365 UNO_QUERY_THROW )->
1366 expandMacros( OUSTR("$URE_BIN_DIR/uno") ) );
1367
1368 ::rtl::OUStringBuffer buf;
1369 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("uno:pipe,name=") );
1370 OUString pipeId( generateRandomPipeId() );
1371 buf.append( pipeId );
1372 buf.appendAscii(
1373 RTL_CONSTASCII_STRINGPARAM(";urp;uno.ComponentContext") );
1374 const OUString connectStr( buf.makeStringAndClear() );
1375
1376 // raise core UNO process to register/run a component,
1377 // javavm service uses unorc next to executable to retrieve deployed
1378 // jar typelibs
1379
1380 ::std::vector<OUString> args;
1381 #if OSL_DEBUG_LEVEL <= 1
1382 args.push_back( OUSTR("--quiet") );
1383 #endif
1384 args.push_back( OUSTR("--singleaccept") );
1385 args.push_back( OUSTR("-u") );
1386 args.push_back( connectStr );
1387 // don't inherit from unorc:
1388 args.push_back( OUSTR("-env:INIFILENAME=") );
1389
1390 //now add the bootstrap variables which were supplied on the command line
1391 ::std::vector<OUString> bootvars = getCmdBootstrapVariables();
1392 args.insert(args.end(), bootvars.begin(), bootvars.end());
1393
1394 oslProcess hProcess = raiseProcess(
1395 url, comphelper::containerToSequence(args) );
1396 try {
1397 return Reference<XComponentContext>(
1398 resolveUnoURL( connectStr, xContext, abortChannel.get() ),
1399 UNO_QUERY_THROW );
1400 }
1401 catch (...) {
1402 // try to terminate process:
1403 if ( osl_terminateProcess( hProcess ) != osl_Process_E_None )
1404 {
1405 OSL_ASSERT( false );
1406 }
1407 throw;
1408 }
1409 }
1410
1411 //------------------------------------------------------------------------------
getComponentInfo(ComponentBackendDb::Data * data,std::vector<css::uno::Reference<css::uno::XInterface>> * factories,Reference<XComponentContext> const & xContext)1412 void BackendImpl::ComponentPackageImpl::getComponentInfo(
1413 ComponentBackendDb::Data * data,
1414 std::vector< css::uno::Reference< css::uno::XInterface > > * factories,
1415 Reference<XComponentContext> const & xContext )
1416 {
1417 const Reference<loader::XImplementationLoader> xLoader(
1418 xContext->getServiceManager()->createInstanceWithContext(
1419 m_loader, xContext ), UNO_QUERY );
1420 if (! xLoader.is())
1421 {
1422 throw css::deployment::DeploymentException(
1423 (rtl::OUString(
1424 RTL_CONSTASCII_USTRINGPARAM("cannot instantiate loader ")) +
1425 m_loader),
1426 static_cast< OWeakObject * >(this), Any());
1427 }
1428
1429 // HACK: highly dependent on stoc/source/servicemanager
1430 // and stoc/source/implreg implementation which rely on the same
1431 // services.rdb format!
1432 // .../UNO/LOCATION and .../UNO/ACTIVATOR appear not to be written by
1433 // writeRegistryInfo, however, but are knwon, fixed values here, so
1434 // can be passed into extractComponentData
1435 rtl::OUString url(getURL());
1436 const Reference<registry::XSimpleRegistry> xMemReg(
1437 xContext->getServiceManager()->createInstanceWithContext(
1438 OUSTR("com.sun.star.registry.SimpleRegistry"), xContext ),
1439 UNO_QUERY_THROW );
1440 xMemReg->open( OUString() /* in mem */, false, true );
1441 xLoader->writeRegistryInfo( xMemReg->getRootKey(), OUString(), url );
1442 getMyBackend()->extractComponentData(
1443 xContext, xMemReg->getRootKey(), data, factories, &xLoader, &url);
1444 }
1445
1446 // Package
1447 //______________________________________________________________________________
1448 //We could use here BackendImpl::hasActiveEntry. However, this check is just as well.
1449 //And it also shows the problem if another extension has overwritten an implementation
1450 //entry, because it contains the same service implementation
1451 beans::Optional< beans::Ambiguous<sal_Bool> >
isRegistered_(::osl::ResettableMutexGuard &,::rtl::Reference<AbortChannel> const & abortChannel,Reference<XCommandEnvironment> const &)1452 BackendImpl::ComponentPackageImpl::isRegistered_(
1453 ::osl::ResettableMutexGuard &,
1454 ::rtl::Reference<AbortChannel> const & abortChannel,
1455 Reference<XCommandEnvironment> const & )
1456 {
1457 if (m_registered == REG_UNINIT)
1458 {
1459 m_registered = REG_NOT_REGISTERED;
1460 bool bAmbiguousComponentName = false;
1461 const Reference<registry::XSimpleRegistry> xRDB( getRDB_RO() );
1462 if (xRDB.is())
1463 {
1464 // lookup rdb for location URL:
1465 const Reference<registry::XRegistryKey> xRootKey(
1466 xRDB->getRootKey() );
1467 const Reference<registry::XRegistryKey> xImplKey(
1468 xRootKey->openKey( OUSTR("IMPLEMENTATIONS") ) );
1469 Sequence<OUString> implNames;
1470 if (xImplKey.is() && xImplKey->isValid())
1471 implNames = xImplKey->getKeyNames();
1472 OUString const * pImplNames = implNames.getConstArray();
1473 sal_Int32 pos = implNames.getLength();
1474 for ( ; pos--; )
1475 {
1476 checkAborted( abortChannel );
1477 const OUString key(
1478 pImplNames[ pos ] + OUSTR("/UNO/LOCATION") );
1479 const Reference<registry::XRegistryKey> xKey(
1480 xRootKey->openKey(key) );
1481 if (xKey.is() && xKey->isValid())
1482 {
1483 const OUString location( xKey->getAsciiValue() );
1484 if (location.equalsIgnoreAsciiCase( getURL() ))
1485 {
1486 break;
1487 }
1488 else
1489 {
1490 //try to match only the file name
1491 OUString thisUrl(getURL());
1492 OUString thisFileName(thisUrl.copy(thisUrl.lastIndexOf('/')));
1493
1494 OUString locationFileName(location.copy(location.lastIndexOf('/')));
1495 if (locationFileName.equalsIgnoreAsciiCase(thisFileName))
1496 bAmbiguousComponentName = true;
1497 }
1498 }
1499 }
1500 if (pos >= 0)
1501 m_registered = REG_REGISTERED;
1502 else if (bAmbiguousComponentName)
1503 m_registered = REG_MAYBE_REGISTERED;
1504 }
1505 }
1506
1507 //Different extensions can use the same service implementations. Then the extensions
1508 //which was installed last will overwrite the one from the other extension. That is
1509 //the registry will contain the path (the location) of the library or jar of the
1510 //second extension. In this case isRegistered called for the lib of the first extension
1511 //would return "not registered". That would mean that during uninstallation
1512 //XPackage::registerPackage is not called, because it just was not registered. This is,
1513 //however, necessary for jar files. Registering and unregistering update
1514 //uno_packages/cache/registry/com.sun.star.comp.deployment.component.PackageRegistryBackend/unorc
1515 //Therefore, we will return always "is ambiguous" if the path of this component cannot
1516 //be found in the registry and if there is another path and both have the same file name (but
1517 //the rest of the path is different).
1518 //If the caller cannot precisely determine that this package was registered, then it must
1519 //call registerPackage.
1520 sal_Bool bAmbiguous = m_registered == REG_VOID // REG_VOID == we are in the progress of unregistration
1521 || m_registered == REG_MAYBE_REGISTERED;
1522 return beans::Optional< beans::Ambiguous<sal_Bool> >(
1523 true /* IsPresent */,
1524 beans::Ambiguous<sal_Bool>(
1525 m_registered == REG_REGISTERED, bAmbiguous) );
1526 }
1527
1528 //______________________________________________________________________________
processPackage_(::osl::ResettableMutexGuard &,bool doRegisterPackage,bool startup,::rtl::Reference<AbortChannel> const & abortChannel,Reference<XCommandEnvironment> const & xCmdEnv)1529 void BackendImpl::ComponentPackageImpl::processPackage_(
1530 ::osl::ResettableMutexGuard &,
1531 bool doRegisterPackage,
1532 bool startup,
1533 ::rtl::Reference<AbortChannel> const & abortChannel,
1534 Reference<XCommandEnvironment> const & xCmdEnv )
1535 {
1536 BackendImpl * that = getMyBackend();
1537 rtl::OUString url(getURL());
1538 if (doRegisterPackage) {
1539 ComponentBackendDb::Data data;
1540 css::uno::Reference< css::uno::XComponentContext > context;
1541 if (startup) {
1542 context = that->getComponentContext();
1543 } else {
1544 context.set(that->getObject(url), css::uno::UNO_QUERY);
1545 if (!context.is()) {
1546 context.set(
1547 that->insertObject(
1548 url,
1549 raise_uno_process(
1550 that->getComponentContext(), abortChannel)),
1551 css::uno::UNO_QUERY_THROW);
1552 }
1553 }
1554 css::uno::Reference< css::registry::XImplementationRegistration>(
1555 context->getServiceManager()->createInstanceWithContext(
1556 rtl::OUString(
1557 RTL_CONSTASCII_USTRINGPARAM(
1558 "com.sun.star.registry.ImplementationRegistration")),
1559 context),
1560 css::uno::UNO_QUERY_THROW)->registerImplementation(
1561 m_loader, url, getRDB());
1562 // Only write to unorc after successful registration; it may fail if
1563 // there is no suitable java
1564 if (m_loader.equalsAsciiL(
1565 RTL_CONSTASCII_STRINGPARAM("com.sun.star.loader.Java2")) &&
1566 !jarManifestHeaderPresent(url, OUSTR("UNO-Type-Path"), xCmdEnv))
1567 {
1568 that->addToUnoRc(RCITEM_JAR_TYPELIB, url, xCmdEnv);
1569 data.javaTypeLibrary = true;
1570 }
1571 std::vector< css::uno::Reference< css::uno::XInterface > > factories;
1572 getComponentInfo(&data, &factories, context);
1573 if (!startup) {
1574 that->componentLiveInsertion(data, factories);
1575 }
1576 m_registered = REG_REGISTERED;
1577 that->addDataToDb(url, data);
1578 } else { // revoke
1579 m_registered = REG_VOID;
1580 ComponentBackendDb::Data data(that->readDataFromDb(url));
1581 css::uno::Reference< css::uno::XComponentContext > context(
1582 that->getObject(url), css::uno::UNO_QUERY);
1583 bool remoteContext = context.is();
1584 if (!remoteContext) {
1585 context = that->getComponentContext();
1586 }
1587 if (!startup) {
1588 that->componentLiveRemoval(data);
1589 }
1590 css::uno::Reference< css::registry::XImplementationRegistration >(
1591 context->getServiceManager()->createInstanceWithContext(
1592 rtl::OUString(
1593 RTL_CONSTASCII_USTRINGPARAM(
1594 "com.sun.star.registry.ImplementationRegistration")),
1595 context),
1596 css::uno::UNO_QUERY_THROW)->revokeImplementation(url, getRDB());
1597 if (data.javaTypeLibrary) {
1598 that->removeFromUnoRc(RCITEM_JAR_TYPELIB, url, xCmdEnv);
1599 }
1600 if (remoteContext) {
1601 that->releaseObject(url);
1602 }
1603 m_registered = REG_NOT_REGISTERED;
1604 getMyBackend()->revokeEntryFromDb(url);
1605 }
1606 }
1607
1608 //##############################################################################
TypelibraryPackageImpl(::rtl::Reference<PackageRegistryBackend> const & myBackend,OUString const & url,OUString const & name,Reference<deployment::XPackageTypeInfo> const & xPackageType,bool jarFile,bool bRemoved,OUString const & identifier)1609 BackendImpl::TypelibraryPackageImpl::TypelibraryPackageImpl(
1610 ::rtl::Reference<PackageRegistryBackend> const & myBackend,
1611 OUString const & url, OUString const & name,
1612 Reference<deployment::XPackageTypeInfo> const & xPackageType,
1613 bool jarFile, bool bRemoved, OUString const & identifier)
1614 : Package( myBackend, url, name, name /* display-name */,
1615 xPackageType, bRemoved, identifier),
1616 m_jarFile( jarFile )
1617 {
1618 }
1619
1620 // Package
getMyBackend() const1621 BackendImpl * BackendImpl::TypelibraryPackageImpl::getMyBackend() const
1622 {
1623 BackendImpl * pBackend = static_cast<BackendImpl *>(m_myBackend.get());
1624 if (NULL == pBackend)
1625 {
1626 //May throw a DisposedException
1627 check();
1628 //We should never get here...
1629 throw RuntimeException(
1630 OUSTR("Failed to get the BackendImpl"),
1631 static_cast<OWeakObject*>(const_cast<TypelibraryPackageImpl *>(this)));
1632 }
1633 return pBackend;
1634 }
1635 //______________________________________________________________________________
1636 beans::Optional< beans::Ambiguous<sal_Bool> >
isRegistered_(::osl::ResettableMutexGuard &,::rtl::Reference<AbortChannel> const &,Reference<XCommandEnvironment> const &)1637 BackendImpl::TypelibraryPackageImpl::isRegistered_(
1638 ::osl::ResettableMutexGuard &,
1639 ::rtl::Reference<AbortChannel> const &,
1640 Reference<XCommandEnvironment> const & )
1641 {
1642 BackendImpl * that = getMyBackend();
1643 return beans::Optional< beans::Ambiguous<sal_Bool> >(
1644 true /* IsPresent */,
1645 beans::Ambiguous<sal_Bool>(
1646 that->hasInUnoRc(
1647 m_jarFile ? RCITEM_JAR_TYPELIB : RCITEM_RDB_TYPELIB, getURL() ),
1648 false /* IsAmbiguous */ ) );
1649 }
1650
1651 //______________________________________________________________________________
processPackage_(::osl::ResettableMutexGuard &,bool doRegisterPackage,bool,::rtl::Reference<AbortChannel> const &,Reference<XCommandEnvironment> const & xCmdEnv)1652 void BackendImpl::TypelibraryPackageImpl::processPackage_(
1653 ::osl::ResettableMutexGuard &,
1654 bool doRegisterPackage,
1655 bool /*startup*/,
1656 ::rtl::Reference<AbortChannel> const &,
1657 Reference<XCommandEnvironment> const & xCmdEnv )
1658 {
1659 BackendImpl * that = getMyBackend();
1660 const OUString url( getURL() );
1661
1662 if (doRegisterPackage)
1663 {
1664 // live insertion:
1665 if (m_jarFile) {
1666 // xxx todo add to classpath at runtime: ???
1667 //SB: It is probably not worth it to add the live inserted type
1668 // library JAR to the UnoClassLoader in the soffice process. Any
1669 // live inserted component JAR that might reference this type
1670 // library JAR runs in its own uno process, so there is probably no
1671 // Java code in the soffice process that would see any UNO types
1672 // introduced by this type library JAR.
1673 }
1674 else // RDB:
1675 {
1676 Reference<XComponentContext> const & xContext =
1677 that->getComponentContext();
1678 if (! m_xTDprov.is())
1679 {
1680 m_xTDprov.set( that->getObject( url ), UNO_QUERY );
1681 if (! m_xTDprov.is())
1682 {
1683 const Reference<registry::XSimpleRegistry> xReg(
1684 xContext->getServiceManager()
1685 ->createInstanceWithContext(
1686 OUSTR("com.sun.star.registry.SimpleRegistry"),
1687 xContext ), UNO_QUERY_THROW );
1688 xReg->open( expandUnoRcUrl(url),
1689 true /* read-only */, false /* ! create */ );
1690 const Any arg(xReg);
1691 Reference<container::XHierarchicalNameAccess> xTDprov(
1692 xContext->getServiceManager()
1693 ->createInstanceWithArgumentsAndContext(
1694 OUSTR("com.sun.star.comp.stoc."
1695 "RegistryTypeDescriptionProvider"),
1696 Sequence<Any>( &arg, 1 ), xContext ), UNO_QUERY );
1697 OSL_ASSERT( xTDprov.is() );
1698 if (xTDprov.is())
1699 m_xTDprov.set( that->insertObject( url, xTDprov ),
1700 UNO_QUERY_THROW );
1701 }
1702 }
1703 if (m_xTDprov.is()) {
1704 Reference<container::XSet> xSet(
1705 xContext->getValueByName(
1706 OUSTR("/singletons/com.sun.star."
1707 "reflection.theTypeDescriptionManager") ),
1708 UNO_QUERY_THROW );
1709 xSet->insert( Any(m_xTDprov) );
1710 }
1711 }
1712
1713 that->addToUnoRc( m_jarFile ? RCITEM_JAR_TYPELIB : RCITEM_RDB_TYPELIB,
1714 url, xCmdEnv );
1715 }
1716 else // revokePackage()
1717 {
1718 that->removeFromUnoRc(
1719 m_jarFile ? RCITEM_JAR_TYPELIB : RCITEM_RDB_TYPELIB, url, xCmdEnv );
1720
1721 // revoking types at runtime, possible, sensible?
1722 if (!m_xTDprov.is())
1723 m_xTDprov.set( that->getObject( url ), UNO_QUERY );
1724 if (m_xTDprov.is()) {
1725 // remove live:
1726 const Reference<container::XSet> xSet(
1727 that->getComponentContext()->getValueByName(
1728 OUSTR("/singletons/com.sun.star."
1729 "reflection.theTypeDescriptionManager") ),
1730 UNO_QUERY_THROW );
1731 xSet->remove( Any(m_xTDprov) );
1732
1733 that->releaseObject( url );
1734 m_xTDprov.clear();
1735 }
1736 }
1737 }
1738
getMyBackend() const1739 BackendImpl * BackendImpl::ComponentsPackageImpl::getMyBackend() const
1740 {
1741 BackendImpl * pBackend = static_cast<BackendImpl *>(m_myBackend.get());
1742 if (NULL == pBackend)
1743 {
1744 //Throws a DisposedException
1745 check();
1746 //We should never get here...
1747 throw RuntimeException(
1748 OUSTR("Failed to get the BackendImpl"),
1749 static_cast<OWeakObject*>(const_cast<ComponentsPackageImpl *>(this)));
1750 }
1751 return pBackend;
1752 }
1753
1754 beans::Optional< beans::Ambiguous<sal_Bool> >
isRegistered_(::osl::ResettableMutexGuard &,::rtl::Reference<AbortChannel> const &,Reference<XCommandEnvironment> const &)1755 BackendImpl::ComponentsPackageImpl::isRegistered_(
1756 ::osl::ResettableMutexGuard &,
1757 ::rtl::Reference<AbortChannel> const &,
1758 Reference<XCommandEnvironment> const & )
1759 {
1760 return beans::Optional< beans::Ambiguous<sal_Bool> >(
1761 true,
1762 beans::Ambiguous<sal_Bool>(
1763 getMyBackend()->hasInUnoRc(RCITEM_COMPONENTS, getURL()), false));
1764 }
1765
processPackage_(::osl::ResettableMutexGuard &,bool doRegisterPackage,bool startup,::rtl::Reference<AbortChannel> const & abortChannel,Reference<XCommandEnvironment> const & xCmdEnv)1766 void BackendImpl::ComponentsPackageImpl::processPackage_(
1767 ::osl::ResettableMutexGuard &,
1768 bool doRegisterPackage,
1769 bool startup,
1770 ::rtl::Reference<AbortChannel> const & abortChannel,
1771 Reference<XCommandEnvironment> const & xCmdEnv )
1772 {
1773 BackendImpl * that = getMyBackend();
1774 rtl::OUString url(getURL());
1775 if (doRegisterPackage) {
1776 ComponentBackendDb::Data data;
1777 data.javaTypeLibrary = false;
1778 css::uno::Reference< css::uno::XComponentContext > context;
1779 if (startup) {
1780 context = that->getComponentContext();
1781 } else {
1782 context.set(that->getObject(url), css::uno::UNO_QUERY);
1783 if (!context.is()) {
1784 context.set(
1785 that->insertObject(
1786 url,
1787 raise_uno_process(
1788 that->getComponentContext(), abortChannel)),
1789 css::uno::UNO_QUERY_THROW);
1790 }
1791 }
1792
1793 std::vector< css::uno::Reference< css::uno::XInterface > > factories;
1794
1795 css::uno::Reference< css::registry::XSimpleRegistry > registry(
1796 css::uno::Reference< css::lang::XMultiComponentFactory >(
1797 that->getComponentContext()->getServiceManager(),
1798 css::uno::UNO_SET_THROW)->createInstanceWithContext(
1799 rtl::OUString(
1800 RTL_CONSTASCII_USTRINGPARAM(
1801 "com.sun.star.registry.SimpleRegistry")),
1802 that->getComponentContext()),
1803 css::uno::UNO_QUERY_THROW);
1804 registry->open(expandUnoRcUrl(url), true, false);
1805 getMyBackend()->extractComponentData(
1806 context,
1807 that->openRegistryKey(
1808 registry->getRootKey(),
1809 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("IMPLEMENTATIONS"))),
1810 &data, &factories, 0, 0);
1811 registry->close();
1812 if (!startup) {
1813 that->componentLiveInsertion(data, factories);
1814 }
1815 that->addDataToDb(url, data);
1816 that->addToUnoRc(RCITEM_COMPONENTS, url, xCmdEnv);
1817 } else { // revoke
1818 that->removeFromUnoRc(RCITEM_COMPONENTS, url, xCmdEnv);
1819 if (!startup) {
1820 that->componentLiveRemoval(that->readDataFromDb(url));
1821 }
1822 that->releaseObject(url);
1823 that->revokeEntryFromDb(url);
1824 }
1825 }
1826
ComponentsPackageImpl(::rtl::Reference<PackageRegistryBackend> const & myBackend,OUString const & url,OUString const & name,Reference<deployment::XPackageTypeInfo> const & xPackageType,bool bRemoved,OUString const & identifier)1827 BackendImpl::ComponentsPackageImpl::ComponentsPackageImpl(
1828 ::rtl::Reference<PackageRegistryBackend> const & myBackend,
1829 OUString const & url, OUString const & name,
1830 Reference<deployment::XPackageTypeInfo> const & xPackageType,
1831 bool bRemoved, OUString const & identifier)
1832 : Package( myBackend, url, name, name /* display-name */,
1833 xPackageType, bRemoved, identifier)
1834 {}
1835
1836 } // anon namespace
1837
1838 namespace sdecl = comphelper::service_decl;
1839 sdecl::class_<BackendImpl, sdecl::with_args<true> > serviceBI;
1840 extern sdecl::ServiceDecl const serviceDecl(
1841 serviceBI,
1842 IMPLEMENTATION_NAME,
1843 BACKEND_SERVICE_NAME );
1844
1845 } // namespace component
1846 } // namespace backend
1847 } // namespace dp_registry
1848
1849
1850