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     //Do not call check here. We must not throw an exception here if the object
377     //is being disposed or is already disposed. See com.sun.star.lang.XComponent
378     WeakComponentImplHelperBase::dispose();
379 }
380 
381 //______________________________________________________________________________
382 void Package::addEventListener(
383     Reference<lang::XEventListener> const & xListener ) throw (RuntimeException)
384 {
385     //Do not call check here. We must not throw an exception here if the object
386     //is being disposed or is already disposed. See com.sun.star.lang.XComponent
387     WeakComponentImplHelperBase::addEventListener( xListener );
388 }
389 
390 //______________________________________________________________________________
391 void Package::removeEventListener(
392     Reference<lang::XEventListener> const & xListener ) throw (RuntimeException)
393 {
394     //Do not call check here. We must not throw an exception here if the object
395     //is being disposed or is already disposed. See com.sun.star.lang.XComponent
396     WeakComponentImplHelperBase::removeEventListener( xListener );
397 }
398 
399 // XModifyBroadcaster
400 //______________________________________________________________________________
401 void Package::addModifyListener(
402     Reference<util::XModifyListener> const & xListener )
403     throw (RuntimeException)
404 {
405     check();
406     rBHelper.addListener( ::getCppuType( &xListener ), xListener );
407 }
408 
409 //______________________________________________________________________________
410 void Package::removeModifyListener(
411     Reference<util::XModifyListener> const & xListener )
412     throw (RuntimeException)
413 {
414     check();
415     rBHelper.removeListener( ::getCppuType( &xListener ), xListener );
416 }
417 
418 //______________________________________________________________________________
419 void Package::checkAborted(
420     ::rtl::Reference<AbortChannel> const & abortChannel )
421 {
422     if (abortChannel.is() && abortChannel->isAborted()) {
423         throw CommandAbortedException(
424             OUSTR("abort!"), static_cast<OWeakObject *>(this) );
425     }
426 }
427 
428 // XPackage
429 //______________________________________________________________________________
430 Reference<task::XAbortChannel> Package::createAbortChannel()
431     throw (RuntimeException)
432 {
433     check();
434     return new AbortChannel;
435 }
436 
437 //______________________________________________________________________________
438 sal_Bool Package::isBundle() throw (RuntimeException)
439 {
440     return false; // default
441 }
442 
443 //______________________________________________________________________________
444 ::sal_Int32 Package::checkPrerequisites(
445 		const css::uno::Reference< css::task::XAbortChannel >&,
446 		const css::uno::Reference< css::ucb::XCommandEnvironment >&,
447         sal_Bool)
448 		throw (css::deployment::DeploymentException,
449                css::deployment::ExtensionRemovedException,
450                css::ucb::CommandFailedException,
451                css::ucb::CommandAbortedException,
452                css::uno::RuntimeException)
453 {
454     if (m_bRemoved)
455         throw deployment::ExtensionRemovedException();
456 	return 0;
457 }
458 
459 //______________________________________________________________________________
460 ::sal_Bool Package::checkDependencies(
461 		const css::uno::Reference< css::ucb::XCommandEnvironment >& )
462 		throw (css::deployment::DeploymentException,
463                css::deployment::ExtensionRemovedException,
464                css::ucb::CommandFailedException,
465                css::uno::RuntimeException)
466 {
467     if (m_bRemoved)
468         throw deployment::ExtensionRemovedException();
469 	return true;
470 }
471 
472 
473 //______________________________________________________________________________
474 Sequence< Reference<deployment::XPackage> > Package::getBundle(
475     Reference<task::XAbortChannel> const &,
476     Reference<XCommandEnvironment> const & )
477     throw (deployment::DeploymentException,
478            CommandFailedException, CommandAbortedException,
479            lang::IllegalArgumentException, RuntimeException)
480 {
481     return Sequence< Reference<deployment::XPackage> >();
482 }
483 
484 //______________________________________________________________________________
485 OUString Package::getName() throw (RuntimeException)
486 {
487     return m_name;
488 }
489 
490 beans::Optional<OUString> Package::getIdentifier() throw (RuntimeException)
491 {
492     if (m_bRemoved)
493         return beans::Optional<OUString>(true, m_identifier);
494 
495     return beans::Optional<OUString>();
496 }
497 
498 //______________________________________________________________________________
499 OUString Package::getVersion() throw (
500     deployment::ExtensionRemovedException,
501     RuntimeException)
502 {
503     if (m_bRemoved)
504         throw deployment::ExtensionRemovedException();
505     return OUString();
506 }
507 
508 //______________________________________________________________________________
509 OUString Package::getURL() throw (RuntimeException)
510 {
511     return m_url;
512 }
513 
514 //______________________________________________________________________________
515 OUString Package::getDisplayName() throw (
516     deployment::ExtensionRemovedException, RuntimeException)
517 {
518     if (m_bRemoved)
519         throw deployment::ExtensionRemovedException();
520     return m_displayName;
521 }
522 
523 //______________________________________________________________________________
524 OUString Package::getDescription() throw (
525     deployment::ExtensionRemovedException,RuntimeException)
526 {
527     if (m_bRemoved)
528         throw deployment::ExtensionRemovedException();
529     return OUString();
530 }
531 
532 //______________________________________________________________________________
533 OUString Package::getLicenseText() throw (
534     deployment::ExtensionRemovedException,RuntimeException)
535 {
536     if (m_bRemoved)
537         throw deployment::ExtensionRemovedException();
538     return OUString();
539 }
540 
541 //______________________________________________________________________________
542 Sequence<OUString> Package::getUpdateInformationURLs() throw (
543     deployment::ExtensionRemovedException, RuntimeException)
544 {
545     if (m_bRemoved)
546         throw deployment::ExtensionRemovedException();
547     return Sequence<OUString>();
548 }
549 
550 //______________________________________________________________________________
551 css::beans::StringPair Package::getPublisherInfo() throw (
552     deployment::ExtensionRemovedException, RuntimeException)
553 {
554     if (m_bRemoved)
555         throw deployment::ExtensionRemovedException();
556     css::beans::StringPair aEmptyPair;
557     return aEmptyPair;
558 }
559 
560 //______________________________________________________________________________
561 uno::Reference< css::graphic::XGraphic > Package::getIcon( sal_Bool /*bHighContrast*/ )
562     throw (deployment::ExtensionRemovedException, RuntimeException )
563 {
564     if (m_bRemoved)
565         throw deployment::ExtensionRemovedException();
566 
567     uno::Reference< css::graphic::XGraphic > aEmpty;
568     return aEmpty;
569 }
570 
571 //______________________________________________________________________________
572 Reference<deployment::XPackageTypeInfo> Package::getPackageType()
573     throw (RuntimeException)
574 {
575     return m_xPackageType;
576 }
577 
578 //______________________________________________________________________________
579 void Package::exportTo(
580     OUString const & destFolderURL, OUString const & newTitle,
581     sal_Int32 nameClashAction, Reference<XCommandEnvironment> const & xCmdEnv )
582     throw (deployment::ExtensionRemovedException,
583            CommandFailedException, CommandAbortedException, RuntimeException)
584 {
585     if (m_bRemoved)
586         throw deployment::ExtensionRemovedException();
587 
588     ::ucbhelper::Content destFolder( destFolderURL, xCmdEnv );
589     ::ucbhelper::Content sourceContent( getURL(), xCmdEnv );
590     if (! destFolder.transferContent(
591             sourceContent, ::ucbhelper::InsertOperation_COPY,
592             newTitle, nameClashAction ))
593         throw RuntimeException( OUSTR("UCB transferContent() failed!"), 0 );
594 }
595 
596 //______________________________________________________________________________
597 void Package::fireModified()
598 {
599     ::cppu::OInterfaceContainerHelper * container = rBHelper.getContainer(
600         ::getCppuType( static_cast<Reference<
601                        util::XModifyListener> const *>(0) ) );
602     if (container != 0) {
603         Sequence< Reference<XInterface> > elements(
604             container->getElements() );
605         lang::EventObject evt( static_cast<OWeakObject *>(this) );
606         for ( sal_Int32 pos = 0; pos < elements.getLength(); ++pos )
607         {
608             Reference<util::XModifyListener> xListener(
609                 elements[ pos ], UNO_QUERY );
610             if (xListener.is())
611                 xListener->modified( evt );
612         }
613     }
614 }
615 
616 // XPackage
617 //______________________________________________________________________________
618 beans::Optional< beans::Ambiguous<sal_Bool> > Package::isRegistered(
619     Reference<task::XAbortChannel> const & xAbortChannel,
620     Reference<XCommandEnvironment> const & xCmdEnv )
621     throw (deployment::DeploymentException,
622            CommandFailedException, CommandAbortedException, RuntimeException)
623 {
624     try {
625         ::osl::ResettableMutexGuard guard( getMutex() );
626         return isRegistered_( guard,
627                               AbortChannel::get(xAbortChannel),
628                               xCmdEnv );
629     }
630     catch (RuntimeException &) {
631         throw;
632     }
633     catch (CommandFailedException &) {
634         throw;
635     }
636     catch (CommandAbortedException &) {
637         throw;
638     }
639     catch (deployment::DeploymentException &) {
640         throw;
641     }
642     catch (Exception &) {
643         Any exc( ::cppu::getCaughtException() );
644         throw deployment::DeploymentException(
645             OUSTR("unexpected exception occured!"),
646             static_cast<OWeakObject *>(this), exc );
647     }
648 }
649 
650 //______________________________________________________________________________
651 void Package::processPackage_impl(
652     bool doRegisterPackage,
653     bool startup,
654     Reference<task::XAbortChannel> const & xAbortChannel,
655     Reference<XCommandEnvironment> const & xCmdEnv )
656 {
657     check();
658     bool action = false;
659 
660     try {
661         try {
662             ::osl::ResettableMutexGuard guard( getMutex() );
663             beans::Optional< beans::Ambiguous<sal_Bool> > option(
664                 isRegistered_( guard, AbortChannel::get(xAbortChannel),
665                                xCmdEnv ) );
666             action = (option.IsPresent &&
667                       (option.Value.IsAmbiguous ||
668                        (doRegisterPackage ? !option.Value.Value
669                                         : option.Value.Value)));
670             if (action) {
671 
672                 OUString displayName = isRemoved() ? getName() : getDisplayName();
673                 ProgressLevel progress(
674                     xCmdEnv,
675                     (doRegisterPackage
676                      ? PackageRegistryBackend::StrRegisteringPackage::get()
677                      : PackageRegistryBackend::StrRevokingPackage::get())
678                     + displayName );
679                 processPackage_( guard,
680                                  doRegisterPackage,
681                                  startup,
682                                  AbortChannel::get(xAbortChannel),
683                                  xCmdEnv );
684             }
685         }
686         catch (RuntimeException &) {
687             OSL_ENSURE( 0, "### unexpected RuntimeException!" );
688             throw;
689         }
690         catch (CommandFailedException &) {
691             throw;
692         }
693         catch (CommandAbortedException &) {
694             throw;
695         }
696         catch (deployment::DeploymentException &) {
697             throw;
698         }
699         catch (Exception &) {
700             Any exc( ::cppu::getCaughtException() );
701             throw deployment::DeploymentException(
702                 (doRegisterPackage
703                  ? getResourceString(RID_STR_ERROR_WHILE_REGISTERING)
704                  : getResourceString(RID_STR_ERROR_WHILE_REVOKING))
705                 + getDisplayName(), static_cast<OWeakObject *>(this), exc );
706         }
707     }
708     catch (...) {
709         if (action)
710             fireModified();
711         throw;
712     }
713     if (action)
714         fireModified();
715 }
716 
717 //______________________________________________________________________________
718 void Package::registerPackage(
719     sal_Bool startup,
720     Reference<task::XAbortChannel> const & xAbortChannel,
721     Reference<XCommandEnvironment> const & xCmdEnv )
722     throw (deployment::DeploymentException,
723            deployment::ExtensionRemovedException,
724            CommandFailedException, CommandAbortedException,
725            lang::IllegalArgumentException, RuntimeException)
726 {
727     if (m_bRemoved)
728         throw deployment::ExtensionRemovedException();
729     processPackage_impl( true /* register */, startup, xAbortChannel, xCmdEnv );
730 }
731 
732 //______________________________________________________________________________
733 void Package::revokePackage(
734     Reference<task::XAbortChannel> const & xAbortChannel,
735     Reference<XCommandEnvironment> const & xCmdEnv )
736     throw (deployment::DeploymentException,
737            CommandFailedException, CommandAbortedException,
738            lang::IllegalArgumentException, RuntimeException)
739 {
740     processPackage_impl( false /* revoke */, false, xAbortChannel, xCmdEnv );
741 
742 }
743 
744 PackageRegistryBackend * Package::getMyBackend() const
745 {
746     PackageRegistryBackend * pBackend = m_myBackend.get();
747     if (NULL == pBackend)
748     {
749         //May throw a DisposedException
750         check();
751         //We should never get here...
752         throw RuntimeException(
753             OUSTR("Failed to get the BackendImpl"),
754             static_cast<OWeakObject*>(const_cast<Package *>(this)));
755     }
756     return pBackend;
757 }
758 OUString Package::getRepositoryName()
759     throw (RuntimeException)
760 {
761     PackageRegistryBackend * backEnd = getMyBackend();
762     return backEnd->getContext();
763 }
764 
765 beans::Optional< OUString > Package::getRegistrationDataURL()
766         throw (deployment::ExtensionRemovedException,
767                css::uno::RuntimeException)
768 {
769     if (m_bRemoved)
770         throw deployment::ExtensionRemovedException();
771     return beans::Optional<OUString>();
772 }
773 
774 sal_Bool Package::isRemoved()
775     throw (RuntimeException)
776 {
777     return m_bRemoved;
778 }
779 
780 //##############################################################################
781 
782 //______________________________________________________________________________
783 Package::TypeInfo::~TypeInfo()
784 {
785 }
786 
787 // XPackageTypeInfo
788 //______________________________________________________________________________
789 OUString Package::TypeInfo::getMediaType() throw (RuntimeException)
790 {
791     return m_mediaType;
792 }
793 
794 //______________________________________________________________________________
795 OUString Package::TypeInfo::getDescription()
796     throw (deployment::ExtensionRemovedException, RuntimeException)
797 {
798     return getShortDescription();
799 }
800 
801 //______________________________________________________________________________
802 OUString Package::TypeInfo::getShortDescription()
803     throw (deployment::ExtensionRemovedException, RuntimeException)
804 {
805     return m_shortDescr;
806 }
807 
808 //______________________________________________________________________________
809 OUString Package::TypeInfo::getFileFilter() throw (RuntimeException)
810 {
811     return m_fileFilter;
812 }
813 
814 //______________________________________________________________________________
815 Any Package::TypeInfo::getIcon( sal_Bool highContrast, sal_Bool smallIcon )
816     throw (RuntimeException)
817 {
818     if (! smallIcon)
819         return Any();
820     const sal_uInt16 nIconId = (highContrast ? m_smallIcon_HC : m_smallIcon);
821     return Any( &nIconId, getCppuType( static_cast<sal_uInt16 const *>(0) ) );
822 }
823 
824 }
825 }
826 
827