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