1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_desktop.hxx"
30 
31 #include "dp_backend.h"
32 #include "dp_ucb.h"
33 #include "rtl/uri.hxx"
34 #include "rtl/bootstrap.hxx"
35 #include "osl/file.hxx"
36 #include "cppuhelper/exc_hlp.hxx"
37 #include "comphelper/servicedecl.hxx"
38 #include "comphelper/unwrapargs.hxx"
39 #include "ucbhelper/content.hxx"
40 #include "com/sun/star/lang/WrappedTargetRuntimeException.hpp"
41 #include "com/sun/star/deployment/InvalidRemovedParameterException.hpp"
42 #include "com/sun/star/deployment/thePackageManagerFactory.hpp"
43 #include "com/sun/star/ucb/InteractiveAugmentedIOException.hpp"
44 #include "com/sun/star/ucb/IOErrorCode.hpp"
45 #include "com/sun/star/beans/StringPair.hpp"
46 #include "com/sun/star/sdbc/XResultSet.hpp"
47 #include "com/sun/star/sdbc/XRow.hpp"
48 #include "unotools/tempfile.hxx"
49 
50 
51 using namespace ::dp_misc;
52 using namespace ::com::sun::star;
53 using namespace ::com::sun::star::uno;
54 using namespace ::com::sun::star::ucb;
55 using ::rtl::OUString;
56 
57 namespace dp_registry {
58 namespace backend {
59 
60 //______________________________________________________________________________
61 PackageRegistryBackend::~PackageRegistryBackend()
62 {
63 }
64 
65 //______________________________________________________________________________
66 void PackageRegistryBackend::disposing( lang::EventObject const & event )
67     throw (RuntimeException)
68 {
69     Reference<deployment::XPackage> xPackage(
70         event.Source, UNO_QUERY_THROW );
71     OUString url( xPackage->getURL() );
72     ::osl::MutexGuard guard( getMutex() );
73     if ( m_bound.erase( url ) != 1 )
74     {
75         OSL_ASSERT( false );
76     }
77 }
78 
79 //______________________________________________________________________________
80 PackageRegistryBackend::PackageRegistryBackend(
81     Sequence<Any> const & args,
82     Reference<XComponentContext> const & xContext )
83     : t_BackendBase( getMutex() ),
84       m_xComponentContext( xContext ),
85       m_eContext( CONTEXT_UNKNOWN ),
86       m_readOnly( false )
87 {
88     boost::optional<OUString> cachePath;
89     boost::optional<bool> readOnly;
90     comphelper::unwrapArgs( args, m_context, cachePath, readOnly );
91     if (cachePath)
92         m_cachePath = *cachePath;
93     if (readOnly)
94         m_readOnly = *readOnly;
95 
96     if (m_context.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("user") ))
97         m_eContext = CONTEXT_USER;
98     else if (m_context.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("shared") ))
99         m_eContext = CONTEXT_SHARED;
100     else if (m_context.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("bundled") ))
101         m_eContext = CONTEXT_BUNDLED;
102     else if (m_context.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("tmp") ))
103         m_eContext = CONTEXT_TMP;
104     else if (m_context.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("bundled_prereg") ))
105         m_eContext = CONTEXT_BUNDLED_PREREG;
106     else if (m_context.matchIgnoreAsciiCaseAsciiL(
107                  RTL_CONSTASCII_STRINGPARAM("vnd.sun.star.tdoc:/") ))
108         m_eContext = CONTEXT_DOCUMENT;
109     else
110         m_eContext = CONTEXT_UNKNOWN;
111 }
112 
113 //______________________________________________________________________________
114 void PackageRegistryBackend::check()
115 {
116     ::osl::MutexGuard guard( getMutex() );
117     if (rBHelper.bInDispose || rBHelper.bDisposed) {
118         throw lang::DisposedException(
119             OUSTR("PackageRegistryBackend instance has already been disposed!"),
120             static_cast<OWeakObject *>(this) );
121     }
122 }
123 
124 //______________________________________________________________________________
125 void PackageRegistryBackend::disposing()
126 {
127     try {
128         for ( t_string2ref::const_iterator i = m_bound.begin(); i != m_bound.end(); i++)
129             i->second->removeEventListener(this);
130         m_bound.clear();
131         m_xComponentContext.clear();
132         WeakComponentImplHelperBase::disposing();
133     }
134     catch (RuntimeException &) {
135         throw;
136     }
137     catch (Exception &) {
138         Any exc( ::cppu::getCaughtException() );
139         throw lang::WrappedTargetRuntimeException(
140             OUSTR("caught unexpected exception while disposing!"),
141             static_cast<OWeakObject *>(this), exc );
142     }
143 }
144 
145 // XPackageRegistry
146 //______________________________________________________________________________
147 Reference<deployment::XPackage> PackageRegistryBackend::bindPackage(
148     OUString const & url, OUString const & mediaType, sal_Bool  bRemoved,
149     OUString const & identifier, Reference<XCommandEnvironment> const & xCmdEnv )
150     throw (deployment::DeploymentException,
151            deployment::InvalidRemovedParameterException,
152            ucb::CommandFailedException,
153            lang::IllegalArgumentException, RuntimeException)
154 {
155     ::osl::ResettableMutexGuard guard( getMutex() );
156     check();
157 
158     t_string2ref::const_iterator const iFind( m_bound.find( url ) );
159     if (iFind != m_bound.end())
160     {
161         Reference<deployment::XPackage> xPackage( iFind->second );
162         if (xPackage.is())
163         {
164             if (mediaType.getLength() &&
165                 mediaType != xPackage->getPackageType()->getMediaType())
166                 throw lang::IllegalArgumentException
167                     (OUSTR("XPackageRegistry::bindPackage: media type does not match"),
168                      static_cast<OWeakObject*>(this), 1);
169             if (xPackage->isRemoved() != bRemoved)
170                 throw deployment::InvalidRemovedParameterException(
171                     OUSTR("XPackageRegistry::bindPackage: bRemoved parameter does not match"),
172                     static_cast<OWeakObject*>(this), xPackage->isRemoved(), xPackage);
173             return xPackage;
174         }
175     }
176 
177     guard.clear();
178 
179     Reference<deployment::XPackage> xNewPackage;
180     try {
181         xNewPackage = bindPackage_( url, mediaType, bRemoved,
182             identifier, xCmdEnv );
183     }
184     catch (RuntimeException &) {
185         throw;
186     }
187     catch (lang::IllegalArgumentException &) {
188         throw;
189     }
190     catch (CommandFailedException &) {
191         throw;
192     }
193     catch (deployment::DeploymentException &) {
194         throw;
195     }
196     catch (Exception &) {
197         Any exc( ::cppu::getCaughtException() );
198         throw deployment::DeploymentException(
199             OUSTR("Error binding package: ") + url,
200             static_cast<OWeakObject *>(this), exc );
201     }
202 
203     guard.reset();
204 
205     ::std::pair< t_string2ref::iterator, bool > insertion(
206         m_bound.insert( t_string2ref::value_type( url, xNewPackage ) ) );
207     if (insertion.second)
208     { // first insertion
209         OSL_ASSERT( Reference<XInterface>(insertion.first->second)
210                     == xNewPackage );
211     }
212     else
213     { // found existing entry
214         Reference<deployment::XPackage> xPackage( insertion.first->second );
215         if (xPackage.is())
216             return xPackage;
217         insertion.first->second = xNewPackage;
218     }
219 
220     guard.clear();
221     xNewPackage->addEventListener( this ); // listen for disposing events
222     return xNewPackage;
223 }
224 
225 OUString PackageRegistryBackend::createFolder(
226     OUString const & relUrl,
227     Reference<ucb::XCommandEnvironment> const & xCmdEnv)
228 {
229     const OUString sDataFolder = makeURL(getCachePath(), relUrl);
230     //make sure the folder exist
231     ucbhelper::Content dataContent;
232     ::dp_misc::create_folder(&dataContent, sDataFolder, xCmdEnv);
233 
234     const OUString sDataFolderURL = dp_misc::expandUnoRcUrl(sDataFolder);
235     const String baseDir(sDataFolder);
236     const ::utl::TempFile aTemp(&baseDir, sal_True);
237     const OUString url = aTemp.GetURL();
238     return sDataFolder + url.copy(url.lastIndexOf('/'));
239 }
240 
241 //folderURL can have the extension .tmp or .tmp_
242 //Before OOo 3.4 the created a tmp file with osl_createTempFile and
243 //then created a Folder with a same name and a trailing '_'
244 //If the folderURL has no '_' then there is no corresponding tmp file.
245 void PackageRegistryBackend::deleteTempFolder(
246     OUString const & folderUrl)
247 {
248     if (folderUrl.getLength())
249     {
250         erase_path( folderUrl, Reference<XCommandEnvironment>(),
251                     false /* no throw: ignore errors */ );
252 
253         if (folderUrl[folderUrl.getLength() - 1] == '_')
254         {
255             const OUString  tempFile = folderUrl.copy(0, folderUrl.getLength() - 1);
256             erase_path( tempFile, Reference<XCommandEnvironment>(),
257                         false /* no throw: ignore errors */ );
258         }
259     }
260 }
261 
262 //usedFolders can contain folder names which have the extension .tmp or .tmp_
263 //Before OOo 3.4 we created a tmp file with osl_createTempFile and
264 //then created a Folder with a same name and a trailing '_'
265 //If the folderURL has no '_' then there is no corresponding tmp file.
266 void PackageRegistryBackend::deleteUnusedFolders(
267     OUString const & relUrl,
268     ::std::list< OUString> const & usedFolders)
269 {
270     try
271     {
272         const OUString sDataFolder = makeURL(getCachePath(), relUrl);
273         ::ucbhelper::Content tempFolder(
274             sDataFolder, Reference<ucb::XCommandEnvironment>());
275         Reference<sdbc::XResultSet> xResultSet(
276             tempFolder.createCursor(
277                 Sequence<OUString>( &StrTitle::get(), 1 ),
278                 ::ucbhelper::INCLUDE_FOLDERS_ONLY ) );
279         // get all temp directories:
280         ::std::vector<OUString> tempEntries;
281 
282         char tmp[] = ".tmp";
283 
284         //Check for ".tmp_" can be removed after OOo 4.0
285         char tmp_[] = ".tmp_";
286         while (xResultSet->next())
287         {
288             OUString title(
289                 Reference<sdbc::XRow>(
290                     xResultSet, UNO_QUERY_THROW )->getString(
291                         1 /* Title */ ) );
292 
293             if (title.endsWithAsciiL(tmp, sizeof(tmp) - 1)
294                 || title.endsWithAsciiL(tmp_, sizeof(tmp_) - 1))
295                 tempEntries.push_back(
296                     makeURLAppendSysPathSegment(sDataFolder, title));
297         }
298 
299         for ( ::std::size_t pos = 0; pos < tempEntries.size(); ++pos )
300         {
301             if (::std::find( usedFolders.begin(), usedFolders.end(), tempEntries[pos] ) ==
302                 usedFolders.end())
303             {
304                 deleteTempFolder(tempEntries[pos]);
305             }
306         }
307     }
308     catch (ucb::InteractiveAugmentedIOException& e)
309     {
310         //In case the folder containing all the data folder does not
311         //exist yet, we ignore the exception
312         if (e.Code != ucb::IOErrorCode_NOT_EXISTING)
313             throw e;
314     }
315 
316 }
317 
318 //##############################################################################
319 
320 //______________________________________________________________________________
321 Package::~Package()
322 {
323 }
324 
325 //______________________________________________________________________________
326 Package::Package( ::rtl::Reference<PackageRegistryBackend> const & myBackend,
327                   OUString const & url,
328                   OUString const & rName,
329                   OUString const & displayName,
330                   Reference<deployment::XPackageTypeInfo> const & xPackageType,
331                   bool bRemoved,
332                   OUString const & identifier)
333     : t_PackageBase( getMutex() ),
334       m_myBackend( myBackend ),
335       m_url( url ),
336       m_name( rName ),
337       m_displayName( displayName ),
338       m_xPackageType( xPackageType ),
339       m_bRemoved(bRemoved),
340       m_identifier(identifier)
341 {
342     if (m_bRemoved)
343     {
344         //We use the last segment of the URL
345         OSL_ASSERT(m_name.getLength() == 0);
346         OUString name = m_url;
347         rtl::Bootstrap::expandMacros(name);
348         sal_Int32 index = name.lastIndexOf('/');
349         if (index != -1 && index < name.getLength())
350             m_name = name.copy(index + 1);
351     }
352 }
353 
354 //______________________________________________________________________________
355 void Package::disposing()
356 {
357     m_myBackend.clear();
358     WeakComponentImplHelperBase::disposing();
359 }
360 
361 //______________________________________________________________________________
362 void Package::check() const
363 {
364     ::osl::MutexGuard guard( getMutex() );
365     if (rBHelper.bInDispose || rBHelper.bDisposed) {
366         throw lang::DisposedException(
367             OUSTR("Package instance has already been disposed!"),
368             static_cast<OWeakObject *>(const_cast<Package *>(this)));
369     }
370 }
371 
372 // XComponent
373 //______________________________________________________________________________
374 void Package::dispose() throw (RuntimeException)
375 {
376     check();
377     WeakComponentImplHelperBase::dispose();
378 }
379 
380 //______________________________________________________________________________
381 void Package::addEventListener(
382     Reference<lang::XEventListener> const & xListener ) throw (RuntimeException)
383 {
384     check();
385     WeakComponentImplHelperBase::addEventListener( xListener );
386 }
387 
388 //______________________________________________________________________________
389 void Package::removeEventListener(
390     Reference<lang::XEventListener> const & xListener ) throw (RuntimeException)
391 {
392     check();
393     WeakComponentImplHelperBase::removeEventListener( xListener );
394 }
395 
396 // XModifyBroadcaster
397 //______________________________________________________________________________
398 void Package::addModifyListener(
399     Reference<util::XModifyListener> const & xListener )
400     throw (RuntimeException)
401 {
402     check();
403     rBHelper.addListener( ::getCppuType( &xListener ), xListener );
404 }
405 
406 //______________________________________________________________________________
407 void Package::removeModifyListener(
408     Reference<util::XModifyListener> const & xListener )
409     throw (RuntimeException)
410 {
411     check();
412     rBHelper.removeListener( ::getCppuType( &xListener ), xListener );
413 }
414 
415 //______________________________________________________________________________
416 void Package::checkAborted(
417     ::rtl::Reference<AbortChannel> const & abortChannel )
418 {
419     if (abortChannel.is() && abortChannel->isAborted()) {
420         throw CommandAbortedException(
421             OUSTR("abort!"), static_cast<OWeakObject *>(this) );
422     }
423 }
424 
425 // XPackage
426 //______________________________________________________________________________
427 Reference<task::XAbortChannel> Package::createAbortChannel()
428     throw (RuntimeException)
429 {
430     check();
431     return new AbortChannel;
432 }
433 
434 //______________________________________________________________________________
435 sal_Bool Package::isBundle() throw (RuntimeException)
436 {
437     return false; // default
438 }
439 
440 //______________________________________________________________________________
441 ::sal_Int32 Package::checkPrerequisites(
442 		const css::uno::Reference< css::task::XAbortChannel >&,
443 		const css::uno::Reference< css::ucb::XCommandEnvironment >&,
444         sal_Bool)
445 		throw (css::deployment::DeploymentException,
446                css::deployment::ExtensionRemovedException,
447                css::ucb::CommandFailedException,
448                css::ucb::CommandAbortedException,
449                css::uno::RuntimeException)
450 {
451     if (m_bRemoved)
452         throw deployment::ExtensionRemovedException();
453 	return 0;
454 }
455 
456 //______________________________________________________________________________
457 ::sal_Bool Package::checkDependencies(
458 		const css::uno::Reference< css::ucb::XCommandEnvironment >& )
459 		throw (css::deployment::DeploymentException,
460                css::deployment::ExtensionRemovedException,
461                css::ucb::CommandFailedException,
462                css::uno::RuntimeException)
463 {
464     if (m_bRemoved)
465         throw deployment::ExtensionRemovedException();
466 	return true;
467 }
468 
469 
470 //______________________________________________________________________________
471 Sequence< Reference<deployment::XPackage> > Package::getBundle(
472     Reference<task::XAbortChannel> const &,
473     Reference<XCommandEnvironment> const & )
474     throw (deployment::DeploymentException,
475            CommandFailedException, CommandAbortedException,
476            lang::IllegalArgumentException, RuntimeException)
477 {
478     return Sequence< Reference<deployment::XPackage> >();
479 }
480 
481 //______________________________________________________________________________
482 OUString Package::getName() throw (RuntimeException)
483 {
484     return m_name;
485 }
486 
487 beans::Optional<OUString> Package::getIdentifier() throw (RuntimeException)
488 {
489     if (m_bRemoved)
490         return beans::Optional<OUString>(true, m_identifier);
491 
492     return beans::Optional<OUString>();
493 }
494 
495 //______________________________________________________________________________
496 OUString Package::getVersion() throw (
497     deployment::ExtensionRemovedException,
498     RuntimeException)
499 {
500     if (m_bRemoved)
501         throw deployment::ExtensionRemovedException();
502     return OUString();
503 }
504 
505 //______________________________________________________________________________
506 OUString Package::getURL() throw (RuntimeException)
507 {
508     return m_url;
509 }
510 
511 //______________________________________________________________________________
512 OUString Package::getDisplayName() throw (
513     deployment::ExtensionRemovedException, RuntimeException)
514 {
515     if (m_bRemoved)
516         throw deployment::ExtensionRemovedException();
517     return m_displayName;
518 }
519 
520 //______________________________________________________________________________
521 OUString Package::getDescription() throw (
522     deployment::ExtensionRemovedException,RuntimeException)
523 {
524     if (m_bRemoved)
525         throw deployment::ExtensionRemovedException();
526     return OUString();
527 }
528 
529 //______________________________________________________________________________
530 OUString Package::getLicenseText() throw (
531     deployment::ExtensionRemovedException,RuntimeException)
532 {
533     if (m_bRemoved)
534         throw deployment::ExtensionRemovedException();
535     return OUString();
536 }
537 
538 //______________________________________________________________________________
539 Sequence<OUString> Package::getUpdateInformationURLs() throw (
540     deployment::ExtensionRemovedException, RuntimeException)
541 {
542     if (m_bRemoved)
543         throw deployment::ExtensionRemovedException();
544     return Sequence<OUString>();
545 }
546 
547 //______________________________________________________________________________
548 css::beans::StringPair Package::getPublisherInfo() throw (
549     deployment::ExtensionRemovedException, RuntimeException)
550 {
551     if (m_bRemoved)
552         throw deployment::ExtensionRemovedException();
553     css::beans::StringPair aEmptyPair;
554     return aEmptyPair;
555 }
556 
557 //______________________________________________________________________________
558 uno::Reference< css::graphic::XGraphic > Package::getIcon( sal_Bool /*bHighContrast*/ )
559     throw (deployment::ExtensionRemovedException, RuntimeException )
560 {
561     if (m_bRemoved)
562         throw deployment::ExtensionRemovedException();
563 
564     uno::Reference< css::graphic::XGraphic > aEmpty;
565     return aEmpty;
566 }
567 
568 //______________________________________________________________________________
569 Reference<deployment::XPackageTypeInfo> Package::getPackageType()
570     throw (RuntimeException)
571 {
572     return m_xPackageType;
573 }
574 
575 //______________________________________________________________________________
576 void Package::exportTo(
577     OUString const & destFolderURL, OUString const & newTitle,
578     sal_Int32 nameClashAction, Reference<XCommandEnvironment> const & xCmdEnv )
579     throw (deployment::ExtensionRemovedException,
580            CommandFailedException, CommandAbortedException, RuntimeException)
581 {
582     if (m_bRemoved)
583         throw deployment::ExtensionRemovedException();
584 
585     ::ucbhelper::Content destFolder( destFolderURL, xCmdEnv );
586     ::ucbhelper::Content sourceContent( getURL(), xCmdEnv );
587     if (! destFolder.transferContent(
588             sourceContent, ::ucbhelper::InsertOperation_COPY,
589             newTitle, nameClashAction ))
590         throw RuntimeException( OUSTR("UCB transferContent() failed!"), 0 );
591 }
592 
593 //______________________________________________________________________________
594 void Package::fireModified()
595 {
596     ::cppu::OInterfaceContainerHelper * container = rBHelper.getContainer(
597         ::getCppuType( static_cast<Reference<
598                        util::XModifyListener> const *>(0) ) );
599     if (container != 0) {
600         Sequence< Reference<XInterface> > elements(
601             container->getElements() );
602         lang::EventObject evt( static_cast<OWeakObject *>(this) );
603         for ( sal_Int32 pos = 0; pos < elements.getLength(); ++pos )
604         {
605             Reference<util::XModifyListener> xListener(
606                 elements[ pos ], UNO_QUERY );
607             if (xListener.is())
608                 xListener->modified( evt );
609         }
610     }
611 }
612 
613 // XPackage
614 //______________________________________________________________________________
615 beans::Optional< beans::Ambiguous<sal_Bool> > Package::isRegistered(
616     Reference<task::XAbortChannel> const & xAbortChannel,
617     Reference<XCommandEnvironment> const & xCmdEnv )
618     throw (deployment::DeploymentException,
619            CommandFailedException, CommandAbortedException, RuntimeException)
620 {
621     try {
622         ::osl::ResettableMutexGuard guard( getMutex() );
623         return isRegistered_( guard,
624                               AbortChannel::get(xAbortChannel),
625                               xCmdEnv );
626     }
627     catch (RuntimeException &) {
628         throw;
629     }
630     catch (CommandFailedException &) {
631         throw;
632     }
633     catch (CommandAbortedException &) {
634         throw;
635     }
636     catch (deployment::DeploymentException &) {
637         throw;
638     }
639     catch (Exception &) {
640         Any exc( ::cppu::getCaughtException() );
641         throw deployment::DeploymentException(
642             OUSTR("unexpected exception occured!"),
643             static_cast<OWeakObject *>(this), exc );
644     }
645 }
646 
647 //______________________________________________________________________________
648 void Package::processPackage_impl(
649     bool doRegisterPackage,
650     bool startup,
651     Reference<task::XAbortChannel> const & xAbortChannel,
652     Reference<XCommandEnvironment> const & xCmdEnv )
653 {
654     check();
655     bool action = false;
656 
657     try {
658         try {
659             ::osl::ResettableMutexGuard guard( getMutex() );
660             beans::Optional< beans::Ambiguous<sal_Bool> > option(
661                 isRegistered_( guard, AbortChannel::get(xAbortChannel),
662                                xCmdEnv ) );
663             action = (option.IsPresent &&
664                       (option.Value.IsAmbiguous ||
665                        (doRegisterPackage ? !option.Value.Value
666                                         : option.Value.Value)));
667             if (action) {
668 
669                 OUString displayName = isRemoved() ? getName() : getDisplayName();
670                 ProgressLevel progress(
671                     xCmdEnv,
672                     (doRegisterPackage
673                      ? PackageRegistryBackend::StrRegisteringPackage::get()
674                      : PackageRegistryBackend::StrRevokingPackage::get())
675                     + displayName );
676                 processPackage_( guard,
677                                  doRegisterPackage,
678                                  startup,
679                                  AbortChannel::get(xAbortChannel),
680                                  xCmdEnv );
681             }
682         }
683         catch (RuntimeException &) {
684             OSL_ENSURE( 0, "### unexpected RuntimeException!" );
685             throw;
686         }
687         catch (CommandFailedException &) {
688             throw;
689         }
690         catch (CommandAbortedException &) {
691             throw;
692         }
693         catch (deployment::DeploymentException &) {
694             throw;
695         }
696         catch (Exception &) {
697             Any exc( ::cppu::getCaughtException() );
698             throw deployment::DeploymentException(
699                 (doRegisterPackage
700                  ? getResourceString(RID_STR_ERROR_WHILE_REGISTERING)
701                  : getResourceString(RID_STR_ERROR_WHILE_REVOKING))
702                 + getDisplayName(), static_cast<OWeakObject *>(this), exc );
703         }
704     }
705     catch (...) {
706         if (action)
707             fireModified();
708         throw;
709     }
710     if (action)
711         fireModified();
712 }
713 
714 //______________________________________________________________________________
715 void Package::registerPackage(
716     sal_Bool startup,
717     Reference<task::XAbortChannel> const & xAbortChannel,
718     Reference<XCommandEnvironment> const & xCmdEnv )
719     throw (deployment::DeploymentException,
720            deployment::ExtensionRemovedException,
721            CommandFailedException, CommandAbortedException,
722            lang::IllegalArgumentException, RuntimeException)
723 {
724     if (m_bRemoved)
725         throw deployment::ExtensionRemovedException();
726     processPackage_impl( true /* register */, startup, xAbortChannel, xCmdEnv );
727 }
728 
729 //______________________________________________________________________________
730 void Package::revokePackage(
731     Reference<task::XAbortChannel> const & xAbortChannel,
732     Reference<XCommandEnvironment> const & xCmdEnv )
733     throw (deployment::DeploymentException,
734            CommandFailedException, CommandAbortedException,
735            lang::IllegalArgumentException, RuntimeException)
736 {
737     processPackage_impl( false /* revoke */, false, xAbortChannel, xCmdEnv );
738 
739 }
740 
741 PackageRegistryBackend * Package::getMyBackend() const
742 {
743     PackageRegistryBackend * pBackend = m_myBackend.get();
744     if (NULL == pBackend)
745     {
746         //May throw a DisposedException
747         check();
748         //We should never get here...
749         throw RuntimeException(
750             OUSTR("Failed to get the BackendImpl"),
751             static_cast<OWeakObject*>(const_cast<Package *>(this)));
752     }
753     return pBackend;
754 }
755 OUString Package::getRepositoryName()
756     throw (RuntimeException)
757 {
758     PackageRegistryBackend * backEnd = getMyBackend();
759     return backEnd->getContext();
760 }
761 
762 beans::Optional< OUString > Package::getRegistrationDataURL()
763         throw (deployment::ExtensionRemovedException,
764                css::uno::RuntimeException)
765 {
766     if (m_bRemoved)
767         throw deployment::ExtensionRemovedException();
768     return beans::Optional<OUString>();
769 }
770 
771 sal_Bool Package::isRemoved()
772     throw (RuntimeException)
773 {
774     return m_bRemoved;
775 }
776 
777 //##############################################################################
778 
779 //______________________________________________________________________________
780 Package::TypeInfo::~TypeInfo()
781 {
782 }
783 
784 // XPackageTypeInfo
785 //______________________________________________________________________________
786 OUString Package::TypeInfo::getMediaType() throw (RuntimeException)
787 {
788     return m_mediaType;
789 }
790 
791 //______________________________________________________________________________
792 OUString Package::TypeInfo::getDescription()
793     throw (deployment::ExtensionRemovedException, RuntimeException)
794 {
795     return getShortDescription();
796 }
797 
798 //______________________________________________________________________________
799 OUString Package::TypeInfo::getShortDescription()
800     throw (deployment::ExtensionRemovedException, RuntimeException)
801 {
802     return m_shortDescr;
803 }
804 
805 //______________________________________________________________________________
806 OUString Package::TypeInfo::getFileFilter() throw (RuntimeException)
807 {
808     return m_fileFilter;
809 }
810 
811 //______________________________________________________________________________
812 Any Package::TypeInfo::getIcon( sal_Bool highContrast, sal_Bool smallIcon )
813     throw (RuntimeException)
814 {
815     if (! smallIcon)
816         return Any();
817     const sal_uInt16 nIconId = (highContrast ? m_smallIcon_HC : m_smallIcon);
818     return Any( &nIconId, getCppuType( static_cast<sal_uInt16 const *>(0) ) );
819 }
820 
821 }
822 }
823 
824