1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_desktop.hxx"
30*cdf0e10cSrcweir 
31*cdf0e10cSrcweir //TODO: Large parts of this file were copied from dp_component.cxx; those parts
32*cdf0e10cSrcweir // should be consolidated.
33*cdf0e10cSrcweir 
34*cdf0e10cSrcweir #include "dp_configuration.hrc"
35*cdf0e10cSrcweir #include "dp_backend.h"
36*cdf0e10cSrcweir #include "dp_persmap.h"
37*cdf0e10cSrcweir #include "dp_ucb.h"
38*cdf0e10cSrcweir #include "rtl/string.hxx"
39*cdf0e10cSrcweir #include "rtl/ustrbuf.hxx"
40*cdf0e10cSrcweir #include "rtl/uri.hxx"
41*cdf0e10cSrcweir #include "rtl/memory.h"
42*cdf0e10cSrcweir #include "osl/file.hxx"
43*cdf0e10cSrcweir #include "cppuhelper/exc_hlp.hxx"
44*cdf0e10cSrcweir #include "ucbhelper/content.hxx"
45*cdf0e10cSrcweir #include "comphelper/anytostring.hxx"
46*cdf0e10cSrcweir #include "comphelper/servicedecl.hxx"
47*cdf0e10cSrcweir #include "xmlscript/xml_helper.hxx"
48*cdf0e10cSrcweir #include "svl/inettype.hxx"
49*cdf0e10cSrcweir #include "com/sun/star/configuration/Update.hpp"
50*cdf0e10cSrcweir #include "com/sun/star/ucb/NameClash.hpp"
51*cdf0e10cSrcweir #include "com/sun/star/io/XActiveDataSink.hpp"
52*cdf0e10cSrcweir #include "com/sun/star/lang/WrappedTargetRuntimeException.hpp"
53*cdf0e10cSrcweir #include "com/sun/star/util/XRefreshable.hpp"
54*cdf0e10cSrcweir #include <list>
55*cdf0e10cSrcweir #include <memory>
56*cdf0e10cSrcweir 
57*cdf0e10cSrcweir #include "dp_configurationbackenddb.hxx"
58*cdf0e10cSrcweir 
59*cdf0e10cSrcweir using namespace ::dp_misc;
60*cdf0e10cSrcweir using namespace ::com::sun::star;
61*cdf0e10cSrcweir using namespace ::com::sun::star::uno;
62*cdf0e10cSrcweir using namespace ::com::sun::star::ucb;
63*cdf0e10cSrcweir using ::rtl::OUString;
64*cdf0e10cSrcweir 
65*cdf0e10cSrcweir namespace dp_registry {
66*cdf0e10cSrcweir namespace backend {
67*cdf0e10cSrcweir namespace configuration {
68*cdf0e10cSrcweir namespace {
69*cdf0e10cSrcweir 
70*cdf0e10cSrcweir typedef ::std::list<OUString> t_stringlist;
71*cdf0e10cSrcweir 
72*cdf0e10cSrcweir //==============================================================================
73*cdf0e10cSrcweir class BackendImpl : public ::dp_registry::backend::PackageRegistryBackend
74*cdf0e10cSrcweir {
75*cdf0e10cSrcweir     class PackageImpl : public ::dp_registry::backend::Package
76*cdf0e10cSrcweir     {
77*cdf0e10cSrcweir         BackendImpl * getMyBackend() const ;
78*cdf0e10cSrcweir 
79*cdf0e10cSrcweir         const bool m_isSchema;
80*cdf0e10cSrcweir 
81*cdf0e10cSrcweir         // Package
82*cdf0e10cSrcweir         virtual beans::Optional< beans::Ambiguous<sal_Bool> > isRegistered_(
83*cdf0e10cSrcweir             ::osl::ResettableMutexGuard & guard,
84*cdf0e10cSrcweir             ::rtl::Reference<AbortChannel> const & abortChannel,
85*cdf0e10cSrcweir             Reference<XCommandEnvironment> const & xCmdEnv );
86*cdf0e10cSrcweir         virtual void processPackage_(
87*cdf0e10cSrcweir             ::osl::ResettableMutexGuard & guard,
88*cdf0e10cSrcweir             bool registerPackage,
89*cdf0e10cSrcweir             bool startup,
90*cdf0e10cSrcweir             ::rtl::Reference<AbortChannel> const & abortChannel,
91*cdf0e10cSrcweir             Reference<XCommandEnvironment> const & xCmdEnv );
92*cdf0e10cSrcweir 
93*cdf0e10cSrcweir     public:
94*cdf0e10cSrcweir         inline PackageImpl(
95*cdf0e10cSrcweir             ::rtl::Reference<PackageRegistryBackend> const & myBackend,
96*cdf0e10cSrcweir             OUString const & url, OUString const & name,
97*cdf0e10cSrcweir             Reference<deployment::XPackageTypeInfo> const & xPackageType,
98*cdf0e10cSrcweir             bool isSchema, bool bRemoved, OUString const & identifier)
99*cdf0e10cSrcweir             : Package( myBackend, url, name, name /* display-name */,
100*cdf0e10cSrcweir                        xPackageType, bRemoved, identifier),
101*cdf0e10cSrcweir               m_isSchema( isSchema )
102*cdf0e10cSrcweir             {}
103*cdf0e10cSrcweir     };
104*cdf0e10cSrcweir     friend class PackageImpl;
105*cdf0e10cSrcweir 
106*cdf0e10cSrcweir     t_stringlist m_xcs_files;
107*cdf0e10cSrcweir     t_stringlist m_xcu_files;
108*cdf0e10cSrcweir     t_stringlist & getFiles( bool xcs ) {
109*cdf0e10cSrcweir         return xcs ? m_xcs_files : m_xcu_files;
110*cdf0e10cSrcweir     }
111*cdf0e10cSrcweir 
112*cdf0e10cSrcweir     bool m_configmgrini_inited;
113*cdf0e10cSrcweir     bool m_configmgrini_modified;
114*cdf0e10cSrcweir     std::auto_ptr<ConfigurationBackendDb> m_backendDb;
115*cdf0e10cSrcweir 
116*cdf0e10cSrcweir     // PackageRegistryBackend
117*cdf0e10cSrcweir     virtual Reference<deployment::XPackage> bindPackage_(
118*cdf0e10cSrcweir         OUString const & url, OUString const & mediaType, sal_Bool bRemoved,
119*cdf0e10cSrcweir         OUString const & identifier,
120*cdf0e10cSrcweir         Reference<XCommandEnvironment> const & xCmdEnv );
121*cdf0e10cSrcweir 
122*cdf0e10cSrcweir     ::std::auto_ptr<PersistentMap> m_registeredPackages;
123*cdf0e10cSrcweir         // for backwards compatibility
124*cdf0e10cSrcweir 
125*cdf0e10cSrcweir     virtual void SAL_CALL disposing();
126*cdf0e10cSrcweir 
127*cdf0e10cSrcweir     const Reference<deployment::XPackageTypeInfo> m_xConfDataTypeInfo;
128*cdf0e10cSrcweir     const Reference<deployment::XPackageTypeInfo> m_xConfSchemaTypeInfo;
129*cdf0e10cSrcweir     Sequence< Reference<deployment::XPackageTypeInfo> > m_typeInfos;
130*cdf0e10cSrcweir 
131*cdf0e10cSrcweir     void configmgrini_verify_init(
132*cdf0e10cSrcweir         Reference<XCommandEnvironment> const & xCmdEnv );
133*cdf0e10cSrcweir     void configmgrini_flush( Reference<XCommandEnvironment> const & xCmdEnv );
134*cdf0e10cSrcweir 
135*cdf0e10cSrcweir     /* The paramter isURL is false in the case of adding the conf:ini-entry
136*cdf0e10cSrcweir        value from the backend db. This entry already contains the path as it
137*cdf0e10cSrcweir        is used in the configmgr.ini.
138*cdf0e10cSrcweir      */
139*cdf0e10cSrcweir     bool addToConfigmgrIni( bool isSchema, bool isURL, OUString const & url,
140*cdf0e10cSrcweir                      Reference<XCommandEnvironment> const & xCmdEnv );
141*cdf0e10cSrcweir     bool removeFromConfigmgrIni( bool isSchema, OUString const & url,
142*cdf0e10cSrcweir                           Reference<XCommandEnvironment> const & xCmdEnv );
143*cdf0e10cSrcweir 
144*cdf0e10cSrcweir     void addDataToDb(OUString const & url, ConfigurationBackendDb::Data const & data);
145*cdf0e10cSrcweir     ::boost::optional<ConfigurationBackendDb::Data> readDataFromDb(OUString const & url);
146*cdf0e10cSrcweir     void revokeEntryFromDb(OUString const & url);
147*cdf0e10cSrcweir     ::std::list<OUString> getAllIniEntries();
148*cdf0e10cSrcweir     bool hasActiveEntry(OUString const & url);
149*cdf0e10cSrcweir     bool activateEntry(OUString const & url);
150*cdf0e10cSrcweir 
151*cdf0e10cSrcweir public:
152*cdf0e10cSrcweir     BackendImpl( Sequence<Any> const & args,
153*cdf0e10cSrcweir                  Reference<XComponentContext> const & xComponentContext );
154*cdf0e10cSrcweir 
155*cdf0e10cSrcweir     // XPackageRegistry
156*cdf0e10cSrcweir     virtual Sequence< Reference<deployment::XPackageTypeInfo> > SAL_CALL
157*cdf0e10cSrcweir     getSupportedPackageTypes() throw (RuntimeException);
158*cdf0e10cSrcweir     virtual void SAL_CALL packageRemoved(OUString const & url, OUString const & mediaType)
159*cdf0e10cSrcweir         throw (deployment::DeploymentException,
160*cdf0e10cSrcweir                uno::RuntimeException);
161*cdf0e10cSrcweir 
162*cdf0e10cSrcweir     using PackageRegistryBackend::disposing;
163*cdf0e10cSrcweir };
164*cdf0e10cSrcweir 
165*cdf0e10cSrcweir //______________________________________________________________________________
166*cdf0e10cSrcweir void BackendImpl::disposing()
167*cdf0e10cSrcweir {
168*cdf0e10cSrcweir     try {
169*cdf0e10cSrcweir         configmgrini_flush( Reference<XCommandEnvironment>() );
170*cdf0e10cSrcweir 
171*cdf0e10cSrcweir         PackageRegistryBackend::disposing();
172*cdf0e10cSrcweir     }
173*cdf0e10cSrcweir     catch (RuntimeException &) {
174*cdf0e10cSrcweir         throw;
175*cdf0e10cSrcweir     }
176*cdf0e10cSrcweir     catch (Exception &) {
177*cdf0e10cSrcweir         Any exc( ::cppu::getCaughtException() );
178*cdf0e10cSrcweir         throw lang::WrappedTargetRuntimeException(
179*cdf0e10cSrcweir             OUSTR("caught unexpected exception while disposing..."),
180*cdf0e10cSrcweir             static_cast<OWeakObject *>(this), exc );
181*cdf0e10cSrcweir     }
182*cdf0e10cSrcweir }
183*cdf0e10cSrcweir 
184*cdf0e10cSrcweir //______________________________________________________________________________
185*cdf0e10cSrcweir BackendImpl::BackendImpl(
186*cdf0e10cSrcweir     Sequence<Any> const & args,
187*cdf0e10cSrcweir     Reference<XComponentContext> const & xComponentContext )
188*cdf0e10cSrcweir     : PackageRegistryBackend( args, xComponentContext ),
189*cdf0e10cSrcweir       m_configmgrini_inited( false ),
190*cdf0e10cSrcweir       m_configmgrini_modified( false ),
191*cdf0e10cSrcweir       m_xConfDataTypeInfo( new Package::TypeInfo(
192*cdf0e10cSrcweir                                OUSTR("application/"
193*cdf0e10cSrcweir                                      "vnd.sun.star.configuration-data"),
194*cdf0e10cSrcweir                                OUSTR("*.xcu"),
195*cdf0e10cSrcweir                                getResourceString(RID_STR_CONF_DATA),
196*cdf0e10cSrcweir                                RID_IMG_CONF_XML, RID_IMG_CONF_XML_HC ) ),
197*cdf0e10cSrcweir       m_xConfSchemaTypeInfo( new Package::TypeInfo(
198*cdf0e10cSrcweir                                  OUSTR("application/"
199*cdf0e10cSrcweir                                        "vnd.sun.star.configuration-schema"),
200*cdf0e10cSrcweir                                  OUSTR("*.xcs"),
201*cdf0e10cSrcweir                                  getResourceString(RID_STR_CONF_SCHEMA),
202*cdf0e10cSrcweir                                  RID_IMG_CONF_XML, RID_IMG_CONF_XML_HC ) ),
203*cdf0e10cSrcweir       m_typeInfos( 2 )
204*cdf0e10cSrcweir {
205*cdf0e10cSrcweir     m_typeInfos[ 0 ] = m_xConfDataTypeInfo;
206*cdf0e10cSrcweir     m_typeInfos[ 1 ] = m_xConfSchemaTypeInfo;
207*cdf0e10cSrcweir 
208*cdf0e10cSrcweir     const Reference<XCommandEnvironment> xCmdEnv;
209*cdf0e10cSrcweir 
210*cdf0e10cSrcweir     if (transientMode())
211*cdf0e10cSrcweir     {
212*cdf0e10cSrcweir         //TODO
213*cdf0e10cSrcweir     }
214*cdf0e10cSrcweir     else
215*cdf0e10cSrcweir     {
216*cdf0e10cSrcweir         OUString dbFile = makeURL(getCachePath(), OUSTR("backenddb.xml"));
217*cdf0e10cSrcweir         m_backendDb.reset(
218*cdf0e10cSrcweir             new ConfigurationBackendDb(getComponentContext(), dbFile));
219*cdf0e10cSrcweir         //clean up data folders which are no longer used.
220*cdf0e10cSrcweir         //This must not be done in the same process where the help files
221*cdf0e10cSrcweir         //are still registers. Only after revoking and restarting OOo the folders
222*cdf0e10cSrcweir         //can be removed. This works now, because the extension manager is a singleton
223*cdf0e10cSrcweir         //and the backends are only create once per process.
224*cdf0e10cSrcweir         ::std::list<OUString> folders = m_backendDb->getAllDataUrls();
225*cdf0e10cSrcweir         deleteUnusedFolders(OUString(), folders);
226*cdf0e10cSrcweir 
227*cdf0e10cSrcweir 
228*cdf0e10cSrcweir         configmgrini_verify_init( xCmdEnv );
229*cdf0e10cSrcweir         m_registeredPackages.reset(
230*cdf0e10cSrcweir             new PersistentMap(
231*cdf0e10cSrcweir                 makeURL( getCachePath(), OUSTR("registered_packages.db") ),
232*cdf0e10cSrcweir                 false ) );
233*cdf0e10cSrcweir      }
234*cdf0e10cSrcweir }
235*cdf0e10cSrcweir 
236*cdf0e10cSrcweir void BackendImpl::addDataToDb(
237*cdf0e10cSrcweir     OUString const & url, ConfigurationBackendDb::Data const & data)
238*cdf0e10cSrcweir {
239*cdf0e10cSrcweir     if (m_backendDb.get())
240*cdf0e10cSrcweir         m_backendDb->addEntry(url, data);
241*cdf0e10cSrcweir }
242*cdf0e10cSrcweir 
243*cdf0e10cSrcweir ::boost::optional<ConfigurationBackendDb::Data> BackendImpl::readDataFromDb(
244*cdf0e10cSrcweir     OUString const & url)
245*cdf0e10cSrcweir {
246*cdf0e10cSrcweir     ::boost::optional<ConfigurationBackendDb::Data> data;
247*cdf0e10cSrcweir     if (m_backendDb.get())
248*cdf0e10cSrcweir         data = m_backendDb->getEntry(url);
249*cdf0e10cSrcweir     return data;
250*cdf0e10cSrcweir }
251*cdf0e10cSrcweir 
252*cdf0e10cSrcweir void BackendImpl::revokeEntryFromDb(OUString const & url)
253*cdf0e10cSrcweir {
254*cdf0e10cSrcweir     if (m_backendDb.get())
255*cdf0e10cSrcweir         m_backendDb->revokeEntry(url);
256*cdf0e10cSrcweir }
257*cdf0e10cSrcweir 
258*cdf0e10cSrcweir ::std::list<OUString> BackendImpl::getAllIniEntries()
259*cdf0e10cSrcweir {
260*cdf0e10cSrcweir     if (m_backendDb.get())
261*cdf0e10cSrcweir         return m_backendDb->getAllIniEntries();
262*cdf0e10cSrcweir     else
263*cdf0e10cSrcweir         return ::std::list<OUString>();
264*cdf0e10cSrcweir }
265*cdf0e10cSrcweir 
266*cdf0e10cSrcweir bool BackendImpl::hasActiveEntry(OUString const & url)
267*cdf0e10cSrcweir {
268*cdf0e10cSrcweir     if (m_backendDb.get())
269*cdf0e10cSrcweir         return m_backendDb->hasActiveEntry(url);
270*cdf0e10cSrcweir     return false;
271*cdf0e10cSrcweir }
272*cdf0e10cSrcweir 
273*cdf0e10cSrcweir bool BackendImpl::activateEntry(OUString const & url)
274*cdf0e10cSrcweir {
275*cdf0e10cSrcweir     if (m_backendDb.get())
276*cdf0e10cSrcweir         return m_backendDb->activateEntry(url);
277*cdf0e10cSrcweir     return false;
278*cdf0e10cSrcweir }
279*cdf0e10cSrcweir 
280*cdf0e10cSrcweir 
281*cdf0e10cSrcweir 
282*cdf0e10cSrcweir // XPackageRegistry
283*cdf0e10cSrcweir //______________________________________________________________________________
284*cdf0e10cSrcweir Sequence< Reference<deployment::XPackageTypeInfo> >
285*cdf0e10cSrcweir BackendImpl::getSupportedPackageTypes() throw (RuntimeException)
286*cdf0e10cSrcweir {
287*cdf0e10cSrcweir     return m_typeInfos;
288*cdf0e10cSrcweir }
289*cdf0e10cSrcweir void BackendImpl::packageRemoved(OUString const & url, OUString const & /*mediaType*/)
290*cdf0e10cSrcweir         throw (deployment::DeploymentException,
291*cdf0e10cSrcweir                uno::RuntimeException)
292*cdf0e10cSrcweir {
293*cdf0e10cSrcweir     if (m_backendDb.get())
294*cdf0e10cSrcweir         m_backendDb->removeEntry(url);
295*cdf0e10cSrcweir }
296*cdf0e10cSrcweir 
297*cdf0e10cSrcweir // PackageRegistryBackend
298*cdf0e10cSrcweir //______________________________________________________________________________
299*cdf0e10cSrcweir Reference<deployment::XPackage> BackendImpl::bindPackage_(
300*cdf0e10cSrcweir     OUString const & url, OUString const & mediaType_,
301*cdf0e10cSrcweir     sal_Bool bRemoved, OUString const & identifier,
302*cdf0e10cSrcweir     Reference<XCommandEnvironment> const & xCmdEnv )
303*cdf0e10cSrcweir {
304*cdf0e10cSrcweir     OUString mediaType( mediaType_ );
305*cdf0e10cSrcweir     if (mediaType.getLength() == 0)
306*cdf0e10cSrcweir     {
307*cdf0e10cSrcweir         // detect media-type:
308*cdf0e10cSrcweir         ::ucbhelper::Content ucbContent;
309*cdf0e10cSrcweir         if (create_ucb_content( &ucbContent, url, xCmdEnv ))
310*cdf0e10cSrcweir         {
311*cdf0e10cSrcweir             const OUString title( ucbContent.getPropertyValue(
312*cdf0e10cSrcweir                                       StrTitle::get() ).get<OUString>() );
313*cdf0e10cSrcweir             if (title.endsWithIgnoreAsciiCaseAsciiL(
314*cdf0e10cSrcweir                     RTL_CONSTASCII_STRINGPARAM(".xcu") )) {
315*cdf0e10cSrcweir                 mediaType = OUSTR("application/"
316*cdf0e10cSrcweir                                   "vnd.sun.star.configuration-data");
317*cdf0e10cSrcweir             }
318*cdf0e10cSrcweir             if (title.endsWithIgnoreAsciiCaseAsciiL(
319*cdf0e10cSrcweir                     RTL_CONSTASCII_STRINGPARAM(".xcs") )) {
320*cdf0e10cSrcweir                 mediaType = OUSTR("application/"
321*cdf0e10cSrcweir                                   "vnd.sun.star.configuration-schema");
322*cdf0e10cSrcweir             }
323*cdf0e10cSrcweir         }
324*cdf0e10cSrcweir         if (mediaType.getLength() == 0)
325*cdf0e10cSrcweir             throw lang::IllegalArgumentException(
326*cdf0e10cSrcweir                 StrCannotDetectMediaType::get() + url,
327*cdf0e10cSrcweir                 static_cast<OWeakObject *>(this), static_cast<sal_Int16>(-1) );
328*cdf0e10cSrcweir     }
329*cdf0e10cSrcweir 
330*cdf0e10cSrcweir     String type, subType;
331*cdf0e10cSrcweir     INetContentTypeParameterList params;
332*cdf0e10cSrcweir     if (INetContentTypes::parse( mediaType, type, subType, &params ))
333*cdf0e10cSrcweir     {
334*cdf0e10cSrcweir         if (type.EqualsIgnoreCaseAscii("application"))
335*cdf0e10cSrcweir         {
336*cdf0e10cSrcweir             OUString name;
337*cdf0e10cSrcweir             if (!bRemoved)
338*cdf0e10cSrcweir             {
339*cdf0e10cSrcweir                 ::ucbhelper::Content ucbContent( url, xCmdEnv );
340*cdf0e10cSrcweir                 name = ucbContent.getPropertyValue(
341*cdf0e10cSrcweir                     StrTitle::get() ).get<OUString>();
342*cdf0e10cSrcweir             }
343*cdf0e10cSrcweir 
344*cdf0e10cSrcweir             ::ucbhelper::Content ucbContent( url, xCmdEnv );
345*cdf0e10cSrcweir             if (subType.EqualsIgnoreCaseAscii(
346*cdf0e10cSrcweir                     "vnd.sun.star.configuration-data"))
347*cdf0e10cSrcweir             {
348*cdf0e10cSrcweir                 return new PackageImpl(
349*cdf0e10cSrcweir                     this, url, name, m_xConfDataTypeInfo, false /* data file */,
350*cdf0e10cSrcweir                     bRemoved, identifier);
351*cdf0e10cSrcweir             }
352*cdf0e10cSrcweir             else if (subType.EqualsIgnoreCaseAscii(
353*cdf0e10cSrcweir                          "vnd.sun.star.configuration-schema")) {
354*cdf0e10cSrcweir                 return new PackageImpl(
355*cdf0e10cSrcweir                     this, url, name, m_xConfSchemaTypeInfo, true /* schema file */,
356*cdf0e10cSrcweir                     bRemoved, identifier);
357*cdf0e10cSrcweir             }
358*cdf0e10cSrcweir         }
359*cdf0e10cSrcweir     }
360*cdf0e10cSrcweir     throw lang::IllegalArgumentException(
361*cdf0e10cSrcweir         StrUnsupportedMediaType::get() + mediaType,
362*cdf0e10cSrcweir         static_cast<OWeakObject *>(this),
363*cdf0e10cSrcweir         static_cast<sal_Int16>(-1) );
364*cdf0e10cSrcweir }
365*cdf0e10cSrcweir 
366*cdf0e10cSrcweir //##############################################################################
367*cdf0e10cSrcweir 
368*cdf0e10cSrcweir //______________________________________________________________________________
369*cdf0e10cSrcweir void BackendImpl::configmgrini_verify_init(
370*cdf0e10cSrcweir     Reference<XCommandEnvironment> const & xCmdEnv )
371*cdf0e10cSrcweir {
372*cdf0e10cSrcweir     if (transientMode())
373*cdf0e10cSrcweir         return;
374*cdf0e10cSrcweir     const ::osl::MutexGuard guard( getMutex() );
375*cdf0e10cSrcweir     if (! m_configmgrini_inited)
376*cdf0e10cSrcweir     {
377*cdf0e10cSrcweir         // common rc:
378*cdf0e10cSrcweir         ::ucbhelper::Content ucb_content;
379*cdf0e10cSrcweir         if (create_ucb_content(
380*cdf0e10cSrcweir                 &ucb_content,
381*cdf0e10cSrcweir                 makeURL( getCachePath(), OUSTR("configmgr.ini") ),
382*cdf0e10cSrcweir                 xCmdEnv, false /* no throw */ ))
383*cdf0e10cSrcweir         {
384*cdf0e10cSrcweir             OUString line;
385*cdf0e10cSrcweir             if (readLine( &line, OUSTR("SCHEMA="), ucb_content,
386*cdf0e10cSrcweir                           RTL_TEXTENCODING_UTF8 ))
387*cdf0e10cSrcweir             {
388*cdf0e10cSrcweir                 sal_Int32 index = sizeof ("SCHEMA=") - 1;
389*cdf0e10cSrcweir                 do {
390*cdf0e10cSrcweir                     OUString token( line.getToken( 0, ' ', index ).trim() );
391*cdf0e10cSrcweir                     if (token.getLength() > 0) {
392*cdf0e10cSrcweir                         //The  file may not exist anymore if a shared or bundled
393*cdf0e10cSrcweir                         //extension was removed, but it can still be in the configmgrini.
394*cdf0e10cSrcweir                         //After running XExtensionManager::synchronize, the configmgrini is
395*cdf0e10cSrcweir                         //cleaned up
396*cdf0e10cSrcweir                         m_xcs_files.push_back( token );
397*cdf0e10cSrcweir                     }
398*cdf0e10cSrcweir                 }
399*cdf0e10cSrcweir                 while (index >= 0);
400*cdf0e10cSrcweir             }
401*cdf0e10cSrcweir             if (readLine( &line, OUSTR("DATA="), ucb_content,
402*cdf0e10cSrcweir                           RTL_TEXTENCODING_UTF8 )) {
403*cdf0e10cSrcweir                 sal_Int32 index = sizeof ("DATA=") - 1;
404*cdf0e10cSrcweir                 do {
405*cdf0e10cSrcweir                     OUString token( line.getToken( 0, ' ', index ).trim() );
406*cdf0e10cSrcweir                     if (token.getLength() > 0)
407*cdf0e10cSrcweir                     {
408*cdf0e10cSrcweir                         if (token[ 0 ] == '?')
409*cdf0e10cSrcweir                             token = token.copy( 1 );
410*cdf0e10cSrcweir                         //The  file may not exist anymore if a shared or bundled
411*cdf0e10cSrcweir                         //extension was removed, but it can still be in the configmgrini.
412*cdf0e10cSrcweir                         //After running XExtensionManager::synchronize, the configmgrini is
413*cdf0e10cSrcweir                         //cleaned up
414*cdf0e10cSrcweir                         m_xcu_files.push_back( token );
415*cdf0e10cSrcweir                     }
416*cdf0e10cSrcweir                 }
417*cdf0e10cSrcweir                 while (index >= 0);
418*cdf0e10cSrcweir             }
419*cdf0e10cSrcweir         }
420*cdf0e10cSrcweir         m_configmgrini_modified = false;
421*cdf0e10cSrcweir         m_configmgrini_inited = true;
422*cdf0e10cSrcweir     }
423*cdf0e10cSrcweir }
424*cdf0e10cSrcweir 
425*cdf0e10cSrcweir //______________________________________________________________________________
426*cdf0e10cSrcweir void BackendImpl::configmgrini_flush(
427*cdf0e10cSrcweir     Reference<XCommandEnvironment> const & xCmdEnv )
428*cdf0e10cSrcweir {
429*cdf0e10cSrcweir     if (transientMode())
430*cdf0e10cSrcweir         return;
431*cdf0e10cSrcweir     if (!m_configmgrini_inited || !m_configmgrini_modified)
432*cdf0e10cSrcweir         return;
433*cdf0e10cSrcweir 
434*cdf0e10cSrcweir     ::rtl::OStringBuffer buf;
435*cdf0e10cSrcweir     if (! m_xcs_files.empty())
436*cdf0e10cSrcweir     {
437*cdf0e10cSrcweir         t_stringlist::const_iterator iPos( m_xcs_files.begin() );
438*cdf0e10cSrcweir         t_stringlist::const_iterator const iEnd( m_xcs_files.end() );
439*cdf0e10cSrcweir         buf.append( RTL_CONSTASCII_STRINGPARAM("SCHEMA=") );
440*cdf0e10cSrcweir         while (iPos != iEnd) {
441*cdf0e10cSrcweir             // encoded ASCII file-urls:
442*cdf0e10cSrcweir             const ::rtl::OString item(
443*cdf0e10cSrcweir                 ::rtl::OUStringToOString( *iPos, RTL_TEXTENCODING_ASCII_US ) );
444*cdf0e10cSrcweir             buf.append( item );
445*cdf0e10cSrcweir             ++iPos;
446*cdf0e10cSrcweir             if (iPos != iEnd)
447*cdf0e10cSrcweir                 buf.append( ' ' );
448*cdf0e10cSrcweir         }
449*cdf0e10cSrcweir         buf.append(LF);
450*cdf0e10cSrcweir     }
451*cdf0e10cSrcweir     if (! m_xcu_files.empty())
452*cdf0e10cSrcweir     {
453*cdf0e10cSrcweir         t_stringlist::const_iterator iPos( m_xcu_files.begin() );
454*cdf0e10cSrcweir         t_stringlist::const_iterator const iEnd( m_xcu_files.end() );
455*cdf0e10cSrcweir         buf.append( RTL_CONSTASCII_STRINGPARAM("DATA=") );
456*cdf0e10cSrcweir         while (iPos != iEnd) {
457*cdf0e10cSrcweir             // encoded ASCII file-urls:
458*cdf0e10cSrcweir             const ::rtl::OString item(
459*cdf0e10cSrcweir                 ::rtl::OUStringToOString( *iPos, RTL_TEXTENCODING_ASCII_US ) );
460*cdf0e10cSrcweir             buf.append( item );
461*cdf0e10cSrcweir             ++iPos;
462*cdf0e10cSrcweir             if (iPos != iEnd)
463*cdf0e10cSrcweir                 buf.append( ' ' );
464*cdf0e10cSrcweir         }
465*cdf0e10cSrcweir         buf.append(LF);
466*cdf0e10cSrcweir     }
467*cdf0e10cSrcweir 
468*cdf0e10cSrcweir     // write configmgr.ini:
469*cdf0e10cSrcweir     const Reference<io::XInputStream> xData(
470*cdf0e10cSrcweir         ::xmlscript::createInputStream(
471*cdf0e10cSrcweir             ::rtl::ByteSequence(
472*cdf0e10cSrcweir                 reinterpret_cast<sal_Int8 const *>(buf.getStr()),
473*cdf0e10cSrcweir                 buf.getLength() ) ) );
474*cdf0e10cSrcweir     ::ucbhelper::Content ucb_content(
475*cdf0e10cSrcweir         makeURL( getCachePath(), OUSTR("configmgr.ini") ), xCmdEnv );
476*cdf0e10cSrcweir     ucb_content.writeStream( xData, true /* replace existing */ );
477*cdf0e10cSrcweir 
478*cdf0e10cSrcweir     m_configmgrini_modified = false;
479*cdf0e10cSrcweir }
480*cdf0e10cSrcweir 
481*cdf0e10cSrcweir //______________________________________________________________________________
482*cdf0e10cSrcweir bool BackendImpl::addToConfigmgrIni( bool isSchema, bool isURL, OUString const & url_,
483*cdf0e10cSrcweir                               Reference<XCommandEnvironment> const & xCmdEnv )
484*cdf0e10cSrcweir {
485*cdf0e10cSrcweir     const OUString rcterm( isURL ? dp_misc::makeRcTerm(url_) : url_ );
486*cdf0e10cSrcweir     const ::osl::MutexGuard guard( getMutex() );
487*cdf0e10cSrcweir     configmgrini_verify_init( xCmdEnv );
488*cdf0e10cSrcweir     t_stringlist & rSet = getFiles(isSchema);
489*cdf0e10cSrcweir     if (::std::find( rSet.begin(), rSet.end(), rcterm ) == rSet.end()) {
490*cdf0e10cSrcweir         rSet.push_front( rcterm ); // prepend to list, thus overriding
491*cdf0e10cSrcweir         // write immediately:
492*cdf0e10cSrcweir         m_configmgrini_modified = true;
493*cdf0e10cSrcweir         configmgrini_flush( xCmdEnv );
494*cdf0e10cSrcweir         return true;
495*cdf0e10cSrcweir     }
496*cdf0e10cSrcweir     else
497*cdf0e10cSrcweir         return false;
498*cdf0e10cSrcweir }
499*cdf0e10cSrcweir 
500*cdf0e10cSrcweir //______________________________________________________________________________
501*cdf0e10cSrcweir bool BackendImpl::removeFromConfigmgrIni(
502*cdf0e10cSrcweir     bool isSchema, OUString const & url_,
503*cdf0e10cSrcweir     Reference<XCommandEnvironment> const & xCmdEnv )
504*cdf0e10cSrcweir {
505*cdf0e10cSrcweir     const OUString rcterm( dp_misc::makeRcTerm(url_) );
506*cdf0e10cSrcweir     const ::osl::MutexGuard guard( getMutex() );
507*cdf0e10cSrcweir     configmgrini_verify_init( xCmdEnv );
508*cdf0e10cSrcweir     t_stringlist & rSet = getFiles(isSchema);
509*cdf0e10cSrcweir     t_stringlist::iterator i(std::find(rSet.begin(), rSet.end(), rcterm));
510*cdf0e10cSrcweir     if (i == rSet.end() && !isSchema)
511*cdf0e10cSrcweir     {
512*cdf0e10cSrcweir         //in case the xcu contained %origin% then the configmr.ini contains the
513*cdf0e10cSrcweir         //url to the file in the user installation (e.g. $BUNDLED_EXTENSIONS_USER)
514*cdf0e10cSrcweir         //However, m_url (getURL()) contains the URL for the file in the actual
515*cdf0e10cSrcweir         //extension installatation.
516*cdf0e10cSrcweir         ::boost::optional<ConfigurationBackendDb::Data> data = readDataFromDb(url_);
517*cdf0e10cSrcweir         if (data)
518*cdf0e10cSrcweir             i = std::find(rSet.begin(), rSet.end(), data->iniEntry);
519*cdf0e10cSrcweir     }
520*cdf0e10cSrcweir     if (i == rSet.end()) {
521*cdf0e10cSrcweir         return false;
522*cdf0e10cSrcweir     }
523*cdf0e10cSrcweir     rSet.erase(i);
524*cdf0e10cSrcweir     // write immediately:
525*cdf0e10cSrcweir     m_configmgrini_modified = true;
526*cdf0e10cSrcweir     configmgrini_flush( xCmdEnv );
527*cdf0e10cSrcweir     return true;
528*cdf0e10cSrcweir }
529*cdf0e10cSrcweir 
530*cdf0e10cSrcweir //##############################################################################
531*cdf0e10cSrcweir 
532*cdf0e10cSrcweir // Package
533*cdf0e10cSrcweir //______________________________________________________________________________
534*cdf0e10cSrcweir 
535*cdf0e10cSrcweir BackendImpl * BackendImpl::PackageImpl::getMyBackend() const
536*cdf0e10cSrcweir {
537*cdf0e10cSrcweir     BackendImpl * pBackend = static_cast<BackendImpl *>(m_myBackend.get());
538*cdf0e10cSrcweir     if (NULL == pBackend)
539*cdf0e10cSrcweir     {
540*cdf0e10cSrcweir         //May throw a DisposedException
541*cdf0e10cSrcweir         check();
542*cdf0e10cSrcweir         //We should never get here...
543*cdf0e10cSrcweir         throw RuntimeException(
544*cdf0e10cSrcweir             OUSTR("Failed to get the BackendImpl"),
545*cdf0e10cSrcweir             static_cast<OWeakObject*>(const_cast<PackageImpl *>(this)));
546*cdf0e10cSrcweir     }
547*cdf0e10cSrcweir     return pBackend;
548*cdf0e10cSrcweir }
549*cdf0e10cSrcweir 
550*cdf0e10cSrcweir beans::Optional< beans::Ambiguous<sal_Bool> >
551*cdf0e10cSrcweir BackendImpl::PackageImpl::isRegistered_(
552*cdf0e10cSrcweir     ::osl::ResettableMutexGuard &,
553*cdf0e10cSrcweir     ::rtl::Reference<AbortChannel> const &,
554*cdf0e10cSrcweir     Reference<XCommandEnvironment> const & )
555*cdf0e10cSrcweir {
556*cdf0e10cSrcweir     BackendImpl * that = getMyBackend();
557*cdf0e10cSrcweir     const rtl::OUString url(getURL());
558*cdf0e10cSrcweir 
559*cdf0e10cSrcweir     bool bReg = false;
560*cdf0e10cSrcweir     if (that->hasActiveEntry(getURL()))
561*cdf0e10cSrcweir         bReg = true;
562*cdf0e10cSrcweir     if (!bReg)
563*cdf0e10cSrcweir         //fallback for user extension registered in berkeley DB
564*cdf0e10cSrcweir         bReg = that->m_registeredPackages->has(
565*cdf0e10cSrcweir             rtl::OUStringToOString( url, RTL_TEXTENCODING_UTF8 ));
566*cdf0e10cSrcweir 
567*cdf0e10cSrcweir 	return beans::Optional< beans::Ambiguous<sal_Bool> >(
568*cdf0e10cSrcweir         true, beans::Ambiguous<sal_Bool>( bReg, false ) );
569*cdf0e10cSrcweir }
570*cdf0e10cSrcweir 
571*cdf0e10cSrcweir //------------------------------------------------------------------------------
572*cdf0e10cSrcweir OUString encodeForXml( OUString const & text )
573*cdf0e10cSrcweir {
574*cdf0e10cSrcweir     // encode conforming xml:
575*cdf0e10cSrcweir     sal_Int32 len = text.getLength();
576*cdf0e10cSrcweir     ::rtl::OUStringBuffer buf;
577*cdf0e10cSrcweir     for ( sal_Int32 pos = 0; pos < len; ++pos )
578*cdf0e10cSrcweir     {
579*cdf0e10cSrcweir         sal_Unicode c = text[ pos ];
580*cdf0e10cSrcweir         switch (c) {
581*cdf0e10cSrcweir         case '<':
582*cdf0e10cSrcweir             buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("&lt;") );
583*cdf0e10cSrcweir             break;
584*cdf0e10cSrcweir         case '>':
585*cdf0e10cSrcweir             buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("&gt;") );
586*cdf0e10cSrcweir             break;
587*cdf0e10cSrcweir         case '&':
588*cdf0e10cSrcweir             buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("&amp;") );
589*cdf0e10cSrcweir             break;
590*cdf0e10cSrcweir         case '\'':
591*cdf0e10cSrcweir             buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("&apos;") );
592*cdf0e10cSrcweir             break;
593*cdf0e10cSrcweir         case '\"':
594*cdf0e10cSrcweir             buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("&quot;") );
595*cdf0e10cSrcweir             break;
596*cdf0e10cSrcweir         default:
597*cdf0e10cSrcweir             buf.append( c );
598*cdf0e10cSrcweir             break;
599*cdf0e10cSrcweir         }
600*cdf0e10cSrcweir     }
601*cdf0e10cSrcweir     return buf.makeStringAndClear();
602*cdf0e10cSrcweir }
603*cdf0e10cSrcweir 
604*cdf0e10cSrcweir //______________________________________________________________________________
605*cdf0e10cSrcweir OUString replaceOrigin(
606*cdf0e10cSrcweir     OUString const & url, OUString const & destFolder, Reference< XCommandEnvironment > const & xCmdEnv, bool & out_replaced)
607*cdf0e10cSrcweir {
608*cdf0e10cSrcweir     // looking for %origin%:
609*cdf0e10cSrcweir     ::ucbhelper::Content ucb_content( url, xCmdEnv );
610*cdf0e10cSrcweir     ::rtl::ByteSequence bytes( readFile( ucb_content ) );
611*cdf0e10cSrcweir     ::rtl::ByteSequence filtered( bytes.getLength() * 2,
612*cdf0e10cSrcweir                                   ::rtl::BYTESEQ_NODEFAULT );
613*cdf0e10cSrcweir     bool use_filtered = false;
614*cdf0e10cSrcweir     ::rtl::OString origin;
615*cdf0e10cSrcweir     sal_Char const * pBytes = reinterpret_cast<sal_Char const *>(
616*cdf0e10cSrcweir         bytes.getConstArray());
617*cdf0e10cSrcweir     sal_Size nBytes = bytes.getLength();
618*cdf0e10cSrcweir     sal_Int32 write_pos = 0;
619*cdf0e10cSrcweir     while (nBytes > 0)
620*cdf0e10cSrcweir     {
621*cdf0e10cSrcweir         sal_Int32 index = rtl_str_indexOfChar_WithLength( pBytes, nBytes, '%' );
622*cdf0e10cSrcweir         if (index < 0) {
623*cdf0e10cSrcweir             if (! use_filtered) // opt
624*cdf0e10cSrcweir                 break;
625*cdf0e10cSrcweir             index = nBytes;
626*cdf0e10cSrcweir         }
627*cdf0e10cSrcweir 
628*cdf0e10cSrcweir         if ((write_pos + index) > filtered.getLength())
629*cdf0e10cSrcweir             filtered.realloc( (filtered.getLength() + index) * 2 );
630*cdf0e10cSrcweir         rtl_copyMemory( filtered.getArray() + write_pos, pBytes, index );
631*cdf0e10cSrcweir         write_pos += index;
632*cdf0e10cSrcweir         pBytes += index;
633*cdf0e10cSrcweir         nBytes -= index;
634*cdf0e10cSrcweir         if (nBytes == 0)
635*cdf0e10cSrcweir             break;
636*cdf0e10cSrcweir 
637*cdf0e10cSrcweir         // consume %:
638*cdf0e10cSrcweir         ++pBytes;
639*cdf0e10cSrcweir         --nBytes;
640*cdf0e10cSrcweir         sal_Char const * pAdd = "%";
641*cdf0e10cSrcweir         sal_Int32 nAdd = 1;
642*cdf0e10cSrcweir         if (nBytes > 1 && pBytes[ 0 ] == '%')
643*cdf0e10cSrcweir         {
644*cdf0e10cSrcweir             // %% => %
645*cdf0e10cSrcweir             ++pBytes;
646*cdf0e10cSrcweir             --nBytes;
647*cdf0e10cSrcweir             use_filtered = true;
648*cdf0e10cSrcweir         }
649*cdf0e10cSrcweir         else if (rtl_str_shortenedCompare_WithLength(
650*cdf0e10cSrcweir                      pBytes, nBytes,
651*cdf0e10cSrcweir                      RTL_CONSTASCII_STRINGPARAM("origin%"),
652*cdf0e10cSrcweir                      sizeof ("origin%") - 1 ) == 0)
653*cdf0e10cSrcweir         {
654*cdf0e10cSrcweir             if (origin.getLength() == 0) {
655*cdf0e10cSrcweir                 // encode only once
656*cdf0e10cSrcweir                 origin = ::rtl::OUStringToOString(
657*cdf0e10cSrcweir                     encodeForXml( url.copy( 0, url.lastIndexOf( '/' ) ) ),
658*cdf0e10cSrcweir                     // xxx todo: encode always for UTF-8? => lookup doc-header?
659*cdf0e10cSrcweir                     RTL_TEXTENCODING_UTF8 );
660*cdf0e10cSrcweir             }
661*cdf0e10cSrcweir             pAdd = origin.getStr();
662*cdf0e10cSrcweir             nAdd = origin.getLength();
663*cdf0e10cSrcweir             pBytes += (sizeof ("origin%") - 1);
664*cdf0e10cSrcweir             nBytes -= (sizeof ("origin%") - 1);
665*cdf0e10cSrcweir             use_filtered = true;
666*cdf0e10cSrcweir         }
667*cdf0e10cSrcweir         if ((write_pos + nAdd) > filtered.getLength())
668*cdf0e10cSrcweir             filtered.realloc( (filtered.getLength() + nAdd) * 2 );
669*cdf0e10cSrcweir         rtl_copyMemory( filtered.getArray() + write_pos, pAdd, nAdd );
670*cdf0e10cSrcweir         write_pos += nAdd;
671*cdf0e10cSrcweir     }
672*cdf0e10cSrcweir     if (!use_filtered)
673*cdf0e10cSrcweir         return url;
674*cdf0e10cSrcweir     if (write_pos < filtered.getLength())
675*cdf0e10cSrcweir         filtered.realloc( write_pos );
676*cdf0e10cSrcweir     rtl::OUString newUrl(url);
677*cdf0e10cSrcweir     if (destFolder.getLength())
678*cdf0e10cSrcweir     {
679*cdf0e10cSrcweir         //get the file name of the xcu and add it to the url of the temporary folder
680*cdf0e10cSrcweir         sal_Int32 i = url.lastIndexOf('/');
681*cdf0e10cSrcweir         newUrl = destFolder + url.copy(i);
682*cdf0e10cSrcweir     }
683*cdf0e10cSrcweir 
684*cdf0e10cSrcweir     ucbhelper::Content(newUrl, xCmdEnv).writeStream(
685*cdf0e10cSrcweir         xmlscript::createInputStream(filtered), true);
686*cdf0e10cSrcweir     out_replaced = true;
687*cdf0e10cSrcweir     return newUrl;
688*cdf0e10cSrcweir }
689*cdf0e10cSrcweir 
690*cdf0e10cSrcweir //______________________________________________________________________________
691*cdf0e10cSrcweir void BackendImpl::PackageImpl::processPackage_(
692*cdf0e10cSrcweir     ::osl::ResettableMutexGuard &,
693*cdf0e10cSrcweir     bool doRegisterPackage,
694*cdf0e10cSrcweir     bool startup,
695*cdf0e10cSrcweir     ::rtl::Reference<AbortChannel> const &,
696*cdf0e10cSrcweir     Reference<XCommandEnvironment> const & xCmdEnv )
697*cdf0e10cSrcweir {
698*cdf0e10cSrcweir     BackendImpl * that = getMyBackend();
699*cdf0e10cSrcweir     OUString url( getURL() );
700*cdf0e10cSrcweir 
701*cdf0e10cSrcweir     if (doRegisterPackage)
702*cdf0e10cSrcweir     {
703*cdf0e10cSrcweir         if (getMyBackend()->activateEntry(getURL()))
704*cdf0e10cSrcweir         {
705*cdf0e10cSrcweir             ::boost::optional<ConfigurationBackendDb::Data> data = that->readDataFromDb(url);
706*cdf0e10cSrcweir             OSL_ASSERT(data);
707*cdf0e10cSrcweir             that->addToConfigmgrIni( m_isSchema, false, data->iniEntry, xCmdEnv );
708*cdf0e10cSrcweir         }
709*cdf0e10cSrcweir         else
710*cdf0e10cSrcweir         {
711*cdf0e10cSrcweir             ConfigurationBackendDb::Data data;
712*cdf0e10cSrcweir             if (!m_isSchema)
713*cdf0e10cSrcweir             {
714*cdf0e10cSrcweir                 const OUString sModFolder = that->createFolder(OUString(), xCmdEnv);
715*cdf0e10cSrcweir                 bool out_replaced = false;
716*cdf0e10cSrcweir                 url = replaceOrigin(url, sModFolder, xCmdEnv, out_replaced);
717*cdf0e10cSrcweir                 if (out_replaced)
718*cdf0e10cSrcweir                     data.dataUrl = sModFolder;
719*cdf0e10cSrcweir                 else
720*cdf0e10cSrcweir                     deleteTempFolder(sModFolder);
721*cdf0e10cSrcweir             }
722*cdf0e10cSrcweir             //No need for live-deployment for bundled extension, because OOo
723*cdf0e10cSrcweir             //restarts after installation
724*cdf0e10cSrcweir             if (that->m_eContext != CONTEXT_BUNDLED
725*cdf0e10cSrcweir                 && that->m_eContext != CONTEXT_BUNDLED_PREREG
726*cdf0e10cSrcweir                 && !startup)
727*cdf0e10cSrcweir             {
728*cdf0e10cSrcweir                 if (m_isSchema)
729*cdf0e10cSrcweir                 {
730*cdf0e10cSrcweir                     com::sun::star::configuration::Update::get(
731*cdf0e10cSrcweir                         that->m_xComponentContext)->insertExtensionXcsFile(
732*cdf0e10cSrcweir                             that->m_eContext == CONTEXT_SHARED, expandUnoRcUrl(url));
733*cdf0e10cSrcweir                 }
734*cdf0e10cSrcweir                 else
735*cdf0e10cSrcweir                 {
736*cdf0e10cSrcweir                     com::sun::star::configuration::Update::get(
737*cdf0e10cSrcweir                         that->m_xComponentContext)->insertExtensionXcuFile(
738*cdf0e10cSrcweir                             that->m_eContext == CONTEXT_SHARED, expandUnoRcUrl(url));
739*cdf0e10cSrcweir                 }
740*cdf0e10cSrcweir             }
741*cdf0e10cSrcweir             that->addToConfigmgrIni( m_isSchema, true, url, xCmdEnv );
742*cdf0e10cSrcweir             data.iniEntry = dp_misc::makeRcTerm(url);
743*cdf0e10cSrcweir             that->addDataToDb(getURL(), data);
744*cdf0e10cSrcweir         }
745*cdf0e10cSrcweir     }
746*cdf0e10cSrcweir     else // revoke
747*cdf0e10cSrcweir     {
748*cdf0e10cSrcweir         if (!that->removeFromConfigmgrIni(m_isSchema, url, xCmdEnv)) {
749*cdf0e10cSrcweir             t_string2string_map entries(
750*cdf0e10cSrcweir                 that->m_registeredPackages->getEntries());
751*cdf0e10cSrcweir             for (t_string2string_map::iterator i(entries.begin());
752*cdf0e10cSrcweir                  i != entries.end(); ++i)
753*cdf0e10cSrcweir             {
754*cdf0e10cSrcweir                 //If the xcu file was installed before the configmgr was chaned
755*cdf0e10cSrcweir                 //to use the configmgr.ini, one needed to rebuild to whole directory
756*cdf0e10cSrcweir                 //structur containing the xcu, xcs files from all extensions. Now,
757*cdf0e10cSrcweir                 //we just add all other xcu/xcs files to the configmgr.ini instead of
758*cdf0e10cSrcweir                 //rebuilding the directory structure.
759*cdf0e10cSrcweir                 rtl::OUString url2(
760*cdf0e10cSrcweir                     rtl::OStringToOUString(i->first, RTL_TEXTENCODING_UTF8));
761*cdf0e10cSrcweir                 if (url2 != url) {
762*cdf0e10cSrcweir                    bool schema = i->second.equalsIgnoreAsciiCase(
763*cdf0e10cSrcweir                        "vnd.sun.star.configuration-schema");
764*cdf0e10cSrcweir                    OUString url_replaced(url2);
765*cdf0e10cSrcweir                    ConfigurationBackendDb::Data data;
766*cdf0e10cSrcweir                    if (!schema)
767*cdf0e10cSrcweir                    {
768*cdf0e10cSrcweir                        const OUString sModFolder = that->createFolder(OUString(), xCmdEnv);
769*cdf0e10cSrcweir                        bool out_replaced = false;
770*cdf0e10cSrcweir                        url_replaced = replaceOrigin(
771*cdf0e10cSrcweir                            url2, sModFolder, xCmdEnv, out_replaced);
772*cdf0e10cSrcweir                        if (out_replaced)
773*cdf0e10cSrcweir                            data.dataUrl = sModFolder;
774*cdf0e10cSrcweir                        else
775*cdf0e10cSrcweir                            deleteTempFolder(sModFolder);
776*cdf0e10cSrcweir                    }
777*cdf0e10cSrcweir                    that->addToConfigmgrIni(schema, true, url_replaced, xCmdEnv);
778*cdf0e10cSrcweir                    data.iniEntry = dp_misc::makeRcTerm(url_replaced);
779*cdf0e10cSrcweir                    that->addDataToDb(url2, data);
780*cdf0e10cSrcweir                 }
781*cdf0e10cSrcweir                 that->m_registeredPackages->erase(i->first);
782*cdf0e10cSrcweir             }
783*cdf0e10cSrcweir             try
784*cdf0e10cSrcweir             {
785*cdf0e10cSrcweir                 ::ucbhelper::Content(
786*cdf0e10cSrcweir                     makeURL( that->getCachePath(), OUSTR("registry") ),
787*cdf0e10cSrcweir                     xCmdEnv ).executeCommand(
788*cdf0e10cSrcweir                         OUSTR("delete"), Any( true /* delete physically */ ) );
789*cdf0e10cSrcweir             }
790*cdf0e10cSrcweir             catch(Exception&)
791*cdf0e10cSrcweir             {
792*cdf0e10cSrcweir                 OSL_ASSERT(0);
793*cdf0e10cSrcweir             }
794*cdf0e10cSrcweir         }
795*cdf0e10cSrcweir 
796*cdf0e10cSrcweir         ::boost::optional<ConfigurationBackendDb::Data> data = that->readDataFromDb(url);
797*cdf0e10cSrcweir         //If an xcu file was life deployed then always a data entry is written.
798*cdf0e10cSrcweir         //If the xcu file was already in the configmr.ini then there is also
799*cdf0e10cSrcweir         //a data entry
800*cdf0e10cSrcweir         if (!m_isSchema && data)
801*cdf0e10cSrcweir         {
802*cdf0e10cSrcweir             com::sun::star::configuration::Update::get(
803*cdf0e10cSrcweir                 that->m_xComponentContext)->removeExtensionXcuFile(expandUnoRcTerm(data->iniEntry));
804*cdf0e10cSrcweir         }
805*cdf0e10cSrcweir         that->revokeEntryFromDb(url);
806*cdf0e10cSrcweir     }
807*cdf0e10cSrcweir }
808*cdf0e10cSrcweir 
809*cdf0e10cSrcweir } // anon namespace
810*cdf0e10cSrcweir 
811*cdf0e10cSrcweir namespace sdecl = comphelper::service_decl;
812*cdf0e10cSrcweir sdecl::class_<BackendImpl, sdecl::with_args<true> > serviceBI;
813*cdf0e10cSrcweir extern sdecl::ServiceDecl const serviceDecl(
814*cdf0e10cSrcweir     serviceBI,
815*cdf0e10cSrcweir     "com.sun.star.comp.deployment.configuration.PackageRegistryBackend",
816*cdf0e10cSrcweir     BACKEND_SERVICE_NAME );
817*cdf0e10cSrcweir 
818*cdf0e10cSrcweir } // namespace configuration
819*cdf0e10cSrcweir } // namespace backend
820*cdf0e10cSrcweir } // namespace dp_registry
821*cdf0e10cSrcweir 
822