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