12722ceddSAndrew Rist /**************************************************************
233608c82Smseidel *
32722ceddSAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one
42722ceddSAndrew Rist * or more contributor license agreements. See the NOTICE file
52722ceddSAndrew Rist * distributed with this work for additional information
62722ceddSAndrew Rist * regarding copyright ownership. The ASF licenses this file
72722ceddSAndrew Rist * to you under the Apache License, Version 2.0 (the
82722ceddSAndrew Rist * "License"); you may not use this file except in compliance
92722ceddSAndrew Rist * with the License. You may obtain a copy of the License at
1033608c82Smseidel *
112722ceddSAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0
1233608c82Smseidel *
132722ceddSAndrew Rist * Unless required by applicable law or agreed to in writing,
142722ceddSAndrew Rist * software distributed under the License is distributed on an
152722ceddSAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
162722ceddSAndrew Rist * KIND, either express or implied. See the License for the
172722ceddSAndrew Rist * specific language governing permissions and limitations
182722ceddSAndrew Rist * under the License.
1933608c82Smseidel *
202722ceddSAndrew Rist *************************************************************/
212722ceddSAndrew Rist
222722ceddSAndrew Rist
23cdf0e10cSrcweir
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir
26cdf0e10cSrcweir #include "dp_misc.h"
27cdf0e10cSrcweir #include "unopkg_main.h"
28cdf0e10cSrcweir #include "unopkg_shared.h"
29cdf0e10cSrcweir #include "dp_identifier.hxx"
30cdf0e10cSrcweir #include "sal/main.h"
31cdf0e10cSrcweir #include "tools/extendapplicationenvironment.hxx"
32cdf0e10cSrcweir #include "rtl/ustrbuf.hxx"
33cdf0e10cSrcweir #include "rtl/uri.hxx"
34cdf0e10cSrcweir #include "rtl/bootstrap.hxx"
35cdf0e10cSrcweir #include "osl/thread.h"
36cdf0e10cSrcweir #include "osl/process.h"
37cdf0e10cSrcweir #include "osl/conditn.hxx"
38cdf0e10cSrcweir #include "osl/file.hxx"
39cdf0e10cSrcweir #include "cppuhelper/implbase1.hxx"
40cdf0e10cSrcweir #include "cppuhelper/exc_hlp.hxx"
41cdf0e10cSrcweir #include "comphelper/anytostring.hxx"
42cdf0e10cSrcweir #include "comphelper/sequence.hxx"
43cdf0e10cSrcweir #include "com/sun/star/deployment/ExtensionManager.hpp"
44cdf0e10cSrcweir
45cdf0e10cSrcweir #include "com/sun/star/deployment/ui/PackageManagerDialog.hpp"
46cdf0e10cSrcweir #include "com/sun/star/ui/dialogs/XExecutableDialog.hpp"
47cdf0e10cSrcweir #include "com/sun/star/lang/DisposedException.hpp"
48cdf0e10cSrcweir #include "boost/scoped_array.hpp"
49cdf0e10cSrcweir #include "com/sun/star/ui/dialogs/XDialogClosedListener.hpp"
50cdf0e10cSrcweir #include "com/sun/star/bridge/XBridgeFactory.hpp"
51cdf0e10cSrcweir #include <stdio.h>
52cdf0e10cSrcweir #include <vector>
53cdf0e10cSrcweir
54cdf0e10cSrcweir
55cdf0e10cSrcweir using namespace ::com::sun::star;
56cdf0e10cSrcweir using namespace ::com::sun::star::uno;
57cdf0e10cSrcweir using namespace ::unopkg;
58cdf0e10cSrcweir using ::rtl::OUString;
59cdf0e10cSrcweir namespace css = ::com::sun::star;
60cdf0e10cSrcweir namespace {
61cdf0e10cSrcweir
62cdf0e10cSrcweir struct ExtensionName
63cdf0e10cSrcweir {
64cdf0e10cSrcweir OUString m_str;
ExtensionName__anon3d4c0c360111::ExtensionName65cdf0e10cSrcweir ExtensionName( OUString const & str ) : m_str( str ) {}
operator ()__anon3d4c0c360111::ExtensionName66cdf0e10cSrcweir bool operator () ( Reference<deployment::XPackage> const & e ) const
67cdf0e10cSrcweir {
68cdf0e10cSrcweir if (m_str.equals(dp_misc::getIdentifier(e))
6933608c82Smseidel || m_str.equals(e->getName()))
70cdf0e10cSrcweir return true;
71cdf0e10cSrcweir return false;
72cdf0e10cSrcweir }
73cdf0e10cSrcweir };
74cdf0e10cSrcweir
75cdf0e10cSrcweir //------------------------------------------------------------------------------
76cdf0e10cSrcweir const char s_usingText [] =
77cdf0e10cSrcweir "\n"
78cdf0e10cSrcweir "using: " APP_NAME " add <options> extension-path...\n"
7933608c82Smseidel " " APP_NAME " validate <options> extension-identifier...\n"
80cdf0e10cSrcweir " " APP_NAME " remove <options> extension-identifier...\n"
81cdf0e10cSrcweir " " APP_NAME " list <options> extension-identifier...\n"
82cdf0e10cSrcweir " " APP_NAME " reinstall <options>\n"
83cdf0e10cSrcweir " " APP_NAME " gui\n"
84cdf0e10cSrcweir " " APP_NAME " -V\n"
85cdf0e10cSrcweir " " APP_NAME " -h\n"
86cdf0e10cSrcweir "\n"
87cdf0e10cSrcweir "sub-commands:\n"
88cdf0e10cSrcweir " add add extension\n"
89cdf0e10cSrcweir " validate checks the prerequisites of an installed extension and"
90cdf0e10cSrcweir " registers it if possible\n"
91cdf0e10cSrcweir " remove remove extensions by identifier\n"
92cdf0e10cSrcweir " reinstall expert feature: reinstall all deployed extensions\n"
93cdf0e10cSrcweir " list list information about deployed extensions\n"
94cdf0e10cSrcweir " gui raise Extension Manager Graphical User Interface (GUI)\n"
95cdf0e10cSrcweir "\n"
96cdf0e10cSrcweir "options:\n"
97cdf0e10cSrcweir " -h, --help this help\n"
98cdf0e10cSrcweir " -V, --version version information\n"
99cdf0e10cSrcweir " -v, --verbose verbose output to stdout\n"
100cdf0e10cSrcweir " -f, --force force overwriting existing extensions\n"
101cdf0e10cSrcweir " -s, --suppress-license prevents showing the license provided that\n"
102cdf0e10cSrcweir " the extension allows it\n"
103cdf0e10cSrcweir " --log-file <file> custom log file; default: <cache-dir>/log.txt\n"
104cdf0e10cSrcweir " --shared expert feature: operate on shared installation\n"
105cdf0e10cSrcweir " deployment context;\n"
106cdf0e10cSrcweir " run only when no concurrent Office\n"
107cdf0e10cSrcweir " process(es) are running!\n"
108cdf0e10cSrcweir " --bundled expert feature: operate on bundled extensions. Only\n"
109cdf0e10cSrcweir " works with list, validate, reinstall;\n"
110cdf0e10cSrcweir " --deployment-context expert feature: explicit deployment context\n"
111cdf0e10cSrcweir " <context>\n"
112cdf0e10cSrcweir "\n"
113cdf0e10cSrcweir "To learn more about the Extension Manager and extensions, see:\n"
114*c059a6bfSmseidel "https://wiki.openoffice.org/wiki/Documentation/DevGuide/Extensions/Extensions\n\n";
115cdf0e10cSrcweir
116cdf0e10cSrcweir //------------------------------------------------------------------------------
117cdf0e10cSrcweir const OptionInfo s_option_infos [] = {
118cdf0e10cSrcweir { RTL_CONSTASCII_STRINGPARAM("help"), 'h', false },
119cdf0e10cSrcweir { RTL_CONSTASCII_STRINGPARAM("version"), 'V', false },
120cdf0e10cSrcweir { RTL_CONSTASCII_STRINGPARAM("verbose"), 'v', false },
121cdf0e10cSrcweir { RTL_CONSTASCII_STRINGPARAM("force"), 'f', false },
122cdf0e10cSrcweir { RTL_CONSTASCII_STRINGPARAM("log-file"), '\0', true },
123cdf0e10cSrcweir { RTL_CONSTASCII_STRINGPARAM("shared"), '\0', false },
124cdf0e10cSrcweir { RTL_CONSTASCII_STRINGPARAM("deployment-context"), '\0', true },
125cdf0e10cSrcweir { RTL_CONSTASCII_STRINGPARAM("bundled"), '\0', false},
126cdf0e10cSrcweir { RTL_CONSTASCII_STRINGPARAM("suppress-license"), 's', false},
127cdf0e10cSrcweir
128cdf0e10cSrcweir { 0, 0, '\0', false }
129cdf0e10cSrcweir };
130cdf0e10cSrcweir
131cdf0e10cSrcweir class DialogClosedListenerImpl :
132cdf0e10cSrcweir public ::cppu::WeakImplHelper1< ui::dialogs::XDialogClosedListener >
133cdf0e10cSrcweir {
134cdf0e10cSrcweir osl::Condition & m_rDialogClosedCondition;
135cdf0e10cSrcweir
136cdf0e10cSrcweir public:
DialogClosedListenerImpl(osl::Condition & rDialogClosedCondition)137cdf0e10cSrcweir DialogClosedListenerImpl( osl::Condition & rDialogClosedCondition )
138cdf0e10cSrcweir : m_rDialogClosedCondition( rDialogClosedCondition ) {}
139cdf0e10cSrcweir
140cdf0e10cSrcweir // XEventListener (base of XDialogClosedListener)
141cdf0e10cSrcweir virtual void SAL_CALL disposing( lang::EventObject const & Source )
142cdf0e10cSrcweir throw (RuntimeException);
143cdf0e10cSrcweir
144cdf0e10cSrcweir // XDialogClosedListener
145cdf0e10cSrcweir virtual void SAL_CALL dialogClosed(
146cdf0e10cSrcweir ui::dialogs::DialogClosedEvent const & aEvent )
147cdf0e10cSrcweir throw (RuntimeException);
148cdf0e10cSrcweir };
149cdf0e10cSrcweir
150cdf0e10cSrcweir // XEventListener (base of XDialogClosedListener)
disposing(lang::EventObject const &)151cdf0e10cSrcweir void DialogClosedListenerImpl::disposing( lang::EventObject const & )
152cdf0e10cSrcweir throw (RuntimeException)
153cdf0e10cSrcweir {
154cdf0e10cSrcweir // nothing to do
155cdf0e10cSrcweir }
156cdf0e10cSrcweir
157cdf0e10cSrcweir // XDialogClosedListener
dialogClosed(ui::dialogs::DialogClosedEvent const &)158cdf0e10cSrcweir void DialogClosedListenerImpl::dialogClosed(
159cdf0e10cSrcweir ui::dialogs::DialogClosedEvent const & )
160cdf0e10cSrcweir throw (RuntimeException)
161cdf0e10cSrcweir {
162cdf0e10cSrcweir m_rDialogClosedCondition.set();
163cdf0e10cSrcweir }
164cdf0e10cSrcweir
165cdf0e10cSrcweir // If a package had been installed with a pre OOo 2.2, it could not normally be
166cdf0e10cSrcweir // found via its identifier; similarly (and for ease of use), a package
167cdf0e10cSrcweir // installed with OOo 2.2 or later could not normally be found via its file
168cdf0e10cSrcweir // name.
findPackage(OUString const & repository,Reference<deployment::XExtensionManager> const & manager,Reference<ucb::XCommandEnvironment> const & environment,OUString const & idOrFileName)169cdf0e10cSrcweir Reference<deployment::XPackage> findPackage(
170cdf0e10cSrcweir OUString const & repository,
171cdf0e10cSrcweir Reference<deployment::XExtensionManager> const & manager,
172cdf0e10cSrcweir Reference<ucb::XCommandEnvironment > const & environment,
173cdf0e10cSrcweir OUString const & idOrFileName )
174cdf0e10cSrcweir {
175cdf0e10cSrcweir Sequence< Reference<deployment::XPackage> > ps(
176cdf0e10cSrcweir manager->getDeployedExtensions(repository,
177cdf0e10cSrcweir Reference<task::XAbortChannel>(), environment ) );
178cdf0e10cSrcweir for ( sal_Int32 i = 0; i < ps.getLength(); ++i )
179cdf0e10cSrcweir if ( dp_misc::getIdentifier( ps[i] ) == idOrFileName )
180cdf0e10cSrcweir return ps[i];
181cdf0e10cSrcweir for ( sal_Int32 i = 0; i < ps.getLength(); ++i )
182cdf0e10cSrcweir if ( ps[i]->getName() == idOrFileName )
183cdf0e10cSrcweir return ps[i];
184cdf0e10cSrcweir return Reference<deployment::XPackage>();
185cdf0e10cSrcweir }
186cdf0e10cSrcweir
187cdf0e10cSrcweir } // anon namespace
188cdf0e10cSrcweir
189cdf0e10cSrcweir
190cdf0e10cSrcweir //workaround for some reason the bridge threads which communicate with the uno.exe
19133608c82Smseidel //process are not released on time
disposeBridges(Reference<css::uno::XComponentContext> ctx)192cdf0e10cSrcweir void disposeBridges(Reference<css::uno::XComponentContext> ctx)
193cdf0e10cSrcweir {
194cdf0e10cSrcweir if (!ctx.is())
195cdf0e10cSrcweir return;
196cdf0e10cSrcweir
197cdf0e10cSrcweir Reference<css::bridge::XBridgeFactory> bridgeFac(
198cdf0e10cSrcweir ctx->getServiceManager()->createInstanceWithContext(
199cdf0e10cSrcweir OUSTR("com.sun.star.bridge.BridgeFactory"), ctx),
200cdf0e10cSrcweir UNO_QUERY);
201cdf0e10cSrcweir
202cdf0e10cSrcweir if (bridgeFac.is())
203cdf0e10cSrcweir {
204cdf0e10cSrcweir const Sequence< Reference<css::bridge::XBridge> >seqBridges = bridgeFac->getExistingBridges();
205cdf0e10cSrcweir for (sal_Int32 i = 0; i < seqBridges.getLength(); i++)
20633608c82Smseidel {
207cdf0e10cSrcweir Reference<css::lang::XComponent> comp(seqBridges[i], UNO_QUERY);
208cdf0e10cSrcweir if (comp.is())
209cdf0e10cSrcweir {
210cdf0e10cSrcweir try {
211cdf0e10cSrcweir comp->dispose();
212cdf0e10cSrcweir }
213cdf0e10cSrcweir catch (css::lang::DisposedException& )
214cdf0e10cSrcweir {
215cdf0e10cSrcweir }
216cdf0e10cSrcweir }
217cdf0e10cSrcweir }
218cdf0e10cSrcweir }
219cdf0e10cSrcweir }
220cdf0e10cSrcweir
221cdf0e10cSrcweir //##############################################################################
unopkg_main()222cdf0e10cSrcweir extern "C" int unopkg_main()
223cdf0e10cSrcweir {
224cdf0e10cSrcweir tools::extendApplicationEnvironment();
225cdf0e10cSrcweir DisposeGuard disposeGuard;
226cdf0e10cSrcweir bool bNoOtherErrorMsg = false;
227cdf0e10cSrcweir OUString subCommand;
228cdf0e10cSrcweir bool option_shared = false;
229cdf0e10cSrcweir bool option_force = false;
230cdf0e10cSrcweir bool option_verbose = false;
231cdf0e10cSrcweir bool option_bundled = false;
232cdf0e10cSrcweir bool option_suppressLicense = false;
233cdf0e10cSrcweir bool subcmd_add = false;
234cdf0e10cSrcweir bool subcmd_gui = false;
235cdf0e10cSrcweir OUString logFile;
236cdf0e10cSrcweir OUString repository;
237cdf0e10cSrcweir OUString cmdArg;
238cdf0e10cSrcweir ::std::vector<OUString> cmdPackages;
23933608c82Smseidel
240cdf0e10cSrcweir OptionInfo const * info_shared = getOptionInfo(
241cdf0e10cSrcweir s_option_infos, OUSTR("shared") );
242cdf0e10cSrcweir OptionInfo const * info_force = getOptionInfo(
243cdf0e10cSrcweir s_option_infos, OUSTR("force") );
244cdf0e10cSrcweir OptionInfo const * info_verbose = getOptionInfo(
245cdf0e10cSrcweir s_option_infos, OUSTR("verbose") );
246cdf0e10cSrcweir OptionInfo const * info_log = getOptionInfo(
247cdf0e10cSrcweir s_option_infos, OUSTR("log-file") );
248cdf0e10cSrcweir OptionInfo const * info_context = getOptionInfo(
249cdf0e10cSrcweir s_option_infos, OUSTR("deployment-context") );
250cdf0e10cSrcweir OptionInfo const * info_help = getOptionInfo(
251cdf0e10cSrcweir s_option_infos, OUSTR("help") );
252cdf0e10cSrcweir OptionInfo const * info_version = getOptionInfo(
253cdf0e10cSrcweir s_option_infos, OUSTR("version") );
254cdf0e10cSrcweir OptionInfo const * info_bundled = getOptionInfo(
255cdf0e10cSrcweir s_option_infos, OUSTR("bundled") );
256cdf0e10cSrcweir OptionInfo const * info_suppressLicense = getOptionInfo(
257cdf0e10cSrcweir s_option_infos, OUSTR("suppress-license") );
258cdf0e10cSrcweir
25933608c82Smseidel
260cdf0e10cSrcweir Reference<XComponentContext> xComponentContext;
261cdf0e10cSrcweir Reference<XComponentContext> xLocalComponentContext;
26233608c82Smseidel
263cdf0e10cSrcweir try {
264cdf0e10cSrcweir sal_uInt32 nPos = 0;
265cdf0e10cSrcweir sal_uInt32 nCount = osl_getCommandArgCount();
266cdf0e10cSrcweir if (nCount == 0 || isOption( info_help, &nPos ))
267cdf0e10cSrcweir {
268cdf0e10cSrcweir dp_misc::writeConsole(s_usingText);
269cdf0e10cSrcweir return 0;
270cdf0e10cSrcweir }
271cdf0e10cSrcweir else if (isOption( info_version, &nPos )) {
2726f51c329SHerbert Dürr dp_misc::writeConsole( "\n" APP_NAME " Version 3.3\n");
273cdf0e10cSrcweir return 0;
274cdf0e10cSrcweir }
27533608c82Smseidel // consume all bootstrap variables which may occur before the subcommand
276cdf0e10cSrcweir while(isBootstrapVariable(&nPos));
27733608c82Smseidel
278cdf0e10cSrcweir if(nPos >= nCount)
279cdf0e10cSrcweir return 0;
280cdf0e10cSrcweir //get the sub command
281cdf0e10cSrcweir osl_getCommandArg( nPos, &subCommand.pData );
282cdf0e10cSrcweir ++nPos;
283cdf0e10cSrcweir subCommand = subCommand.trim();
284cdf0e10cSrcweir subcmd_add = subCommand.equalsAsciiL(
285cdf0e10cSrcweir RTL_CONSTASCII_STRINGPARAM("add") );
286cdf0e10cSrcweir subcmd_gui = subCommand.equalsAsciiL(
287cdf0e10cSrcweir RTL_CONSTASCII_STRINGPARAM("gui") );
28833608c82Smseidel
289cdf0e10cSrcweir // sun-command options and packages:
290cdf0e10cSrcweir while (nPos < nCount)
291cdf0e10cSrcweir {
292cdf0e10cSrcweir if (readArgument( &cmdArg, info_log, &nPos )) {
293cdf0e10cSrcweir logFile = makeAbsoluteFileUrl(
294cdf0e10cSrcweir cmdArg.trim(), getProcessWorkingDir() );
295cdf0e10cSrcweir }
296cdf0e10cSrcweir else if (!readOption( &option_verbose, info_verbose, &nPos ) &&
297cdf0e10cSrcweir !readOption( &option_shared, info_shared, &nPos ) &&
298cdf0e10cSrcweir !readOption( &option_force, info_force, &nPos ) &&
299cdf0e10cSrcweir !readOption( &option_bundled, info_bundled, &nPos ) &&
300cdf0e10cSrcweir !readOption( &option_suppressLicense, info_suppressLicense, &nPos ) &&
301cdf0e10cSrcweir !readArgument( &repository, info_context, &nPos ) &&
302cdf0e10cSrcweir !isBootstrapVariable(&nPos))
303cdf0e10cSrcweir {
304cdf0e10cSrcweir osl_getCommandArg( nPos, &cmdArg.pData );
305cdf0e10cSrcweir ++nPos;
306cdf0e10cSrcweir cmdArg = cmdArg.trim();
307cdf0e10cSrcweir if (cmdArg.getLength() > 0)
308cdf0e10cSrcweir {
309cdf0e10cSrcweir if (cmdArg[ 0 ] == '-')
310cdf0e10cSrcweir {
311cdf0e10cSrcweir // is option:
312cdf0e10cSrcweir dp_misc::writeConsoleError(
313cdf0e10cSrcweir OUSTR("\nERROR: unexpected option ") +
314cdf0e10cSrcweir cmdArg +
315cdf0e10cSrcweir OUSTR("!\n") +
31633608c82Smseidel OUSTR(" Use " APP_NAME " ") +
317cdf0e10cSrcweir toString(info_help) +
318cdf0e10cSrcweir OUSTR(" to print all options.\n"));
319cdf0e10cSrcweir return 1;
320cdf0e10cSrcweir }
321cdf0e10cSrcweir else
322cdf0e10cSrcweir {
323cdf0e10cSrcweir // is package:
324cdf0e10cSrcweir cmdPackages.push_back(
325cdf0e10cSrcweir subcmd_add || subcmd_gui
326cdf0e10cSrcweir ? makeAbsoluteFileUrl(
327cdf0e10cSrcweir cmdArg, getProcessWorkingDir() )
328cdf0e10cSrcweir : cmdArg );
329cdf0e10cSrcweir }
330cdf0e10cSrcweir }
331cdf0e10cSrcweir }
332cdf0e10cSrcweir }
33333608c82Smseidel
33433608c82Smseidel if (repository.getLength() == 0)
335cdf0e10cSrcweir {
336cdf0e10cSrcweir if (option_shared)
337cdf0e10cSrcweir repository = OUSTR("shared");
338cdf0e10cSrcweir else if (option_bundled)
33933608c82Smseidel repository = OUSTR("bundled");
34033608c82Smseidel else
341cdf0e10cSrcweir repository = OUSTR("user");
342cdf0e10cSrcweir }
343cdf0e10cSrcweir else
344cdf0e10cSrcweir {
345cdf0e10cSrcweir if (repository.equalsAsciiL(
346cdf0e10cSrcweir RTL_CONSTASCII_STRINGPARAM("shared") )) {
347cdf0e10cSrcweir option_shared = true;
348cdf0e10cSrcweir }
349cdf0e10cSrcweir else if (option_shared) {
350cdf0e10cSrcweir dp_misc::writeConsoleError(
351cdf0e10cSrcweir OUSTR("WARNING: explicit context given! ") +
352cdf0e10cSrcweir OUSTR("Ignoring option ") +
353cdf0e10cSrcweir toString( info_shared ) +
354cdf0e10cSrcweir OUSTR("!\n") );
355cdf0e10cSrcweir }
356cdf0e10cSrcweir }
357cdf0e10cSrcweir
358cdf0e10cSrcweir if (subCommand.equals(OUSTR("reinstall")))
359cdf0e10cSrcweir {
360cdf0e10cSrcweir //We must prevent that services and types are loaded by UNO,
361cdf0e10cSrcweir //otherwise we cannot delete the registry data folder.
362cdf0e10cSrcweir OUString extensionUnorc;
363cdf0e10cSrcweir if (repository.equals(OUSTR("user")))
364cdf0e10cSrcweir extensionUnorc = OUSTR("$UNO_USER_PACKAGES_CACHE/registry/com.sun.star.comp.deployment.component.PackageRegistryBackend/unorc");
365cdf0e10cSrcweir else if (repository.equals(OUSTR("shared")))
366cdf0e10cSrcweir extensionUnorc = OUSTR("$SHARED_EXTENSIONS_USER/registry/com.sun.star.comp.deployment.component.PackageRegistryBackend/unorc");
367cdf0e10cSrcweir else if (repository.equals(OUSTR("bundled")))
368cdf0e10cSrcweir extensionUnorc = OUSTR("$BUNDLED_EXTENSIONS_USER/registry/com.sun.star.comp.deployment.component.PackageRegistryBackend/unorc");
369cdf0e10cSrcweir else
370cdf0e10cSrcweir OSL_ASSERT(0);
371cdf0e10cSrcweir
372cdf0e10cSrcweir ::rtl::Bootstrap::expandMacros(extensionUnorc);
373cdf0e10cSrcweir oslFileError e = osl_removeFile(extensionUnorc.pData);
374cdf0e10cSrcweir if (e != osl_File_E_None && e != osl_File_E_NOENT)
375cdf0e10cSrcweir throw Exception(OUSTR("Could not delete ") + extensionUnorc, 0);
376cdf0e10cSrcweir }
377cdf0e10cSrcweir else if (subCommand.equals(OUSTR("sync")))
378cdf0e10cSrcweir {
379cdf0e10cSrcweir //sync is private!!!! Only to be called from setup!!!
380cdf0e10cSrcweir //The UserInstallation is diverted to the prereg folder. But only
381cdf0e10cSrcweir //the lock file is written! This requires that
382cdf0e10cSrcweir //-env:UNO_JAVA_JFW_INSTALL_DATA is passed to javaldx and unopkg otherwise the
38333608c82Smseidel //javasettings file is written to the prereg folder.
384cdf0e10cSrcweir //
385cdf0e10cSrcweir //For performance reasons unopkg sync is called during the setup and
386cdf0e10cSrcweir //creates the registration data for the repository of the bundled
387cdf0e10cSrcweir //extensions. It is then copied to the user installation during
38833608c82Smseidel //startup of AOO (userdata/extensions/bundled). The registration
389cdf0e10cSrcweir //data is in the brand installation and must be removed when
39033608c82Smseidel //uninstalling AOO. We do this here, before UNO is
39133608c82Smseidel //bootstrapped. Otherwise files could be locked by this process.
392cdf0e10cSrcweir
393cdf0e10cSrcweir //If there is no folder left in
394910823aeSJürgen Schmidt //$OOO_BASE_DIR/share/extensions
395cdf0e10cSrcweir //then we can delete the registration data at
396cdf0e10cSrcweir //$BUNDLED_EXTENSIONS_USER
397910823aeSJürgen Schmidt if (hasNoFolder(OUSTR("$OOO_BASE_DIR/share/extensions")))
398cdf0e10cSrcweir {
399cdf0e10cSrcweir removeFolder(OUSTR("$BUNDLED_EXTENSIONS_PREREG"));
400cdf0e10cSrcweir //return otherwise we create the registration data again
401cdf0e10cSrcweir return 0;
402cdf0e10cSrcweir }
403cdf0e10cSrcweir //redirect the UserInstallation, so we do not create a
404cdf0e10cSrcweir //user installation for the admin and we also do not need
405cdf0e10cSrcweir //to call unopkg with -env:UserInstallation
406cdf0e10cSrcweir ::rtl::Bootstrap::set(OUSTR("UserInstallation"),
407cdf0e10cSrcweir OUSTR("$BUNDLED_EXTENSIONS_PREREG/.."));
408cdf0e10cSrcweir //Setting UNO_JAVA_JFW_INSTALL_DATA causes the javasettings to be written
409cdf0e10cSrcweir //in the office installation. We do not want to create the user data folder
410cdf0e10cSrcweir //for the admin. The value must also be set in the unopkg script (Linux, etc.)
411cdf0e10cSrcweir //when calling javaldx
412cdf0e10cSrcweir ::rtl::Bootstrap::set(OUSTR("UNO_JAVA_JFW_INSTALL_DATA"),
413cdf0e10cSrcweir OUSTR("$OOO_BASE_DIR/share/config/javasettingsunopkginstall.xml"));
414cdf0e10cSrcweir
415cdf0e10cSrcweir }
416cdf0e10cSrcweir
417cdf0e10cSrcweir xComponentContext = getUNO(
418cdf0e10cSrcweir disposeGuard, option_verbose, option_shared, subcmd_gui,
419cdf0e10cSrcweir xLocalComponentContext );
42033608c82Smseidel
421cdf0e10cSrcweir Reference<deployment::XExtensionManager> xExtensionManager(
422cdf0e10cSrcweir deployment::ExtensionManager::get( xComponentContext ) );
423cdf0e10cSrcweir
424cdf0e10cSrcweir Reference< ::com::sun::star::ucb::XCommandEnvironment > xCmdEnv(
425cdf0e10cSrcweir createCmdEnv( xComponentContext, logFile,
426cdf0e10cSrcweir option_force, option_verbose) );
42733608c82Smseidel
428cdf0e10cSrcweir //synchronize bundled/shared extensions
429cdf0e10cSrcweir //Do not synchronize when command is "reinstall". This could add types and services to UNO and
430cdf0e10cSrcweir //prevent the deletion of the registry data folder
431cdf0e10cSrcweir //synching is done in XExtensionManager.reinstall
432cdf0e10cSrcweir if (!subcmd_gui && ! subCommand.equals(OUSTR("reinstall"))
433cdf0e10cSrcweir && ! subCommand.equals(OUSTR("sync"))
434cdf0e10cSrcweir && ! dp_misc::office_is_running())
435cdf0e10cSrcweir dp_misc::syncRepositories(xCmdEnv);
436cdf0e10cSrcweir
437cdf0e10cSrcweir if (subcmd_add ||
438cdf0e10cSrcweir subCommand.equalsAsciiL(
439cdf0e10cSrcweir RTL_CONSTASCII_STRINGPARAM("remove") ))
440cdf0e10cSrcweir {
441cdf0e10cSrcweir for ( ::std::size_t pos = 0; pos < cmdPackages.size(); ++pos )
442cdf0e10cSrcweir {
443cdf0e10cSrcweir OUString const & cmdPackage = cmdPackages[ pos ];
444cdf0e10cSrcweir if (subcmd_add)
445cdf0e10cSrcweir {
446cdf0e10cSrcweir beans::NamedValue nvSuppress(
447cdf0e10cSrcweir OUSTR("SUPPRESS_LICENSE"), option_suppressLicense ?
448cdf0e10cSrcweir makeAny(OUSTR("1")):makeAny(OUSTR("0")));
449cdf0e10cSrcweir xExtensionManager->addExtension(
450cdf0e10cSrcweir cmdPackage, Sequence<beans::NamedValue>(&nvSuppress, 1),
451cdf0e10cSrcweir repository, Reference<task::XAbortChannel>(), xCmdEnv);
452cdf0e10cSrcweir }
453cdf0e10cSrcweir else
454cdf0e10cSrcweir {
455cdf0e10cSrcweir try
456cdf0e10cSrcweir {
457cdf0e10cSrcweir xExtensionManager->removeExtension(
458cdf0e10cSrcweir cmdPackage, cmdPackage, repository,
459cdf0e10cSrcweir Reference<task::XAbortChannel>(), xCmdEnv );
460cdf0e10cSrcweir }
461cdf0e10cSrcweir catch (lang::IllegalArgumentException &)
462cdf0e10cSrcweir {
463cdf0e10cSrcweir Reference<deployment::XPackage> p(
464cdf0e10cSrcweir findPackage(repository,
465cdf0e10cSrcweir xExtensionManager, xCmdEnv, cmdPackage ) );
466cdf0e10cSrcweir if ( !p.is())
467cdf0e10cSrcweir throw;
468cdf0e10cSrcweir else if (p.is())
469cdf0e10cSrcweir xExtensionManager->removeExtension(
47033608c82Smseidel ::dp_misc::getIdentifier(p), p->getName(),
471cdf0e10cSrcweir repository,
472cdf0e10cSrcweir Reference<task::XAbortChannel>(), xCmdEnv );
473cdf0e10cSrcweir }
474cdf0e10cSrcweir }
475cdf0e10cSrcweir }
476cdf0e10cSrcweir }
477cdf0e10cSrcweir else if (subCommand.equalsAsciiL(
478cdf0e10cSrcweir RTL_CONSTASCII_STRINGPARAM("reinstall") ))
479cdf0e10cSrcweir {
480cdf0e10cSrcweir xExtensionManager->reinstallDeployedExtensions(
481cdf0e10cSrcweir repository, Reference<task::XAbortChannel>(), xCmdEnv);
482cdf0e10cSrcweir }
483cdf0e10cSrcweir else if (subCommand.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("list") ))
484cdf0e10cSrcweir {
485cdf0e10cSrcweir ::std::vector<Reference<deployment::XPackage> > vecExtUnaccepted;
486cdf0e10cSrcweir ::comphelper::sequenceToContainer(vecExtUnaccepted,
487cdf0e10cSrcweir xExtensionManager->getExtensionsWithUnacceptedLicenses(
488cdf0e10cSrcweir repository, xCmdEnv));
48933608c82Smseidel
49033608c82Smseidel //This vector tells what XPackage in allExtensions has an
491cdf0e10cSrcweir //unaccepted license.
492cdf0e10cSrcweir std::vector<bool> vecUnaccepted;
493cdf0e10cSrcweir std::vector<Reference<deployment::XPackage> > allExtensions;
494cdf0e10cSrcweir if (cmdPackages.empty())
495cdf0e10cSrcweir {
49633608c82Smseidel Sequence< Reference<deployment::XPackage> >
497cdf0e10cSrcweir packages = xExtensionManager->getDeployedExtensions(
498cdf0e10cSrcweir repository, Reference<task::XAbortChannel>(), xCmdEnv );
499cdf0e10cSrcweir
500cdf0e10cSrcweir ::std::vector<Reference<deployment::XPackage> > vec_packages;
501cdf0e10cSrcweir ::comphelper::sequenceToContainer(vec_packages, packages);
50233608c82Smseidel
503cdf0e10cSrcweir //First copy the extensions with the unaccepted license
504cdf0e10cSrcweir //to vector allExtensions.
505cdf0e10cSrcweir allExtensions.resize(vecExtUnaccepted.size() + vec_packages.size());
506cdf0e10cSrcweir
507cdf0e10cSrcweir ::std::vector<Reference<deployment::XPackage> >::iterator i_all_ext =
508cdf0e10cSrcweir ::std::copy(vecExtUnaccepted.begin(), vecExtUnaccepted.end(),
509cdf0e10cSrcweir allExtensions.begin());
510cdf0e10cSrcweir //Now copy those we got from getDeployedExtensions
511cdf0e10cSrcweir ::std::copy(vec_packages.begin(), vec_packages.end(), i_all_ext);
512cdf0e10cSrcweir
513cdf0e10cSrcweir //Now prepare the vector which tells what extension has an
514cdf0e10cSrcweir //unaccepted license
515cdf0e10cSrcweir vecUnaccepted.resize(vecExtUnaccepted.size() + vec_packages.size());
516a77e1d27SHerbert Dürr ::std::fill_n( vecUnaccepted.begin(), vecExtUnaccepted.size(), true);
517a77e1d27SHerbert Dürr std::vector<bool>::iterator i_unaccepted = vecUnaccepted.begin() + vecExtUnaccepted.size();
518cdf0e10cSrcweir ::std::fill_n(i_unaccepted, vec_packages.size(), false);
51933608c82Smseidel
520cdf0e10cSrcweir dp_misc::writeConsole(
521cdf0e10cSrcweir OUSTR("All deployed ") + repository + OUSTR(" extensions:\n\n"));
522cdf0e10cSrcweir }
523cdf0e10cSrcweir else
524cdf0e10cSrcweir {
525cdf0e10cSrcweir //The user provided the names (ids or file names) of the extensions
526cdf0e10cSrcweir //which shall be listed
527cdf0e10cSrcweir for ( ::std::size_t pos = 0; pos < cmdPackages.size(); ++pos )
528cdf0e10cSrcweir {
529cdf0e10cSrcweir Reference<deployment::XPackage> extension;
530cdf0e10cSrcweir try
531cdf0e10cSrcweir {
532cdf0e10cSrcweir extension = xExtensionManager->getDeployedExtension(
533cdf0e10cSrcweir repository, cmdPackages[ pos ], cmdPackages[ pos ], xCmdEnv );
534cdf0e10cSrcweir }
535cdf0e10cSrcweir catch (lang::IllegalArgumentException &)
536cdf0e10cSrcweir {
537cdf0e10cSrcweir extension = findPackage(repository,
538cdf0e10cSrcweir xExtensionManager, xCmdEnv, cmdPackages[ pos ] );
539cdf0e10cSrcweir }
540cdf0e10cSrcweir
541cdf0e10cSrcweir //Now look if the requested extension has an unaccepted license
542cdf0e10cSrcweir bool bUnacceptedLic = false;
543cdf0e10cSrcweir if (!extension.is())
544cdf0e10cSrcweir {
545cdf0e10cSrcweir ::std::vector<Reference<deployment::XPackage> >::const_iterator
546cdf0e10cSrcweir i = ::std::find_if(
547cdf0e10cSrcweir vecExtUnaccepted.begin(),
548cdf0e10cSrcweir vecExtUnaccepted.end(), ExtensionName(cmdPackages[pos]));
549cdf0e10cSrcweir if (i != vecExtUnaccepted.end())
550cdf0e10cSrcweir {
551cdf0e10cSrcweir extension = *i;
552cdf0e10cSrcweir bUnacceptedLic = true;
553cdf0e10cSrcweir }
554cdf0e10cSrcweir }
555cdf0e10cSrcweir
556cdf0e10cSrcweir if (extension.is())
557cdf0e10cSrcweir {
558cdf0e10cSrcweir allExtensions.push_back(extension);
559cdf0e10cSrcweir vecUnaccepted.push_back(bUnacceptedLic);
560cdf0e10cSrcweir }
56133608c82Smseidel
562cdf0e10cSrcweir else
563cdf0e10cSrcweir throw lang::IllegalArgumentException(
564cdf0e10cSrcweir OUSTR("There is no such extension deployed: ") +
565cdf0e10cSrcweir cmdPackages[pos],0,-1);
566cdf0e10cSrcweir }
56733608c82Smseidel
568cdf0e10cSrcweir }
56933608c82Smseidel
570cdf0e10cSrcweir printf_packages(allExtensions, vecUnaccepted, xCmdEnv );
571cdf0e10cSrcweir }
572cdf0e10cSrcweir else if (subCommand.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("validate") ))
573cdf0e10cSrcweir {
574cdf0e10cSrcweir ::std::vector<Reference<deployment::XPackage> > vecExtUnaccepted;
575cdf0e10cSrcweir ::comphelper::sequenceToContainer(
576cdf0e10cSrcweir vecExtUnaccepted, xExtensionManager->getExtensionsWithUnacceptedLicenses(
577cdf0e10cSrcweir repository, xCmdEnv));
578cdf0e10cSrcweir
579cdf0e10cSrcweir for ( ::std::size_t pos = 0; pos < cmdPackages.size(); ++pos )
580cdf0e10cSrcweir {
581cdf0e10cSrcweir Reference<deployment::XPackage> extension;
582cdf0e10cSrcweir try
583cdf0e10cSrcweir {
584cdf0e10cSrcweir extension = xExtensionManager->getDeployedExtension(
585cdf0e10cSrcweir repository, cmdPackages[ pos ], cmdPackages[ pos ], xCmdEnv );
586cdf0e10cSrcweir }
587cdf0e10cSrcweir catch (lang::IllegalArgumentException &)
588cdf0e10cSrcweir {
589cdf0e10cSrcweir extension = findPackage(
590cdf0e10cSrcweir repository, xExtensionManager, xCmdEnv, cmdPackages[ pos ] );
591cdf0e10cSrcweir }
592cdf0e10cSrcweir
593cdf0e10cSrcweir if (!extension.is())
594cdf0e10cSrcweir {
595cdf0e10cSrcweir ::std::vector<Reference<deployment::XPackage> >::const_iterator
596cdf0e10cSrcweir i = ::std::find_if(
597cdf0e10cSrcweir vecExtUnaccepted.begin(),
598cdf0e10cSrcweir vecExtUnaccepted.end(), ExtensionName(cmdPackages[pos]));
599cdf0e10cSrcweir if (i != vecExtUnaccepted.end())
600cdf0e10cSrcweir {
601cdf0e10cSrcweir extension = *i;
602cdf0e10cSrcweir }
603cdf0e10cSrcweir }
604cdf0e10cSrcweir
605cdf0e10cSrcweir if (extension.is())
606cdf0e10cSrcweir xExtensionManager->checkPrerequisitesAndEnable(
607cdf0e10cSrcweir extension, Reference<task::XAbortChannel>(), xCmdEnv);
608cdf0e10cSrcweir }
609cdf0e10cSrcweir }
610cdf0e10cSrcweir else if (subCommand.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("gui") ))
611cdf0e10cSrcweir {
612cdf0e10cSrcweir Reference<ui::dialogs::XAsynchronousExecutableDialog> xDialog(
613cdf0e10cSrcweir deployment::ui::PackageManagerDialog::createAndInstall(
61433608c82Smseidel xComponentContext,
615cdf0e10cSrcweir cmdPackages.size() > 0 ? cmdPackages[0] : OUString() ));
616cdf0e10cSrcweir
617cdf0e10cSrcweir osl::Condition dialogEnded;
618cdf0e10cSrcweir dialogEnded.reset();
619cdf0e10cSrcweir
620cdf0e10cSrcweir Reference< ui::dialogs::XDialogClosedListener > xListener(
621cdf0e10cSrcweir new DialogClosedListenerImpl( dialogEnded ) );
622cdf0e10cSrcweir
623cdf0e10cSrcweir xDialog->startExecuteModal(xListener);
624cdf0e10cSrcweir dialogEnded.wait();
625cdf0e10cSrcweir }
626cdf0e10cSrcweir else if (subCommand.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("sync")))
627cdf0e10cSrcweir {
628cdf0e10cSrcweir if (! dp_misc::office_is_running())
629cdf0e10cSrcweir {
630cdf0e10cSrcweir xExtensionManager->synchronizeBundledPrereg(
631cdf0e10cSrcweir Reference<task::XAbortChannel>(), xCmdEnv);
632cdf0e10cSrcweir }
633cdf0e10cSrcweir else
634cdf0e10cSrcweir {
635cdf0e10cSrcweir dp_misc::writeConsoleError(OUSTR("\nError: office is running"));
63633608c82Smseidel }
637cdf0e10cSrcweir }
638cdf0e10cSrcweir else
639cdf0e10cSrcweir {
640cdf0e10cSrcweir dp_misc::writeConsoleError(
64133608c82Smseidel OUSTR("\nERROR: unknown sub-command ") +
642cdf0e10cSrcweir subCommand +
64333608c82Smseidel OUSTR("!\n") +
64433608c82Smseidel OUSTR(" Use " APP_NAME " ") +
645cdf0e10cSrcweir toString(info_help) +
646cdf0e10cSrcweir OUSTR(" to print all options.\n"));
647cdf0e10cSrcweir return 1;
648cdf0e10cSrcweir }
64933608c82Smseidel
650cdf0e10cSrcweir if (option_verbose)
6516f51c329SHerbert Dürr dp_misc::writeConsole( OUSTR( "\n" APP_NAME " done.\n"));
652cdf0e10cSrcweir //Force to release all bridges which connect us to the child processes
653cdf0e10cSrcweir disposeBridges(xLocalComponentContext);
654cdf0e10cSrcweir return 0;
655cdf0e10cSrcweir }
65633608c82Smseidel catch (ucb::CommandFailedException &e)
657cdf0e10cSrcweir {
658cdf0e10cSrcweir dp_misc::writeConsoleError(e.Message + OUSTR("\n"));
65933608c82Smseidel bNoOtherErrorMsg = true;
660cdf0e10cSrcweir }
66133608c82Smseidel catch (ucb::CommandAbortedException &)
662cdf0e10cSrcweir {
6636f51c329SHerbert Dürr dp_misc::writeConsoleError( "\n" APP_NAME " aborted!\n");
664cdf0e10cSrcweir }
66533608c82Smseidel catch (deployment::DeploymentException & exc)
666cdf0e10cSrcweir {
667cdf0e10cSrcweir OUString cause;
668cdf0e10cSrcweir if (option_verbose)
669cdf0e10cSrcweir {
670cdf0e10cSrcweir cause = ::comphelper::anyToString(exc.Cause);
671cdf0e10cSrcweir }
672cdf0e10cSrcweir else
673cdf0e10cSrcweir {
674cdf0e10cSrcweir css::uno::Exception e;
675cdf0e10cSrcweir if (exc.Cause >>= e)
67633608c82Smseidel cause = e.Message;
677cdf0e10cSrcweir }
678cdf0e10cSrcweir
679cdf0e10cSrcweir dp_misc::writeConsoleError(
680cdf0e10cSrcweir OUSTR("\nERROR: ") + exc.Message + OUSTR("\n"));
681cdf0e10cSrcweir if (cause.getLength())
682cdf0e10cSrcweir dp_misc::writeConsoleError(
683cdf0e10cSrcweir OUSTR(" Cause: ") + cause + OUSTR("\n"));
684cdf0e10cSrcweir }
68533608c82Smseidel catch (LockFileException & e)
686cdf0e10cSrcweir {
687cdf0e10cSrcweir if (!subcmd_gui)
688cdf0e10cSrcweir dp_misc::writeConsoleError(e.Message);
689cdf0e10cSrcweir bNoOtherErrorMsg = true;
690cdf0e10cSrcweir }
691cdf0e10cSrcweir catch (::com::sun::star::uno::Exception & e ) {
692cdf0e10cSrcweir Any exc( ::cppu::getCaughtException() );
69333608c82Smseidel
694cdf0e10cSrcweir dp_misc::writeConsoleError(
69533608c82Smseidel OUSTR("\nERROR: ") +
696*c059a6bfSmseidel OUString(option_verbose ? e.Message + OUSTR("\nException details: \n") +
697cdf0e10cSrcweir ::comphelper::anyToString(exc) : e.Message) +
698cdf0e10cSrcweir OUSTR("\n"));
699cdf0e10cSrcweir }
700cdf0e10cSrcweir if (!bNoOtherErrorMsg)
7016f51c329SHerbert Dürr dp_misc::writeConsoleError( "\n" APP_NAME " failed.\n");
702cdf0e10cSrcweir disposeBridges(xLocalComponentContext);
703cdf0e10cSrcweir return 1;
704cdf0e10cSrcweir }
705cdf0e10cSrcweir
706