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