Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
30 : : #include "dp_registry.hrc"
31 : : #include "dp_misc.h"
32 : : #include "dp_resource.h"
33 : : #include "dp_interact.h"
34 : : #include "dp_ucb.h"
35 : : #include "osl/diagnose.h"
36 : : #include "rtl/ustrbuf.hxx"
37 : : #include "rtl/uri.hxx"
38 : : #include "cppuhelper/compbase2.hxx"
39 : : #include "cppuhelper/exc_hlp.hxx"
40 : : #include "comphelper/sequence.hxx"
41 : : #include "ucbhelper/content.hxx"
42 : : #include "com/sun/star/uno/DeploymentException.hpp"
43 : : #include "com/sun/star/lang/DisposedException.hpp"
44 : : #include "com/sun/star/lang/WrappedTargetRuntimeException.hpp"
45 : : #include "com/sun/star/lang/XServiceInfo.hpp"
46 : : #include "com/sun/star/lang/XSingleComponentFactory.hpp"
47 : : #include "com/sun/star/lang/XSingleServiceFactory.hpp"
48 : : #include "com/sun/star/util/XUpdatable.hpp"
49 : : #include "com/sun/star/container/XContentEnumerationAccess.hpp"
50 : : #include "com/sun/star/deployment/PackageRegistryBackend.hpp"
51 : : #include <boost/unordered_map.hpp>
52 : : #include <set>
53 : : #include <boost/unordered_set.hpp>
54 : : #include <memory>
55 : :
56 : : using namespace ::dp_misc;
57 : : using namespace ::com::sun::star;
58 : : using namespace ::com::sun::star::uno;
59 : : using namespace ::com::sun::star::ucb;
60 : : using ::rtl::OUString;
61 : :
62 : :
63 : : namespace dp_registry {
64 : :
65 : : namespace backend {
66 : : namespace bundle {
67 : : Reference<deployment::XPackageRegistry> create(
68 : : Reference<deployment::XPackageRegistry> const & xRootRegistry,
69 : : OUString const & context, OUString const & cachePath, bool readOnly,
70 : : Reference<XComponentContext> const & xComponentContext );
71 : : }
72 : : }
73 : :
74 : : namespace {
75 : :
76 : : typedef ::cppu::WeakComponentImplHelper2<
77 : : deployment::XPackageRegistry, util::XUpdatable > t_helper;
78 : :
79 : : //==============================================================================
80 : : class PackageRegistryImpl : private MutexHolder, public t_helper
81 : : {
82 : : struct ci_string_hash {
83 : 19998 : ::std::size_t operator () ( OUString const & str ) const {
84 : 19998 : return str.toAsciiLowerCase().hashCode();
85 : : }
86 : : };
87 : : struct ci_string_equals {
88 : 10118 : bool operator () ( OUString const & str1, OUString const & str2 ) const{
89 : 10118 : return str1.equalsIgnoreAsciiCase( str2 );
90 : : }
91 : : };
92 : : typedef ::boost::unordered_map<
93 : : OUString, Reference<deployment::XPackageRegistry>,
94 : : ci_string_hash, ci_string_equals > t_string2registry;
95 : : typedef ::boost::unordered_map<
96 : : OUString, OUString,
97 : : ci_string_hash, ci_string_equals > t_string2string;
98 : : typedef ::std::set<
99 : : Reference<deployment::XPackageRegistry> > t_registryset;
100 : :
101 : : t_string2registry m_mediaType2backend;
102 : : t_string2string m_filter2mediaType;
103 : : t_registryset m_ambiguousBackends;
104 : : t_registryset m_allBackends;
105 : : ::std::vector< Reference<deployment::XPackageTypeInfo> > m_typesInfos;
106 : :
107 : : void insertBackend(
108 : : Reference<deployment::XPackageRegistry> const & xBackend );
109 : :
110 : : protected:
111 : : inline void check();
112 : : virtual void SAL_CALL disposing();
113 : :
114 : : virtual ~PackageRegistryImpl();
115 [ + - ][ + - ]: 380 : PackageRegistryImpl() : t_helper( getMutex() ) {}
[ + - ][ + - ]
[ + - ]
116 : :
117 : :
118 : : public:
119 : : static Reference<deployment::XPackageRegistry> create(
120 : : OUString const & context,
121 : : OUString const & cachePath, bool readOnly,
122 : : Reference<XComponentContext> const & xComponentContext );
123 : :
124 : : // XUpdatable
125 : : virtual void SAL_CALL update() throw (RuntimeException);
126 : :
127 : : // XPackageRegistry
128 : : virtual Reference<deployment::XPackage> SAL_CALL bindPackage(
129 : : OUString const & url, OUString const & mediaType, sal_Bool bRemoved,
130 : : OUString const & identifier, Reference<XCommandEnvironment> const & xCmdEnv )
131 : : throw (deployment::DeploymentException,
132 : : deployment::InvalidRemovedParameterException,
133 : : CommandFailedException,
134 : : lang::IllegalArgumentException, RuntimeException);
135 : : virtual Sequence< Reference<deployment::XPackageTypeInfo> > SAL_CALL
136 : : getSupportedPackageTypes() throw (RuntimeException);
137 : : virtual void SAL_CALL packageRemoved(OUString const & url, OUString const & mediaType)
138 : : throw (deployment::DeploymentException,
139 : : RuntimeException);
140 : :
141 : : };
142 : :
143 : : //______________________________________________________________________________
144 : 8332 : inline void PackageRegistryImpl::check()
145 : : {
146 [ + - ]: 8332 : ::osl::MutexGuard guard( getMutex() );
147 [ + - ][ - + ]: 8332 : if (rBHelper.bInDispose || rBHelper.bDisposed) {
148 : : throw lang::DisposedException(
149 : : OUSTR("PackageRegistry instance has already been disposed!"),
150 [ # # ][ # # ]: 0 : static_cast<OWeakObject *>(this) );
[ # # ]
151 [ + - ]: 8332 : }
152 : 8332 : }
153 : :
154 : : //______________________________________________________________________________
155 : 380 : void PackageRegistryImpl::disposing()
156 : : {
157 : : // dispose all backends:
158 : 380 : t_registryset::const_iterator iPos( m_allBackends.begin() );
159 : 380 : t_registryset::const_iterator const iEnd( m_allBackends.end() );
160 [ + + ]: 3040 : for ( ; iPos != iEnd; ++iPos ) {
161 [ + - ]: 2660 : try_dispose( *iPos );
162 : : }
163 [ + - ][ + - ]: 380 : m_mediaType2backend = t_string2registry();
[ + - ]
164 [ + - ][ + - ]: 380 : m_ambiguousBackends = t_registryset();
165 [ + - ][ + - ]: 380 : m_allBackends = t_registryset();
166 : :
167 [ + - ]: 380 : t_helper::disposing();
168 : 380 : }
169 : :
170 : : //______________________________________________________________________________
171 [ + - ][ + - ]: 380 : PackageRegistryImpl::~PackageRegistryImpl()
[ + - ]
172 : : {
173 [ - + ]: 760 : }
174 : :
175 : : //______________________________________________________________________________
176 : 13902 : OUString normalizeMediaType( OUString const & mediaType )
177 : : {
178 : 13902 : ::rtl::OUStringBuffer buf;
179 : 13902 : sal_Int32 index = 0;
180 : 13902 : for (;;) {
181 [ + - ]: 27804 : buf.append( mediaType.getToken( 0, '/', index ).trim() );
182 [ + + ]: 27804 : if (index < 0)
183 : 13902 : break;
184 [ + - ]: 13902 : buf.append( static_cast< sal_Unicode >('/') );
185 : : }
186 [ + - ]: 13902 : return buf.makeStringAndClear();
187 : : }
188 : :
189 : : //______________________________________________________________________________
190 : :
191 : 8 : void PackageRegistryImpl::packageRemoved(
192 : : ::rtl::OUString const & url, ::rtl::OUString const & mediaType)
193 : : throw (css::deployment::DeploymentException,
194 : : css::uno::RuntimeException)
195 : : {
196 : : const t_string2registry::const_iterator i =
197 [ + - ]: 8 : m_mediaType2backend.find(mediaType);
198 : :
199 [ + - ][ + - ]: 8 : if (i != m_mediaType2backend.end())
200 : : {
201 [ + - ][ + - ]: 8 : i->second->packageRemoved(url, mediaType);
[ + - ]
202 : : }
203 : 8 : }
204 : :
205 : 2660 : void PackageRegistryImpl::insertBackend(
206 : : Reference<deployment::XPackageRegistry> const & xBackend )
207 : : {
208 [ + - ]: 2660 : m_allBackends.insert( xBackend );
209 : : typedef ::boost::unordered_set<OUString, ::rtl::OUStringHash> t_stringset;
210 [ + - ]: 2660 : t_stringset ambiguousFilters;
211 : :
212 : : const Sequence< Reference<deployment::XPackageTypeInfo> > packageTypes(
213 [ + - ][ + - ]: 2660 : xBackend->getSupportedPackageTypes() );
214 [ + + ]: 8360 : for ( sal_Int32 pos = 0; pos < packageTypes.getLength(); ++pos )
215 : : {
216 : : Reference<deployment::XPackageTypeInfo> const & xPackageType =
217 : 5700 : packageTypes[ pos ];
218 [ + - ]: 5700 : m_typesInfos.push_back( xPackageType );
219 : :
220 : : const OUString mediaType( normalizeMediaType(
221 [ + - ][ + - ]: 5700 : xPackageType->getMediaType() ) );
[ + - ]
222 : : ::std::pair<t_string2registry::iterator, bool> mb_insertion(
223 : : m_mediaType2backend.insert( t_string2registry::value_type(
224 [ + - ][ + - ]: 5700 : mediaType, xBackend ) ) );
[ + - ]
225 [ + - ]: 5700 : if (mb_insertion.second)
226 : : {
227 : : // add parameterless media-type, too:
228 : 5700 : sal_Int32 semi = mediaType.indexOf( ';' );
229 [ + + ]: 5700 : if (semi >= 0) {
230 : : m_mediaType2backend.insert(
231 : : t_string2registry::value_type(
232 [ + - ][ + - ]: 1900 : mediaType.copy( 0, semi ), xBackend ) );
[ + - ]
233 : : }
234 [ + - ][ + - ]: 5700 : const OUString fileFilter( xPackageType->getFileFilter() );
235 : : //The package backend shall also be called to determine the mediatype
236 : : //(XPackageRegistry.bindPackage) when the URL points to a directory.
237 [ + - ]: 5700 : const bool bExtension = mediaType.equals(OUSTR("application/vnd.sun.star.package-bundle"));
238 [ + - ][ + - ]: 5700 : if (fileFilter.isEmpty() || fileFilter == "*.*" || fileFilter == "*" || bExtension)
[ + + ][ + + ]
[ + + ]
239 : : {
240 [ + - ]: 2280 : m_ambiguousBackends.insert( xBackend );
241 : : }
242 : : else
243 : : {
244 : 3420 : sal_Int32 nIndex = 0;
245 [ - + ]: 3420 : do {
246 : 3420 : OUString token( fileFilter.getToken( 0, ';', nIndex ) );
247 [ + - ]: 3420 : if (token.matchAsciiL( RTL_CONSTASCII_STRINGPARAM("*.") ))
248 : 3420 : token = token.copy( 1 );
249 [ - + ]: 3420 : if (token.isEmpty())
250 : 0 : continue;
251 : : // mark any further wildcards ambig:
252 : 3420 : bool ambig = (token.indexOf('*') >= 0 ||
253 [ - + ][ + - ]: 3420 : token.indexOf('?') >= 0);
254 [ + - ]: 3420 : if (! ambig) {
255 : : ::std::pair<t_string2string::iterator, bool> ins(
256 : : m_filter2mediaType.insert(
257 : : t_string2string::value_type(
258 [ + - ]: 3420 : token, mediaType ) ) );
259 : 3420 : ambig = !ins.second;
260 [ + + ]: 3420 : if (ambig) {
261 : : // filter has already been in: add previously
262 : : // added backend to ambig set
263 : : const t_string2registry::const_iterator iFind(
264 : : m_mediaType2backend.find(
265 : : /* media-type of pr. added backend */
266 [ + - ][ + - ]: 380 : ins.first->second ) );
267 : : OSL_ASSERT(
268 : : iFind != m_mediaType2backend.end() );
269 [ + - ][ + - ]: 380 : if (iFind != m_mediaType2backend.end())
270 [ + - ][ + - ]: 3420 : m_ambiguousBackends.insert( iFind->second );
271 : : }
272 : : }
273 [ + + ]: 3420 : if (ambig) {
274 [ + - ]: 380 : m_ambiguousBackends.insert( xBackend );
275 : : // mark filter to be removed later from filters map:
276 [ + - ]: 3420 : ambiguousFilters.insert( token );
277 [ + - ]: 3420 : }
278 : : }
279 : : while (nIndex >= 0);
280 : 5700 : }
281 : : }
282 : : #if OSL_DEBUG_LEVEL > 0
283 : : else
284 : : {
285 : : ::rtl::OUStringBuffer buf;
286 : : buf.appendAscii(
287 : : RTL_CONSTASCII_STRINGPARAM(
288 : : "more than one PackageRegistryBackend for "
289 : : "media-type=\"") );
290 : : buf.append( mediaType );
291 : : buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\" => ") );
292 : : buf.append( Reference<lang::XServiceInfo>(
293 : : xBackend, UNO_QUERY_THROW )->
294 : : getImplementationName() );
295 : : buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\"!") );
296 : : OSL_FAIL( ::rtl::OUStringToOString(
297 : : buf.makeStringAndClear(),
298 : : RTL_TEXTENCODING_UTF8).getStr() );
299 : : }
300 : : #endif
301 : 5700 : }
302 : :
303 : : // cut out ambiguous filters:
304 [ + - ]: 2660 : t_stringset::const_iterator iPos( ambiguousFilters.begin() );
305 [ + - ]: 2660 : const t_stringset::const_iterator iEnd( ambiguousFilters.end() );
306 [ + + ]: 3040 : for ( ; iPos != iEnd; ++iPos ) {
307 [ + - ][ + - ]: 380 : m_filter2mediaType.erase( *iPos );
308 [ + - ][ + - ]: 2660 : }
309 : 2660 : }
310 : :
311 : : //______________________________________________________________________________
312 : 380 : Reference<deployment::XPackageRegistry> PackageRegistryImpl::create(
313 : : OUString const & context,
314 : : OUString const & cachePath, bool readOnly,
315 : : Reference<XComponentContext> const & xComponentContext )
316 : : {
317 [ + - ]: 380 : PackageRegistryImpl * that = new PackageRegistryImpl;
318 [ + - ][ + - ]: 380 : Reference<deployment::XPackageRegistry> xRet(that);
319 : :
320 : : // auto-detect all registered package registries:
321 : : Reference<container::XEnumeration> xEnum(
322 : : Reference<container::XContentEnumerationAccess>(
323 [ + - ]: 380 : xComponentContext->getServiceManager(),
324 [ + - ][ + - ]: 760 : UNO_QUERY_THROW )->createContentEnumeration(
[ + - ]
325 [ + - ][ + - ]: 380 : OUSTR("com.sun.star.deployment.PackageRegistryBackend") ) );
326 [ + - ]: 380 : if (xEnum.is())
327 : : {
328 [ + - ][ + - ]: 2660 : while (xEnum->hasMoreElements())
[ + + ]
329 : : {
330 [ + - ][ + - ]: 2280 : Any element( xEnum->nextElement() );
331 [ - + ][ + - ]: 2280 : Sequence<Any> registryArgs(cachePath.isEmpty() ? 1 : 3 );
332 [ + - ][ + - ]: 2280 : registryArgs[ 0 ] <<= context;
333 [ + - ]: 2280 : if (!cachePath.isEmpty())
334 : : {
335 : : Reference<lang::XServiceInfo> xServiceInfo(
336 [ + - ]: 2280 : element, UNO_QUERY_THROW );
337 : : OUString registryCachePath(
338 : : makeURL( cachePath,
339 : : ::rtl::Uri::encode(
340 [ + - ]: 2280 : xServiceInfo->getImplementationName(),
341 : : rtl_UriCharClassPchar,
342 : : rtl_UriEncodeIgnoreEscapes,
343 [ + - ][ + - ]: 2280 : RTL_TEXTENCODING_UTF8 ) ) );
344 [ + - ][ + - ]: 2280 : registryArgs[ 1 ] <<= registryCachePath;
345 [ + - ][ + - ]: 2280 : registryArgs[ 2 ] <<= readOnly;
346 [ + - ]: 2280 : if (! readOnly)
347 : : create_folder( 0, registryCachePath,
348 [ + - ]: 2280 : Reference<XCommandEnvironment>() );
349 : : }
350 : :
351 : 2280 : Reference<deployment::XPackageRegistry> xBackend;
352 [ + - ]: 2280 : Reference<lang::XSingleComponentFactory> xFac( element, UNO_QUERY );
353 [ + - ]: 2280 : if (xFac.is()) {
354 : : xBackend.set(
355 [ + - ]: 2280 : xFac->createInstanceWithArgumentsAndContext(
356 [ + - ][ + - ]: 2280 : registryArgs, xComponentContext ), UNO_QUERY );
357 : : }
358 : : else {
359 : : Reference<lang::XSingleServiceFactory> xSingleServiceFac(
360 [ # # ]: 0 : element, UNO_QUERY_THROW );
361 : : xBackend.set(
362 [ # # ]: 0 : xSingleServiceFac->createInstanceWithArguments(
363 [ # # ][ # # ]: 0 : registryArgs ), UNO_QUERY );
364 : : }
365 [ - + ]: 2280 : if (! xBackend.is()) {
366 : : throw DeploymentException(
367 : : OUSTR("cannot instantiate PackageRegistryBackend service: ")
368 : : + Reference<lang::XServiceInfo>(
369 [ # # ][ # # ]: 0 : element, UNO_QUERY_THROW )->getImplementationName(),
370 [ # # ][ # # ]: 0 : static_cast<OWeakObject *>(that) );
[ # # ][ # # ]
371 : : }
372 : :
373 [ + - ]: 2280 : that->insertBackend( xBackend );
374 [ + - ]: 2280 : }
375 : : }
376 : :
377 : : // Insert bundle back-end.
378 : : // Always register as last, because we want to add extensions also as folders
379 : : // and as a default we accept every folder, which was not recognized by the other
380 : : // backends.
381 : : Reference<deployment::XPackageRegistry> extensionBackend =
382 : : ::dp_registry::backend::bundle::create(
383 [ + - ][ + - ]: 380 : that, context, cachePath, readOnly, xComponentContext);
[ + - ]
384 [ + - ]: 380 : that->insertBackend(extensionBackend);
385 : :
386 : : Reference<lang::XServiceInfo> xServiceInfo(
387 [ + - ]: 380 : extensionBackend, UNO_QUERY_THROW );
388 : :
389 : : OSL_ASSERT(xServiceInfo.is());
390 : : OUString registryCachePath(
391 : : makeURL( cachePath,
392 : : ::rtl::Uri::encode(
393 [ + - ]: 380 : xServiceInfo->getImplementationName(),
394 : : rtl_UriCharClassPchar,
395 : : rtl_UriEncodeIgnoreEscapes,
396 [ + - ][ + - ]: 380 : RTL_TEXTENCODING_UTF8 ) ) );
397 [ + - ]: 380 : create_folder( 0, registryCachePath, Reference<XCommandEnvironment>());
398 : :
399 : :
400 : : #if OSL_DEBUG_LEVEL > 1
401 : : // dump tables:
402 : : {
403 : : t_registryset allBackends;
404 : : dp_misc::TRACE("> [dp_registry.cxx] media-type detection:\n\n" );
405 : : for ( t_string2string::const_iterator iPos(
406 : : that->m_filter2mediaType.begin() );
407 : : iPos != that->m_filter2mediaType.end(); ++iPos )
408 : : {
409 : : ::rtl::OUStringBuffer buf;
410 : : buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("extension \"") );
411 : : buf.append( iPos->first );
412 : : buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
413 : : "\" maps to media-type \"") );
414 : : buf.append( iPos->second );
415 : : buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
416 : : "\" maps to backend ") );
417 : : const Reference<deployment::XPackageRegistry> xBackend(
418 : : that->m_mediaType2backend.find( iPos->second )->second );
419 : : allBackends.insert( xBackend );
420 : : buf.append( Reference<lang::XServiceInfo>(
421 : : xBackend, UNO_QUERY_THROW )
422 : : ->getImplementationName() );
423 : : dp_misc::writeConsole( buf.makeStringAndClear() + OUSTR("\n"));
424 : : }
425 : : dp_misc::TRACE( "> [dp_registry.cxx] ambiguous backends:\n\n" );
426 : : for ( t_registryset::const_iterator iPos(
427 : : that->m_ambiguousBackends.begin() );
428 : : iPos != that->m_ambiguousBackends.end(); ++iPos )
429 : : {
430 : : ::rtl::OUStringBuffer buf;
431 : : buf.append(
432 : : Reference<lang::XServiceInfo>(
433 : : *iPos, UNO_QUERY_THROW )->getImplementationName() );
434 : : buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(": ") );
435 : : const Sequence< Reference<deployment::XPackageTypeInfo> > types(
436 : : (*iPos)->getSupportedPackageTypes() );
437 : : for ( sal_Int32 pos = 0; pos < types.getLength(); ++pos ) {
438 : : Reference<deployment::XPackageTypeInfo> const & xInfo =
439 : : types[ pos ];
440 : : buf.append( xInfo->getMediaType() );
441 : : const OUString filter( xInfo->getFileFilter() );
442 : : if (!filter.isEmpty()) {
443 : : buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" (") );
444 : : buf.append( filter );
445 : : buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(")") );
446 : : }
447 : : if (pos < (types.getLength() - 1))
448 : : buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(", ") );
449 : : }
450 : : dp_misc::TRACE(buf.makeStringAndClear() + OUSTR("\n\n"));
451 : : }
452 : : allBackends.insert( that->m_ambiguousBackends.begin(),
453 : : that->m_ambiguousBackends.end() );
454 : : OSL_ASSERT( allBackends == that->m_allBackends );
455 : : }
456 : : #endif
457 : :
458 : 380 : return xRet;
459 : : }
460 : :
461 : : // XUpdatable: broadcast to backends
462 : : //______________________________________________________________________________
463 : 0 : void PackageRegistryImpl::update() throw (RuntimeException)
464 : : {
465 [ # # ]: 0 : check();
466 : 0 : t_registryset::const_iterator iPos( m_allBackends.begin() );
467 : 0 : const t_registryset::const_iterator iEnd( m_allBackends.end() );
468 [ # # ]: 0 : for ( ; iPos != iEnd; ++iPos ) {
469 [ # # ]: 0 : const Reference<util::XUpdatable> xUpdatable( *iPos, UNO_QUERY );
470 [ # # ]: 0 : if (xUpdatable.is())
471 [ # # ][ # # ]: 0 : xUpdatable->update();
472 : 0 : }
473 : 0 : }
474 : :
475 : : // XPackageRegistry
476 : : //______________________________________________________________________________
477 : 8332 : Reference<deployment::XPackage> PackageRegistryImpl::bindPackage(
478 : : OUString const & url, OUString const & mediaType_, sal_Bool bRemoved,
479 : : OUString const & identifier, Reference<XCommandEnvironment> const & xCmdEnv )
480 : : throw (deployment::DeploymentException, deployment::InvalidRemovedParameterException,
481 : : CommandFailedException,
482 : : lang::IllegalArgumentException, RuntimeException)
483 : : {
484 [ + - ]: 8332 : check();
485 : 8332 : OUString mediaType(mediaType_);
486 [ + + ]: 8332 : if (mediaType.isEmpty())
487 : : {
488 [ + - ]: 502 : ::ucbhelper::Content ucbContent;
489 [ + - ][ + + ]: 1004 : if (create_ucb_content(
[ + + ]
490 [ + - ]: 502 : &ucbContent, url, xCmdEnv, false /* no throw */ )
491 [ + - ]: 502 : && !ucbContent.isFolder())
492 : : {
493 [ + - ]: 4 : OUString title( StrTitle::getTitle( ucbContent ) );
494 : 4 : for (;;)
495 : : {
496 : : const t_string2string::const_iterator iFind(
497 [ + - ]: 8 : m_filter2mediaType.find(title) );
498 [ - + ][ + - ]: 8 : if (iFind != m_filter2mediaType.end()) {
499 [ # # ]: 0 : mediaType = iFind->second;
500 : : break;
501 : : }
502 : 8 : sal_Int32 point = title.indexOf( '.', 1 /* consume . */ );
503 [ + + ]: 8 : if (point < 0)
504 : : break;
505 : 4 : title = title.copy(point);
506 : 4 : }
507 [ + - ][ - + ]: 2580 : }
508 : : }
509 [ + + ]: 8332 : if (mediaType.isEmpty())
510 : : {
511 : : // try ambiguous backends:
512 : 502 : t_registryset::const_iterator iPos( m_ambiguousBackends.begin() );
513 : 502 : const t_registryset::const_iterator iEnd( m_ambiguousBackends.end() );
514 [ + - ]: 2580 : for ( ; iPos != iEnd; ++iPos )
515 : : {
516 : : try {
517 [ + - ]: 2580 : return (*iPos)->bindPackage( url, mediaType, bRemoved,
518 [ + + ]: 2580 : identifier, xCmdEnv );
519 : : }
520 [ + - ]: 2078 : catch (const lang::IllegalArgumentException &) {
521 : : }
522 : : }
523 : : throw lang::IllegalArgumentException(
524 : : getResourceString(RID_STR_CANNOT_DETECT_MEDIA_TYPE) + url,
525 [ # # ][ # # ]: 502 : static_cast<OWeakObject *>(this), static_cast<sal_Int16>(-1) );
[ # # ][ # # ]
526 : : }
527 : : else
528 : : {
529 : : // get backend by media-type:
530 : : t_string2registry::const_iterator iFind(
531 [ + - ][ + - ]: 7830 : m_mediaType2backend.find( normalizeMediaType(mediaType) ) );
532 [ + + ][ + - ]: 7830 : if (iFind == m_mediaType2backend.end()) {
533 : : // xxx todo: more sophisticated media-type argument parsing...
534 : 372 : sal_Int32 q = mediaType.indexOf( ';' );
535 [ + - ]: 372 : if (q >= 0) {
536 : : iFind = m_mediaType2backend.find(
537 : : normalizeMediaType(
538 : : // cut parameters:
539 [ + - ][ + - ]: 372 : mediaType.copy( 0, q ) ) );
540 : : }
541 : : }
542 [ + - ][ - + ]: 7830 : if (iFind == m_mediaType2backend.end()) {
543 : : throw lang::IllegalArgumentException(
544 : : getResourceString(RID_STR_UNSUPPORTED_MEDIA_TYPE) + mediaType,
545 [ # # ][ # # ]: 0 : static_cast<OWeakObject *>(this), static_cast<sal_Int16>(-1) );
[ # # ][ # # ]
546 : : }
547 [ + - ][ + - ]: 7830 : return iFind->second->bindPackage( url, mediaType, bRemoved,
548 [ + - ]: 7830 : identifier, xCmdEnv );
549 : 8332 : }
550 : : }
551 : :
552 : : //______________________________________________________________________________
553 : : Sequence< Reference<deployment::XPackageTypeInfo> >
554 : 0 : PackageRegistryImpl::getSupportedPackageTypes() throw (RuntimeException)
555 : : {
556 : 0 : return comphelper::containerToSequence(m_typesInfos);
557 : : }
558 : : } // anon namespace
559 : :
560 : : //==============================================================================
561 : 380 : Reference<deployment::XPackageRegistry> SAL_CALL create(
562 : : OUString const & context,
563 : : OUString const & cachePath, bool readOnly,
564 : : Reference<XComponentContext> const & xComponentContext )
565 : : {
566 : : return PackageRegistryImpl::create(
567 : 380 : context, cachePath, readOnly, xComponentContext );
568 : : }
569 : :
570 : : } // namespace dp_registry
571 : :
572 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|