1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2009 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
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.
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).
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.
26 ************************************************************************/
27 // MARKER(update_precomp.py): autogen include statement, do not remove
28 #include "precompiled_desktop.hxx"
30 #include <rtl/bootstrap.hxx>
31 #include <rtl/ustring.hxx>
32 #include <unotools/configmgr.hxx>
34 #include <comphelper/processfactory.hxx>
35 #include <comphelper/sequence.hxx>
36 #include <cppuhelper/bootstrap.hxx>
38 #include <com/sun/star/beans/XPropertySet.hpp>
39 #include <com/sun/star/beans/NamedValue.hpp>
40 #include "com/sun/star/deployment/XPackage.hpp"
41 #include "com/sun/star/deployment/XPackageManager.hpp"
42 #include "com/sun/star/deployment/thePackageManagerFactory.hpp"
43 #include <com/sun/star/task/XJob.hpp>
44 #include <com/sun/star/task/XJobExecutor.hpp>
45 #include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
46 #include <com/sun/star/util/XChangesBatch.hpp>
51 using namespace desktop
;
52 using namespace com::sun::star
;
54 #define UNISTRING(s) rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(s))
56 static const OUString
sConfigSrvc( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.configuration.ConfigurationProvider" ) );
57 static const OUString
sAccessSrvc( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.configuration.ConfigurationUpdateAccess" ) );
59 //------------------------------------------------------------------------------
60 static sal_Int16
impl_showExtensionDialog( uno::Reference
< uno::XComponentContext
> &xContext
)
62 rtl::OUString sServiceName
= UNISTRING("com.sun.star.deployment.ui.UpdateRequiredDialog");
63 uno::Reference
< uno::XInterface
> xService
;
66 uno::Reference
< lang::XMultiComponentFactory
> xServiceManager( xContext
->getServiceManager() );
67 if( !xServiceManager
.is() )
68 throw uno::RuntimeException(
69 UNISTRING( "impl_showExtensionDialog(): unable to obtain service manager from component context" ), uno::Reference
< uno::XInterface
> () );
71 xService
= xServiceManager
->createInstanceWithContext( sServiceName
, xContext
);
72 uno::Reference
< ui::dialogs::XExecutableDialog
> xExecuteable( xService
, uno::UNO_QUERY
);
73 if ( xExecuteable
.is() )
74 nRet
= xExecuteable
->execute();
79 //------------------------------------------------------------------------------
80 // Check dependencies of all packages
81 //------------------------------------------------------------------------------
82 static bool impl_checkDependencies( const uno::Reference
< deployment::XPackageManager
> &xPackageManager
)
84 uno::Sequence
< uno::Reference
< deployment::XPackage
> > packages
;
87 packages
= xPackageManager
->getDeployedPackages( uno::Reference
< task::XAbortChannel
>(),
88 uno::Reference
< ucb::XCommandEnvironment
>() );
90 catch ( deployment::DeploymentException
& ) { /* handleGeneralError(e.Cause);*/ }
91 catch ( ucb::CommandFailedException
& ) { /* handleGeneralError(e.Reason);*/ }
92 catch ( ucb::CommandAbortedException
& ) {}
93 catch ( lang::IllegalArgumentException
& e
) {
94 throw uno::RuntimeException( e
.Message
, e
.Context
);
97 for ( sal_Int32 i
= 0; i
< packages
.getLength(); ++i
)
99 bool bRegistered
= false;
101 beans::Optional
< beans::Ambiguous
< sal_Bool
> > option( packages
[i
]->isRegistered( uno::Reference
< task::XAbortChannel
>(),
102 uno::Reference
< ucb::XCommandEnvironment
>() ) );
103 if ( option
.IsPresent
)
105 ::beans::Ambiguous
< sal_Bool
> const & reg
= option
.Value
;
106 if ( reg
.IsAmbiguous
)
109 bRegistered
= reg
.Value
? true : false;
114 catch ( uno::RuntimeException
& ) { throw; }
115 catch ( uno::Exception
& exc
) {
117 OSL_ENSURE( 0, ::rtl::OUStringToOString( exc
.Message
, RTL_TEXTENCODING_UTF8
).getStr() );
123 bool bDependenciesValid
= false;
125 bDependenciesValid
= packages
[i
]->checkDependencies( uno::Reference
< ucb::XCommandEnvironment
>() );
127 catch ( deployment::DeploymentException
& ) {}
128 if ( ! bDependenciesValid
)
137 //------------------------------------------------------------------------------
138 // resets the 'check needed' flag (needed, if aborted)
139 //------------------------------------------------------------------------------
140 static void impl_setNeedsCompatCheck()
143 Reference
< XMultiServiceFactory
> xFactory
= ::comphelper::getProcessServiceFactory();
144 // get configuration provider
145 Reference
< XMultiServiceFactory
> theConfigProvider
= Reference
< XMultiServiceFactory
>(
146 xFactory
->createInstance(sConfigSrvc
), UNO_QUERY_THROW
);
148 Sequence
< Any
> theArgs(1);
149 beans::NamedValue
v( OUString::createFromAscii("NodePath"),
150 makeAny( OUString::createFromAscii("org.openoffice.Setup/Office") ) );
152 Reference
< beans::XPropertySet
> pset
= Reference
< beans::XPropertySet
>(
153 theConfigProvider
->createInstanceWithArguments( sAccessSrvc
, theArgs
), UNO_QUERY_THROW
);
155 Any value
= makeAny( OUString::createFromAscii("never") );
157 pset
->setPropertyValue( OUString::createFromAscii("LastCompatibilityCheckID"), value
);
158 Reference
< util::XChangesBatch
>( pset
, UNO_QUERY_THROW
)->commitChanges();
160 catch (const Exception
&) {}
163 //------------------------------------------------------------------------------
164 static bool impl_check()
166 uno::Reference
< uno::XComponentContext
> xContext
= comphelper_getProcessComponentContext();
167 uno::Reference
< deployment::XPackageManager
> xManager
;
168 bool bDependenciesValid
= true;
171 xManager
= deployment::thePackageManagerFactory::get( xContext
)->getPackageManager( UNISTRING("user") );
173 catch ( ucb::CommandFailedException
& ){}
174 catch ( uno::RuntimeException
& ) {}
177 bDependenciesValid
= impl_checkDependencies( xManager
);
179 if ( bDependenciesValid
)
182 xManager
= deployment::thePackageManagerFactory::get( xContext
)->getPackageManager( UNISTRING("shared") );
184 catch ( ucb::CommandFailedException
& ){}
185 catch ( uno::RuntimeException
& ) {}
188 bDependenciesValid
= impl_checkDependencies( xManager
);
192 if ( !bDependenciesValid
)
193 nRet
= impl_showExtensionDialog( xContext
);
197 impl_setNeedsCompatCheck();
204 //------------------------------------------------------------------------------
205 // to check, if we need checking the dependencies of the extensions again, we compare
206 // the build id of the office with the one of the last check
207 //------------------------------------------------------------------------------
208 static bool impl_needsCompatCheck()
210 bool bNeedsCheck
= false;
211 rtl::OUString aLastCheckBuildID
;
212 rtl::OUString
aCurrentBuildID( UNISTRING( "${$OOO_BASE_DIR/program/" SAL_CONFIGFILE("version") ":buildid}" ) );
213 rtl::Bootstrap::expandMacros( aCurrentBuildID
);
216 Reference
< XMultiServiceFactory
> xFactory
= ::comphelper::getProcessServiceFactory();
217 // get configuration provider
218 Reference
< XMultiServiceFactory
> theConfigProvider
= Reference
< XMultiServiceFactory
>(
219 xFactory
->createInstance(sConfigSrvc
), UNO_QUERY_THROW
);
221 Sequence
< Any
> theArgs(1);
222 beans::NamedValue
v( OUString::createFromAscii("NodePath"),
223 makeAny( OUString::createFromAscii("org.openoffice.Setup/Office") ) );
225 Reference
< beans::XPropertySet
> pset
= Reference
< beans::XPropertySet
>(
226 theConfigProvider
->createInstanceWithArguments( sAccessSrvc
, theArgs
), UNO_QUERY_THROW
);
228 Any result
= pset
->getPropertyValue( OUString::createFromAscii("LastCompatibilityCheckID") );
230 result
>>= aLastCheckBuildID
;
231 if ( aLastCheckBuildID
!= aCurrentBuildID
)
234 result
<<= aCurrentBuildID
;
235 pset
->setPropertyValue( OUString::createFromAscii("LastCompatibilityCheckID"), result
);
236 Reference
< util::XChangesBatch
>( pset
, UNO_QUERY_THROW
)->commitChanges();
239 catch (const Exception
&) {}
244 //------------------------------------------------------------------------------
245 // Do we need to check the dependencies of the extensions?
246 // When there are unresolved issues, we can't continue with startup
247 sal_Bool
Desktop::CheckExtensionDependencies()
249 sal_Bool bAbort
= false;
251 if ( impl_needsCompatCheck() )
252 bAbort
= impl_check();