xref: /AOO41X/main/desktop/source/deployment/manager/dp_manager.cxx (revision c6dedb65bb4f6c53874f76e9916c5b19be04c6b1)
12722ceddSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
32722ceddSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
42722ceddSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
52722ceddSAndrew Rist  * distributed with this work for additional information
62722ceddSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
72722ceddSAndrew Rist  * to you under the Apache License, Version 2.0 (the
82722ceddSAndrew Rist  * "License"); you may not use this file except in compliance
92722ceddSAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
112722ceddSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
132722ceddSAndrew Rist  * Unless required by applicable law or agreed to in writing,
142722ceddSAndrew Rist  * software distributed under the License is distributed on an
152722ceddSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
162722ceddSAndrew Rist  * KIND, either express or implied.  See the License for the
172722ceddSAndrew Rist  * specific language governing permissions and limitations
182722ceddSAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
202722ceddSAndrew Rist  *************************************************************/
212722ceddSAndrew Rist 
222722ceddSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_desktop.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include "dp_ucb.h"
28cdf0e10cSrcweir #include "dp_resource.h"
29cdf0e10cSrcweir #include "dp_platform.hxx"
30cdf0e10cSrcweir #include "dp_manager.h"
31cdf0e10cSrcweir #include "dp_identifier.hxx"
32cdf0e10cSrcweir #include "rtl/ustrbuf.hxx"
33cdf0e10cSrcweir #include "rtl/string.hxx"
34cdf0e10cSrcweir #include "rtl/uri.hxx"
35cdf0e10cSrcweir #include "rtl/bootstrap.hxx"
36cdf0e10cSrcweir #include "osl/diagnose.h"
37cdf0e10cSrcweir #include "osl/file.hxx"
38cdf0e10cSrcweir #include "osl/security.hxx"
39cdf0e10cSrcweir #include "cppuhelper/weakref.hxx"
40cdf0e10cSrcweir #include "cppuhelper/exc_hlp.hxx"
41cdf0e10cSrcweir #include "cppuhelper/implbase1.hxx"
42cdf0e10cSrcweir #include "cppuhelper/interfacecontainer.hxx"
43cdf0e10cSrcweir #include "comphelper/servicedecl.hxx"
44cdf0e10cSrcweir #include "comphelper/sequence.hxx"
45cdf0e10cSrcweir #include "xmlscript/xml_helper.hxx"
46cdf0e10cSrcweir #include "svl/inettype.hxx"
47cdf0e10cSrcweir #include "com/sun/star/lang/DisposedException.hpp"
48cdf0e10cSrcweir #include "com/sun/star/lang/WrappedTargetRuntimeException.hpp"
49cdf0e10cSrcweir #include "com/sun/star/beans/UnknownPropertyException.hpp"
50cdf0e10cSrcweir #include "com/sun/star/util/XUpdatable.hpp"
51cdf0e10cSrcweir #include "com/sun/star/sdbc/XResultSet.hpp"
52cdf0e10cSrcweir #include "com/sun/star/sdbc/XRow.hpp"
53cdf0e10cSrcweir #include "com/sun/star/ucb/XContentAccess.hpp"
54cdf0e10cSrcweir #include "com/sun/star/ucb/NameClash.hpp"
55cdf0e10cSrcweir #include "com/sun/star/deployment/VersionException.hpp"
56cdf0e10cSrcweir #include "com/sun/star/deployment/InstallException.hpp"
57cdf0e10cSrcweir #include "com/sun/star/deployment/Prerequisites.hpp"
58cdf0e10cSrcweir #include "com/sun/star/task/XInteractionApprove.hpp"
59cdf0e10cSrcweir #include "com/sun/star/ucb/UnsupportedCommandException.hpp"
60cdf0e10cSrcweir #include "boost/bind.hpp"
61cdf0e10cSrcweir #include "tools/urlobj.hxx"
62cdf0e10cSrcweir #include "unotools/tempfile.hxx"
63cdf0e10cSrcweir 
64cdf0e10cSrcweir #include "osl/file.hxx"
65cdf0e10cSrcweir #include <vector>
66cdf0e10cSrcweir #include <list>
67cdf0e10cSrcweir #include "dp_descriptioninfoset.hxx"
68cdf0e10cSrcweir #include "dp_commandenvironments.hxx"
69cdf0e10cSrcweir #include "dp_properties.hxx"
70cdf0e10cSrcweir 
71cdf0e10cSrcweir using namespace ::dp_misc;
72cdf0e10cSrcweir using namespace ::com::sun::star;
73cdf0e10cSrcweir using namespace ::com::sun::star::uno;
74cdf0e10cSrcweir using namespace ::com::sun::star::ucb;
75cdf0e10cSrcweir using ::rtl::OUString;
76cdf0e10cSrcweir 
77cdf0e10cSrcweir namespace dp_log {
78cdf0e10cSrcweir extern comphelper::service_decl::ServiceDecl const serviceDecl;
79cdf0e10cSrcweir }
80cdf0e10cSrcweir 
81cdf0e10cSrcweir namespace dp_registry {
82cdf0e10cSrcweir Reference<deployment::XPackageRegistry> create(
83cdf0e10cSrcweir     OUString const & context,
84cdf0e10cSrcweir     OUString const & cachePath, bool readOnly,
85cdf0e10cSrcweir     Reference<XComponentContext> const & xComponentContext );
86cdf0e10cSrcweir }
87cdf0e10cSrcweir 
88cdf0e10cSrcweir namespace dp_manager {
89cdf0e10cSrcweir 
90cdf0e10cSrcweir struct MatchTempDir
91cdf0e10cSrcweir {
92cdf0e10cSrcweir     OUString m_str;
MatchTempDirdp_manager::MatchTempDir93cdf0e10cSrcweir     MatchTempDir( OUString const & str ) : m_str( str ) {}
operator ()dp_manager::MatchTempDir94cdf0e10cSrcweir     bool operator () ( ActivePackages::Entries::value_type const & v ) const {
95cdf0e10cSrcweir         return v.second.temporaryName.equalsIgnoreAsciiCase( m_str );
96cdf0e10cSrcweir     }
97cdf0e10cSrcweir };
98cdf0e10cSrcweir 
99cdf0e10cSrcweir 
100cdf0e10cSrcweir namespace {
getExtensionFolder(OUString const & parentFolder,Reference<ucb::XCommandEnvironment> const & xCmdEnv)101cdf0e10cSrcweir OUString getExtensionFolder(OUString const &  parentFolder,
102cdf0e10cSrcweir                             Reference<ucb::XCommandEnvironment> const & xCmdEnv)
103cdf0e10cSrcweir {
104cdf0e10cSrcweir     ::ucbhelper::Content tempFolder(
105cdf0e10cSrcweir         parentFolder, xCmdEnv );
106cdf0e10cSrcweir     Reference<sdbc::XResultSet> xResultSet(
107cdf0e10cSrcweir         tempFolder.createCursor(
108cdf0e10cSrcweir             Sequence<OUString>( &StrTitle::get(), 1 ),
109cdf0e10cSrcweir             ::ucbhelper::INCLUDE_FOLDERS_ONLY ) );
110cdf0e10cSrcweir 
111cdf0e10cSrcweir     OUString title;
112cdf0e10cSrcweir     while (xResultSet->next())
113cdf0e10cSrcweir     {
114cdf0e10cSrcweir         title = Reference<sdbc::XRow>(
115cdf0e10cSrcweir             xResultSet, UNO_QUERY_THROW )->getString(1 /* Title */ ) ;
116cdf0e10cSrcweir         break;
117cdf0e10cSrcweir     }
118cdf0e10cSrcweir     return title;
119cdf0e10cSrcweir }
120cdf0e10cSrcweir }
121cdf0e10cSrcweir //______________________________________________________________________________
initActivationLayer(Reference<XCommandEnvironment> const & xCmdEnv)122cdf0e10cSrcweir void PackageManagerImpl::initActivationLayer(
123cdf0e10cSrcweir     Reference<XCommandEnvironment> const & xCmdEnv )
124cdf0e10cSrcweir {
125cdf0e10cSrcweir     if (m_activePackages.getLength() == 0)
126cdf0e10cSrcweir     {
127cdf0e10cSrcweir         OSL_ASSERT( m_registryCache.getLength() == 0 );
128cdf0e10cSrcweir         // documents temp activation:
129cdf0e10cSrcweir         m_activePackagesDB.reset( new ActivePackages );
130cdf0e10cSrcweir         ::ucbhelper::Content ucbContent;
131cdf0e10cSrcweir         if (create_ucb_content( &ucbContent, m_context, xCmdEnv,
132cdf0e10cSrcweir                                 false /* no throw */ ))
133cdf0e10cSrcweir         {
134cdf0e10cSrcweir             // scan for all entries in m_packagesDir:
135cdf0e10cSrcweir             Reference<sdbc::XResultSet> xResultSet(
136cdf0e10cSrcweir                 ucbContent.createCursor(
137cdf0e10cSrcweir                     Sequence<OUString>( &StrTitle::get(), 1 ),
138cdf0e10cSrcweir                     ::ucbhelper::INCLUDE_FOLDERS_AND_DOCUMENTS ) );
139cdf0e10cSrcweir             while (xResultSet->next())
140cdf0e10cSrcweir             {
141cdf0e10cSrcweir                 Reference<sdbc::XRow> xRow( xResultSet, UNO_QUERY_THROW );
142cdf0e10cSrcweir                 OUString title( xRow->getString( 1 /* Title */ ) );
143cdf0e10cSrcweir                 // xxx todo: remove workaround for tdoc
144cdf0e10cSrcweir                 if (title.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(
145cdf0e10cSrcweir                                             "this_is_a_dummy_stream_just_there_"
146cdf0e10cSrcweir                                             "as_a_workaround_for_a_"
147cdf0e10cSrcweir                                             "temporary_limitation_of_the_"
148cdf0e10cSrcweir                                             "storage_api_implementation") ))
149cdf0e10cSrcweir                     continue;
150cdf0e10cSrcweir                 if (title.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(
151cdf0e10cSrcweir                                              "META-INF") ) )
152cdf0e10cSrcweir                     continue;
153cdf0e10cSrcweir 
154cdf0e10cSrcweir                 ::ucbhelper::Content sourceContent(
155cdf0e10cSrcweir                     Reference<XContentAccess>(
156cdf0e10cSrcweir                         xResultSet, UNO_QUERY_THROW )->queryContent(),
157cdf0e10cSrcweir                     xCmdEnv );
158cdf0e10cSrcweir 
159cdf0e10cSrcweir                 OUString mediaType( detectMediaType( sourceContent,
160cdf0e10cSrcweir                                                      false /* no throw */) );
161cdf0e10cSrcweir                 if (mediaType.getLength() >0)
162cdf0e10cSrcweir                 {
163cdf0e10cSrcweir                     ActivePackages::Data dbData;
164cdf0e10cSrcweir                     insertToActivationLayer(
165cdf0e10cSrcweir                         Sequence<css::beans::NamedValue>(),mediaType, sourceContent,
166cdf0e10cSrcweir                         title, &dbData );
167cdf0e10cSrcweir 
168cdf0e10cSrcweir                     insertToActivationLayerDB( title, dbData );
169cdf0e10cSrcweir                         //TODO #i73136#: insertToActivationLayerDB needs id not
170cdf0e10cSrcweir                         // title, but the whole m_activePackages.getLength()==0
171cdf0e10cSrcweir                         // case (i.e., document-relative deployment) currently
172cdf0e10cSrcweir                         // does not work, anyway.
173cdf0e10cSrcweir                 }
174cdf0e10cSrcweir             }
175cdf0e10cSrcweir         }
176cdf0e10cSrcweir     }
177cdf0e10cSrcweir     else
178cdf0e10cSrcweir     {
179cdf0e10cSrcweir         // user|share:
180cdf0e10cSrcweir         OSL_ASSERT( m_activePackages.getLength() > 0 );
181cdf0e10cSrcweir         m_activePackages_expanded = expandUnoRcUrl( m_activePackages );
182cdf0e10cSrcweir         m_registrationData_expanded = expandUnoRcUrl(m_registrationData);
183cdf0e10cSrcweir         if (!m_readOnly)
184cdf0e10cSrcweir             create_folder( 0, m_activePackages_expanded, xCmdEnv, true);
185cdf0e10cSrcweir 
186cdf0e10cSrcweir         OUString dbName;
187cdf0e10cSrcweir         if (m_context.equals(OUSTR("user")))
1883a63f8e7SHerbert Dürr             dbName = m_activePackages_expanded + OUSTR(".pmap");
189cdf0e10cSrcweir         else
190cdf0e10cSrcweir         {
191cdf0e10cSrcweir             //Create the extension data base in the user installation
192cdf0e10cSrcweir             create_folder( 0, m_registrationData_expanded, xCmdEnv, true);
1933a63f8e7SHerbert Dürr             dbName = m_registrationData_expanded + OUSTR("/extensions.pmap");
194cdf0e10cSrcweir         }
195cdf0e10cSrcweir         //The data base can always be written because it it always in the user installation
196cdf0e10cSrcweir         m_activePackagesDB.reset(
197cdf0e10cSrcweir             new ActivePackages( dbName, false ) );
198cdf0e10cSrcweir 
199cdf0e10cSrcweir         if (! m_readOnly && ! m_context.equals(OUSTR("bundled")))
200cdf0e10cSrcweir         {
201cdf0e10cSrcweir             // clean up activation layer, scan for zombie temp dirs:
202cdf0e10cSrcweir             ActivePackages::Entries id2temp( m_activePackagesDB->getEntries() );
203cdf0e10cSrcweir 
204cdf0e10cSrcweir             ::ucbhelper::Content tempFolder(
205cdf0e10cSrcweir                 m_activePackages_expanded, xCmdEnv );
206cdf0e10cSrcweir             Reference<sdbc::XResultSet> xResultSet(
207cdf0e10cSrcweir                 tempFolder.createCursor(
208cdf0e10cSrcweir                     Sequence<OUString>( &StrTitle::get(), 1 ),
209cdf0e10cSrcweir                     ::ucbhelper::INCLUDE_DOCUMENTS_ONLY ) );
210cdf0e10cSrcweir             // get all temp directories:
211cdf0e10cSrcweir             ::std::vector<OUString> tempEntries;
212cdf0e10cSrcweir             ::std::vector<OUString> removedEntries;
213cdf0e10cSrcweir             while (xResultSet->next())
214cdf0e10cSrcweir             {
215cdf0e10cSrcweir                 OUString title(
216cdf0e10cSrcweir                     Reference<sdbc::XRow>(
217cdf0e10cSrcweir                         xResultSet, UNO_QUERY_THROW )->getString(
218cdf0e10cSrcweir                             1 /* Title */ ) );
219cdf0e10cSrcweir 
220cdf0e10cSrcweir                 const char extensionRemoved[] = "removed";
221cdf0e10cSrcweir                 if (title.endsWithAsciiL(
222cdf0e10cSrcweir                         extensionRemoved, sizeof(extensionRemoved) - 1))
223cdf0e10cSrcweir                 {
224cdf0e10cSrcweir                     //save the file name withouth the "removed" part
225cdf0e10cSrcweir                     sal_Int32 index = title.lastIndexOfAsciiL(
226cdf0e10cSrcweir                         extensionRemoved, sizeof(extensionRemoved) - 1);
227cdf0e10cSrcweir                     OUString remFile = title.copy(0, index);
228cdf0e10cSrcweir                     removedEntries.push_back(::rtl::Uri::encode(
229cdf0e10cSrcweir                                                 remFile, rtl_UriCharClassPchar,
230cdf0e10cSrcweir                                                 rtl_UriEncodeIgnoreEscapes,
231cdf0e10cSrcweir                                                 RTL_TEXTENCODING_UTF8 ) );
232cdf0e10cSrcweir                 }
233cdf0e10cSrcweir                 else
234cdf0e10cSrcweir                 {
235cdf0e10cSrcweir                     tempEntries.push_back( ::rtl::Uri::encode(
236cdf0e10cSrcweir                                                title, rtl_UriCharClassPchar,
237cdf0e10cSrcweir                                                rtl_UriEncodeIgnoreEscapes,
238cdf0e10cSrcweir                                                RTL_TEXTENCODING_UTF8 ) );
239cdf0e10cSrcweir                 }
240cdf0e10cSrcweir             }
241cdf0e10cSrcweir 
242cdf0e10cSrcweir             bool bShared = m_context.equals(OUSTR("shared")) ? true : false;
243cdf0e10cSrcweir             for ( ::std::size_t pos = 0; pos < tempEntries.size(); ++pos )
244cdf0e10cSrcweir             {
245cdf0e10cSrcweir                 OUString const & tempEntry = tempEntries[ pos ];
246cdf0e10cSrcweir                 const MatchTempDir match( tempEntry );
247cdf0e10cSrcweir                 if (::std::find_if( id2temp.begin(), id2temp.end(), match ) ==
248cdf0e10cSrcweir                     id2temp.end())
249cdf0e10cSrcweir                 {
250cdf0e10cSrcweir                     const OUString url(
251cdf0e10cSrcweir                         makeURL(m_activePackages_expanded, tempEntry ) );
252cdf0e10cSrcweir 
253cdf0e10cSrcweir                     //In case of shared extensions, new entries are regarded as
254cdf0e10cSrcweir                     //added extensions if there is no xxx.tmpremoved file.
255cdf0e10cSrcweir                     if (bShared)
256cdf0e10cSrcweir                     {
257cdf0e10cSrcweir                         if (::std::find(removedEntries.begin(), removedEntries.end(), tempEntry) ==
258cdf0e10cSrcweir                             removedEntries.end())
259cdf0e10cSrcweir                         {
260cdf0e10cSrcweir                             continue;
261cdf0e10cSrcweir                         }
262cdf0e10cSrcweir                         else
263cdf0e10cSrcweir                         {
264cdf0e10cSrcweir                             //Make sure only the same user removes the extension, who
265cdf0e10cSrcweir                             //previously unregistered it. This is avoid races if multiple instances
266cdf0e10cSrcweir                             //of OOo are running which all have write access to the shared installation.
267cdf0e10cSrcweir                             //For example, a user removes the extension, but keeps OOo
268cdf0e10cSrcweir                             //running. Parts of the extension may still be loaded and used by OOo.
269cdf0e10cSrcweir                             //Therefore the extension is only deleted the next time the extension manager is
270cdf0e10cSrcweir                             //run after restarting OOo. While OOo is still running, another user starts OOo
271cdf0e10cSrcweir                             //which would deleted the extension files. If the same user starts another
272cdf0e10cSrcweir                             //instance of OOo then the lock file will prevent this.
273cdf0e10cSrcweir                             OUString aUserName;
274cdf0e10cSrcweir                             ::osl::Security aSecurity;
275cdf0e10cSrcweir                             aSecurity.getUserName( aUserName );
276cdf0e10cSrcweir                             ucbhelper::Content remFileContent(
277cdf0e10cSrcweir                                 url + OUSTR("removed"), Reference<XCommandEnvironment>());
278cdf0e10cSrcweir                             ::rtl::ByteSequence data = dp_misc::readFile(remFileContent);
279cdf0e10cSrcweir                             ::rtl::OString osData(reinterpret_cast<const sal_Char*>(data.getConstArray()),
280cdf0e10cSrcweir                                                   data.getLength());
281cdf0e10cSrcweir                             OUString sData = ::rtl::OStringToOUString(
282cdf0e10cSrcweir                                 osData, RTL_TEXTENCODING_UTF8);
283cdf0e10cSrcweir                             if (!sData.equals(aUserName))
284cdf0e10cSrcweir                                 continue;
285cdf0e10cSrcweir                         }
286cdf0e10cSrcweir                     }
287cdf0e10cSrcweir                     // temp entry not needed anymore:
288cdf0e10cSrcweir                     erase_path( url + OUSTR("_"),
289cdf0e10cSrcweir                                 Reference<XCommandEnvironment>(),
290cdf0e10cSrcweir                                 false /* no throw: ignore errors */ );
291cdf0e10cSrcweir                     erase_path( url, Reference<XCommandEnvironment>(),
292cdf0e10cSrcweir                                 false /* no throw: ignore errors */ );
293cdf0e10cSrcweir                     //delete the xxx.tmpremoved file
294cdf0e10cSrcweir                     erase_path(url + OUSTR("removed"),
295cdf0e10cSrcweir                                Reference<XCommandEnvironment>(), false);
296cdf0e10cSrcweir                 }
297cdf0e10cSrcweir             }
298cdf0e10cSrcweir         }
299cdf0e10cSrcweir     }
300cdf0e10cSrcweir }
301cdf0e10cSrcweir 
302cdf0e10cSrcweir //______________________________________________________________________________
initRegistryBackends()303cdf0e10cSrcweir void PackageManagerImpl::initRegistryBackends()
304cdf0e10cSrcweir {
305cdf0e10cSrcweir     if (m_registryCache.getLength() > 0)
306cdf0e10cSrcweir         create_folder( 0, m_registryCache,
307cdf0e10cSrcweir                        Reference<XCommandEnvironment>(), false);
308cdf0e10cSrcweir     m_xRegistry.set( ::dp_registry::create(
309cdf0e10cSrcweir                          m_context, m_registryCache, false,
310cdf0e10cSrcweir                          m_xComponentContext ) );
311cdf0e10cSrcweir }
312cdf0e10cSrcweir 
313cdf0e10cSrcweir //______________________________________________________________________________
create(Reference<XComponentContext> const & xComponentContext,OUString const & context)314cdf0e10cSrcweir Reference<deployment::XPackageManager> PackageManagerImpl::create(
315cdf0e10cSrcweir     Reference<XComponentContext> const & xComponentContext,
316cdf0e10cSrcweir     OUString const & context )
317cdf0e10cSrcweir {
318cdf0e10cSrcweir     PackageManagerImpl * that = new PackageManagerImpl(
319cdf0e10cSrcweir         xComponentContext, context );
320cdf0e10cSrcweir     Reference<deployment::XPackageManager> xPackageManager( that );
321cdf0e10cSrcweir 
322cdf0e10cSrcweir     OUString packages, logFile, stampURL;
323cdf0e10cSrcweir     if (context.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("user") )) {
324cdf0e10cSrcweir         that->m_activePackages = OUSTR(
325cdf0e10cSrcweir             "vnd.sun.star.expand:$UNO_USER_PACKAGES_CACHE/uno_packages");
326cdf0e10cSrcweir         that->m_registrationData = OUSTR(
327cdf0e10cSrcweir             "vnd.sun.star.expand:$UNO_USER_PACKAGES_CACHE");
328cdf0e10cSrcweir         that->m_registryCache = OUSTR(
329cdf0e10cSrcweir             "vnd.sun.star.expand:$UNO_USER_PACKAGES_CACHE/registry");
330cdf0e10cSrcweir         logFile = OUSTR(
331cdf0e10cSrcweir             "vnd.sun.star.expand:$UNO_USER_PACKAGES_CACHE/log.txt");
332cdf0e10cSrcweir         //We use the extension .sys for the file because on Windows Vista a sys
333cdf0e10cSrcweir         //(as well as exe and dll) file
334cdf0e10cSrcweir         //will not be written in the VirtualStore. For example if the process has no
335cdf0e10cSrcweir         //admin right once cannot write to the %programfiles% folder. However, when
336cdf0e10cSrcweir         //virtualization is used, the file will be written into the VirtualStore and
337cdf0e10cSrcweir         //it appears as if one could write to %programfiles%. When we test for write
338cdf0e10cSrcweir         //access to the office/shared folder for shared extensions then this typically
339cdf0e10cSrcweir         //fails because a normal user typically cannot write to this folder. However,
340cdf0e10cSrcweir         //using virtualization it appears that he/she can. Then a shared extension can
341cdf0e10cSrcweir         //be installed but is only visible for the user (because the extension is in
342cdf0e10cSrcweir         //the virtual store).
343cdf0e10cSrcweir         stampURL = OUSTR(
344cdf0e10cSrcweir             "vnd.sun.star.expand:$UNO_USER_PACKAGES_CACHE/stamp.sys");
345cdf0e10cSrcweir     }
346cdf0e10cSrcweir     else if (context.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("shared") )) {
347cdf0e10cSrcweir         that->m_activePackages = OUSTR(
348cdf0e10cSrcweir             "vnd.sun.star.expand:$UNO_SHARED_PACKAGES_CACHE/uno_packages");
349cdf0e10cSrcweir         that->m_registrationData = OUSTR(
350cdf0e10cSrcweir             "vnd.sun.star.expand:$SHARED_EXTENSIONS_USER");
351cdf0e10cSrcweir         that->m_registryCache = OUSTR(
352cdf0e10cSrcweir             "vnd.sun.star.expand:$SHARED_EXTENSIONS_USER/registry");
353cdf0e10cSrcweir         logFile = OUSTR(
354cdf0e10cSrcweir             "vnd.sun.star.expand:$SHARED_EXTENSIONS_USER/log.txt");
355cdf0e10cSrcweir         stampURL = OUSTR(
356cdf0e10cSrcweir             "vnd.sun.star.expand:$UNO_SHARED_PACKAGES_CACHE/stamp.sys");
357cdf0e10cSrcweir     }
358cdf0e10cSrcweir     else if (context.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("bundled") )) {
359cdf0e10cSrcweir         that->m_activePackages = OUSTR(
360cdf0e10cSrcweir             "vnd.sun.star.expand:$BUNDLED_EXTENSIONS");
361cdf0e10cSrcweir         that->m_registrationData = OUSTR(
362cdf0e10cSrcweir             "vnd.sun.star.expand:$BUNDLED_EXTENSIONS_USER");
363cdf0e10cSrcweir         that->m_registryCache = OUSTR(
364cdf0e10cSrcweir             "vnd.sun.star.expand:$BUNDLED_EXTENSIONS_USER/registry");
365cdf0e10cSrcweir         logFile = OUSTR(
366cdf0e10cSrcweir             "vnd.sun.star.expand:$BUNDLED_EXTENSIONS_USER/log.txt");
367cdf0e10cSrcweir         //No stamp file. We assume that bundled is always readonly. It must not be
368cdf0e10cSrcweir         //modified from ExtensionManager but only by the installer
369cdf0e10cSrcweir     }
370cdf0e10cSrcweir     else if (context.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("bundled_prereg") )) {
371cdf0e10cSrcweir         //This is a bundled repository but the registration data
372cdf0e10cSrcweir         //is in the brand layer: share/prereg
373cdf0e10cSrcweir         //It is special because the registration data are copied at the first startup
374cdf0e10cSrcweir         //into the user installation. The processed help and xcu files are not
375cdf0e10cSrcweir         //copied. Instead the backenddb.xml for the help backend references the help
376cdf0e10cSrcweir         //by using $BUNDLED_EXTENSION_PREREG instead $BUNDLED_EXTENSIONS_USER. The
377cdf0e10cSrcweir         //configmgr.ini also used $BUNDLED_EXTENSIONS_PREREG to refer to the xcu file
378cdf0e10cSrcweir         //which contain the replacement for %origin%.
379cdf0e10cSrcweir         that->m_activePackages = OUSTR(
380*c6dedb65SAndre Fischer             "vnd.sun.star.expand:$BUNDLED_EXTENSIONS_PREREG");
381cdf0e10cSrcweir         that->m_registrationData = OUSTR(
382cdf0e10cSrcweir             "vnd.sun.star.expand:$BUNDLED_EXTENSIONS_PREREG");
383cdf0e10cSrcweir         that->m_registryCache = OUSTR(
384cdf0e10cSrcweir             "vnd.sun.star.expand:$BUNDLED_EXTENSIONS_PREREG/registry");
385cdf0e10cSrcweir         logFile = OUSTR(
386cdf0e10cSrcweir             "vnd.sun.star.expand:$BUNDLED_EXTENSIONS_PREREG/log.txt");
387cdf0e10cSrcweir     }
388cdf0e10cSrcweir     else if (context.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("tmp") )) {
389cdf0e10cSrcweir         that->m_activePackages = OUSTR(
390cdf0e10cSrcweir             "vnd.sun.star.expand:$TMP_EXTENSIONS/extensions");
391cdf0e10cSrcweir         that->m_registrationData = OUSTR(
392cdf0e10cSrcweir             "vnd.sun.star.expand:$TMP_EXTENSIONS");
393cdf0e10cSrcweir         that->m_registryCache = OUSTR(
394cdf0e10cSrcweir             "vnd.sun.star.expand:$TMP_EXTENSIONS/registry");
395cdf0e10cSrcweir         stampURL = OUSTR(
396cdf0e10cSrcweir             "vnd.sun.star.expand:$TMP_EXTENSIONS/stamp.sys");
397cdf0e10cSrcweir     }
3987bc7b19fSMichael Stahl     else if (context.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("bak") )) {
3997bc7b19fSMichael Stahl         that->m_activePackages = OUSTR(
4007bc7b19fSMichael Stahl             "vnd.sun.star.expand:$BAK_EXTENSIONS/extensions");
4017bc7b19fSMichael Stahl         that->m_registrationData = OUSTR(
4027bc7b19fSMichael Stahl             "vnd.sun.star.expand:$BAK_EXTENSIONS");
4037bc7b19fSMichael Stahl         that->m_registryCache = OUSTR(
4047bc7b19fSMichael Stahl             "vnd.sun.star.expand:$BAK_EXTENSIONS/registry");
4057bc7b19fSMichael Stahl         stampURL = OUSTR(
4067bc7b19fSMichael Stahl             "vnd.sun.star.expand:$BAK_EXTENSIONS/stamp.sys");
4077bc7b19fSMichael Stahl     }
4087bc7b19fSMichael Stahl 
409cdf0e10cSrcweir     else if (! context.matchAsciiL(
410cdf0e10cSrcweir                  RTL_CONSTASCII_STRINGPARAM("vnd.sun.star.tdoc:/") )) {
411cdf0e10cSrcweir         throw lang::IllegalArgumentException(
412cdf0e10cSrcweir             OUSTR("invalid context given: ") + context,
413cdf0e10cSrcweir             Reference<XInterface>(), static_cast<sal_Int16>(-1) );
414cdf0e10cSrcweir     }
415cdf0e10cSrcweir 
416cdf0e10cSrcweir     Reference<XCommandEnvironment> xCmdEnv;
417cdf0e10cSrcweir 
418cdf0e10cSrcweir     try {
419cdf0e10cSrcweir         //There is no stampURL for the bundled folder
420cdf0e10cSrcweir         if (stampURL.getLength() > 0)
421cdf0e10cSrcweir         {
422cdf0e10cSrcweir #define CURRENT_STAMP "1"
423cdf0e10cSrcweir             try {
424cdf0e10cSrcweir                 //The osl file API does not allow to find out if one can write
425cdf0e10cSrcweir                 //into a folder. Therefore we try to write a file. Then we delete
426cdf0e10cSrcweir                 //it, so that it does not hinder uninstallation of OOo
427cdf0e10cSrcweir                 // probe writing:
428cdf0e10cSrcweir                 ::ucbhelper::Content ucbStamp( stampURL, xCmdEnv );
429cdf0e10cSrcweir                 ::rtl::OString stamp(
430cdf0e10cSrcweir                     RTL_CONSTASCII_STRINGPARAM(CURRENT_STAMP) );
431cdf0e10cSrcweir                 Reference<io::XInputStream> xData(
432cdf0e10cSrcweir                     ::xmlscript::createInputStream(
433cdf0e10cSrcweir                         ::rtl::ByteSequence(
434cdf0e10cSrcweir                             reinterpret_cast<sal_Int8 const *>(stamp.getStr()),
435cdf0e10cSrcweir                             stamp.getLength() ) ) );
436cdf0e10cSrcweir                 ucbStamp.writeStream( xData, true /* replace existing */ );
437cdf0e10cSrcweir                 that->m_readOnly = false;
438cdf0e10cSrcweir                 erase_path( stampURL, xCmdEnv );
439cdf0e10cSrcweir             }
440cdf0e10cSrcweir             catch (RuntimeException &) {
441cdf0e10cSrcweir                 try {
442cdf0e10cSrcweir                     erase_path( stampURL, xCmdEnv );
443cdf0e10cSrcweir                 } catch (...)
444cdf0e10cSrcweir                 {
445cdf0e10cSrcweir                 }
446cdf0e10cSrcweir                 throw;
447cdf0e10cSrcweir             }
448cdf0e10cSrcweir             catch (Exception &) {
449cdf0e10cSrcweir                 that->m_readOnly = true;
450cdf0e10cSrcweir             }
451cdf0e10cSrcweir         }
452cdf0e10cSrcweir 
453cdf0e10cSrcweir         if (!that->m_readOnly && logFile.getLength() > 0)
454cdf0e10cSrcweir         {
455cdf0e10cSrcweir             const Any any_logFile(logFile);
456cdf0e10cSrcweir             that->m_xLogFile.set(
457cdf0e10cSrcweir                 that->m_xComponentContext->getServiceManager()
458cdf0e10cSrcweir                 ->createInstanceWithArgumentsAndContext(
459cdf0e10cSrcweir                     dp_log::serviceDecl.getSupportedServiceNames()[0],
460cdf0e10cSrcweir                     Sequence<Any>( &any_logFile, 1 ),
461cdf0e10cSrcweir                     that->m_xComponentContext ),
462cdf0e10cSrcweir                 UNO_QUERY_THROW );
463cdf0e10cSrcweir             xCmdEnv.set( new CmdEnvWrapperImpl( xCmdEnv, that->m_xLogFile ) );
464cdf0e10cSrcweir         }
465cdf0e10cSrcweir 
466cdf0e10cSrcweir         that->initRegistryBackends();
467cdf0e10cSrcweir         that->initActivationLayer( xCmdEnv );
468cdf0e10cSrcweir 
469cdf0e10cSrcweir         return xPackageManager;
470cdf0e10cSrcweir 
471cdf0e10cSrcweir     }
472cdf0e10cSrcweir     catch (RuntimeException &) {
473cdf0e10cSrcweir         throw;
474cdf0e10cSrcweir     }
475cdf0e10cSrcweir     catch (Exception &) {
476cdf0e10cSrcweir         Any exc( ::cppu::getCaughtException() );
477cdf0e10cSrcweir         ::rtl::OUStringBuffer buf;
478cdf0e10cSrcweir         buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[context=\"") );
479cdf0e10cSrcweir         buf.append( context );
480cdf0e10cSrcweir         buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
481cdf0e10cSrcweir                              "\"] caught unexpected exception!") );
482cdf0e10cSrcweir         throw lang::WrappedTargetRuntimeException(
483cdf0e10cSrcweir             buf.makeStringAndClear(), Reference<XInterface>(), exc );
484cdf0e10cSrcweir     }
485cdf0e10cSrcweir }
486cdf0e10cSrcweir 
487cdf0e10cSrcweir //______________________________________________________________________________
~PackageManagerImpl()488cdf0e10cSrcweir PackageManagerImpl::~PackageManagerImpl()
489cdf0e10cSrcweir {
490cdf0e10cSrcweir }
491cdf0e10cSrcweir 
492cdf0e10cSrcweir //______________________________________________________________________________
fireModified()493cdf0e10cSrcweir void PackageManagerImpl::fireModified()
494cdf0e10cSrcweir {
495cdf0e10cSrcweir     ::cppu::OInterfaceContainerHelper * pContainer = rBHelper.getContainer(
496cdf0e10cSrcweir         util::XModifyListener::static_type() );
497cdf0e10cSrcweir     if (pContainer != 0) {
498cdf0e10cSrcweir         pContainer->forEach<util::XModifyListener>(
499cdf0e10cSrcweir             boost::bind(&util::XModifyListener::modified, _1,
500cdf0e10cSrcweir                         lang::EventObject(static_cast<OWeakObject *>(this))) );
501cdf0e10cSrcweir     }
502cdf0e10cSrcweir }
503cdf0e10cSrcweir 
504cdf0e10cSrcweir //______________________________________________________________________________
disposing()505cdf0e10cSrcweir void PackageManagerImpl::disposing()
506cdf0e10cSrcweir {
507cdf0e10cSrcweir     try {
508cdf0e10cSrcweir //     // xxx todo: guarding?
509cdf0e10cSrcweir //     ::osl::MutexGuard guard( getMutex() );
510cdf0e10cSrcweir         try_dispose( m_xLogFile );
511cdf0e10cSrcweir         m_xLogFile.clear();
512cdf0e10cSrcweir         try_dispose( m_xRegistry );
513cdf0e10cSrcweir         m_xRegistry.clear();
514cdf0e10cSrcweir         m_activePackagesDB.reset(0);
515cdf0e10cSrcweir         m_xComponentContext.clear();
516cdf0e10cSrcweir 
517cdf0e10cSrcweir         t_pm_helper::disposing();
518cdf0e10cSrcweir 
519cdf0e10cSrcweir     }
520cdf0e10cSrcweir     catch (RuntimeException &) {
521cdf0e10cSrcweir         throw;
522cdf0e10cSrcweir     }
523cdf0e10cSrcweir     catch (Exception &) {
524cdf0e10cSrcweir         Any exc( ::cppu::getCaughtException() );
525cdf0e10cSrcweir         throw lang::WrappedTargetRuntimeException(
526cdf0e10cSrcweir             OUSTR("caught unexpected exception while disposing..."),
527cdf0e10cSrcweir             static_cast<OWeakObject *>(this), exc );
528cdf0e10cSrcweir     }
529cdf0e10cSrcweir }
530cdf0e10cSrcweir 
531cdf0e10cSrcweir // XComponent
532cdf0e10cSrcweir //______________________________________________________________________________
dispose()533cdf0e10cSrcweir void PackageManagerImpl::dispose() throw (RuntimeException)
534cdf0e10cSrcweir {
5358402cd44SMichael Stahl     //Do not call check here. We must not throw an exception here if the object
5368402cd44SMichael Stahl     //is being disposed or is already disposed. See com.sun.star.lang.XComponent
537cdf0e10cSrcweir     WeakComponentImplHelperBase::dispose();
538cdf0e10cSrcweir }
539cdf0e10cSrcweir 
540cdf0e10cSrcweir //______________________________________________________________________________
addEventListener(Reference<lang::XEventListener> const & xListener)541cdf0e10cSrcweir void PackageManagerImpl::addEventListener(
542cdf0e10cSrcweir     Reference<lang::XEventListener> const & xListener ) throw (RuntimeException)
543cdf0e10cSrcweir {
5448402cd44SMichael Stahl     //Do not call check here. We must not throw an exception here if the object
5458402cd44SMichael Stahl     //is being disposed or is already disposed. See com.sun.star.lang.XComponent
546cdf0e10cSrcweir     WeakComponentImplHelperBase::addEventListener( xListener );
547cdf0e10cSrcweir }
548cdf0e10cSrcweir 
549cdf0e10cSrcweir //______________________________________________________________________________
removeEventListener(Reference<lang::XEventListener> const & xListener)550cdf0e10cSrcweir void PackageManagerImpl::removeEventListener(
551cdf0e10cSrcweir     Reference<lang::XEventListener> const & xListener ) throw (RuntimeException)
552cdf0e10cSrcweir {
5538402cd44SMichael Stahl     //Do not call check here. We must not throw an exception here if the object
5548402cd44SMichael Stahl     //is being disposed or is already disposed. See com.sun.star.lang.XComponent
555cdf0e10cSrcweir     WeakComponentImplHelperBase::removeEventListener( xListener );
556cdf0e10cSrcweir }
557cdf0e10cSrcweir 
558cdf0e10cSrcweir // XPackageManager
559cdf0e10cSrcweir //______________________________________________________________________________
getContext()560cdf0e10cSrcweir OUString PackageManagerImpl::getContext() throw (RuntimeException)
561cdf0e10cSrcweir {
562cdf0e10cSrcweir     check();
563cdf0e10cSrcweir     return m_context;
564cdf0e10cSrcweir }
565cdf0e10cSrcweir 
566cdf0e10cSrcweir //______________________________________________________________________________
567cdf0e10cSrcweir Sequence< Reference<deployment::XPackageTypeInfo> >
getSupportedPackageTypes()568cdf0e10cSrcweir PackageManagerImpl::getSupportedPackageTypes() throw (RuntimeException)
569cdf0e10cSrcweir {
570cdf0e10cSrcweir     OSL_ASSERT( m_xRegistry.is() );
571cdf0e10cSrcweir     return m_xRegistry->getSupportedPackageTypes();
572cdf0e10cSrcweir }
573cdf0e10cSrcweir 
574cdf0e10cSrcweir //______________________________________________________________________________
createAbortChannel()575cdf0e10cSrcweir Reference<task::XAbortChannel> PackageManagerImpl::createAbortChannel()
576cdf0e10cSrcweir     throw (RuntimeException)
577cdf0e10cSrcweir {
578cdf0e10cSrcweir     check();
579cdf0e10cSrcweir     return new AbortChannel;
580cdf0e10cSrcweir }
581cdf0e10cSrcweir 
582cdf0e10cSrcweir // XModifyBroadcaster
583cdf0e10cSrcweir //______________________________________________________________________________
addModifyListener(Reference<util::XModifyListener> const & xListener)584cdf0e10cSrcweir void PackageManagerImpl::addModifyListener(
585cdf0e10cSrcweir     Reference<util::XModifyListener> const & xListener )
586cdf0e10cSrcweir     throw (RuntimeException)
587cdf0e10cSrcweir {
588cdf0e10cSrcweir     check();
589cdf0e10cSrcweir     rBHelper.addListener( ::getCppuType( &xListener ), xListener );
590cdf0e10cSrcweir }
591cdf0e10cSrcweir 
592cdf0e10cSrcweir //______________________________________________________________________________
removeModifyListener(Reference<util::XModifyListener> const & xListener)593cdf0e10cSrcweir void PackageManagerImpl::removeModifyListener(
594cdf0e10cSrcweir     Reference<util::XModifyListener> const & xListener )
595cdf0e10cSrcweir     throw (RuntimeException)
596cdf0e10cSrcweir {
597cdf0e10cSrcweir     check();
598cdf0e10cSrcweir     rBHelper.removeListener( ::getCppuType( &xListener ), xListener );
599cdf0e10cSrcweir }
600cdf0e10cSrcweir 
601cdf0e10cSrcweir //______________________________________________________________________________
detectMediaType(::ucbhelper::Content const & ucbContent_,bool throw_exc)602cdf0e10cSrcweir OUString PackageManagerImpl::detectMediaType(
603cdf0e10cSrcweir     ::ucbhelper::Content const & ucbContent_, bool throw_exc )
604cdf0e10cSrcweir {
605cdf0e10cSrcweir     ::ucbhelper::Content ucbContent(ucbContent_);
606cdf0e10cSrcweir     OUString url( ucbContent.getURL() );
607cdf0e10cSrcweir     OUString mediaType;
608cdf0e10cSrcweir     if (url.matchAsciiL( RTL_CONSTASCII_STRINGPARAM("vnd.sun.star.tdoc:") ) ||
609cdf0e10cSrcweir         url.matchAsciiL( RTL_CONSTASCII_STRINGPARAM("vnd.sun.star.pkg:") ))
610cdf0e10cSrcweir     {
611cdf0e10cSrcweir         try {
612cdf0e10cSrcweir             ucbContent.getPropertyValue( OUSTR("MediaType") ) >>= mediaType;
613cdf0e10cSrcweir         }
614cdf0e10cSrcweir         catch (beans::UnknownPropertyException &) {
615cdf0e10cSrcweir         }
616cdf0e10cSrcweir         OSL_ENSURE( mediaType.getLength() > 0, "### no media-type?!" );
617cdf0e10cSrcweir     }
618cdf0e10cSrcweir     if (mediaType.getLength() == 0)
619cdf0e10cSrcweir     {
620cdf0e10cSrcweir         try {
621cdf0e10cSrcweir             Reference<deployment::XPackage> xPackage(
622cdf0e10cSrcweir                 m_xRegistry->bindPackage(
623cdf0e10cSrcweir                     url, OUString(), false, OUString(), ucbContent.getCommandEnvironment() ) );
624cdf0e10cSrcweir             const Reference<deployment::XPackageTypeInfo> xPackageType(
625cdf0e10cSrcweir                 xPackage->getPackageType() );
626cdf0e10cSrcweir             OSL_ASSERT( xPackageType.is() );
627cdf0e10cSrcweir             if (xPackageType.is())
628cdf0e10cSrcweir                 mediaType = xPackageType->getMediaType();
629cdf0e10cSrcweir         }
630cdf0e10cSrcweir         catch (lang::IllegalArgumentException & exc) {
631cdf0e10cSrcweir             if (throw_exc)
632cdf0e10cSrcweir                 throw;
633cdf0e10cSrcweir             (void) exc;
634cdf0e10cSrcweir             OSL_ENSURE( 0, ::rtl::OUStringToOString(
635cdf0e10cSrcweir                             exc.Message, RTL_TEXTENCODING_UTF8 ).getStr() );
636cdf0e10cSrcweir         }
637cdf0e10cSrcweir     }
638cdf0e10cSrcweir     return mediaType;
639cdf0e10cSrcweir }
640cdf0e10cSrcweir 
641cdf0e10cSrcweir //______________________________________________________________________________
insertToActivationLayer(Sequence<beans::NamedValue> const & properties,OUString const & mediaType,::ucbhelper::Content const & sourceContent_,OUString const & title,ActivePackages::Data * dbData)642cdf0e10cSrcweir OUString PackageManagerImpl::insertToActivationLayer(
643cdf0e10cSrcweir     Sequence<beans::NamedValue> const & properties,
644cdf0e10cSrcweir     OUString const & mediaType, ::ucbhelper::Content const & sourceContent_,
645cdf0e10cSrcweir     OUString const & title, ActivePackages::Data * dbData )
646cdf0e10cSrcweir {
647cdf0e10cSrcweir     ::ucbhelper::Content sourceContent(sourceContent_);
648cdf0e10cSrcweir     Reference<XCommandEnvironment> xCmdEnv(
649cdf0e10cSrcweir         sourceContent.getCommandEnvironment() );
650cdf0e10cSrcweir 
651cdf0e10cSrcweir     String baseDir(m_activePackages_expanded);
652cdf0e10cSrcweir     ::utl::TempFile aTemp(&baseDir, sal_False);
653cdf0e10cSrcweir     OUString tempEntry = aTemp.GetURL();
654cdf0e10cSrcweir     tempEntry = tempEntry.copy(tempEntry.lastIndexOf('/') + 1);
655cdf0e10cSrcweir     OUString destFolder = makeURL( m_activePackages, tempEntry);
656cdf0e10cSrcweir     destFolder += OUSTR("_");
657cdf0e10cSrcweir 
658cdf0e10cSrcweir     // prepare activation folder:
659cdf0e10cSrcweir     ::ucbhelper::Content destFolderContent;
660cdf0e10cSrcweir     create_folder( &destFolderContent, destFolder, xCmdEnv );
661cdf0e10cSrcweir 
662cdf0e10cSrcweir     // copy content into activation temp dir:
663cdf0e10cSrcweir     if (mediaType.matchIgnoreAsciiCaseAsciiL(
664cdf0e10cSrcweir             RTL_CONSTASCII_STRINGPARAM(
665cdf0e10cSrcweir                 "application/vnd.sun.star.package-bundle") ) ||
666cdf0e10cSrcweir         // xxx todo: more sophisticated parsing
667cdf0e10cSrcweir         mediaType.matchIgnoreAsciiCaseAsciiL(
668cdf0e10cSrcweir             RTL_CONSTASCII_STRINGPARAM(
669cdf0e10cSrcweir                 "application/vnd.sun.star.legacy-package-bundle") ))
670cdf0e10cSrcweir     {
671cdf0e10cSrcweir         // inflate content:
672cdf0e10cSrcweir         ::rtl::OUStringBuffer buf;
673cdf0e10cSrcweir         if (!sourceContent.isFolder())
674cdf0e10cSrcweir         {
675cdf0e10cSrcweir             buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("vnd.sun.star.zip://") );
676cdf0e10cSrcweir             buf.append( ::rtl::Uri::encode( sourceContent.getURL(),
677cdf0e10cSrcweir                                             rtl_UriCharClassRegName,
678cdf0e10cSrcweir                                             rtl_UriEncodeIgnoreEscapes,
679cdf0e10cSrcweir                                             RTL_TEXTENCODING_UTF8 ) );
680cdf0e10cSrcweir         }
681cdf0e10cSrcweir         else
682cdf0e10cSrcweir         {
683cdf0e10cSrcweir             //Folder. No need to unzip, just copy
684cdf0e10cSrcweir             buf.append(sourceContent.getURL());
685cdf0e10cSrcweir         }
686cdf0e10cSrcweir         buf.append( static_cast<sal_Unicode>('/') );
687cdf0e10cSrcweir         sourceContent = ::ucbhelper::Content(
688cdf0e10cSrcweir             buf.makeStringAndClear(), xCmdEnv );
689cdf0e10cSrcweir     }
690cdf0e10cSrcweir     if (! destFolderContent.transferContent(
691cdf0e10cSrcweir             sourceContent, ::ucbhelper::InsertOperation_COPY,
692cdf0e10cSrcweir             title, NameClash::OVERWRITE ))
693cdf0e10cSrcweir         throw RuntimeException( OUSTR("UCB transferContent() failed!"), 0 );
694cdf0e10cSrcweir 
695cdf0e10cSrcweir 
696cdf0e10cSrcweir     // write to DB:
697cdf0e10cSrcweir     //bundled extensions should only be added by the synchronizeAddedExtensions
698cdf0e10cSrcweir     //functions. Moreover, there is no "temporary folder" for bundled extensions.
699cdf0e10cSrcweir     OSL_ASSERT(!m_context.equals(OUSTR("bundled")));
700cdf0e10cSrcweir     OUString sFolderUrl = makeURLAppendSysPathSegment(destFolderContent.getURL(), title);
701cdf0e10cSrcweir     DescriptionInfoset info =
702cdf0e10cSrcweir         dp_misc::getDescriptionInfoset(sFolderUrl);
703cdf0e10cSrcweir     dbData->temporaryName = tempEntry;
704cdf0e10cSrcweir     dbData->fileName = title;
705cdf0e10cSrcweir     dbData->mediaType = mediaType;
706cdf0e10cSrcweir     dbData->version = info.getVersion();
707cdf0e10cSrcweir 
708cdf0e10cSrcweir     //No write the properties file next to the extension
709cdf0e10cSrcweir     ExtensionProperties props(sFolderUrl, properties, xCmdEnv);
710cdf0e10cSrcweir     props.write();
711cdf0e10cSrcweir     return destFolder;
712cdf0e10cSrcweir }
713cdf0e10cSrcweir 
714cdf0e10cSrcweir //______________________________________________________________________________
insertToActivationLayerDB(OUString const & id,ActivePackages::Data const & dbData)715cdf0e10cSrcweir void PackageManagerImpl::insertToActivationLayerDB(
716cdf0e10cSrcweir     OUString const & id, ActivePackages::Data const & dbData )
717cdf0e10cSrcweir {
718cdf0e10cSrcweir     //access to the database must be guarded. See removePackage
719cdf0e10cSrcweir     const ::osl::MutexGuard guard( getMutex() );
720cdf0e10cSrcweir     m_activePackagesDB->put( id, dbData );
721cdf0e10cSrcweir }
722cdf0e10cSrcweir 
723cdf0e10cSrcweir //______________________________________________________________________________
724cdf0e10cSrcweir /* The function returns true if there is an extension with the same id already
725cdf0e10cSrcweir     installed which needs to be uninstalled, before the new extension can be installed.
726cdf0e10cSrcweir */
isInstalled(Reference<deployment::XPackage> const & package)727cdf0e10cSrcweir bool PackageManagerImpl::isInstalled(
728cdf0e10cSrcweir     Reference<deployment::XPackage> const & package)
729cdf0e10cSrcweir {
730cdf0e10cSrcweir     OUString id(dp_misc::getIdentifier(package));
731cdf0e10cSrcweir     OUString fn(package->getName());
732cdf0e10cSrcweir     bool bInstalled = false;
733cdf0e10cSrcweir     if (m_activePackagesDB->has( id, fn ))
734cdf0e10cSrcweir     {
735cdf0e10cSrcweir         bInstalled = true;
736cdf0e10cSrcweir     }
737cdf0e10cSrcweir     return bInstalled;
738cdf0e10cSrcweir }
739cdf0e10cSrcweir 
740cdf0e10cSrcweir // XPackageManager
741cdf0e10cSrcweir //______________________________________________________________________________
importExtension(Reference<deployment::XPackage> const & extension,Reference<task::XAbortChannel> const & xAbortChannel,Reference<XCommandEnvironment> const & xCmdEnv_)742cdf0e10cSrcweir Reference<deployment::XPackage> PackageManagerImpl::importExtension(
743cdf0e10cSrcweir     Reference<deployment::XPackage> const & extension,
744cdf0e10cSrcweir     Reference<task::XAbortChannel> const & xAbortChannel,
745cdf0e10cSrcweir     Reference<XCommandEnvironment> const & xCmdEnv_ )
746cdf0e10cSrcweir     throw (deployment::DeploymentException, CommandFailedException,
747cdf0e10cSrcweir            CommandAbortedException, lang::IllegalArgumentException,
748cdf0e10cSrcweir            RuntimeException)
749cdf0e10cSrcweir {
750cdf0e10cSrcweir     return addPackage(extension->getURL(), Sequence<beans::NamedValue>(),
751cdf0e10cSrcweir                       OUString(), xAbortChannel, xCmdEnv_);
752cdf0e10cSrcweir }
753cdf0e10cSrcweir 
754cdf0e10cSrcweir /* The function adds an extension but does not register it!!!
755cdf0e10cSrcweir     It may not do any user interaction. This is done in XExtensionManager::addExtension
756cdf0e10cSrcweir */
addPackage(OUString const & url,css::uno::Sequence<css::beans::NamedValue> const & properties,OUString const & mediaType_,Reference<task::XAbortChannel> const & xAbortChannel,Reference<XCommandEnvironment> const & xCmdEnv_)757cdf0e10cSrcweir Reference<deployment::XPackage> PackageManagerImpl::addPackage(
758cdf0e10cSrcweir     OUString const & url,
759cdf0e10cSrcweir     css::uno::Sequence<css::beans::NamedValue> const & properties,
760cdf0e10cSrcweir     OUString const & mediaType_,
761cdf0e10cSrcweir     Reference<task::XAbortChannel> const & xAbortChannel,
762cdf0e10cSrcweir     Reference<XCommandEnvironment> const & xCmdEnv_ )
763cdf0e10cSrcweir     throw (deployment::DeploymentException, CommandFailedException,
764cdf0e10cSrcweir            CommandAbortedException, lang::IllegalArgumentException,
765cdf0e10cSrcweir            RuntimeException)
766cdf0e10cSrcweir {
767cdf0e10cSrcweir     check();
768cdf0e10cSrcweir     if (m_readOnly)
769cdf0e10cSrcweir 	{
770cdf0e10cSrcweir 		OUString message;
771cdf0e10cSrcweir 		if (m_context == OUSTR("shared"))
772cdf0e10cSrcweir 			message = OUSTR("You need write permissions to install a shared extension!");
773cdf0e10cSrcweir 		else
774cdf0e10cSrcweir 			message = OUSTR("You need write permissions to install this extension!");
775cdf0e10cSrcweir         throw deployment::DeploymentException(
776cdf0e10cSrcweir             message, static_cast<OWeakObject *>(this), Any() );
777cdf0e10cSrcweir 	}
778cdf0e10cSrcweir     Reference<XCommandEnvironment> xCmdEnv;
779cdf0e10cSrcweir     if (m_xLogFile.is())
780cdf0e10cSrcweir         xCmdEnv.set( new CmdEnvWrapperImpl( xCmdEnv_, m_xLogFile ) );
781cdf0e10cSrcweir     else
782cdf0e10cSrcweir         xCmdEnv.set( xCmdEnv_ );
783cdf0e10cSrcweir 
784cdf0e10cSrcweir     try {
785cdf0e10cSrcweir         ::ucbhelper::Content sourceContent;
786cdf0e10cSrcweir         create_ucb_content( &sourceContent, url, xCmdEnv ); // throws exc
787cdf0e10cSrcweir         const OUString title(sourceContent.getPropertyValue(
788cdf0e10cSrcweir                              StrTitle::get() ).get<OUString>() );
789cdf0e10cSrcweir         const OUString title_enc( ::rtl::Uri::encode(
790cdf0e10cSrcweir                                       title, rtl_UriCharClassPchar,
791cdf0e10cSrcweir                                       rtl_UriEncodeIgnoreEscapes,
792cdf0e10cSrcweir                                       RTL_TEXTENCODING_UTF8 ) );
793cdf0e10cSrcweir         OUString destFolder;
794cdf0e10cSrcweir 
795cdf0e10cSrcweir         OUString mediaType(mediaType_);
796cdf0e10cSrcweir         if (mediaType.getLength() == 0)
797cdf0e10cSrcweir             mediaType = detectMediaType( sourceContent );
798cdf0e10cSrcweir 
799cdf0e10cSrcweir         Reference<deployment::XPackage> xPackage;
800cdf0e10cSrcweir         // copy file:
801cdf0e10cSrcweir         progressUpdate(
802cdf0e10cSrcweir             getResourceString(RID_STR_COPYING_PACKAGE) + title, xCmdEnv );
803cdf0e10cSrcweir         if (m_activePackages.getLength() == 0)
804cdf0e10cSrcweir         {
805cdf0e10cSrcweir             ::ucbhelper::Content docFolderContent;
806cdf0e10cSrcweir             create_folder( &docFolderContent, m_context, xCmdEnv );
807cdf0e10cSrcweir             // copy into document, first:
808cdf0e10cSrcweir             if (! docFolderContent.transferContent(
809cdf0e10cSrcweir                     sourceContent, ::ucbhelper::InsertOperation_COPY,
810cdf0e10cSrcweir                     OUString(),
811cdf0e10cSrcweir                     NameClash::ASK /* xxx todo: ASK not needed? */))
812cdf0e10cSrcweir                 throw RuntimeException(
813cdf0e10cSrcweir                     OUSTR("UCB transferContent() failed!"), 0 );
814cdf0e10cSrcweir             // set media-type:
815cdf0e10cSrcweir             ::ucbhelper::Content docContent(
816cdf0e10cSrcweir                 makeURL( m_context, title_enc ), xCmdEnv );
817cdf0e10cSrcweir                 //TODO #i73136#: using title instead of id can lead to
818cdf0e10cSrcweir                 // clashes, but the whole m_activePackages.getLength()==0
819cdf0e10cSrcweir                 // case (i.e., document-relative deployment) currently does
820cdf0e10cSrcweir                 // not work, anyway.
821cdf0e10cSrcweir             docContent.setPropertyValue(
822cdf0e10cSrcweir                 OUSTR("MediaType"), Any(mediaType) );
823cdf0e10cSrcweir 
824cdf0e10cSrcweir             // xxx todo: obsolete in the future
825cdf0e10cSrcweir             try {
826cdf0e10cSrcweir                 docFolderContent.executeCommand( OUSTR("flush"), Any() );
827cdf0e10cSrcweir             }
828cdf0e10cSrcweir             catch (UnsupportedCommandException &) {
829cdf0e10cSrcweir             }
830cdf0e10cSrcweir         }
831cdf0e10cSrcweir         ActivePackages::Data dbData;
832cdf0e10cSrcweir         destFolder = insertToActivationLayer(
833cdf0e10cSrcweir             properties, mediaType, sourceContent, title, &dbData );
834cdf0e10cSrcweir 
835cdf0e10cSrcweir 
836cdf0e10cSrcweir         // bind activation package:
837cdf0e10cSrcweir         //Because every shared/user extension will be unpacked in a folder,
838cdf0e10cSrcweir         //which was created with a unique name we will always have two different
839cdf0e10cSrcweir         //XPackage objects, even if the second extension is the same.
840cdf0e10cSrcweir         //Therefore bindPackage does not need a guard here.
841cdf0e10cSrcweir         xPackage = m_xRegistry->bindPackage(
842cdf0e10cSrcweir             makeURL( destFolder, title_enc ), mediaType, false, OUString(), xCmdEnv );
843cdf0e10cSrcweir 
844cdf0e10cSrcweir         OSL_ASSERT( xPackage.is() );
845cdf0e10cSrcweir         if (xPackage.is())
846cdf0e10cSrcweir         {
847cdf0e10cSrcweir             bool install = false;
848cdf0e10cSrcweir             try
849cdf0e10cSrcweir             {
850cdf0e10cSrcweir                 OUString const id = dp_misc::getIdentifier( xPackage );
851cdf0e10cSrcweir 
852cdf0e10cSrcweir                 ::osl::MutexGuard g(m_addMutex);
853cdf0e10cSrcweir                 if (isInstalled(xPackage))
854cdf0e10cSrcweir                 {
855cdf0e10cSrcweir                     //Do not guard the complete function with the getMutex
856cdf0e10cSrcweir                     removePackage(id, xPackage->getName(), xAbortChannel,
857cdf0e10cSrcweir                                   xCmdEnv);
858cdf0e10cSrcweir                 }
859cdf0e10cSrcweir                 install = true;
860cdf0e10cSrcweir                 insertToActivationLayerDB(id, dbData);
861cdf0e10cSrcweir             }
862cdf0e10cSrcweir             catch (...)
863cdf0e10cSrcweir             {
864cdf0e10cSrcweir                 deletePackageFromCache( xPackage, destFolder );
865cdf0e10cSrcweir                 throw;
866cdf0e10cSrcweir             }
867cdf0e10cSrcweir             if (!install)
868cdf0e10cSrcweir             {
869cdf0e10cSrcweir                 deletePackageFromCache( xPackage, destFolder );
870cdf0e10cSrcweir             }
871cdf0e10cSrcweir             //ToDo: We should notify only if the extension is registered
872cdf0e10cSrcweir             fireModified();
873cdf0e10cSrcweir         }
874cdf0e10cSrcweir         return xPackage;
875cdf0e10cSrcweir     }
876cdf0e10cSrcweir     catch (RuntimeException &) {
877cdf0e10cSrcweir         throw;
878cdf0e10cSrcweir     }
879cdf0e10cSrcweir     catch (CommandFailedException & exc) {
880cdf0e10cSrcweir         logIntern( Any(exc) );
881cdf0e10cSrcweir         throw;
882cdf0e10cSrcweir     }
883cdf0e10cSrcweir     catch (CommandAbortedException & exc) {
884cdf0e10cSrcweir         logIntern( Any(exc) );
885cdf0e10cSrcweir         throw;
886cdf0e10cSrcweir     }
887cdf0e10cSrcweir     catch (deployment::DeploymentException & exc) {
888cdf0e10cSrcweir         logIntern( Any(exc) );
889cdf0e10cSrcweir         throw;
890cdf0e10cSrcweir     }
891cdf0e10cSrcweir     catch (Exception &) {
892cdf0e10cSrcweir         Any exc( ::cppu::getCaughtException() );
893cdf0e10cSrcweir         logIntern( exc );
894cdf0e10cSrcweir         throw deployment::DeploymentException(
895cdf0e10cSrcweir             getResourceString(RID_STR_ERROR_WHILE_ADDING) + url,
896cdf0e10cSrcweir             static_cast<OWeakObject *>(this), exc );
897cdf0e10cSrcweir     }
898cdf0e10cSrcweir }
deletePackageFromCache(Reference<deployment::XPackage> const & xPackage,OUString const & destFolder)899cdf0e10cSrcweir void PackageManagerImpl::deletePackageFromCache(
900cdf0e10cSrcweir     Reference<deployment::XPackage> const & xPackage,
901cdf0e10cSrcweir     OUString const & destFolder)
902cdf0e10cSrcweir {
903cdf0e10cSrcweir     try_dispose( xPackage );
904cdf0e10cSrcweir 
905cdf0e10cSrcweir 	//we remove the package from the uno cache
906cdf0e10cSrcweir 	//no service from the package may be loaded at this time!!!
907cdf0e10cSrcweir 	erase_path( destFolder, Reference<XCommandEnvironment>(),
908cdf0e10cSrcweir         false /* no throw: ignore errors */ );
909cdf0e10cSrcweir 	//rm last character '_'
910cdf0e10cSrcweir 	OUString url = destFolder.copy(0, destFolder.getLength() - 1);
911cdf0e10cSrcweir 	erase_path( url, Reference<XCommandEnvironment>(),
912cdf0e10cSrcweir         false /* no throw: ignore errors */ );
913cdf0e10cSrcweir 
914cdf0e10cSrcweir }
915cdf0e10cSrcweir //______________________________________________________________________________
removePackage(OUString const & id,::rtl::OUString const & fileName,Reference<task::XAbortChannel> const &,Reference<XCommandEnvironment> const & xCmdEnv_)916cdf0e10cSrcweir void PackageManagerImpl::removePackage(
917cdf0e10cSrcweir     OUString const & id, ::rtl::OUString const & fileName,
918cdf0e10cSrcweir     Reference<task::XAbortChannel> const & /*xAbortChannel*/,
919cdf0e10cSrcweir     Reference<XCommandEnvironment> const & xCmdEnv_ )
920cdf0e10cSrcweir     throw (deployment::DeploymentException, CommandFailedException,
921cdf0e10cSrcweir            CommandAbortedException, lang::IllegalArgumentException,
922cdf0e10cSrcweir            RuntimeException)
923cdf0e10cSrcweir {
924cdf0e10cSrcweir     check();
925cdf0e10cSrcweir 
926cdf0e10cSrcweir     Reference<XCommandEnvironment> xCmdEnv;
927cdf0e10cSrcweir     if (m_xLogFile.is())
928cdf0e10cSrcweir         xCmdEnv.set( new CmdEnvWrapperImpl( xCmdEnv_, m_xLogFile ) );
929cdf0e10cSrcweir     else
930cdf0e10cSrcweir         xCmdEnv.set( xCmdEnv_ );
931cdf0e10cSrcweir 
932cdf0e10cSrcweir     try {
933cdf0e10cSrcweir         Reference<deployment::XPackage> xPackage;
934cdf0e10cSrcweir         {
935cdf0e10cSrcweir             const ::osl::MutexGuard guard(getMutex());
936cdf0e10cSrcweir             //Check if this extension exist and throw an IllegalArgumentException
937cdf0e10cSrcweir             //if it does not
938cdf0e10cSrcweir             //If the files of the extension are already removed, or there is a
939cdf0e10cSrcweir             //different extension at the same place, for example after updating the
940cdf0e10cSrcweir             //extension, then the returned object is that which uses the database data.
941cdf0e10cSrcweir             xPackage = getDeployedPackage_(id, fileName, xCmdEnv );
942cdf0e10cSrcweir 
943cdf0e10cSrcweir 
944cdf0e10cSrcweir             //Because the extension is only removed the next time the extension
945cdf0e10cSrcweir             //manager runs after restarting OOo, we need to indicate that a
946cdf0e10cSrcweir             //shared extension was "deleted". When a user starts OOo, then it
947cdf0e10cSrcweir             //will check if something changed in the shared repository. Based on
948cdf0e10cSrcweir             //the flag file it will then recognize, that the extension was
949cdf0e10cSrcweir             //deleted and can then update the extnesion database of the shared
950cdf0e10cSrcweir             //extensions in the user installation.
951cdf0e10cSrcweir             if ( xPackage.is() && !m_readOnly && !xPackage->isRemoved() && m_context.equals(OUSTR("shared")))
952cdf0e10cSrcweir             {
953cdf0e10cSrcweir                 ActivePackages::Data val;
954cdf0e10cSrcweir                 m_activePackagesDB->get( & val, id, fileName);
955cdf0e10cSrcweir                 OSL_ASSERT(val.temporaryName.getLength());
956cdf0e10cSrcweir                 OUString url(makeURL(m_activePackages_expanded,
957cdf0e10cSrcweir                                      val.temporaryName + OUSTR("removed")));
958cdf0e10cSrcweir                 ::ucbhelper::Content contentRemoved(url, xCmdEnv );
959cdf0e10cSrcweir                 OUString aUserName;
960cdf0e10cSrcweir                 ::osl::Security aSecurity;
961cdf0e10cSrcweir                 aSecurity.getUserName( aUserName );
962cdf0e10cSrcweir 
963cdf0e10cSrcweir                 ::rtl::OString stamp = ::rtl::OUStringToOString(aUserName, RTL_TEXTENCODING_UTF8);
964cdf0e10cSrcweir                 Reference<css::io::XInputStream> xData(
965cdf0e10cSrcweir                     ::xmlscript::createInputStream(
966cdf0e10cSrcweir                         ::rtl::ByteSequence(
967cdf0e10cSrcweir                             reinterpret_cast<sal_Int8 const *>(stamp.getStr()),
968cdf0e10cSrcweir                             stamp.getLength() ) ) );
969cdf0e10cSrcweir                 contentRemoved.writeStream( xData, true /* replace existing */ );
970cdf0e10cSrcweir             }
971cdf0e10cSrcweir             m_activePackagesDB->erase( id, fileName ); // to be removed upon next start
972cdf0e10cSrcweir             //remove any cached data hold by the backend
973cdf0e10cSrcweir             m_xRegistry->packageRemoved(xPackage->getURL(), xPackage->getPackageType()->getMediaType());
974cdf0e10cSrcweir         }
975cdf0e10cSrcweir         try_dispose( xPackage );
976cdf0e10cSrcweir 
977cdf0e10cSrcweir         fireModified();
978cdf0e10cSrcweir     }
979cdf0e10cSrcweir     catch (RuntimeException &) {
980cdf0e10cSrcweir         throw;
981cdf0e10cSrcweir     }
982cdf0e10cSrcweir     catch (lang::IllegalArgumentException &) {
983cdf0e10cSrcweir         throw;
984cdf0e10cSrcweir     }
985cdf0e10cSrcweir     catch (CommandFailedException & exc) {
986cdf0e10cSrcweir         logIntern( Any(exc) );
987cdf0e10cSrcweir         throw;
988cdf0e10cSrcweir     }
989cdf0e10cSrcweir     catch (CommandAbortedException & exc) {
990cdf0e10cSrcweir         logIntern( Any(exc) );
991cdf0e10cSrcweir         throw;
992cdf0e10cSrcweir     }
993cdf0e10cSrcweir     catch (deployment::DeploymentException & exc) {
994cdf0e10cSrcweir         logIntern( Any(exc) );
995cdf0e10cSrcweir         throw;
996cdf0e10cSrcweir     }
997cdf0e10cSrcweir     catch (Exception &) {
998cdf0e10cSrcweir         Any exc( ::cppu::getCaughtException() );
999cdf0e10cSrcweir         logIntern( exc );
1000cdf0e10cSrcweir         throw deployment::DeploymentException(
1001cdf0e10cSrcweir             getResourceString(RID_STR_ERROR_WHILE_REMOVING) + id,
1002cdf0e10cSrcweir             static_cast<OWeakObject *>(this), exc );
1003cdf0e10cSrcweir     }
1004cdf0e10cSrcweir }
1005cdf0e10cSrcweir 
1006cdf0e10cSrcweir //______________________________________________________________________________
getDeployPath(ActivePackages::Data const & data)1007cdf0e10cSrcweir OUString PackageManagerImpl::getDeployPath( ActivePackages::Data const & data )
1008cdf0e10cSrcweir {
1009cdf0e10cSrcweir     ::rtl::OUStringBuffer buf;
1010cdf0e10cSrcweir     buf.append( data.temporaryName );
1011cdf0e10cSrcweir     //The bundled extensions are not contained in an additional folder
1012cdf0e10cSrcweir     //with a unique name. data.temporaryName contains already the
1013cdf0e10cSrcweir     //UTF8 encoded folder name. See PackageManagerImpl::synchronize
1014cdf0e10cSrcweir     if (!m_context.equals(OUSTR("bundled"))
1015cdf0e10cSrcweir         && !m_context.equals(OUSTR("bundled_prereg")))
1016cdf0e10cSrcweir     {
1017cdf0e10cSrcweir         buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("_/") );
1018cdf0e10cSrcweir         buf.append( ::rtl::Uri::encode( data.fileName, rtl_UriCharClassPchar,
1019cdf0e10cSrcweir                                     rtl_UriEncodeIgnoreEscapes,
1020cdf0e10cSrcweir                                     RTL_TEXTENCODING_UTF8 ) );
1021cdf0e10cSrcweir     }
1022cdf0e10cSrcweir     return makeURL( m_activePackages, buf.makeStringAndClear() );
1023cdf0e10cSrcweir }
1024cdf0e10cSrcweir 
1025cdf0e10cSrcweir //______________________________________________________________________________
getDeployedPackage_(OUString const & id,OUString const & fileName,Reference<XCommandEnvironment> const & xCmdEnv)1026cdf0e10cSrcweir Reference<deployment::XPackage> PackageManagerImpl::getDeployedPackage_(
1027cdf0e10cSrcweir     OUString const & id, OUString const & fileName,
1028cdf0e10cSrcweir     Reference<XCommandEnvironment> const & xCmdEnv )
1029cdf0e10cSrcweir {
1030cdf0e10cSrcweir     ActivePackages::Data val;
1031cdf0e10cSrcweir     if (m_activePackagesDB->get( &val, id, fileName ))
1032cdf0e10cSrcweir     {
1033cdf0e10cSrcweir         return getDeployedPackage_( id, val, xCmdEnv, false );
1034cdf0e10cSrcweir     }
1035cdf0e10cSrcweir     throw lang::IllegalArgumentException(
1036cdf0e10cSrcweir         getResourceString(RID_STR_NO_SUCH_PACKAGE) + id,
1037cdf0e10cSrcweir         static_cast<OWeakObject *>(this), static_cast<sal_Int16>(-1) );
1038cdf0e10cSrcweir }
1039cdf0e10cSrcweir 
1040cdf0e10cSrcweir //______________________________________________________________________________
getDeployedPackage_(OUString const & id,ActivePackages::Data const & data,Reference<XCommandEnvironment> const & xCmdEnv,bool ignoreAlienPlatforms)1041cdf0e10cSrcweir Reference<deployment::XPackage> PackageManagerImpl::getDeployedPackage_(
1042cdf0e10cSrcweir     OUString const & id, ActivePackages::Data const & data,
1043cdf0e10cSrcweir     Reference<XCommandEnvironment> const & xCmdEnv, bool ignoreAlienPlatforms )
1044cdf0e10cSrcweir {
1045cdf0e10cSrcweir     if (ignoreAlienPlatforms)
1046cdf0e10cSrcweir     {
1047cdf0e10cSrcweir         String type, subType;
1048cdf0e10cSrcweir         INetContentTypeParameterList params;
1049cdf0e10cSrcweir         if (INetContentTypes::parse( data.mediaType, type, subType, &params ))
1050cdf0e10cSrcweir         {
1051cdf0e10cSrcweir             INetContentTypeParameter const * param = params.find(
1052cdf0e10cSrcweir                 ByteString("platform") );
1053cdf0e10cSrcweir             if (param != 0 && !platform_fits( param->m_sValue ))
1054cdf0e10cSrcweir                 throw lang::IllegalArgumentException(
1055cdf0e10cSrcweir                     getResourceString(RID_STR_NO_SUCH_PACKAGE) + id,
1056cdf0e10cSrcweir                     static_cast<OWeakObject *>(this),
1057cdf0e10cSrcweir                     static_cast<sal_Int16>(-1) );
1058cdf0e10cSrcweir         }
1059cdf0e10cSrcweir     }
1060cdf0e10cSrcweir     Reference<deployment::XPackage> xExtension;
1061cdf0e10cSrcweir     try
1062cdf0e10cSrcweir     {
1063cdf0e10cSrcweir         //Ignore extensions where XPackage::checkPrerequisites failed.
1064cdf0e10cSrcweir         //They must not be usable for this user.
1065cdf0e10cSrcweir         if (data.failedPrerequisites.equals(OUSTR("0")))
1066cdf0e10cSrcweir         {
1067cdf0e10cSrcweir             xExtension = m_xRegistry->bindPackage(
1068cdf0e10cSrcweir                 getDeployPath( data ), data.mediaType, false, OUString(), xCmdEnv );
1069cdf0e10cSrcweir         }
1070cdf0e10cSrcweir     }
1071cdf0e10cSrcweir     catch (deployment::InvalidRemovedParameterException& e)
1072cdf0e10cSrcweir     {
1073cdf0e10cSrcweir         xExtension = e.Extension;
1074cdf0e10cSrcweir     }
1075cdf0e10cSrcweir     return xExtension;
1076cdf0e10cSrcweir }
1077cdf0e10cSrcweir 
1078cdf0e10cSrcweir //______________________________________________________________________________
1079cdf0e10cSrcweir Sequence< Reference<deployment::XPackage> >
getDeployedPackages_(Reference<XCommandEnvironment> const & xCmdEnv)1080cdf0e10cSrcweir PackageManagerImpl::getDeployedPackages_(
1081cdf0e10cSrcweir     Reference<XCommandEnvironment> const & xCmdEnv )
1082cdf0e10cSrcweir {
1083cdf0e10cSrcweir     ::std::vector< Reference<deployment::XPackage> > packages;
1084cdf0e10cSrcweir     ActivePackages::Entries id2temp( m_activePackagesDB->getEntries() );
1085cdf0e10cSrcweir     ActivePackages::Entries::const_iterator iPos( id2temp.begin() );
1086cdf0e10cSrcweir     ActivePackages::Entries::const_iterator const iEnd( id2temp.end() );
1087cdf0e10cSrcweir     for ( ; iPos != iEnd; ++iPos )
1088cdf0e10cSrcweir     {
1089cdf0e10cSrcweir         if (! iPos->second.failedPrerequisites.equals(OUSTR("0")))
1090cdf0e10cSrcweir             continue;
1091cdf0e10cSrcweir         try {
1092cdf0e10cSrcweir             packages.push_back(
1093cdf0e10cSrcweir                 getDeployedPackage_(
1094cdf0e10cSrcweir                     iPos->first, iPos->second, xCmdEnv,
1095cdf0e10cSrcweir                     true /* xxx todo: think of GUI:
1096cdf0e10cSrcweir                             ignore other platforms than the current one */ ) );
1097cdf0e10cSrcweir         }
1098cdf0e10cSrcweir         catch (lang::IllegalArgumentException & exc) {
1099cdf0e10cSrcweir             // ignore
1100cdf0e10cSrcweir             (void) exc; // avoid warnings
1101cdf0e10cSrcweir             OSL_ENSURE( 0, ::rtl::OUStringToOString(
1102cdf0e10cSrcweir                             exc.Message, RTL_TEXTENCODING_UTF8 ).getStr() );
1103cdf0e10cSrcweir         }
1104cdf0e10cSrcweir         catch (deployment::DeploymentException& exc) {
1105cdf0e10cSrcweir             // ignore
1106cdf0e10cSrcweir             (void) exc; // avoid warnings
1107cdf0e10cSrcweir             OSL_ENSURE( 0, ::rtl::OUStringToOString(
1108cdf0e10cSrcweir                             exc.Message, RTL_TEXTENCODING_UTF8 ).getStr() );
1109cdf0e10cSrcweir         }
1110cdf0e10cSrcweir     }
1111cdf0e10cSrcweir     return comphelper::containerToSequence(packages);
1112cdf0e10cSrcweir }
1113cdf0e10cSrcweir 
1114cdf0e10cSrcweir //______________________________________________________________________________
getDeployedPackage(OUString const & id,::rtl::OUString const & fileName,Reference<XCommandEnvironment> const & xCmdEnv_)1115cdf0e10cSrcweir Reference<deployment::XPackage> PackageManagerImpl::getDeployedPackage(
1116cdf0e10cSrcweir     OUString const & id, ::rtl::OUString const & fileName,
1117cdf0e10cSrcweir     Reference<XCommandEnvironment> const & xCmdEnv_ )
1118cdf0e10cSrcweir     throw (deployment::DeploymentException, CommandFailedException,
1119cdf0e10cSrcweir            lang::IllegalArgumentException, RuntimeException)
1120cdf0e10cSrcweir {
1121cdf0e10cSrcweir     check();
1122cdf0e10cSrcweir     Reference<XCommandEnvironment> xCmdEnv;
1123cdf0e10cSrcweir     if (m_xLogFile.is())
1124cdf0e10cSrcweir         xCmdEnv.set( new CmdEnvWrapperImpl( xCmdEnv_, m_xLogFile ) );
1125cdf0e10cSrcweir     else
1126cdf0e10cSrcweir         xCmdEnv.set( xCmdEnv_ );
1127cdf0e10cSrcweir 
1128cdf0e10cSrcweir     try {
1129cdf0e10cSrcweir         const ::osl::MutexGuard guard( getMutex() );
1130cdf0e10cSrcweir         return getDeployedPackage_( id, fileName, xCmdEnv );
1131cdf0e10cSrcweir     }
1132cdf0e10cSrcweir     catch (RuntimeException &) {
1133cdf0e10cSrcweir         throw;
1134cdf0e10cSrcweir     }
1135cdf0e10cSrcweir     catch (CommandFailedException & exc) {
1136cdf0e10cSrcweir         logIntern( Any(exc) );
1137cdf0e10cSrcweir         throw;
1138cdf0e10cSrcweir     }
1139cdf0e10cSrcweir     catch (lang::IllegalArgumentException & exc) {
1140cdf0e10cSrcweir         logIntern( Any(exc) );
1141cdf0e10cSrcweir         throw;
1142cdf0e10cSrcweir     }
1143cdf0e10cSrcweir     catch (deployment::DeploymentException & exc) {
1144cdf0e10cSrcweir         logIntern( Any(exc) );
1145cdf0e10cSrcweir         throw;
1146cdf0e10cSrcweir     }
1147cdf0e10cSrcweir     catch (Exception &) {
1148cdf0e10cSrcweir         Any exc( ::cppu::getCaughtException() );
1149cdf0e10cSrcweir         logIntern( exc );
1150cdf0e10cSrcweir         throw deployment::DeploymentException(
1151cdf0e10cSrcweir             // ought never occur...
1152cdf0e10cSrcweir             OUSTR("error while accessing deployed package: ") + id,
1153cdf0e10cSrcweir             static_cast<OWeakObject *>(this), exc );
1154cdf0e10cSrcweir     }
1155cdf0e10cSrcweir }
1156cdf0e10cSrcweir 
1157cdf0e10cSrcweir //______________________________________________________________________________
1158cdf0e10cSrcweir Sequence< Reference<deployment::XPackage> >
getDeployedPackages(Reference<task::XAbortChannel> const &,Reference<XCommandEnvironment> const & xCmdEnv_)1159cdf0e10cSrcweir PackageManagerImpl::getDeployedPackages(
1160cdf0e10cSrcweir     Reference<task::XAbortChannel> const &,
1161cdf0e10cSrcweir     Reference<XCommandEnvironment> const & xCmdEnv_ )
1162cdf0e10cSrcweir     throw (deployment::DeploymentException, CommandFailedException,
1163cdf0e10cSrcweir            CommandAbortedException, lang::IllegalArgumentException,
1164cdf0e10cSrcweir            RuntimeException)
1165cdf0e10cSrcweir {
1166cdf0e10cSrcweir     check();
1167cdf0e10cSrcweir     Reference<XCommandEnvironment> xCmdEnv;
1168cdf0e10cSrcweir     if (m_xLogFile.is())
1169cdf0e10cSrcweir         xCmdEnv.set( new CmdEnvWrapperImpl( xCmdEnv_, m_xLogFile ) );
1170cdf0e10cSrcweir     else
1171cdf0e10cSrcweir         xCmdEnv.set( xCmdEnv_ );
1172cdf0e10cSrcweir 
1173cdf0e10cSrcweir     try {
1174cdf0e10cSrcweir         const ::osl::MutexGuard guard( getMutex() );
1175cdf0e10cSrcweir         return getDeployedPackages_( xCmdEnv );
1176cdf0e10cSrcweir     }
1177cdf0e10cSrcweir     catch (RuntimeException &) {
1178cdf0e10cSrcweir         throw;
1179cdf0e10cSrcweir     }
1180cdf0e10cSrcweir     catch (CommandFailedException & exc) {
1181cdf0e10cSrcweir         logIntern( Any(exc) );
1182cdf0e10cSrcweir         throw;
1183cdf0e10cSrcweir     }
1184cdf0e10cSrcweir     catch (CommandAbortedException & exc) {
1185cdf0e10cSrcweir         logIntern( Any(exc) );
1186cdf0e10cSrcweir         throw;
1187cdf0e10cSrcweir     }
1188cdf0e10cSrcweir     catch (deployment::DeploymentException & exc) {
1189cdf0e10cSrcweir         logIntern( Any(exc) );
1190cdf0e10cSrcweir         throw;
1191cdf0e10cSrcweir     }
1192cdf0e10cSrcweir     catch (Exception &) {
1193cdf0e10cSrcweir         Any exc( ::cppu::getCaughtException() );
1194cdf0e10cSrcweir         logIntern( exc );
1195cdf0e10cSrcweir         throw deployment::DeploymentException(
1196cdf0e10cSrcweir             // ought never occur...
1197cdf0e10cSrcweir             OUSTR("error while getting all deployed packages: ") + m_context,
1198cdf0e10cSrcweir             static_cast<OWeakObject *>(this), exc );
1199cdf0e10cSrcweir     }
1200cdf0e10cSrcweir }
1201cdf0e10cSrcweir 
1202cdf0e10cSrcweir //______________________________________________________________________________
1203cdf0e10cSrcweir 
1204cdf0e10cSrcweir 
1205cdf0e10cSrcweir //ToDo: the function must not call registerPackage, do this in
1206cdf0e10cSrcweir //XExtensionManager.reinstallDeployedExtensions
reinstallDeployedPackages(Reference<task::XAbortChannel> const &,Reference<XCommandEnvironment> const & xCmdEnv_)1207cdf0e10cSrcweir void PackageManagerImpl::reinstallDeployedPackages(
1208cdf0e10cSrcweir     Reference<task::XAbortChannel> const &  /*xAbortChannel*/,
1209cdf0e10cSrcweir     Reference<XCommandEnvironment> const & xCmdEnv_ )
1210cdf0e10cSrcweir     throw (deployment::DeploymentException,
1211cdf0e10cSrcweir            CommandFailedException, CommandAbortedException,
1212cdf0e10cSrcweir            lang::IllegalArgumentException, RuntimeException)
1213cdf0e10cSrcweir {
1214cdf0e10cSrcweir     check();
1215cdf0e10cSrcweir     if (office_is_running())
1216cdf0e10cSrcweir         throw RuntimeException(
1217cdf0e10cSrcweir             OUSTR("You must close any running Office process before "
1218cdf0e10cSrcweir                   "reinstalling packages!"), static_cast<OWeakObject *>(this) );
1219cdf0e10cSrcweir 
1220cdf0e10cSrcweir     Reference<XCommandEnvironment> xCmdEnv;
1221cdf0e10cSrcweir     if (m_xLogFile.is())
1222cdf0e10cSrcweir         xCmdEnv.set( new CmdEnvWrapperImpl( xCmdEnv_, m_xLogFile ) );
1223cdf0e10cSrcweir     else
1224cdf0e10cSrcweir         xCmdEnv.set( xCmdEnv_ );
1225cdf0e10cSrcweir 
1226cdf0e10cSrcweir     try {
1227cdf0e10cSrcweir         ProgressLevel progress(
1228cdf0e10cSrcweir             xCmdEnv, OUSTR("Reinstalling all deployed packages...") );
1229cdf0e10cSrcweir 
1230cdf0e10cSrcweir         try_dispose( m_xRegistry );
1231cdf0e10cSrcweir         m_xRegistry.clear();
1232cdf0e10cSrcweir         if (m_registryCache.getLength() > 0)
1233cdf0e10cSrcweir             erase_path( m_registryCache, xCmdEnv );
1234cdf0e10cSrcweir         initRegistryBackends();
1235cdf0e10cSrcweir         Reference<util::XUpdatable> xUpdatable( m_xRegistry, UNO_QUERY );
1236cdf0e10cSrcweir         if (xUpdatable.is())
1237cdf0e10cSrcweir             xUpdatable->update();
1238cdf0e10cSrcweir 
1239cdf0e10cSrcweir         //registering is done by the ExtensionManager service.
1240cdf0e10cSrcweir     }
1241cdf0e10cSrcweir     catch (RuntimeException &) {
1242cdf0e10cSrcweir         throw;
1243cdf0e10cSrcweir     }
1244cdf0e10cSrcweir     catch (CommandFailedException & exc) {
1245cdf0e10cSrcweir         logIntern( Any(exc) );
1246cdf0e10cSrcweir         throw;
1247cdf0e10cSrcweir     }
1248cdf0e10cSrcweir     catch (CommandAbortedException & exc) {
1249cdf0e10cSrcweir         logIntern( Any(exc) );
1250cdf0e10cSrcweir         throw;
1251cdf0e10cSrcweir     }
1252cdf0e10cSrcweir     catch (deployment::DeploymentException & exc) {
1253cdf0e10cSrcweir         logIntern( Any(exc) );
1254cdf0e10cSrcweir         throw;
1255cdf0e10cSrcweir     }
1256cdf0e10cSrcweir     catch (Exception &) {
1257cdf0e10cSrcweir         Any exc( ::cppu::getCaughtException() );
1258cdf0e10cSrcweir         logIntern( exc );
1259cdf0e10cSrcweir         throw deployment::DeploymentException(
1260cdf0e10cSrcweir             OUSTR("Error while reinstalling all previously deployed "
1261cdf0e10cSrcweir                   "packages of context ") + m_context,
1262cdf0e10cSrcweir             static_cast<OWeakObject *>(this), exc );
1263cdf0e10cSrcweir     }
1264cdf0e10cSrcweir }
1265cdf0e10cSrcweir 
1266cdf0e10cSrcweir 
isReadOnly()1267cdf0e10cSrcweir ::sal_Bool SAL_CALL PackageManagerImpl::isReadOnly(  )
1268cdf0e10cSrcweir         throw (::com::sun::star::uno::RuntimeException)
1269cdf0e10cSrcweir {
1270cdf0e10cSrcweir     return m_readOnly;
1271cdf0e10cSrcweir }
synchronizeRemovedExtensions(Reference<task::XAbortChannel> const & xAbortChannel,Reference<css::ucb::XCommandEnvironment> const & xCmdEnv)1272cdf0e10cSrcweir bool PackageManagerImpl::synchronizeRemovedExtensions(
1273cdf0e10cSrcweir     Reference<task::XAbortChannel> const & xAbortChannel,
1274cdf0e10cSrcweir     Reference<css::ucb::XCommandEnvironment> const & xCmdEnv)
1275cdf0e10cSrcweir {
1276cdf0e10cSrcweir 
1277cdf0e10cSrcweir     //find all which are in the extension data base but which
1278cdf0e10cSrcweir     //are removed already.
1279cdf0e10cSrcweir     OSL_ASSERT(!m_context.equals(OUSTR("user")));
1280cdf0e10cSrcweir     bool bModified = false;
1281cdf0e10cSrcweir     ActivePackages::Entries id2temp( m_activePackagesDB->getEntries() );
1282cdf0e10cSrcweir 
1283cdf0e10cSrcweir     typedef ActivePackages::Entries::const_iterator ITActive;
1284cdf0e10cSrcweir     bool bShared = m_context.equals(OUSTR("shared"));
1285cdf0e10cSrcweir 
1286cdf0e10cSrcweir     for (ITActive i = id2temp.begin(); i != id2temp.end(); i++)
1287cdf0e10cSrcweir     {
1288cdf0e10cSrcweir         try
1289cdf0e10cSrcweir         {
1290cdf0e10cSrcweir             //Get the URL to the extensions folder, first make the url for the
1291cdf0e10cSrcweir             //shared repository including the temporary name
1292cdf0e10cSrcweir             OUString url = makeURL(m_activePackages, i->second.temporaryName);
1293cdf0e10cSrcweir             if (bShared)
1294cdf0e10cSrcweir                 url = makeURLAppendSysPathSegment( url + OUSTR("_"), i->second.fileName);
1295cdf0e10cSrcweir 
1296cdf0e10cSrcweir             bool bRemoved = false;
1297cdf0e10cSrcweir             //Check if the URL to the extension is still the same
1298cdf0e10cSrcweir             ::ucbhelper::Content contentExtension;
1299cdf0e10cSrcweir 
1300cdf0e10cSrcweir             if (!create_ucb_content(
1301cdf0e10cSrcweir                     &contentExtension, url,
1302cdf0e10cSrcweir                     Reference<XCommandEnvironment>(), false))
1303cdf0e10cSrcweir             {
1304cdf0e10cSrcweir                 bRemoved = true;
1305cdf0e10cSrcweir             }
1306cdf0e10cSrcweir 
1307cdf0e10cSrcweir             //The folder is in the extension database, but it can still be deleted.
1308cdf0e10cSrcweir             //look for the xxx.tmpremoved file
1309cdf0e10cSrcweir             //There can also be the case that a different extension was installed
1310cdf0e10cSrcweir             //in a "temp" folder with name that is already used.
1311cdf0e10cSrcweir             if (!bRemoved && bShared)
1312cdf0e10cSrcweir             {
1313cdf0e10cSrcweir                 ::ucbhelper::Content contentRemoved;
1314cdf0e10cSrcweir 
1315cdf0e10cSrcweir                 if (create_ucb_content(
1316cdf0e10cSrcweir                         &contentRemoved,
1317cdf0e10cSrcweir                         m_activePackages_expanded + OUSTR("/") +
1318cdf0e10cSrcweir                         i->second.temporaryName + OUSTR("removed"),
1319cdf0e10cSrcweir                         Reference<XCommandEnvironment>(), false))
1320cdf0e10cSrcweir                 {
1321cdf0e10cSrcweir                     bRemoved = true;
1322cdf0e10cSrcweir                 }
1323cdf0e10cSrcweir             }
1324cdf0e10cSrcweir 
1325cdf0e10cSrcweir             if (!bRemoved)
1326cdf0e10cSrcweir             {
1327cdf0e10cSrcweir                 //There may be another extensions at the same place
1328cdf0e10cSrcweir                 dp_misc::DescriptionInfoset infoset =
1329cdf0e10cSrcweir                     dp_misc::getDescriptionInfoset(url);
1330cdf0e10cSrcweir                 OSL_ENSURE(infoset.hasDescription(),
1331cdf0e10cSrcweir                            "Extension Manager: bundled and shared extensions "
1332cdf0e10cSrcweir                            "must have an identifer and a version");
1333cdf0e10cSrcweir                 if (infoset.hasDescription() &&
1334cdf0e10cSrcweir                     infoset.getIdentifier() &&
1335cdf0e10cSrcweir                     (! i->first.equals(*(infoset.getIdentifier()))
1336cdf0e10cSrcweir                      || ! i->second.version.equals(infoset.getVersion())))
1337cdf0e10cSrcweir                 {
1338cdf0e10cSrcweir                     bRemoved = true;
1339cdf0e10cSrcweir                 }
1340cdf0e10cSrcweir 
1341cdf0e10cSrcweir             }
1342cdf0e10cSrcweir             if (bRemoved)
1343cdf0e10cSrcweir             {
1344cdf0e10cSrcweir                 Reference<deployment::XPackage> xPackage = m_xRegistry->bindPackage(
1345cdf0e10cSrcweir                     url, i->second.mediaType, true, i->first, xCmdEnv );
1346cdf0e10cSrcweir                 OSL_ASSERT(xPackage.is()); //Even if the files are removed, we must get the object.
1347cdf0e10cSrcweir                 xPackage->revokePackage(xAbortChannel, xCmdEnv);
1348cdf0e10cSrcweir                 removePackage(xPackage->getIdentifier().Value, xPackage->getName(),
1349cdf0e10cSrcweir                               xAbortChannel, xCmdEnv);
1350cdf0e10cSrcweir                 bModified |= true;
1351cdf0e10cSrcweir             }
1352cdf0e10cSrcweir         }
1353cdf0e10cSrcweir         catch( uno::Exception & )
1354cdf0e10cSrcweir         {
1355cdf0e10cSrcweir             OSL_ASSERT(0);
1356cdf0e10cSrcweir         }
1357cdf0e10cSrcweir     }
1358cdf0e10cSrcweir     return bModified;
1359cdf0e10cSrcweir }
1360cdf0e10cSrcweir 
1361cdf0e10cSrcweir 
synchronizeAddedExtensions(Reference<task::XAbortChannel> const & xAbortChannel,Reference<css::ucb::XCommandEnvironment> const & xCmdEnv)1362cdf0e10cSrcweir bool PackageManagerImpl::synchronizeAddedExtensions(
1363cdf0e10cSrcweir     Reference<task::XAbortChannel> const & xAbortChannel,
1364cdf0e10cSrcweir     Reference<css::ucb::XCommandEnvironment> const & xCmdEnv)
1365cdf0e10cSrcweir {
1366cdf0e10cSrcweir     bool bModified = false;
1367cdf0e10cSrcweir     OSL_ASSERT(!m_context.equals(OUSTR("user")));
1368cdf0e10cSrcweir 
1369cdf0e10cSrcweir     ActivePackages::Entries id2temp( m_activePackagesDB->getEntries() );
1370cdf0e10cSrcweir     //check if the folder exist at all. The shared extension folder
1371cdf0e10cSrcweir     //may not exist for a normal user.
1372cdf0e10cSrcweir     if (!create_ucb_content(
1373cdf0e10cSrcweir             NULL, m_activePackages_expanded, Reference<css::ucb::XCommandEnvironment>(), false))
1374cdf0e10cSrcweir         return bModified;
1375cdf0e10cSrcweir     ::ucbhelper::Content tempFolder(
1376cdf0e10cSrcweir         m_activePackages_expanded, xCmdEnv );
1377cdf0e10cSrcweir 
1378cdf0e10cSrcweir     Reference<sdbc::XResultSet> xResultSet(
1379cdf0e10cSrcweir         tempFolder.createCursor(
1380cdf0e10cSrcweir             Sequence<OUString>( &StrTitle::get(), 1 ),
1381cdf0e10cSrcweir             ::ucbhelper::INCLUDE_FOLDERS_ONLY ) );
1382cdf0e10cSrcweir 
1383cdf0e10cSrcweir     while (xResultSet->next())
1384cdf0e10cSrcweir     {
1385cdf0e10cSrcweir         try
1386cdf0e10cSrcweir         {
1387cdf0e10cSrcweir             OUString title(
1388cdf0e10cSrcweir                 Reference<sdbc::XRow>(
1389cdf0e10cSrcweir                     xResultSet, UNO_QUERY_THROW )->getString(
1390cdf0e10cSrcweir                         1 /* Title */ ) );
1391cdf0e10cSrcweir             //The temporary folders of user and shared have an '_' at then end.
1392cdf0e10cSrcweir             //But the name in ActivePackages.temporaryName is saved without.
1393cdf0e10cSrcweir             OUString title2 = title;
1394cdf0e10cSrcweir             bool bShared = m_context.equals(OUSTR("shared"));
1395cdf0e10cSrcweir             if (bShared)
1396cdf0e10cSrcweir             {
1397cdf0e10cSrcweir                 OSL_ASSERT(title2[title2.getLength() -1] == '_');
1398cdf0e10cSrcweir                 title2 = title2.copy(0, title2.getLength() -1);
1399cdf0e10cSrcweir             }
1400cdf0e10cSrcweir             OUString titleEncoded =  ::rtl::Uri::encode(
1401cdf0e10cSrcweir                 title2, rtl_UriCharClassPchar,
1402cdf0e10cSrcweir                 rtl_UriEncodeIgnoreEscapes,
1403cdf0e10cSrcweir                 RTL_TEXTENCODING_UTF8);
1404cdf0e10cSrcweir 
1405cdf0e10cSrcweir             //It it sufficient to check for the folder name, because when the administor
1406cdf0e10cSrcweir             //installed the extension it was already checked if there is one with the
1407cdf0e10cSrcweir             //same identifier.
1408cdf0e10cSrcweir             const MatchTempDir match(titleEncoded);
1409cdf0e10cSrcweir             if (::std::find_if( id2temp.begin(), id2temp.end(), match ) ==
1410cdf0e10cSrcweir                 id2temp.end())
1411cdf0e10cSrcweir             {
1412cdf0e10cSrcweir 
1413cdf0e10cSrcweir                 // The folder was not found in the data base, so it must be
1414cdf0e10cSrcweir                 // an added extension
1415cdf0e10cSrcweir                 OUString url(m_activePackages_expanded + OUSTR("/") + titleEncoded);
1416cdf0e10cSrcweir                 OUString sExtFolder;
1417cdf0e10cSrcweir                 if (bShared) //that is, shared
1418cdf0e10cSrcweir                 {
1419cdf0e10cSrcweir                     //Check if the extension was not "deleted" already which is indicated
1420cdf0e10cSrcweir                     //by a xxx.tmpremoved file
1421cdf0e10cSrcweir                     ::ucbhelper::Content contentRemoved;
1422cdf0e10cSrcweir                     if (create_ucb_content(&contentRemoved, url + OUSTR("removed"),
1423cdf0e10cSrcweir                                            Reference<XCommandEnvironment>(), false))
1424cdf0e10cSrcweir                         continue;
1425cdf0e10cSrcweir                     sExtFolder = getExtensionFolder(
1426cdf0e10cSrcweir                         m_activePackages_expanded +
1427cdf0e10cSrcweir                         OUString(OUSTR("/")) + titleEncoded + OUSTR("_"), xCmdEnv);
1428cdf0e10cSrcweir                     url = makeURLAppendSysPathSegment(m_activePackages_expanded, title);
1429cdf0e10cSrcweir                     url = makeURLAppendSysPathSegment(url, sExtFolder);
1430cdf0e10cSrcweir                 }
1431cdf0e10cSrcweir                 Reference<deployment::XPackage> xPackage = m_xRegistry->bindPackage(
1432cdf0e10cSrcweir                     url, OUString(), false, OUString(), xCmdEnv );
1433cdf0e10cSrcweir                 if (xPackage.is())
1434cdf0e10cSrcweir                 {
1435cdf0e10cSrcweir                     //Prepare the database entry
1436cdf0e10cSrcweir                     ActivePackages::Data dbData;
1437cdf0e10cSrcweir 
1438cdf0e10cSrcweir                     dbData.temporaryName = titleEncoded;
1439cdf0e10cSrcweir                     if (bShared)
1440cdf0e10cSrcweir                         dbData.fileName = sExtFolder;
1441cdf0e10cSrcweir                     else
1442cdf0e10cSrcweir                         dbData.fileName = title;
1443cdf0e10cSrcweir                     dbData.mediaType = xPackage->getPackageType()->getMediaType();
1444cdf0e10cSrcweir                     dbData.version = xPackage->getVersion();
1445cdf0e10cSrcweir                     OSL_ENSURE(dbData.version.getLength() > 0,
1446cdf0e10cSrcweir                                "Extension Manager: bundled and shared extensions must have "
1447cdf0e10cSrcweir                                "an identifier and a version");
1448cdf0e10cSrcweir 
1449cdf0e10cSrcweir                     OUString id = dp_misc::getIdentifier( xPackage );
1450cdf0e10cSrcweir 
1451cdf0e10cSrcweir                     //We provide a special command environment that will prevent
1452cdf0e10cSrcweir                     //showing a license if simple-licens/@accept-by = "admin"
1453cdf0e10cSrcweir                     //It will also prevent showing the license for bundled extensions
1454cdf0e10cSrcweir                     //which is not supported.
1455cdf0e10cSrcweir                     OSL_ASSERT(!m_context.equals(OUSTR("user")));
1456cdf0e10cSrcweir 
1457cdf0e10cSrcweir                     // shall the license be suppressed?
1458cdf0e10cSrcweir                     DescriptionInfoset info =
1459cdf0e10cSrcweir                         dp_misc::getDescriptionInfoset(url);
1460cdf0e10cSrcweir                     ::boost::optional<dp_misc::SimpleLicenseAttributes>
1461cdf0e10cSrcweir                           attr = info.getSimpleLicenseAttributes();
1462cdf0e10cSrcweir                     ExtensionProperties props(url,xCmdEnv);
1463cdf0e10cSrcweir                     bool bNoLicense = false;
1464cdf0e10cSrcweir                     if (attr && attr->suppressIfRequired && props.isSuppressedLicense())
1465cdf0e10cSrcweir                         bNoLicense = true;
1466cdf0e10cSrcweir 
1467cdf0e10cSrcweir                     Reference<ucb::XCommandEnvironment> licCmdEnv(
1468cdf0e10cSrcweir                         new LicenseCommandEnv(xCmdEnv->getInteractionHandler(),
1469cdf0e10cSrcweir                                               bNoLicense, m_context));
1470cdf0e10cSrcweir                     sal_Int32 failedPrereq = xPackage->checkPrerequisites(
1471cdf0e10cSrcweir                         xAbortChannel, licCmdEnv, false);
1472cdf0e10cSrcweir                     //Remember that this failed. For example, the user
1473cdf0e10cSrcweir                     //could have declined the license. Then the next time the
1474cdf0e10cSrcweir                     //extension folder is investigated we do not want to
1475cdf0e10cSrcweir                     //try to install the extension again.
1476cdf0e10cSrcweir                     dbData.failedPrerequisites = OUString::valueOf(failedPrereq);
1477cdf0e10cSrcweir                     insertToActivationLayerDB(id, dbData);
1478cdf0e10cSrcweir                     bModified |= true;
1479cdf0e10cSrcweir                 }
1480cdf0e10cSrcweir             }
1481cdf0e10cSrcweir         }
1482cdf0e10cSrcweir         catch (uno::Exception &)
1483cdf0e10cSrcweir         {
1484*c6dedb65SAndre Fischer             // Looks like exceptions being caught here is not an
1485*c6dedb65SAndre Fischer             // uncommon case.
1486*c6dedb65SAndre Fischer 			OSL_TRACE("caught exception in PackageManagerImpl::synchronizeAddedExtensions");
1487cdf0e10cSrcweir         }
1488cdf0e10cSrcweir     }
1489cdf0e10cSrcweir     return bModified;
1490cdf0e10cSrcweir }
1491cdf0e10cSrcweir 
synchronize(Reference<task::XAbortChannel> const & xAbortChannel,Reference<css::ucb::XCommandEnvironment> const & xCmdEnv)1492cdf0e10cSrcweir sal_Bool PackageManagerImpl::synchronize(
1493cdf0e10cSrcweir     Reference<task::XAbortChannel> const & xAbortChannel,
1494cdf0e10cSrcweir     Reference<css::ucb::XCommandEnvironment> const & xCmdEnv)
1495cdf0e10cSrcweir     throw (css::deployment::DeploymentException,
1496cdf0e10cSrcweir            css::ucb::CommandFailedException,
1497cdf0e10cSrcweir            css::ucb::CommandAbortedException,
1498cdf0e10cSrcweir            css::uno::RuntimeException)
1499cdf0e10cSrcweir {
1500cdf0e10cSrcweir     check();
1501cdf0e10cSrcweir     bool bModified = false;
1502cdf0e10cSrcweir     if (m_context.equals(OUSTR("user")))
1503cdf0e10cSrcweir         return bModified;
1504cdf0e10cSrcweir     bModified |=
1505cdf0e10cSrcweir         synchronizeRemovedExtensions(xAbortChannel, xCmdEnv);
1506cdf0e10cSrcweir     bModified |= synchronizeAddedExtensions(xAbortChannel, xCmdEnv);
1507cdf0e10cSrcweir 
1508cdf0e10cSrcweir     return bModified;
1509cdf0e10cSrcweir }
1510cdf0e10cSrcweir 
getExtensionsWithUnacceptedLicenses(Reference<ucb::XCommandEnvironment> const & xCmdEnv)1511cdf0e10cSrcweir Sequence< Reference<deployment::XPackage> > PackageManagerImpl::getExtensionsWithUnacceptedLicenses(
1512cdf0e10cSrcweir     Reference<ucb::XCommandEnvironment> const & xCmdEnv)
1513cdf0e10cSrcweir     throw (deployment::DeploymentException, RuntimeException)
1514cdf0e10cSrcweir {
1515cdf0e10cSrcweir     ::std::vector<Reference<deployment::XPackage> > vec;
1516cdf0e10cSrcweir 
1517cdf0e10cSrcweir     try
1518cdf0e10cSrcweir     {
1519cdf0e10cSrcweir         const ::osl::MutexGuard guard( getMutex() );
1520cdf0e10cSrcweir         // clean up activation layer, scan for zombie temp dirs:
1521cdf0e10cSrcweir         ActivePackages::Entries id2temp( m_activePackagesDB->getEntries() );
1522cdf0e10cSrcweir 
1523cdf0e10cSrcweir         ActivePackages::Entries::const_iterator i = id2temp.begin();
1524cdf0e10cSrcweir         bool bShared = m_context.equals(OUSTR("shared"));
1525cdf0e10cSrcweir 
1526cdf0e10cSrcweir         for (; i != id2temp.end(); i++ )
1527cdf0e10cSrcweir         {
1528cdf0e10cSrcweir             //Get the database entry
1529cdf0e10cSrcweir             ActivePackages::Data const & dbData = i->second;
1530cdf0e10cSrcweir             sal_Int32 failedPrereq = dbData.failedPrerequisites.toInt32();
1531cdf0e10cSrcweir             //If the installation failed for other reason then the license then we
1532cdf0e10cSrcweir             //ignore it.
1533cdf0e10cSrcweir             if (failedPrereq ^= deployment::Prerequisites::LICENSE)
1534cdf0e10cSrcweir                 continue;
1535cdf0e10cSrcweir 
1536cdf0e10cSrcweir             //Prepare the URL to the extension
1537cdf0e10cSrcweir             OUString url = makeURL(m_activePackages, i->second.temporaryName);
1538cdf0e10cSrcweir             if (bShared)
1539cdf0e10cSrcweir                 url = makeURLAppendSysPathSegment( url + OUSTR("_"), i->second.fileName);
1540cdf0e10cSrcweir 
1541cdf0e10cSrcweir             Reference<deployment::XPackage> p = m_xRegistry->bindPackage(
1542cdf0e10cSrcweir                 url, OUString(), false, OUString(), xCmdEnv );
1543cdf0e10cSrcweir 
1544cdf0e10cSrcweir             if (p.is())
1545cdf0e10cSrcweir                 vec.push_back(p);
1546cdf0e10cSrcweir 
1547cdf0e10cSrcweir         }
1548cdf0e10cSrcweir         return ::comphelper::containerToSequence(vec);
1549cdf0e10cSrcweir     }
1550cdf0e10cSrcweir     catch (deployment::DeploymentException &)
1551cdf0e10cSrcweir     {
1552cdf0e10cSrcweir         throw;
1553cdf0e10cSrcweir     }
1554cdf0e10cSrcweir     catch (RuntimeException&)
1555cdf0e10cSrcweir     {
1556cdf0e10cSrcweir         throw;
1557cdf0e10cSrcweir     }
1558cdf0e10cSrcweir     catch (...)
1559cdf0e10cSrcweir     {
1560cdf0e10cSrcweir         Any exc = ::cppu::getCaughtException();
1561cdf0e10cSrcweir         deployment::DeploymentException de(
1562cdf0e10cSrcweir             OUSTR("PackageManagerImpl::getExtensionsWithUnacceptedLicenses"),
1563cdf0e10cSrcweir             static_cast<OWeakObject*>(this), exc);
1564cdf0e10cSrcweir         exc <<= de;
1565cdf0e10cSrcweir         ::cppu::throwException(exc);
1566cdf0e10cSrcweir     }
1567cdf0e10cSrcweir 
1568cdf0e10cSrcweir     return ::comphelper::containerToSequence(vec);
1569cdf0e10cSrcweir }
1570cdf0e10cSrcweir 
checkPrerequisites(css::uno::Reference<css::deployment::XPackage> const & extension,css::uno::Reference<css::task::XAbortChannel> const & xAbortChannel,css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv)1571cdf0e10cSrcweir sal_Int32 PackageManagerImpl::checkPrerequisites(
1572cdf0e10cSrcweir     css::uno::Reference<css::deployment::XPackage> const & extension,
1573cdf0e10cSrcweir     css::uno::Reference<css::task::XAbortChannel> const & xAbortChannel,
1574cdf0e10cSrcweir     css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv )
1575cdf0e10cSrcweir     throw (css::deployment::DeploymentException,
1576cdf0e10cSrcweir            css::ucb::CommandFailedException,
1577cdf0e10cSrcweir            css::ucb::CommandAbortedException,
1578cdf0e10cSrcweir            css::lang::IllegalArgumentException,
1579cdf0e10cSrcweir            css::uno::RuntimeException)
1580cdf0e10cSrcweir {
1581cdf0e10cSrcweir     try
1582cdf0e10cSrcweir     {
1583cdf0e10cSrcweir         if (!extension.is())
1584cdf0e10cSrcweir             return 0;
1585cdf0e10cSrcweir         if (!m_context.equals(extension->getRepositoryName()))
1586cdf0e10cSrcweir             throw lang::IllegalArgumentException(
1587cdf0e10cSrcweir                 OUSTR("PackageManagerImpl::checkPrerequisites: extension is not"
1588cdf0e10cSrcweir                       " from this repository."), 0, 0);
1589cdf0e10cSrcweir 
1590cdf0e10cSrcweir         ActivePackages::Data dbData;
1591cdf0e10cSrcweir         OUString id = dp_misc::getIdentifier(extension);
1592cdf0e10cSrcweir         if (m_activePackagesDB->get( &dbData, id, OUString()))
1593cdf0e10cSrcweir         {
1594cdf0e10cSrcweir             //If the license was already displayed, then do not show it again
1595cdf0e10cSrcweir             Reference<ucb::XCommandEnvironment> _xCmdEnv = xCmdEnv;
1596cdf0e10cSrcweir             sal_Int32 prereq = dbData.failedPrerequisites.toInt32();
1597cdf0e10cSrcweir             if ( !(prereq & deployment::Prerequisites::LICENSE))
1598cdf0e10cSrcweir                 _xCmdEnv = new NoLicenseCommandEnv(xCmdEnv->getInteractionHandler());
1599cdf0e10cSrcweir 
1600cdf0e10cSrcweir             sal_Int32 failedPrereq = extension->checkPrerequisites(
1601cdf0e10cSrcweir                 xAbortChannel, _xCmdEnv, false);
1602cdf0e10cSrcweir             dbData.failedPrerequisites = OUString::valueOf(failedPrereq);
1603cdf0e10cSrcweir             insertToActivationLayerDB(id, dbData);
1604cdf0e10cSrcweir         }
1605cdf0e10cSrcweir         else
1606cdf0e10cSrcweir         {
1607cdf0e10cSrcweir             throw lang::IllegalArgumentException(
1608cdf0e10cSrcweir                 OUSTR("PackageManagerImpl::checkPrerequisites: unknown extension"),
1609cdf0e10cSrcweir                 0, 0);
1610cdf0e10cSrcweir 
1611cdf0e10cSrcweir         }
1612cdf0e10cSrcweir         return 0;
1613cdf0e10cSrcweir     }
1614cdf0e10cSrcweir     catch (deployment::DeploymentException& ) {
1615cdf0e10cSrcweir         throw;
1616cdf0e10cSrcweir     } catch (ucb::CommandFailedException & ) {
1617cdf0e10cSrcweir         throw;
1618cdf0e10cSrcweir     } catch (ucb::CommandAbortedException & ) {
1619cdf0e10cSrcweir         throw;
1620cdf0e10cSrcweir     } catch (lang::IllegalArgumentException &) {
1621cdf0e10cSrcweir         throw;
1622cdf0e10cSrcweir     } catch (uno::RuntimeException &) {
1623cdf0e10cSrcweir         throw;
1624cdf0e10cSrcweir     } catch (...) {
1625cdf0e10cSrcweir         uno::Any excOccurred = ::cppu::getCaughtException();
1626cdf0e10cSrcweir         deployment::DeploymentException exc(
1627cdf0e10cSrcweir             OUSTR("PackageManagerImpl::checkPrerequisites: exception "),
1628cdf0e10cSrcweir             static_cast<OWeakObject*>(this), excOccurred);
1629cdf0e10cSrcweir         throw exc;
1630cdf0e10cSrcweir     }
1631cdf0e10cSrcweir }
1632cdf0e10cSrcweir 
1633cdf0e10cSrcweir //##############################################################################
1634cdf0e10cSrcweir 
1635cdf0e10cSrcweir //______________________________________________________________________________
~CmdEnvWrapperImpl()1636cdf0e10cSrcweir PackageManagerImpl::CmdEnvWrapperImpl::~CmdEnvWrapperImpl()
1637cdf0e10cSrcweir {
1638cdf0e10cSrcweir }
1639cdf0e10cSrcweir 
1640cdf0e10cSrcweir //______________________________________________________________________________
CmdEnvWrapperImpl(Reference<XCommandEnvironment> const & xUserCmdEnv,Reference<XProgressHandler> const & xLogFile)1641cdf0e10cSrcweir PackageManagerImpl::CmdEnvWrapperImpl::CmdEnvWrapperImpl(
1642cdf0e10cSrcweir     Reference<XCommandEnvironment> const & xUserCmdEnv,
1643cdf0e10cSrcweir     Reference<XProgressHandler> const & xLogFile )
1644cdf0e10cSrcweir     : m_xLogFile( xLogFile )
1645cdf0e10cSrcweir {
1646cdf0e10cSrcweir     if (xUserCmdEnv.is()) {
1647cdf0e10cSrcweir         m_xUserProgress.set( xUserCmdEnv->getProgressHandler() );
1648cdf0e10cSrcweir         m_xUserInteractionHandler.set( xUserCmdEnv->getInteractionHandler() );
1649cdf0e10cSrcweir     }
1650cdf0e10cSrcweir }
1651cdf0e10cSrcweir 
1652cdf0e10cSrcweir // XCommandEnvironment
1653cdf0e10cSrcweir //______________________________________________________________________________
1654cdf0e10cSrcweir Reference<task::XInteractionHandler>
getInteractionHandler()1655cdf0e10cSrcweir PackageManagerImpl::CmdEnvWrapperImpl::getInteractionHandler()
1656cdf0e10cSrcweir     throw (RuntimeException)
1657cdf0e10cSrcweir {
1658cdf0e10cSrcweir     return m_xUserInteractionHandler;
1659cdf0e10cSrcweir }
1660cdf0e10cSrcweir 
1661cdf0e10cSrcweir //______________________________________________________________________________
1662cdf0e10cSrcweir Reference<XProgressHandler>
getProgressHandler()1663cdf0e10cSrcweir PackageManagerImpl::CmdEnvWrapperImpl::getProgressHandler()
1664cdf0e10cSrcweir     throw (RuntimeException)
1665cdf0e10cSrcweir {
1666cdf0e10cSrcweir     return this;
1667cdf0e10cSrcweir }
1668cdf0e10cSrcweir 
1669cdf0e10cSrcweir // XProgressHandler
1670cdf0e10cSrcweir //______________________________________________________________________________
push(Any const & Status)1671cdf0e10cSrcweir void PackageManagerImpl::CmdEnvWrapperImpl::push( Any const & Status )
1672cdf0e10cSrcweir     throw (RuntimeException)
1673cdf0e10cSrcweir {
1674cdf0e10cSrcweir     if (m_xLogFile.is())
1675cdf0e10cSrcweir         m_xLogFile->push( Status );
1676cdf0e10cSrcweir     if (m_xUserProgress.is())
1677cdf0e10cSrcweir         m_xUserProgress->push( Status );
1678cdf0e10cSrcweir }
1679cdf0e10cSrcweir 
1680cdf0e10cSrcweir //______________________________________________________________________________
update(Any const & Status)1681cdf0e10cSrcweir void PackageManagerImpl::CmdEnvWrapperImpl::update( Any const & Status )
1682cdf0e10cSrcweir     throw (RuntimeException)
1683cdf0e10cSrcweir {
1684cdf0e10cSrcweir     if (m_xLogFile.is())
1685cdf0e10cSrcweir         m_xLogFile->update( Status );
1686cdf0e10cSrcweir     if (m_xUserProgress.is())
1687cdf0e10cSrcweir         m_xUserProgress->update( Status );
1688cdf0e10cSrcweir }
1689cdf0e10cSrcweir 
1690cdf0e10cSrcweir //______________________________________________________________________________
pop()1691cdf0e10cSrcweir void PackageManagerImpl::CmdEnvWrapperImpl::pop() throw (RuntimeException)
1692cdf0e10cSrcweir {
1693cdf0e10cSrcweir     if (m_xLogFile.is())
1694cdf0e10cSrcweir         m_xLogFile->pop();
1695cdf0e10cSrcweir     if (m_xUserProgress.is())
1696cdf0e10cSrcweir         m_xUserProgress->pop();
1697cdf0e10cSrcweir }
1698cdf0e10cSrcweir 
1699cdf0e10cSrcweir } // namespace dp_manager
1700cdf0e10cSrcweir 
1701