summaryrefslogtreecommitdiff
path: root/desktop/source
diff options
context:
space:
mode:
Diffstat (limited to 'desktop/source')
-rw-r--r--desktop/source/app/app.cxx3307
-rw-r--r--desktop/source/app/appfirststart.cxx116
-rw-r--r--desktop/source/app/appinit.cxx464
-rw-r--r--desktop/source/app/appinit.hxx53
-rw-r--r--desktop/source/app/appsys.cxx70
-rw-r--r--desktop/source/app/appsys.hxx45
-rw-r--r--desktop/source/app/check_ext_deps.cxx432
-rw-r--r--desktop/source/app/checkinstall.cxx122
-rw-r--r--desktop/source/app/checkinstall.hxx45
-rw-r--r--desktop/source/app/cmdlineargs.cxx1008
-rw-r--r--desktop/source/app/cmdlineargs.hxx230
-rw-r--r--desktop/source/app/cmdlinehelp.cxx214
-rw-r--r--desktop/source/app/cmdlinehelp.hxx25
-rw-r--r--desktop/source/app/configinit.cxx304
-rw-r--r--desktop/source/app/configinit.hxx74
-rwxr-xr-xdesktop/source/app/copyright_ascii_ooo.c12
-rwxr-xr-xdesktop/source/app/copyright_ascii_sun.c10
-rwxr-xr-xdesktop/source/app/desktop.hrc91
-rw-r--r--desktop/source/app/desktop.src235
-rw-r--r--desktop/source/app/desktopcontext.cxx67
-rw-r--r--desktop/source/app/desktopcontext.hxx53
-rw-r--r--desktop/source/app/desktopresid.cxx47
-rw-r--r--desktop/source/app/desktopresid.hxx47
-rw-r--r--desktop/source/app/dispatchwatcher.cxx666
-rw-r--r--desktop/source/app/dispatchwatcher.hxx130
-rwxr-xr-xdesktop/source/app/exports.dxp2
-rw-r--r--desktop/source/app/langselect.cxx563
-rw-r--r--desktop/source/app/langselect.hxx77
-rw-r--r--desktop/source/app/lockfile.cxx238
-rw-r--r--desktop/source/app/lockfile.hxx101
-rw-r--r--desktop/source/app/lockfile2.cxx72
-rwxr-xr-xdesktop/source/app/main.c39
-rwxr-xr-xdesktop/source/app/makefile.mk119
-rw-r--r--desktop/source/app/officeipcthread.cxx1043
-rw-r--r--desktop/source/app/officeipcthread.hxx167
-rw-r--r--desktop/source/app/omutexmember.hxx64
-rw-r--r--desktop/source/app/sofficemain.cxx71
-rwxr-xr-xdesktop/source/app/sofficemain.h46
-rw-r--r--desktop/source/app/userinstall.cxx297
-rw-r--r--desktop/source/app/userinstall.hxx55
-rwxr-xr-xdesktop/source/app/version.map34
-rwxr-xr-xdesktop/source/deployment/deployment.component64
-rw-r--r--desktop/source/deployment/dp_log.cxx213
-rw-r--r--desktop/source/deployment/dp_persmap.cxx254
-rw-r--r--desktop/source/deployment/dp_services.cxx117
-rw-r--r--desktop/source/deployment/dp_xml.cxx67
-rwxr-xr-xdesktop/source/deployment/gui/deploymentgui.component40
-rw-r--r--desktop/source/deployment/gui/descedit.cxx102
-rw-r--r--desktop/source/deployment/gui/descedit.hxx59
-rwxr-xr-xdesktop/source/deployment/gui/dp_gui.h101
-rwxr-xr-xdesktop/source/deployment/gui/dp_gui.hrc181
-rw-r--r--desktop/source/deployment/gui/dp_gui_autoscrolledit.cxx75
-rw-r--r--desktop/source/deployment/gui/dp_gui_autoscrolledit.hxx54
-rw-r--r--desktop/source/deployment/gui/dp_gui_backend.src86
-rw-r--r--desktop/source/deployment/gui/dp_gui_dependencydialog.cxx89
-rw-r--r--desktop/source/deployment/gui/dp_gui_dependencydialog.hxx69
-rw-r--r--desktop/source/deployment/gui/dp_gui_dependencydialog.src72
-rw-r--r--desktop/source/deployment/gui/dp_gui_dialog.src387
-rw-r--r--desktop/source/deployment/gui/dp_gui_dialog2.cxx1827
-rw-r--r--desktop/source/deployment/gui/dp_gui_dialog2.hxx283
-rw-r--r--desktop/source/deployment/gui/dp_gui_dialog2.src236
-rw-r--r--desktop/source/deployment/gui/dp_gui_extensioncmdqueue.cxx1178
-rw-r--r--desktop/source/deployment/gui/dp_gui_extensioncmdqueue.hxx114
-rw-r--r--desktop/source/deployment/gui/dp_gui_extlistbox.cxx1214
-rw-r--r--desktop/source/deployment/gui/dp_gui_extlistbox.hxx269
-rw-r--r--desktop/source/deployment/gui/dp_gui_service.cxx371
-rw-r--r--desktop/source/deployment/gui/dp_gui_shared.hxx65
-rw-r--r--desktop/source/deployment/gui/dp_gui_theextmgr.cxx533
-rw-r--r--desktop/source/deployment/gui/dp_gui_theextmgr.hxx133
-rw-r--r--desktop/source/deployment/gui/dp_gui_thread.cxx85
-rw-r--r--desktop/source/deployment/gui/dp_gui_thread.hxx87
-rw-r--r--desktop/source/deployment/gui/dp_gui_updatedata.hxx94
-rw-r--r--desktop/source/deployment/gui/dp_gui_updatedialog.cxx1436
-rw-r--r--desktop/source/deployment/gui/dp_gui_updatedialog.hxx232
-rw-r--r--desktop/source/deployment/gui/dp_gui_updatedialog.src275
-rw-r--r--desktop/source/deployment/gui/dp_gui_updateinstalldialog.cxx757
-rw-r--r--desktop/source/deployment/gui/dp_gui_updateinstalldialog.hxx145
-rw-r--r--desktop/source/deployment/gui/dp_gui_updateinstalldialog.src204
-rw-r--r--desktop/source/deployment/gui/dp_gui_versionboxes.src76
-rw-r--r--desktop/source/deployment/gui/license_dialog.cxx325
-rw-r--r--desktop/source/deployment/gui/license_dialog.hxx69
-rwxr-xr-xdesktop/source/deployment/gui/makefile.mk113
-rw-r--r--desktop/source/deployment/inc/db.hxx147
-rw-r--r--desktop/source/deployment/inc/dp_dependencies.hxx94
-rw-r--r--desktop/source/deployment/inc/dp_descriptioninfoset.hxx302
-rw-r--r--desktop/source/deployment/inc/dp_identifier.hxx95
-rwxr-xr-xdesktop/source/deployment/inc/dp_interact.h153
-rwxr-xr-xdesktop/source/deployment/inc/dp_misc.h182
-rwxr-xr-xdesktop/source/deployment/inc/dp_misc.mk42
-rw-r--r--desktop/source/deployment/inc/dp_misc_api.hxx43
-rwxr-xr-xdesktop/source/deployment/inc/dp_persmap.h68
-rw-r--r--desktop/source/deployment/inc/dp_platform.hxx57
-rwxr-xr-xdesktop/source/deployment/inc/dp_resource.h70
-rwxr-xr-xdesktop/source/deployment/inc/dp_ucb.h94
-rw-r--r--desktop/source/deployment/inc/dp_update.hxx150
-rw-r--r--desktop/source/deployment/inc/dp_version.hxx51
-rwxr-xr-xdesktop/source/deployment/inc/dp_xml.h60
-rwxr-xr-xdesktop/source/deployment/makefile.mk119
-rw-r--r--desktop/source/deployment/manager/dp_activepackages.cxx209
-rw-r--r--desktop/source/deployment/manager/dp_activepackages.hxx102
-rw-r--r--desktop/source/deployment/manager/dp_commandenvironments.cxx287
-rw-r--r--desktop/source/deployment/manager/dp_commandenvironments.hxx161
-rw-r--r--desktop/source/deployment/manager/dp_extensionmanager.cxx1575
-rw-r--r--desktop/source/deployment/manager/dp_extensionmanager.hxx321
-rw-r--r--desktop/source/deployment/manager/dp_informationprovider.cxx368
-rw-r--r--desktop/source/deployment/manager/dp_manager.cxx1689
-rwxr-xr-xdesktop/source/deployment/manager/dp_manager.h296
-rwxr-xr-xdesktop/source/deployment/manager/dp_manager.hrc39
-rw-r--r--desktop/source/deployment/manager/dp_manager.src59
-rw-r--r--desktop/source/deployment/manager/dp_managerfac.cxx202
-rw-r--r--desktop/source/deployment/manager/dp_properties.cxx171
-rw-r--r--desktop/source/deployment/manager/dp_properties.hxx80
-rwxr-xr-xdesktop/source/deployment/manager/makefile.mk55
-rw-r--r--desktop/source/deployment/misc/db.cxx273
-rw-r--r--desktop/source/deployment/misc/dp_dependencies.cxx180
-rw-r--r--desktop/source/deployment/misc/dp_descriptioninfoset.cxx866
-rw-r--r--desktop/source/deployment/misc/dp_identifier.cxx76
-rw-r--r--desktop/source/deployment/misc/dp_interact.cxx187
-rw-r--r--desktop/source/deployment/misc/dp_misc.cxx632
-rwxr-xr-xdesktop/source/deployment/misc/dp_misc.hrc33
-rw-r--r--desktop/source/deployment/misc/dp_misc.src40
-rw-r--r--desktop/source/deployment/misc/dp_platform.cxx256
-rw-r--r--desktop/source/deployment/misc/dp_resource.cxx235
-rw-r--r--desktop/source/deployment/misc/dp_ucb.cxx323
-rw-r--r--desktop/source/deployment/misc/dp_update.cxx425
-rw-r--r--desktop/source/deployment/misc/dp_version.cxx77
-rwxr-xr-xdesktop/source/deployment/misc/makefile.mk95
-rw-r--r--desktop/source/deployment/registry/component/dp_compbackenddb.cxx161
-rw-r--r--desktop/source/deployment/registry/component/dp_compbackenddb.hxx122
-rw-r--r--desktop/source/deployment/registry/component/dp_component.cxx1993
-rwxr-xr-xdesktop/source/deployment/registry/component/dp_component.hrc40
-rw-r--r--desktop/source/deployment/registry/component/dp_component.src59
-rwxr-xr-xdesktop/source/deployment/registry/component/makefile.mk48
-rw-r--r--desktop/source/deployment/registry/configuration/dp_configuration.cxx812
-rwxr-xr-xdesktop/source/deployment/registry/configuration/dp_configuration.hrc36
-rw-r--r--desktop/source/deployment/registry/configuration/dp_configuration.src39
-rw-r--r--desktop/source/deployment/registry/configuration/dp_configurationbackenddb.cxx181
-rw-r--r--desktop/source/deployment/registry/configuration/dp_configurationbackenddb.hxx94
-rwxr-xr-xdesktop/source/deployment/registry/configuration/makefile.mk52
-rw-r--r--desktop/source/deployment/registry/dp_backend.cxx827
-rw-r--r--desktop/source/deployment/registry/dp_backenddb.cxx716
-rw-r--r--desktop/source/deployment/registry/dp_registry.cxx578
-rw-r--r--desktop/source/deployment/registry/dp_registry.src59
-rw-r--r--desktop/source/deployment/registry/executable/dp_executable.cxx344
-rw-r--r--desktop/source/deployment/registry/executable/dp_executablebackenddb.cxx83
-rw-r--r--desktop/source/deployment/registry/executable/dp_executablebackenddb.hxx78
-rwxr-xr-xdesktop/source/deployment/registry/executable/makefile.mk44
-rw-r--r--desktop/source/deployment/registry/help/dp_help.cxx676
-rwxr-xr-xdesktop/source/deployment/registry/help/dp_help.hrc39
-rw-r--r--desktop/source/deployment/registry/help/dp_help.src44
-rw-r--r--desktop/source/deployment/registry/help/dp_helpbackenddb.cxx149
-rw-r--r--desktop/source/deployment/registry/help/dp_helpbackenddb.hxx93
-rwxr-xr-xdesktop/source/deployment/registry/help/makefile.mk52
-rwxr-xr-xdesktop/source/deployment/registry/inc/dp_backend.h401
-rw-r--r--desktop/source/deployment/registry/inc/dp_backenddb.hxx181
-rwxr-xr-xdesktop/source/deployment/registry/inc/dp_registry.hrc40
-rwxr-xr-xdesktop/source/deployment/registry/makefile.mk49
-rw-r--r--desktop/source/deployment/registry/package/dp_extbackenddb.cxx140
-rw-r--r--desktop/source/deployment/registry/package/dp_extbackenddb.hxx95
-rw-r--r--desktop/source/deployment/registry/package/dp_package.cxx1691
-rwxr-xr-xdesktop/source/deployment/registry/package/dp_package.hrc35
-rw-r--r--desktop/source/deployment/registry/package/dp_package.src34
-rwxr-xr-xdesktop/source/deployment/registry/package/makefile.mk48
-rw-r--r--desktop/source/deployment/registry/script/dp_lib_container.cxx81
-rwxr-xr-xdesktop/source/deployment/registry/script/dp_lib_container.h69
-rw-r--r--desktop/source/deployment/registry/script/dp_script.cxx483
-rwxr-xr-xdesktop/source/deployment/registry/script/dp_script.hrc39
-rw-r--r--desktop/source/deployment/registry/script/dp_script.src49
-rw-r--r--desktop/source/deployment/registry/script/dp_scriptbackenddb.cxx87
-rw-r--r--desktop/source/deployment/registry/script/dp_scriptbackenddb.hxx75
-rwxr-xr-xdesktop/source/deployment/registry/script/makefile.mk49
-rw-r--r--desktop/source/deployment/registry/sfwk/dp_parceldesc.cxx132
-rw-r--r--desktop/source/deployment/registry/sfwk/dp_parceldesc.hxx92
-rw-r--r--desktop/source/deployment/registry/sfwk/dp_sfwk.cxx396
-rwxr-xr-xdesktop/source/deployment/registry/sfwk/dp_sfwk.hrc35
-rw-r--r--desktop/source/deployment/registry/sfwk/dp_sfwk.src35
-rwxr-xr-xdesktop/source/deployment/registry/sfwk/makefile.mk48
-rwxr-xr-xdesktop/source/deployment/target.pmk36
-rwxr-xr-xdesktop/source/deployment/unopkg/makefile.mk48
-rw-r--r--desktop/source/deployment/unopkg/unopkg.src84
-rw-r--r--desktop/source/inc/exithelper.hxx71
-rwxr-xr-xdesktop/source/inc/helpid.hrc67
-rwxr-xr-xdesktop/source/migration/makefile.mk52
-rw-r--r--desktop/source/migration/migration.cxx1356
-rw-r--r--desktop/source/migration/migration_impl.hxx254
-rw-r--r--desktop/source/migration/pages.cxx671
-rw-r--r--desktop/source/migration/pages.hxx212
-rw-r--r--desktop/source/migration/services/autocorrmigration.cxx288
-rw-r--r--desktop/source/migration/services/autocorrmigration.hxx105
-rw-r--r--desktop/source/migration/services/basicmigration.cxx277
-rw-r--r--desktop/source/migration/services/basicmigration.hxx105
-rw-r--r--desktop/source/migration/services/cexports.cxx79
-rw-r--r--desktop/source/migration/services/cexportsoo3.cxx64
-rwxr-xr-xdesktop/source/migration/services/cppumaker.mk36
-rw-r--r--desktop/source/migration/services/jvmfwk.cxx531
-rw-r--r--desktop/source/migration/services/jvmfwk.hxx52
-rwxr-xr-xdesktop/source/migration/services/makefile.mk133
-rwxr-xr-xdesktop/source/migration/services/migrationoo2.component37
-rwxr-xr-xdesktop/source/migration/services/migrationoo2.xml78
-rwxr-xr-xdesktop/source/migration/services/migrationoo3.component34
-rw-r--r--desktop/source/migration/services/misc.hxx51
-rw-r--r--desktop/source/migration/services/oo3extensionmigration.cxx564
-rw-r--r--desktop/source/migration/services/oo3extensionmigration.hxx163
-rw-r--r--desktop/source/migration/services/wordbookmigration.cxx325
-rw-r--r--desktop/source/migration/services/wordbookmigration.hxx105
-rw-r--r--desktop/source/migration/wizard.cxx603
-rwxr-xr-xdesktop/source/migration/wizard.hrc100
-rw-r--r--desktop/source/migration/wizard.hxx105
-rw-r--r--desktop/source/migration/wizard.src442
-rw-r--r--desktop/source/offacc/acceptor.cxx338
-rw-r--r--desktop/source/offacc/acceptor.hxx131
-rwxr-xr-xdesktop/source/offacc/makefile.mk70
-rwxr-xr-xdesktop/source/offacc/offacc.component34
-rwxr-xr-xdesktop/source/pagein/file_image.h81
-rwxr-xr-xdesktop/source/pagein/file_image_unx.c153
-rwxr-xr-xdesktop/source/pagein/makefile.mk196
-rw-r--r--desktop/source/pagein/pagein-main.c12
-rwxr-xr-xdesktop/source/pagein/pagein.c153
-rwxr-xr-xdesktop/source/pkgchk/unopkg/makefile.mk104
-rw-r--r--desktop/source/pkgchk/unopkg/unopkg_app.cxx710
-rw-r--r--desktop/source/pkgchk/unopkg/unopkg_cmdenv.cxx446
-rwxr-xr-xdesktop/source/pkgchk/unopkg/unopkg_main.c39
-rwxr-xr-xdesktop/source/pkgchk/unopkg/unopkg_main.h46
-rw-r--r--desktop/source/pkgchk/unopkg/unopkg_misc.cxx638
-rwxr-xr-xdesktop/source/pkgchk/unopkg/unopkg_shared.h197
-rwxr-xr-xdesktop/source/pkgchk/unopkg/version.map34
-rwxr-xr-xdesktop/source/registration/com/sun/star/registration/Registration.java334
-rwxr-xr-xdesktop/source/registration/com/sun/star/registration/makefile.mk62
-rwxr-xr-xdesktop/source/registration/com/sun/star/registration/manifest2
-rwxr-xr-xdesktop/source/registration/com/sun/star/registration/productregistration.jar.component34
-rwxr-xr-xdesktop/source/registration/com/sun/star/servicetag/BrowserSupport.java201
-rwxr-xr-xdesktop/source/registration/com/sun/star/servicetag/Installer.java943
-rwxr-xr-xdesktop/source/registration/com/sun/star/servicetag/LinuxSystemEnvironment.java322
-rwxr-xr-xdesktop/source/registration/com/sun/star/servicetag/RegistrationData.java531
-rwxr-xr-xdesktop/source/registration/com/sun/star/servicetag/RegistrationDocument.java440
-rwxr-xr-xdesktop/source/registration/com/sun/star/servicetag/Registry.java553
-rwxr-xr-xdesktop/source/registration/com/sun/star/servicetag/ServiceTag.java636
-rwxr-xr-xdesktop/source/registration/com/sun/star/servicetag/SolarisServiceTag.java64
-rwxr-xr-xdesktop/source/registration/com/sun/star/servicetag/SolarisSystemEnvironment.java420
-rwxr-xr-xdesktop/source/registration/com/sun/star/servicetag/SunConnection.java292
-rwxr-xr-xdesktop/source/registration/com/sun/star/servicetag/SysnetRegistryHelper.java375
-rwxr-xr-xdesktop/source/registration/com/sun/star/servicetag/SystemEnvironment.java436
-rwxr-xr-xdesktop/source/registration/com/sun/star/servicetag/UnauthorizedAccessException.java55
-rwxr-xr-xdesktop/source/registration/com/sun/star/servicetag/Util.java293
-rwxr-xr-xdesktop/source/registration/com/sun/star/servicetag/WindowsSystemEnvironment.java232
-rwxr-xr-xdesktop/source/registration/com/sun/star/servicetag/makefile.mk79
-rwxr-xr-xdesktop/source/registration/com/sun/star/servicetag/resources/product_registration.xsd366
-rw-r--r--desktop/source/so_comp/evaluation.cxx209
-rw-r--r--desktop/source/so_comp/evaluation.hxx95
-rwxr-xr-xdesktop/source/so_comp/makefile.mk79
-rw-r--r--desktop/source/so_comp/oemjob.cxx250
-rw-r--r--desktop/source/so_comp/oemjob.hxx95
-rw-r--r--desktop/source/so_comp/services.cxx137
-rwxr-xr-xdesktop/source/so_comp/socomp.component37
-rwxr-xr-xdesktop/source/splash/makefile.mk80
-rw-r--r--desktop/source/splash/services_spl.cxx128
-rwxr-xr-xdesktop/source/splash/spl.component37
-rw-r--r--desktop/source/splash/splash.cxx580
-rw-r--r--desktop/source/splash/splash.hxx134
259 files changed, 64889 insertions, 0 deletions
diff --git a/desktop/source/app/app.cxx b/desktop/source/app/app.cxx
new file mode 100644
index 000000000000..22ac1988636b
--- /dev/null
+++ b/desktop/source/app/app.cxx
@@ -0,0 +1,3307 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include <cstdlib>
+#include <vector>
+
+#include <memory>
+#include <unistd.h>
+#include "app.hxx"
+#include "desktop.hrc"
+#include "appinit.hxx"
+#include "officeipcthread.hxx"
+#include "cmdlineargs.hxx"
+#include "desktopresid.hxx"
+#include "dispatchwatcher.hxx"
+#include "configinit.hxx"
+#include "lockfile.hxx"
+#include "checkinstall.hxx"
+#include "cmdlinehelp.hxx"
+#include "userinstall.hxx"
+#include "desktopcontext.hxx"
+#include "exithelper.hxx"
+#include "migration.hxx"
+
+#include <svtools/javacontext.hxx>
+#include <com/sun/star/frame/XSessionManagerListener.hpp>
+#include <com/sun/star/frame/XSynchronousDispatch.hpp>
+#include <com/sun/star/document/CorruptedFilterConfigurationException.hpp>
+#include <com/sun/star/configuration/CorruptedConfigurationException.hpp>
+#include <com/sun/star/frame/XStorable.hpp>
+#include <com/sun/star/util/XModifiable.hpp>
+#include <com/sun/star/util/XFlushable.hpp>
+#include <com/sun/star/system/XSystemShellExecute.hpp>
+#include <com/sun/star/system/SystemShellExecuteFlags.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/uno/RuntimeException.hpp>
+#include <com/sun/star/io/IOException.hpp>
+#include <com/sun/star/lang/IllegalArgumentException.hpp>
+#include <com/sun/star/lang/WrappedTargetException.hpp>
+#include <com/sun/star/frame/XDesktop.hpp>
+#include <com/sun/star/frame/XComponentLoader.hpp>
+#include <com/sun/star/view/XPrintable.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/frame/XFramesSupplier.hpp>
+#include <com/sun/star/awt/XTopWindow.hpp>
+#include <com/sun/star/util/XURLTransformer.hpp>
+#include <com/sun/star/util/URL.hpp>
+#include <com/sun/star/util/XCloseable.hpp>
+#include <com/sun/star/frame/XDispatch.hpp>
+#include <com/sun/star/frame/XDispatchProvider.hpp>
+#include <com/sun/star/lang/ServiceNotRegisteredException.hpp>
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#include <com/sun/star/configuration/MissingBootstrapFileException.hpp>
+#include <com/sun/star/configuration/InvalidBootstrapFileException.hpp>
+#include <com/sun/star/configuration/InstallationIncompleteException.hpp>
+#include <com/sun/star/configuration/backend/BackendSetupException.hpp>
+#include <com/sun/star/configuration/backend/BackendAccessException.hpp>
+#include <com/sun/star/container/XEnumeration.hpp>
+#include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
+#include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
+#include <com/sun/star/task/XJobExecutor.hpp>
+#include <com/sun/star/task/XRestartManager.hpp>
+#include <com/sun/star/task/XJob.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <com/sun/star/task/XJob.hpp>
+#include <com/sun/star/document/XEventListener.hpp>
+#include <com/sun/star/ui/XUIElementFactoryRegistration.hpp>
+#include <com/sun/star/frame/XUIControllerRegistration.hpp>
+
+#include <com/sun/star/java/XJavaVM.hpp>
+#include <tools/testtoolloader.hxx>
+#include <tools/solar.h>
+#include <toolkit/unohlp.hxx>
+#include <osl/security.hxx>
+#include <rtl/ref.hxx>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/componentcontext.hxx>
+#include <comphelper/configurationhelper.hxx>
+#include <unotools/configmgr.hxx>
+#include <unotools/configitem.hxx>
+#include <unotools/confignode.hxx>
+#include <unotools/ucbhelper.hxx>
+#include <tools/tempfile.hxx>
+#include <tools/urlobj.hxx>
+#include <unotools/moduleoptions.hxx>
+#include <osl/module.h>
+#include <osl/file.hxx>
+#include <osl/process.h>
+#include <osl/signal.h>
+#include <osl/thread.hxx>
+#include <rtl/uuid.h>
+#include <rtl/uri.hxx>
+#include <unotools/pathoptions.hxx>
+#include <svl/languageoptions.hxx>
+#include <unotools/internaloptions.hxx>
+#include <svtools/miscopt.hxx>
+#include <svtools/menuoptions.hxx>
+#include <unotools/syslocaleoptions.hxx>
+#include <unotools/syslocale.hxx>
+#include <svl/folderrestriction.hxx>
+#include <unotools/tempfile.hxx>
+#include <rtl/logfile.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <rtl/strbuf.hxx>
+#include <rtl/bootstrap.hxx>
+#include <rtl/instance.hxx>
+#include <unotools/configmgr.hxx>
+#include <vcl/help.hxx>
+#include <vcl/msgbox.hxx>
+#include <vcl/bitmap.hxx>
+#include <vcl/stdtext.hxx>
+#include <vcl/msgbox.hxx>
+#include <sfx2/sfx.hrc>
+#include <sfx2/app.hxx>
+#include <svl/itemset.hxx>
+#include <svl/eitem.hxx>
+#include <ucbhelper/contentbroker.hxx>
+#include <unotools/bootstrap.hxx>
+#include <cppuhelper/bootstrap.hxx>
+
+#include <svtools/fontsubstconfig.hxx>
+#include <svtools/accessibilityoptions.hxx>
+#include <svtools/apearcfg.hxx>
+#include <unotools/misccfg.hxx>
+#include <svtools/filter.hxx>
+#include <unotools/regoptions.hxx>
+
+#include "langselect.hxx"
+
+#if defined MACOSX
+#include <errno.h>
+#include <sys/wait.h>
+#endif
+
+#define DEFINE_CONST_UNICODE(CONSTASCII) UniString(RTL_CONSTASCII_USTRINGPARAM(CONSTASCII))
+#define U2S(STRING) ::rtl::OUStringToOString(STRING, RTL_TEXTENCODING_UTF8)
+
+using rtl::OUString;
+using rtl::OUStringBuffer;
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::util;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::document;
+using namespace ::com::sun::star::view;
+using namespace ::com::sun::star::task;
+using namespace ::com::sun::star::system;
+using namespace ::com::sun::star::ui::dialogs;
+using namespace ::com::sun::star::container;
+
+namespace css = ::com::sun::star;
+
+ResMgr* desktop::Desktop::pResMgr = 0;
+
+namespace desktop
+{
+
+static oslSignalHandler pSignalHandler = 0;
+static sal_Bool _bCrashReporterEnabled = sal_True;
+
+static ::rtl::OUString getBrandSharePreregBundledPathURL();
+// ----------------------------------------------------------------------------
+
+ResMgr* Desktop::GetDesktopResManager()
+{
+ if ( !Desktop::pResMgr )
+ {
+ // Create desktop resource manager and bootstrap process
+ // was successful. Use default way to get language specific message.
+ if ( Application::IsInExecute() )
+ Desktop::pResMgr = ResMgr::CreateResMgr("dkt");
+
+ if ( !Desktop::pResMgr )
+ {
+ // Use VCL to get the correct language specific message as we
+ // are in the bootstrap process and not able to get the installed
+ // language!!
+ OUString aUILocaleString = LanguageSelection::getLanguageString();
+ sal_Int32 nIndex = 0;
+ OUString aLanguage = aUILocaleString.getToken( 0, '-', nIndex);
+ OUString aCountry = aUILocaleString.getToken( 0, '-', nIndex);
+ OUString aVariant = aUILocaleString.getToken( 0, '-', nIndex);
+
+ ::com::sun::star::lang::Locale aLocale( aLanguage, aCountry, aVariant );
+
+ Desktop::pResMgr = ResMgr::SearchCreateResMgr( "dkt", aLocale);
+ AllSettings as = GetSettings();
+ as.SetUILocale(aLocale);
+ SetSettings(as);
+ }
+ }
+
+ return Desktop::pResMgr;
+}
+
+// ----------------------------------------------------------------------------
+// Get a message string securely. There is a fallback string if the resource
+// is not available.
+
+OUString Desktop::GetMsgString( sal_uInt16 nId, const OUString& aFaultBackMsg )
+{
+ ResMgr* resMgr = GetDesktopResManager();
+ if ( !resMgr )
+ return aFaultBackMsg;
+ else
+ return OUString( String( ResId( nId, *resMgr )));
+}
+
+OUString MakeStartupErrorMessage(OUString const & aErrorMessage)
+{
+ OUStringBuffer aDiagnosticMessage( 100 );
+
+ ResMgr* pResMgr = Desktop::GetDesktopResManager();
+ if ( pResMgr )
+ aDiagnosticMessage.append( OUString(String(ResId(STR_BOOTSTRAP_ERR_CANNOT_START, *pResMgr))) );
+ else
+ aDiagnosticMessage.appendAscii( "The program cannot be started." );
+
+ aDiagnosticMessage.appendAscii( "\n" );
+
+ aDiagnosticMessage.append( aErrorMessage );
+
+ return aDiagnosticMessage.makeStringAndClear();
+}
+
+OUString MakeStartupConfigAccessErrorMessage( OUString const & aInternalErrMsg )
+{
+ OUStringBuffer aDiagnosticMessage( 200 );
+
+ ResMgr* pResMgr = Desktop::GetDesktopResManager();
+ if ( pResMgr )
+ aDiagnosticMessage.append( OUString(String(ResId(STR_BOOTSTRAP_ERR_CFG_DATAACCESS, *pResMgr ))) );
+ else
+ aDiagnosticMessage.appendAscii( "The program cannot be started." );
+
+ if ( aInternalErrMsg.getLength() > 0 )
+ {
+ aDiagnosticMessage.appendAscii( "\n\n" );
+ if ( pResMgr )
+ aDiagnosticMessage.append( OUString(String(ResId(STR_INTERNAL_ERRMSG, *pResMgr ))) );
+ else
+ aDiagnosticMessage.appendAscii( "The following internal error has occurred:\n\n" );
+ aDiagnosticMessage.append( aInternalErrMsg );
+ }
+
+ return aDiagnosticMessage.makeStringAndClear();
+}
+
+//=============================================================================
+// shows a simple error box with the given message ... but exits from these process !
+// Fatal errors cant be solved by the process ... nor any recovery can help.
+// Mostly the installation was damaged and must be repaired manually .. or by calling
+// setup again.
+// On the other side we must make sure that no further actions will be possible within
+// the current office process ! No pipe requests, no menu/toolbar/shortuct actions
+// are allowed. Otherwise we will force a "crash inside a crash".
+// Thats why we have to use a special native message box here which does not use yield :-)
+//=============================================================================
+void FatalError(const ::rtl::OUString& sMessage)
+{
+ ::rtl::OUString sProductKey = ::utl::Bootstrap::getProductKey();
+ if ( ! sProductKey.getLength())
+ {
+ osl_getExecutableFile( &sProductKey.pData );
+
+ ::sal_uInt32 nLastIndex = sProductKey.lastIndexOf('/');
+ if ( nLastIndex > 0 )
+ sProductKey = sProductKey.copy( nLastIndex+1 );
+ }
+
+ ::rtl::OUStringBuffer sTitle (128);
+ sTitle.append (sProductKey );
+ sTitle.appendAscii (" - Fatal Error");
+
+ Application::ShowNativeErrorBox (sTitle.makeStringAndClear (), sMessage);
+ _exit(ExitHelper::E_FATAL_ERROR);
+}
+
+static bool ShouldSuppressUI(CommandLineArgs* pCmdLine)
+{
+ return pCmdLine->IsInvisible() ||
+ pCmdLine->IsHeadless() ||
+ pCmdLine->IsQuickstart();
+}
+
+CommandLineArgs* Desktop::GetCommandLineArgs()
+{
+ static CommandLineArgs* pArgs = 0;
+ if ( !pArgs )
+ {
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ if ( !pArgs )
+ pArgs = new CommandLineArgs;
+ }
+
+ return pArgs;
+}
+
+sal_Bool InitConfiguration()
+{
+ RTL_LOGFILE_CONTEXT( aLog, "desktop (jb99855) ::InitConfiguration" );
+
+ Reference< XMultiServiceFactory > xProvider( CreateApplicationConfigurationProvider( ) );
+ return xProvider.is();
+}
+
+namespace
+{
+ struct BrandName
+ : public rtl::Static< String, BrandName > {};
+ struct Version
+ : public rtl::Static< String, Version > {};
+ struct AboutBoxVersion
+ : public rtl::Static< String, AboutBoxVersion > {};
+ struct OOOVendor
+ : public rtl::Static< String, OOOVendor > {};
+ struct Extension
+ : public rtl::Static< String, Extension > {};
+ struct XMLFileFormatName
+ : public rtl::Static< String, XMLFileFormatName > {};
+ struct XMLFileFormatVersion
+ : public rtl::Static< String, XMLFileFormatVersion > {};
+ struct WriterCompatibilityVersionOOo11
+ : public rtl::Static< String, WriterCompatibilityVersionOOo11 > {};
+}
+
+void ReplaceStringHookProc( UniString& rStr )
+{
+ static int nAll = 0, nPro = 0;
+
+ nAll++;
+ if ( rStr.SearchAscii( "%PRODUCT" ) != STRING_NOTFOUND )
+ {
+ String &rBrandName = BrandName::get();
+ String &rVersion = Version::get();
+ String &rAboutBoxVersion = AboutBoxVersion::get();
+ String &rExtension = Extension::get();
+ String &rXMLFileFormatName = XMLFileFormatName::get();
+ String &rXMLFileFormatVersion = XMLFileFormatVersion::get();
+
+ if ( !rBrandName.Len() )
+ {
+ rtl::OUString aTmp;
+ Any aRet = ::utl::ConfigManager::GetDirectConfigProperty( ::utl::ConfigManager::PRODUCTNAME );
+ aRet >>= aTmp;
+ rBrandName = aTmp;
+
+ aRet = ::utl::ConfigManager::GetDirectConfigProperty( ::utl::ConfigManager::PRODUCTXMLFILEFORMATNAME );
+ aRet >>= aTmp;
+ rXMLFileFormatName = aTmp;
+
+ aRet = ::utl::ConfigManager::GetDirectConfigProperty( ::utl::ConfigManager::PRODUCTXMLFILEFORMATVERSION );
+ aRet >>= aTmp;
+ rXMLFileFormatVersion = aTmp;
+
+ aRet = ::utl::ConfigManager::GetDirectConfigProperty( ::utl::ConfigManager::PRODUCTVERSION );
+ aRet >>= aTmp;
+ rVersion = aTmp;
+
+ aRet = ::utl::ConfigManager::GetDirectConfigProperty( ::utl::ConfigManager::ABOUTBOXPRODUCTVERSION );
+ aRet >>= aTmp;
+ rAboutBoxVersion = aTmp;
+
+ if ( !rExtension.Len() )
+ {
+ aRet = ::utl::ConfigManager::GetDirectConfigProperty( ::utl::ConfigManager::PRODUCTEXTENSION );
+ aRet >>= aTmp;
+ rExtension = aTmp;
+ }
+ }
+
+ nPro++;
+ rStr.SearchAndReplaceAllAscii( "%PRODUCTNAME", rBrandName );
+ rStr.SearchAndReplaceAllAscii( "%PRODUCTVERSION", rVersion );
+ rStr.SearchAndReplaceAllAscii( "%ABOUTBOXPRODUCTVERSION", rAboutBoxVersion );
+ rStr.SearchAndReplaceAllAscii( "%PRODUCTEXTENSION", rExtension );
+ rStr.SearchAndReplaceAllAscii( "%PRODUCTXMLFILEFORMATNAME", rXMLFileFormatName );
+ rStr.SearchAndReplaceAllAscii( "%PRODUCTXMLFILEFORMATVERSION", rXMLFileFormatVersion );
+ }
+ if ( rStr.SearchAscii( "%OOOVENDOR" ) != STRING_NOTFOUND )
+ {
+ String &rOOOVendor = OOOVendor::get();
+
+ if ( !rOOOVendor.Len() )
+ {
+ rtl::OUString aTmp;
+ Any aRet = ::utl::ConfigManager::GetDirectConfigProperty(
+ ::utl::ConfigManager::OOOVENDOR );
+ aRet >>= aTmp;
+ rOOOVendor = aTmp;
+
+ }
+ rStr.SearchAndReplaceAllAscii( "%OOOVENDOR" ,rOOOVendor );
+ }
+
+ if ( rStr.SearchAscii( "%WRITERCOMPATIBILITYVERSIONOOO11" ) != STRING_NOTFOUND )
+ {
+ String &rWriterCompatibilityVersionOOo11 = WriterCompatibilityVersionOOo11::get();
+ if ( !rWriterCompatibilityVersionOOo11.Len() )
+ {
+ rtl::OUString aTmp;
+ Any aRet = ::utl::ConfigManager::GetDirectConfigProperty(
+ ::utl::ConfigManager::WRITERCOMPATIBILITYVERSIONOOO11 );
+ aRet >>= aTmp;
+ rWriterCompatibilityVersionOOo11 = aTmp;
+ }
+
+ rStr.SearchAndReplaceAllAscii( "%WRITERCOMPATIBILITYVERSIONOOO11",
+ rWriterCompatibilityVersionOOo11 );
+ }
+}
+
+static const char pLastSyncFileName[] = "lastsynchronized";
+static const sal_Int32 nStrLenLastSync = 16;
+
+static bool needsSynchronization(
+ ::rtl::OUString const & baseSynchronizedURL, ::rtl::OUString const & userSynchronizedURL )
+{
+ bool bNeedsSync( false );
+
+ ::osl::DirectoryItem itemUserFile;
+ ::osl::File::RC err1 =
+ ::osl::DirectoryItem::get(userSynchronizedURL, itemUserFile);
+
+ //If it does not exist, then there is nothing to be done
+ if (err1 == ::osl::File::E_NOENT)
+ {
+ return true;
+ }
+ else if (err1 != ::osl::File::E_None)
+ {
+ OSL_FAIL("Cannot access lastsynchronized in user layer");
+ return true; //sync just in case
+ }
+
+ //If last synchronized does not exist in base layer, then do nothing
+ ::osl::DirectoryItem itemBaseFile;
+ ::osl::File::RC err2 = ::osl::DirectoryItem::get(baseSynchronizedURL, itemBaseFile);
+ if (err2 == ::osl::File::E_NOENT)
+ {
+ return true;
+
+ }
+ else if (err2 != ::osl::File::E_None)
+ {
+ OSL_FAIL("Cannot access file lastsynchronized in base layer");
+ return true; //sync just in case
+ }
+
+ //compare the modification time of the extension folder and the last
+ //modified file
+ ::osl::FileStatus statUser(FileStatusMask_ModifyTime);
+ ::osl::FileStatus statBase(FileStatusMask_ModifyTime);
+ if (itemUserFile.getFileStatus(statUser) == ::osl::File::E_None)
+ {
+ if (itemBaseFile.getFileStatus(statBase) == ::osl::File::E_None)
+ {
+ TimeValue timeUser = statUser.getModifyTime();
+ TimeValue timeBase = statBase.getModifyTime();
+
+ if (timeUser.Seconds < timeBase.Seconds)
+ bNeedsSync = true;
+ }
+ else
+ {
+ OSL_ASSERT(0);
+ bNeedsSync = true;
+ }
+ }
+ else
+ {
+ OSL_ASSERT(0);
+ bNeedsSync = true;
+ }
+
+ return bNeedsSync;
+}
+
+static ::rtl::OUString getBrandSharePreregBundledPathURL()
+{
+ ::rtl::OUString url(
+ RTL_CONSTASCII_USTRINGPARAM("$BRAND_BASE_DIR/share/prereg/bundled"));
+
+ ::rtl::Bootstrap::expandMacros(url);
+ return url;
+}
+
+static ::rtl::OUString getUserBundledExtPathURL()
+{
+ ::rtl::OUString folder( RTL_CONSTASCII_USTRINGPARAM( "$BUNDLED_EXTENSIONS_USER" ));
+ ::rtl::Bootstrap::expandMacros(folder);
+
+ return folder;
+}
+
+static ::rtl::OUString getLastSyncFileURLFromBrandInstallation()
+{
+ ::rtl::OUString aURL = getBrandSharePreregBundledPathURL();
+ ::sal_Int32 nLastIndex = aURL.lastIndexOf('/');
+
+ ::rtl::OUStringBuffer aTmp( aURL );
+
+ if ( nLastIndex != aURL.getLength()-1 )
+ aTmp.appendAscii( "/" );
+ aTmp.appendAscii( pLastSyncFileName );
+
+ return aTmp.makeStringAndClear();
+}
+
+static ::rtl::OUString getLastSyncFileURLFromUserInstallation()
+{
+ ::rtl::OUString aUserBundledPathURL = getUserBundledExtPathURL();
+ ::sal_Int32 nLastIndex = aUserBundledPathURL.lastIndexOf('/');
+
+ ::rtl::OUStringBuffer aTmp( aUserBundledPathURL );
+
+ if ( nLastIndex != aUserBundledPathURL.getLength()-1 )
+ aTmp.appendAscii( "/" );
+ aTmp.appendAscii( pLastSyncFileName );
+
+ return aTmp.makeStringAndClear();
+}
+//Checks if the argument src is the folder of the help or configuration
+//backend in the prereg folder
+static bool excludeTmpFilesAndFolders(const rtl::OUString & src)
+{
+ const char helpBackend[] = "com.sun.star.comp.deployment.help.PackageRegistryBackend";
+ const char configBackend[] = "com.sun.star.comp.deployment.configuration.PackageRegistryBackend";
+ if (src.endsWithAsciiL(helpBackend, sizeof(helpBackend) - 1 )
+ || src.endsWithAsciiL(configBackend, sizeof(configBackend) - 1))
+ {
+ return true;
+ }
+ return false;
+}
+
+//If we are about to copy the contents of some special folder as determined
+//by excludeTmpFilesAndFolders, then we omit those files or folders with a name
+//derived from temporary folders.
+static bool isExcludedFileOrFolder( const rtl::OUString & name)
+{
+ char const * allowed[] = {
+ "backenddb.xml",
+ "configmgr.ini",
+ "registered_packages.db"
+ };
+
+ const unsigned int size = sizeof(allowed) / sizeof (char const *);
+ bool bExclude = true;
+ for (unsigned int i= 0; i < size; i ++)
+ {
+ ::rtl::OUString allowedName = ::rtl::OUString::createFromAscii(allowed[i]);
+ if (allowedName.equals(name))
+ {
+ bExclude = false;
+ break;
+ }
+ }
+ return bExclude;
+}
+
+static osl::FileBase::RC copy_bundled_recursive(
+ const rtl::OUString& srcUnqPath,
+ const rtl::OUString& dstUnqPath,
+ sal_Int32 TypeToCopy )
+throw()
+{
+ osl::FileBase::RC err = osl::FileBase::E_None;
+
+ if( TypeToCopy == -1 ) // Document
+ {
+ err = osl::File::copy( srcUnqPath,dstUnqPath );
+ }
+ else if( TypeToCopy == +1 ) // Folder
+ {
+ err = osl::Directory::create( dstUnqPath );
+ osl::FileBase::RC next = err;
+ if( err == osl::FileBase::E_None || err == osl::FileBase::E_EXIST )
+ {
+ err = osl::FileBase::E_None;
+
+ osl::Directory aDir( srcUnqPath );
+ bool bExcludeFiles = excludeTmpFilesAndFolders(srcUnqPath);
+ if (aDir.open() == osl::FileBase::E_None)
+ {
+ sal_Int32 n_Mask = FileStatusMask_FileURL |
+ FileStatusMask_FileName |
+ FileStatusMask_Type;
+
+ osl::DirectoryItem aDirItem;
+ while( err == osl::FileBase::E_None && ( next = aDir.getNextItem( aDirItem ) ) == osl::FileBase::E_None )
+ {
+ sal_Bool IsDoc = false;
+ sal_Bool bFilter = false;
+ osl::FileStatus aFileStatus( n_Mask );
+ aDirItem.getFileStatus( aFileStatus );
+ if( aFileStatus.isValid( FileStatusMask_Type ) )
+ IsDoc = aFileStatus.getFileType() == osl::FileStatus::Regular;
+
+ // Getting the information for the next recursive copy
+ sal_Int32 newTypeToCopy = IsDoc ? -1 : +1;
+
+ rtl::OUString newSrcUnqPath;
+ if( aFileStatus.isValid( FileStatusMask_FileURL ) )
+ newSrcUnqPath = aFileStatus.getFileURL();
+
+ rtl::OUString newDstUnqPath = dstUnqPath;
+ rtl::OUString tit;
+ if( aFileStatus.isValid( FileStatusMask_FileName ) )
+ {
+ ::rtl::OUString aFileName = aFileStatus.getFileName();
+ tit = rtl::Uri::encode( aFileName,
+ rtl_UriCharClassPchar,
+ rtl_UriEncodeIgnoreEscapes,
+ RTL_TEXTENCODING_UTF8 );
+
+ // Special treatment for "lastsychronized" file. Must not be
+ // copied from the bundled folder!
+ //Also do not copy *.tmp files and *.tmp_ folders. This affects the files/folders
+ //from the help and configuration backend
+ if ( IsDoc && (aFileName.equalsAscii( pLastSyncFileName )
+ || (bExcludeFiles && isExcludedFileOrFolder(aFileName))))
+ bFilter = true;
+ else if (!IsDoc && bExcludeFiles && isExcludedFileOrFolder(aFileName))
+ bFilter = true;
+ }
+
+ if( newDstUnqPath.lastIndexOf( sal_Unicode('/') ) != newDstUnqPath.getLength()-1 )
+ newDstUnqPath += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/"));
+
+ newDstUnqPath += tit;
+
+ if (( newSrcUnqPath != dstUnqPath ) && !bFilter )
+ err = copy_bundled_recursive( newSrcUnqPath,newDstUnqPath, newTypeToCopy );
+ }
+
+ if( err == osl::FileBase::E_None && next != osl::FileBase::E_NOENT )
+ err = next;
+
+ aDir.close();
+ }
+ }
+ }
+
+ return err;
+}
+
+Desktop::Desktop()
+: m_bServicesRegistered( false )
+, m_aBootstrapError( BE_OK )
+, m_pLockfile( NULL )
+{
+ RTL_LOGFILE_TRACE( "desktop (cd100003) ::Desktop::Desktop" );
+}
+
+Desktop::~Desktop()
+{
+}
+
+void Desktop::Init()
+{
+ RTL_LOGFILE_CONTEXT( aLog, "desktop (cd100003) ::Desktop::Init" );
+ SetBootstrapStatus(BS_OK);
+
+ // Check for lastsynchronized file for bundled extensions in the user directory
+ // and test if synchronzation is necessary!
+ {
+ ::rtl::OUString aUserLastSyncFilePathURL = getLastSyncFileURLFromUserInstallation();
+ ::rtl::OUString aPreregSyncFilePathURL = getLastSyncFileURLFromBrandInstallation();
+
+ if ( needsSynchronization( aPreregSyncFilePathURL, aUserLastSyncFilePathURL ))
+ {
+ rtl::OUString aUserPath = getUserBundledExtPathURL();
+ rtl::OUString aPreregBundledPath = getBrandSharePreregBundledPathURL();
+
+ // copy bundled folder to the user directory
+ osl::FileBase::RC rc = osl::Directory::createPath(aUserPath);
+ (void) rc;
+ copy_bundled_recursive( aPreregBundledPath, aUserPath, +1 );
+ }
+ }
+
+ // We need to have service factory before going further.
+ if( !::comphelper::getProcessServiceFactory().is())
+ {
+ OSL_FAIL("Service factory should have been crated in soffice_main().");
+ SetBootstrapError( BE_UNO_SERVICEMANAGER );
+ }
+
+ if ( GetBootstrapError() == BE_OK )
+ {
+ // prepare language
+ if ( !LanguageSelection::prepareLanguage() )
+ {
+ if ( LanguageSelection::getStatus() == LanguageSelection::LS_STATUS_CANNOT_DETERMINE_LANGUAGE )
+ SetBootstrapError( BE_LANGUAGE_MISSING );
+ else
+ SetBootstrapError( BE_OFFICECONFIG_BROKEN );
+ }
+ }
+
+ if ( GetBootstrapError() == BE_OK )
+ {
+ CommandLineArgs* pCmdLineArgs = GetCommandLineArgs();
+ // start ipc thread only for non-remote offices
+ RTL_LOGFILE_CONTEXT( aLog2, "desktop (cd100003) ::OfficeIPCThread::EnableOfficeIPCThread" );
+ OfficeIPCThread::Status aStatus = OfficeIPCThread::EnableOfficeIPCThread();
+ if ( aStatus == OfficeIPCThread::IPC_STATUS_BOOTSTRAP_ERROR )
+ {
+ SetBootstrapError( BE_PATHINFO_MISSING );
+ }
+ else if ( aStatus == OfficeIPCThread::IPC_STATUS_2ND_OFFICE )
+ {
+ // 2nd office startup should terminate after sending cmdlineargs through pipe
+ SetBootstrapStatus(BS_TERMINATE);
+ }
+ else if ( pCmdLineArgs->IsHelp() )
+ {
+ // disable IPC thread in an instance that is just showing a help message
+ OfficeIPCThread::DisableOfficeIPCThread();
+ }
+ pSignalHandler = osl_addSignalHandler(SalMainPipeExchangeSignal_impl, NULL);
+ }
+}
+
+void Desktop::InitFinished()
+{
+ RTL_LOGFILE_CONTEXT( aLog, "desktop (cd100003) ::Desktop::InitFinished" );
+
+ CloseSplashScreen();
+}
+
+// GetCommandLineArgs() requires this code to work, otherwise it will abort, and
+// on Unix command line args needs to be checked before Desktop::Init()
+void Desktop::CreateProcessServiceFactory()
+{
+ Reference < XMultiServiceFactory > rSMgr = CreateApplicationServiceManager();
+ if( rSMgr.is() )
+ {
+ ::comphelper::setProcessServiceFactory( rSMgr );
+ }
+}
+
+void Desktop::DeInit()
+{
+ RTL_LOGFILE_CONTEXT( aLog, "desktop (cd100003) ::Desktop::DeInit" );
+
+ try {
+ // instead of removing of the configManager just let it commit all the changes
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "<- store config items" );
+ utl::ConfigManager::GetConfigManager().StoreConfigItems();
+ FlushConfiguration();
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "<- store config items" );
+
+ // close splashscreen if it's still open
+ CloseSplashScreen();
+ Reference<XMultiServiceFactory> xXMultiServiceFactory(::comphelper::getProcessServiceFactory());
+ DestroyApplicationServiceManager( xXMultiServiceFactory );
+ // nobody should get a destroyd service factory...
+ ::comphelper::setProcessServiceFactory( NULL );
+
+ // clear lockfile
+ if (m_pLockfile != NULL)
+ m_pLockfile->clean();
+
+ OfficeIPCThread::DisableOfficeIPCThread();
+ if( pSignalHandler )
+ osl_removeSignalHandler( pSignalHandler );
+ } catch (RuntimeException&) {
+ // someone threw an exception during shutdown
+ // this will leave some garbage behind..
+ }
+
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "FINISHED WITH Destop::DeInit" );
+}
+
+sal_Bool Desktop::QueryExit()
+{
+ try
+ {
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "<- store config items" );
+ utl::ConfigManager::GetConfigManager().StoreConfigItems();
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "<- store config items" );
+ }
+ catch ( RuntimeException& )
+ {
+ }
+
+ const sal_Char SUSPEND_QUICKSTARTVETO[] = "SuspendQuickstartVeto";
+
+ Reference< ::com::sun::star::frame::XDesktop >
+ xDesktop( ::comphelper::getProcessServiceFactory()->createInstance( OUSTRING(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.Desktop")) ),
+ UNO_QUERY );
+
+ Reference < ::com::sun::star::beans::XPropertySet > xPropertySet( xDesktop, UNO_QUERY );
+ if ( xPropertySet.is() )
+ {
+ Any a;
+ a <<= (sal_Bool)sal_True;
+ xPropertySet->setPropertyValue( OUSTRING(RTL_CONSTASCII_USTRINGPARAM( SUSPEND_QUICKSTARTVETO )), a );
+ }
+
+ sal_Bool bExit = ( !xDesktop.is() || xDesktop->terminate() );
+
+
+ if ( !bExit && xPropertySet.is() )
+ {
+ Any a;
+ a <<= (sal_Bool)sal_False;
+ xPropertySet->setPropertyValue( OUSTRING(RTL_CONSTASCII_USTRINGPARAM( SUSPEND_QUICKSTARTVETO )), a );
+ }
+ else
+ {
+ FlushConfiguration();
+ try
+ {
+ // it is no problem to call DisableOfficeIPCThread() more than once
+ // it also looks to be threadsafe
+ OfficeIPCThread::DisableOfficeIPCThread();
+ }
+ catch ( RuntimeException& )
+ {
+ }
+
+ if (m_pLockfile != NULL) m_pLockfile->clean();
+ }
+
+ return bExit;
+}
+
+void Desktop::HandleBootstrapPathErrors( ::utl::Bootstrap::Status aBootstrapStatus, const OUString& aDiagnosticMessage )
+{
+ if ( aBootstrapStatus != ::utl::Bootstrap::DATA_OK )
+ {
+ ::rtl::OUString aProductKey;
+ ::rtl::OUString aTemp;
+
+ osl_getExecutableFile( &aProductKey.pData );
+ sal_uInt32 lastIndex = aProductKey.lastIndexOf('/');
+ if ( lastIndex > 0 )
+ aProductKey = aProductKey.copy( lastIndex+1 );
+
+ aTemp = ::utl::Bootstrap::getProductKey( aProductKey );
+ if ( aTemp.getLength() > 0 )
+ aProductKey = aTemp;
+
+ OUString aMessage;
+ OUStringBuffer aBuffer( 100 );
+ aBuffer.append( aDiagnosticMessage );
+
+ aBuffer.appendAscii( "\n" );
+
+ ErrorBox aBootstrapFailedBox( NULL, WB_OK, aMessage );
+ aBootstrapFailedBox.SetText( aProductKey );
+ aBootstrapFailedBox.Execute();
+ }
+}
+
+// Create a error message depending on bootstrap failure code and an optional file url
+::rtl::OUString Desktop::CreateErrorMsgString(
+ utl::Bootstrap::FailureCode nFailureCode,
+ const ::rtl::OUString& aFileURL )
+{
+ OUString aMsg;
+ OUString aFilePath;
+ sal_Bool bFileInfo = sal_True;
+
+ switch ( nFailureCode )
+ {
+ /// the shared installation directory could not be located
+ case ::utl::Bootstrap::MISSING_INSTALL_DIRECTORY:
+ {
+ aMsg = GetMsgString( STR_BOOTSTRAP_ERR_PATH_INVALID,
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "The installation path is not available." )) );
+ bFileInfo = sal_False;
+ }
+ break;
+
+ /// the bootstrap INI file could not be found or read
+ case ::utl::Bootstrap::MISSING_BOOTSTRAP_FILE:
+ {
+ aMsg = GetMsgString( STR_BOOTSTRAP_ERR_FILE_MISSING,
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "The configuration file \"$1\" is missing." )) );
+ }
+ break;
+
+ /// the bootstrap INI is missing a required entry
+ /// the bootstrap INI contains invalid data
+ case ::utl::Bootstrap::MISSING_BOOTSTRAP_FILE_ENTRY:
+ case ::utl::Bootstrap::INVALID_BOOTSTRAP_FILE_ENTRY:
+ {
+ aMsg = GetMsgString( STR_BOOTSTRAP_ERR_FILE_CORRUPT,
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "The configuration file \"$1\" is corrupt." )) );
+ }
+ break;
+
+ /// the version locator INI file could not be found or read
+ case ::utl::Bootstrap::MISSING_VERSION_FILE:
+ {
+ aMsg = GetMsgString( STR_BOOTSTRAP_ERR_FILE_MISSING,
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "The configuration file \"$1\" is missing." )) );
+ }
+ break;
+
+ /// the version locator INI has no entry for this version
+ case ::utl::Bootstrap::MISSING_VERSION_FILE_ENTRY:
+ {
+ aMsg = GetMsgString( STR_BOOTSTRAP_ERR_NO_SUPPORT,
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "The main configuration file \"$1\" does not support the current version." )) );
+ }
+ break;
+
+ /// the user installation directory does not exist
+ case ::utl::Bootstrap::MISSING_USER_DIRECTORY:
+ {
+ aMsg = GetMsgString( STR_BOOTSTRAP_ERR_DIR_MISSING,
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "The configuration directory \"$1\" is missing." )) );
+ }
+ break;
+
+ /// some bootstrap data was invalid in unexpected ways
+ case ::utl::Bootstrap::INVALID_BOOTSTRAP_DATA:
+ {
+ aMsg = GetMsgString( STR_BOOTSTRAP_ERR_INTERNAL,
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "An internal failure occurred." )) );
+ bFileInfo = sal_False;
+ }
+ break;
+
+ case ::utl::Bootstrap::INVALID_VERSION_FILE_ENTRY:
+ {
+ // This needs to be improved, see #i67575#:
+ aMsg = OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "Invalid version file entry" ) );
+ bFileInfo = sal_False;
+ }
+ break;
+
+ case ::utl::Bootstrap::NO_FAILURE:
+ {
+ OSL_ASSERT(false);
+ }
+ break;
+ }
+
+ if ( bFileInfo )
+ {
+ String aMsgString( aMsg );
+
+ osl::File::getSystemPathFromFileURL( aFileURL, aFilePath );
+
+ aMsgString.SearchAndReplaceAscii( "$1", aFilePath );
+ aMsg = aMsgString;
+ }
+
+ return MakeStartupErrorMessage( aMsg );
+}
+
+void Desktop::HandleBootstrapErrors( BootstrapError aBootstrapError )
+{
+ if ( aBootstrapError == BE_PATHINFO_MISSING )
+ {
+ OUString aErrorMsg;
+ OUString aBuffer;
+ utl::Bootstrap::Status aBootstrapStatus;
+ utl::Bootstrap::FailureCode nFailureCode;
+
+ aBootstrapStatus = ::utl::Bootstrap::checkBootstrapStatus( aBuffer, nFailureCode );
+ if ( aBootstrapStatus != ::utl::Bootstrap::DATA_OK )
+ {
+ switch ( nFailureCode )
+ {
+ case ::utl::Bootstrap::MISSING_INSTALL_DIRECTORY:
+ case ::utl::Bootstrap::INVALID_BOOTSTRAP_DATA:
+ {
+ aErrorMsg = CreateErrorMsgString( nFailureCode, OUString() );
+ }
+ break;
+
+ /// the bootstrap INI file could not be found or read
+ /// the bootstrap INI is missing a required entry
+ /// the bootstrap INI contains invalid data
+ case ::utl::Bootstrap::MISSING_BOOTSTRAP_FILE_ENTRY:
+ case ::utl::Bootstrap::INVALID_BOOTSTRAP_FILE_ENTRY:
+ case ::utl::Bootstrap::MISSING_BOOTSTRAP_FILE:
+ {
+ OUString aBootstrapFileURL;
+
+ utl::Bootstrap::locateBootstrapFile( aBootstrapFileURL );
+ aErrorMsg = CreateErrorMsgString( nFailureCode, aBootstrapFileURL );
+ }
+ break;
+
+ /// the version locator INI file could not be found or read
+ /// the version locator INI has no entry for this version
+ /// the version locator INI entry is not a valid directory URL
+ case ::utl::Bootstrap::INVALID_VERSION_FILE_ENTRY:
+ case ::utl::Bootstrap::MISSING_VERSION_FILE_ENTRY:
+ case ::utl::Bootstrap::MISSING_VERSION_FILE:
+ {
+ OUString aVersionFileURL;
+
+ utl::Bootstrap::locateVersionFile( aVersionFileURL );
+ aErrorMsg = CreateErrorMsgString( nFailureCode, aVersionFileURL );
+ }
+ break;
+
+ /// the user installation directory does not exist
+ case ::utl::Bootstrap::MISSING_USER_DIRECTORY:
+ {
+ OUString aUserInstallationURL;
+
+ utl::Bootstrap::locateUserInstallation( aUserInstallationURL );
+ aErrorMsg = CreateErrorMsgString( nFailureCode, aUserInstallationURL );
+ }
+ break;
+
+ case ::utl::Bootstrap::NO_FAILURE:
+ {
+ OSL_ASSERT(false);
+ }
+ break;
+ }
+
+ HandleBootstrapPathErrors( aBootstrapStatus, aErrorMsg );
+ }
+ }
+ else if ( aBootstrapError == BE_UNO_SERVICEMANAGER || aBootstrapError == BE_UNO_SERVICE_CONFIG_MISSING )
+ {
+ // Uno service manager is not available. VCL needs a uno service manager to display a message box!!!
+ // Currently we are not able to display a message box with a service manager due to this limitations inside VCL.
+
+ // When UNO is not properly initialized, all kinds of things can fail
+ // and cause the process to crash (e.g., a call to GetMsgString may
+ // crash when somewhere deep within that call Any::operator <= is used
+ // with a PropertyValue, and no binary UNO type description for
+ // PropertyValue is available). To give the user a hint even if
+ // generating and displaying a message box below crashes, print a
+ // hard-coded message on stderr first:
+ fputs(
+ aBootstrapError == BE_UNO_SERVICEMANAGER
+ ? ("The application cannot be started. " "\n"
+ "The component manager is not available." "\n")
+ // STR_BOOTSTRAP_ERR_CANNOT_START, STR_BOOTSTRAP_ERR_NO_SERVICE
+ : ("The application cannot be started. " "\n"
+ "The configuration service is not available." "\n"),
+ // STR_BOOTSTRAP_ERR_CANNOT_START,
+ // STR_BOOTSTRAP_ERR_NO_CFG_SERVICE
+ stderr);
+
+ // First sentence. We cannot bootstrap office further!
+ OUString aMessage;
+ OUStringBuffer aDiagnosticMessage( 100 );
+
+ OUString aErrorMsg;
+
+ if ( aBootstrapError == BE_UNO_SERVICEMANAGER )
+ aErrorMsg = GetMsgString( STR_BOOTSTRAP_ERR_NO_SERVICE,
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "The service manager is not available." )) );
+ else
+ aErrorMsg = GetMsgString( STR_BOOTSTRAP_ERR_NO_CFG_SERVICE,
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "The configuration service is not available." )) );
+
+ aDiagnosticMessage.append( aErrorMsg );
+ aDiagnosticMessage.appendAscii( "\n" );
+
+ // Due to the fact the we haven't a backup applicat.rdb file anymore it is not possible to
+ // repair the installation with the setup executable besides the office executable. Now
+ // we have to ask the user to start the setup on CD/installation directory manually!!
+ OUString aStartSetupManually( GetMsgString(
+ STR_ASK_START_SETUP_MANUALLY,
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "Start setup application to repair the installation from CD, or the folder containing the installation packages." )) ));
+
+ aDiagnosticMessage.append( aStartSetupManually );
+ aMessage = MakeStartupErrorMessage( aDiagnosticMessage.makeStringAndClear() );
+
+ FatalError( aMessage);
+ }
+ else if ( aBootstrapError == BE_OFFICECONFIG_BROKEN )
+ {
+ OUString aMessage;
+ OUStringBuffer aDiagnosticMessage( 100 );
+ OUString aErrorMsg;
+ aErrorMsg = GetMsgString( STR_CONFIG_ERR_ACCESS_GENERAL,
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "A general error occurred while accessing your central configuration." )) );
+ aDiagnosticMessage.append( aErrorMsg );
+ aMessage = MakeStartupErrorMessage( aDiagnosticMessage.makeStringAndClear() );
+ FatalError(aMessage);
+ }
+ else if ( aBootstrapError == BE_USERINSTALL_FAILED )
+ {
+ OUString aMessage;
+ OUStringBuffer aDiagnosticMessage( 100 );
+ OUString aErrorMsg;
+ aErrorMsg = GetMsgString( STR_BOOTSTRAP_ERR_INTERNAL,
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "User installation could not be completed" )) );
+ aDiagnosticMessage.append( aErrorMsg );
+ aMessage = MakeStartupErrorMessage( aDiagnosticMessage.makeStringAndClear() );
+ FatalError(aMessage);
+ }
+ else if ( aBootstrapError == BE_LANGUAGE_MISSING )
+ {
+ OUString aMessage;
+ OUStringBuffer aDiagnosticMessage( 100 );
+ OUString aErrorMsg;
+ aErrorMsg = GetMsgString(
+ //@@@ FIXME: should use an own resource string => #i36213#
+ STR_BOOTSTRAP_ERR_LANGUAGE_MISSING,
+ OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "Language could not be determined." )) );
+ aDiagnosticMessage.append( aErrorMsg );
+ aMessage = MakeStartupErrorMessage(
+ aDiagnosticMessage.makeStringAndClear() );
+ FatalError(aMessage);
+ }
+ else if (( aBootstrapError == BE_USERINSTALL_NOTENOUGHDISKSPACE ) ||
+ ( aBootstrapError == BE_USERINSTALL_NOWRITEACCESS ))
+ {
+ OUString aUserInstallationURL;
+ OUString aUserInstallationPath;
+ OUString aMessage;
+ OUString aErrorMsg;
+ OUStringBuffer aDiagnosticMessage( 100 );
+
+ utl::Bootstrap::locateUserInstallation( aUserInstallationURL );
+
+ if ( aBootstrapError == BE_USERINSTALL_NOTENOUGHDISKSPACE )
+ aErrorMsg = GetMsgString(
+ STR_BOOSTRAP_ERR_NOTENOUGHDISKSPACE,
+ OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "User installation could not be completed due to insufficient free disk space." )) );
+ else
+ aErrorMsg = GetMsgString(
+ STR_BOOSTRAP_ERR_NOACCESSRIGHTS,
+ OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "User installation could not be processed due to missing access rights." )) );
+
+ osl::File::getSystemPathFromFileURL( aUserInstallationURL, aUserInstallationPath );
+
+ aDiagnosticMessage.append( aErrorMsg );
+ aDiagnosticMessage.append( aUserInstallationPath );
+ aMessage = MakeStartupErrorMessage(
+ aDiagnosticMessage.makeStringAndClear() );
+ FatalError(aMessage);
+ }
+
+ return;
+}
+
+
+void Desktop::retrieveCrashReporterState()
+{
+ static const ::rtl::OUString CFG_PACKAGE_RECOVERY(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.Office.Recovery/"));
+ static const ::rtl::OUString CFG_PATH_CRASHREPORTER(RTL_CONSTASCII_USTRINGPARAM("CrashReporter"));
+ static const ::rtl::OUString CFG_ENTRY_ENABLED(RTL_CONSTASCII_USTRINGPARAM("Enabled"));
+
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = ::comphelper::getProcessServiceFactory();
+
+ sal_Bool bEnabled( sal_True );
+ if ( xSMGR.is() )
+ {
+ css::uno::Any aVal = ::comphelper::ConfigurationHelper::readDirectKey(
+ xSMGR,
+ CFG_PACKAGE_RECOVERY,
+ CFG_PATH_CRASHREPORTER,
+ CFG_ENTRY_ENABLED,
+ ::comphelper::ConfigurationHelper::E_READONLY);
+ aVal >>= bEnabled;
+ }
+ _bCrashReporterEnabled = bEnabled;
+}
+
+sal_Bool Desktop::isUIOnSessionShutdownAllowed()
+{
+ static const ::rtl::OUString CFG_PACKAGE_RECOVERY(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.Office.Recovery/"));
+ static const ::rtl::OUString CFG_PATH_SESSION(RTL_CONSTASCII_USTRINGPARAM("SessionShutdown"));
+ static const ::rtl::OUString CFG_ENTRY_UIENABLED(RTL_CONSTASCII_USTRINGPARAM("DocumentStoreUIEnabled"));
+
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = ::comphelper::getProcessServiceFactory();
+
+ sal_Bool bResult = sal_False;
+ if ( xSMGR.is() )
+ {
+ css::uno::Any aVal = ::comphelper::ConfigurationHelper::readDirectKey(
+ xSMGR,
+ CFG_PACKAGE_RECOVERY,
+ CFG_PATH_SESSION,
+ CFG_ENTRY_UIENABLED,
+ ::comphelper::ConfigurationHelper::E_READONLY);
+ aVal >>= bResult;
+ }
+
+ return bResult;
+}
+
+//-----------------------------------------------
+/** @short check if crash reporter feature is enabled or
+ disabled.
+*/
+sal_Bool Desktop::isCrashReporterEnabled()
+{
+ return _bCrashReporterEnabled;
+}
+
+//-----------------------------------------------
+/** @short check if recovery must be started or not.
+
+ @param bCrashed [boolean ... out!]
+ the office crashed last times.
+ But may be there are no recovery data.
+ Usefull to trigger the error report tool without
+ showing the recovery UI.
+
+ @param bRecoveryDataExists [boolean ... out!]
+ there exists some recovery data.
+
+ @param bSessionDataExists [boolean ... out!]
+ there exists some session data.
+ Because the user may be logged out last time from it's
+ unix session...
+*/
+void impl_checkRecoveryState(sal_Bool& bCrashed ,
+ sal_Bool& bRecoveryDataExists,
+ sal_Bool& bSessionDataExists )
+{
+ static const ::rtl::OUString SERVICENAME_RECOVERYCORE(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.AutoRecovery"));
+ static const ::rtl::OUString PROP_CRASHED(RTL_CONSTASCII_USTRINGPARAM("Crashed"));
+ static const ::rtl::OUString PROP_EXISTSRECOVERY(RTL_CONSTASCII_USTRINGPARAM("ExistsRecoveryData"));
+ static const ::rtl::OUString PROP_EXISTSSESSION(RTL_CONSTASCII_USTRINGPARAM("ExistsSessionData"));
+
+ bCrashed = sal_False;
+ bRecoveryDataExists = sal_False;
+ bSessionDataExists = sal_False;
+
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = ::comphelper::getProcessServiceFactory();
+ try
+ {
+ css::uno::Reference< css::beans::XPropertySet > xRecovery(
+ xSMGR->createInstance(SERVICENAME_RECOVERYCORE),
+ css::uno::UNO_QUERY_THROW);
+
+ xRecovery->getPropertyValue(PROP_CRASHED ) >>= bCrashed ;
+ xRecovery->getPropertyValue(PROP_EXISTSRECOVERY) >>= bRecoveryDataExists;
+ xRecovery->getPropertyValue(PROP_EXISTSSESSION ) >>= bSessionDataExists ;
+ }
+ catch(const css::uno::Exception&) {}
+}
+
+//-----------------------------------------------
+/* @short start the recovery wizard.
+
+ @param bEmergencySave
+ differs between EMERGENCY_SAVE and RECOVERY
+*/
+sal_Bool impl_callRecoveryUI(sal_Bool bEmergencySave ,
+ sal_Bool bCrashed ,
+ sal_Bool bExistsRecoveryData)
+{
+ static ::rtl::OUString SERVICENAME_RECOVERYUI(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.svx.RecoveryUI"));
+ static ::rtl::OUString SERVICENAME_URLPARSER(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.util.URLTransformer"));
+ static ::rtl::OUString COMMAND_EMERGENCYSAVE(RTL_CONSTASCII_USTRINGPARAM("vnd.sun.star.autorecovery:/doEmergencySave"));
+ static ::rtl::OUString COMMAND_RECOVERY(RTL_CONSTASCII_USTRINGPARAM("vnd.sun.star.autorecovery:/doAutoRecovery"));
+ static ::rtl::OUString COMMAND_CRASHREPORT(RTL_CONSTASCII_USTRINGPARAM("vnd.sun.star.autorecovery:/doCrashReport"));
+
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = ::comphelper::getProcessServiceFactory();
+
+ css::uno::Reference< css::frame::XSynchronousDispatch > xRecoveryUI(
+ xSMGR->createInstance(SERVICENAME_RECOVERYUI),
+ css::uno::UNO_QUERY_THROW);
+
+ css::uno::Reference< css::util::XURLTransformer > xURLParser(
+ xSMGR->createInstance(SERVICENAME_URLPARSER),
+ css::uno::UNO_QUERY_THROW);
+
+ css::util::URL aURL;
+ if (bEmergencySave)
+ aURL.Complete = COMMAND_EMERGENCYSAVE;
+ else
+ {
+ if (bExistsRecoveryData)
+ aURL.Complete = COMMAND_RECOVERY;
+ else
+ if (bCrashed && Desktop::isCrashReporterEnabled() )
+ aURL.Complete = COMMAND_CRASHREPORT;
+ }
+
+ sal_Bool bRet = sal_False;
+ if ( aURL.Complete.getLength() > 0 )
+ {
+ xURLParser->parseStrict(aURL);
+
+ css::uno::Any aRet = xRecoveryUI->dispatchWithReturnValue(aURL, css::uno::Sequence< css::beans::PropertyValue >());
+ aRet >>= bRet;
+ }
+ return bRet;
+}
+
+/*
+ * Save all open documents so they will be reopened
+ * the next time the application ist started
+ *
+ * returns sal_True if at least one document could be saved...
+ *
+ */
+
+sal_Bool Desktop::_bTasksSaved = sal_False;
+
+sal_Bool Desktop::SaveTasks()
+{
+ return impl_callRecoveryUI(
+ sal_True , // sal_True => force emergency save
+ sal_False, // 2. and 3. param not used if 1. = true!
+ sal_False);
+}
+
+namespace {
+
+void restartOnMac(bool passArguments) {
+#if defined MACOSX
+ OfficeIPCThread::DisableOfficeIPCThread();
+ rtl::OUString execUrl;
+ OSL_VERIFY(osl_getExecutableFile(&execUrl.pData) == osl_Process_E_None);
+ rtl::OUString execPath;
+ rtl::OString execPath8;
+ if ((osl::FileBase::getSystemPathFromFileURL(execUrl, execPath)
+ != osl::FileBase::E_None) ||
+ !execPath.convertToString(
+ &execPath8, osl_getThreadTextEncoding(),
+ (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR |
+ RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR)))
+ {
+ std::abort();
+ }
+ std::vector< rtl::OString > args;
+ args.push_back(execPath8);
+ bool wait = false;
+ if (passArguments) {
+ sal_uInt32 n = osl_getCommandArgCount();
+ for (sal_uInt32 i = 0; i < n; ++i) {
+ rtl::OUString arg;
+ OSL_VERIFY(osl_getCommandArg(i, &arg.pData) == osl_Process_E_None);
+ if (arg.matchAsciiL(RTL_CONSTASCII_STRINGPARAM("-accept="))) {
+ wait = true;
+ }
+ rtl::OString arg8;
+ if (!arg.convertToString(
+ &arg8, osl_getThreadTextEncoding(),
+ (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR |
+ RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR)))
+ {
+ std::abort();
+ }
+ args.push_back(arg8);
+ }
+ }
+ std::vector< char const * > argPtrs;
+ for (std::vector< rtl::OString >::iterator i(args.begin()); i != args.end();
+ ++i)
+ {
+ argPtrs.push_back(i->getStr());
+ }
+ argPtrs.push_back(0);
+ execv(execPath8.getStr(), const_cast< char ** >(&argPtrs[0]));
+ if (errno == ENOTSUP) { // happens when multithreaded on OS X < 10.6
+ pid_t pid = fork();
+ if (pid == 0) {
+ execv(execPath8.getStr(), const_cast< char ** >(&argPtrs[0]));
+ } else if (pid > 0) {
+ // Two simultaneously running soffice processes lead to two dock
+ // icons, so avoid waiting here unless it must be assumed that the
+ // process invoking soffice itself wants to wait for soffice to
+ // finish:
+ if (!wait) {
+ return;
+ }
+ int stat;
+ if (waitpid(pid, &stat, 0) == pid && WIFEXITED(stat)) {
+ _exit(WEXITSTATUS(stat));
+ }
+ }
+ }
+ std::abort();
+#else
+ (void) passArguments; // avoid warnings
+#endif
+}
+
+}
+
+sal_uInt16 Desktop::Exception(sal_uInt16 nError)
+{
+ // protect against recursive calls
+ static sal_Bool bInException = sal_False;
+
+ sal_uInt16 nOldMode = Application::GetSystemWindowMode();
+ Application::SetSystemWindowMode( nOldMode & ~SYSTEMWINDOW_MODE_NOAUTOMODE );
+ Application::SetDefDialogParent( NULL );
+
+ if ( bInException )
+ {
+ String aDoubleExceptionString;
+ Application::Abort( aDoubleExceptionString );
+ }
+
+ bInException = sal_True;
+ CommandLineArgs* pArgs = GetCommandLineArgs();
+
+ // save all modified documents ... if it's allowed doing so.
+ sal_Bool bRestart = sal_False;
+ sal_Bool bAllowRecoveryAndSessionManagement = (
+ ( !pArgs->IsNoRestore() ) && // some use cases of office must work without recovery
+ ( !pArgs->IsHeadless() ) &&
+ ( !pArgs->IsServer() ) &&
+ (( nError & EXC_MAJORTYPE ) != EXC_DISPLAY ) && // recovery cant work without UI ... but UI layer seams to be the reason for this crash
+ ( Application::IsInExecute() ) // crashes during startup and shutdown should be ignored (they indicates a corrupt installation ...)
+ );
+ if ( bAllowRecoveryAndSessionManagement )
+ bRestart = SaveTasks();
+
+ FlushConfiguration();
+
+ switch( nError & EXC_MAJORTYPE )
+ {
+ case EXC_RSCNOTLOADED:
+ {
+ String aResExceptionString;
+ Application::Abort( aResExceptionString );
+ break;
+ }
+
+ case EXC_SYSOBJNOTCREATED:
+ {
+ String aSysResExceptionString;
+ Application::Abort( aSysResExceptionString );
+ break;
+ }
+
+ default:
+ {
+ if (m_pLockfile != NULL) {
+ m_pLockfile->clean();
+ }
+ if( bRestart )
+ {
+ OfficeIPCThread::DisableOfficeIPCThread();
+ if( pSignalHandler )
+ osl_removeSignalHandler( pSignalHandler );
+
+ restartOnMac(false);
+ if ( m_rSplashScreen.is() )
+ m_rSplashScreen->reset();
+
+ _exit( ExitHelper::E_CRASH_WITH_RESTART );
+ }
+ else
+ {
+ Application::Abort( String() );
+ }
+
+ break;
+ }
+ }
+
+ OSL_ASSERT(false); // unreachable
+ return 0;
+}
+
+void Desktop::AppEvent( const ApplicationEvent& rAppEvent )
+{
+ HandleAppEvent( rAppEvent );
+}
+
+namespace {
+ void SetDocumentExtendedStyle( const Reference< ::com::sun::star::awt::XWindow > &xContainerWindow )
+ {
+ // set the WB_EXT_DOCUMENT style. Normally, this is done by the TaskCreator service when a "_blank"
+ // frame/window is created. Since we do not use the TaskCreator here, we need to mimic its behavior,
+ // otherwise documents loaded into this frame will later on miss functionality depending on the style.
+ Window* pContainerWindow = VCLUnoHelper::GetWindow( xContainerWindow );
+ OSL_ENSURE( pContainerWindow, "Desktop::Main: no implementation access to the frame's container window!" );
+ if (!pContainerWindow) {
+ fprintf (stderr, "Error: It very much looks as if you have used 'linkoo' (or bin/ooinstall -l)\n"
+ "but have then forgotten to source 'ooenv' into your shell before running !\n"
+ "to save a crash, we will exit now with an error - please '. ./ooenv' first.\n");
+ exit (1);
+ }
+ pContainerWindow->SetExtendedStyle( pContainerWindow->GetExtendedStyle() | WB_EXT_DOCUMENT );
+ }
+}
+
+struct ExecuteGlobals
+{
+ Reference < css::document::XEventListener > xGlobalBroadcaster;
+ sal_Bool bRestartRequested;
+ sal_Bool bUseSystemFileDialog;
+ std::auto_ptr<SvtLanguageOptions> pLanguageOptions;
+ std::auto_ptr<SvtPathOptions> pPathOptions;
+
+ ExecuteGlobals()
+ : bRestartRequested( sal_False )
+ , bUseSystemFileDialog( sal_True )
+ {}
+};
+
+static ExecuteGlobals* pExecGlobals = NULL;
+
+int Desktop::Main()
+{
+ pExecGlobals = new ExecuteGlobals();
+
+ RTL_LOGFILE_CONTEXT( aLog, "desktop (cd100003) ::Desktop::Main" );
+
+ // Remember current context object
+ com::sun::star::uno::ContextLayer layer(
+ com::sun::star::uno::getCurrentContext() );
+
+ BootstrapError eError = GetBootstrapError();
+ if ( eError != BE_OK )
+ {
+ HandleBootstrapErrors( eError );
+ return EXIT_FAILURE;
+ }
+
+ BootstrapStatus eStatus = GetBootstrapStatus();
+ if (eStatus == BS_TERMINATE) {
+ return EXIT_FAILURE;
+ }
+
+ // Detect desktop environment - need to do this as early as possible
+ com::sun::star::uno::setCurrentContext(
+ new DesktopContext( com::sun::star::uno::getCurrentContext() ) );
+
+ CommandLineArgs* pCmdLineArgs = GetCommandLineArgs();
+
+ // setup configuration error handling
+ ConfigurationErrorHandler aConfigErrHandler;
+ if (!ShouldSuppressUI(pCmdLineArgs))
+ aConfigErrHandler.activate();
+
+ ResMgr::SetReadStringHook( ReplaceStringHookProc );
+
+ // Startup screen
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "desktop (lo119109) Desktop::Main { OpenSplashScreen" );
+ OpenSplashScreen();
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "desktop (lo119109) Desktop::Main } OpenSplashScreen" );
+
+ SetSplashScreenProgress(10);
+ {
+ UserInstall::UserInstallError instErr_fin = UserInstall::finalize();
+ if ( instErr_fin != UserInstall::E_None)
+ {
+ OSL_FAIL("userinstall failed");
+ if ( instErr_fin == UserInstall::E_NoDiskSpace )
+ HandleBootstrapErrors( BE_USERINSTALL_NOTENOUGHDISKSPACE );
+ else if ( instErr_fin == UserInstall::E_NoWriteAccess )
+ HandleBootstrapErrors( BE_USERINSTALL_NOWRITEACCESS );
+ else
+ HandleBootstrapErrors( BE_USERINSTALL_FAILED );
+ return EXIT_FAILURE;
+ }
+ // refresh path information
+ utl::Bootstrap::reloadData();
+ SetSplashScreenProgress(20);
+ }
+
+ Reference< XMultiServiceFactory > xSMgr =
+ ::comphelper::getProcessServiceFactory();
+
+ Reference< ::com::sun::star::task::XRestartManager > xRestartManager;
+ int nAcquireCount( 0 );
+ try
+ {
+ RegisterServices( xSMgr );
+
+ SetSplashScreenProgress(25);
+
+#ifndef UNX
+ if ( pCmdLineArgs->IsHelp() ) {
+ displayCmdlineHelp();
+ return EXIT_SUCCESS;
+ }
+#endif
+
+ // check user installation directory for lockfile so we can be sure
+ // there is no other instance using our data files from a remote host
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "desktop (lo119109) Desktop::Main -> Lockfile" );
+ m_pLockfile = new Lockfile;
+ if ( !pCmdLineArgs->IsHeadless() && !pCmdLineArgs->IsInvisible() &&
+ !pCmdLineArgs->IsNoLockcheck() && !m_pLockfile->check( Lockfile_execWarning )) {
+ // Lockfile exists, and user clicked 'no'
+ return EXIT_FAILURE;
+ }
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "desktop (lo119109) Desktop::Main <- Lockfile" );
+
+ // check if accessibility is enabled but not working and allow to quit
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "{ GetEnableATToolSupport" );
+ if( Application::GetSettings().GetMiscSettings().GetEnableATToolSupport() )
+ {
+ sal_Bool bQuitApp;
+
+ if( !InitAccessBridge( true, bQuitApp ) )
+ if( bQuitApp )
+ return EXIT_FAILURE;
+ }
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "} GetEnableATToolSupport" );
+
+ // terminate if requested...
+ if( pCmdLineArgs->IsTerminateAfterInit() )
+ return EXIT_SUCCESS;
+
+
+ // Read the common configuration items for optimization purpose
+ if ( !InitializeConfiguration() )
+ return EXIT_FAILURE;
+
+ SetSplashScreenProgress(30);
+
+ // set static variable to enabled/disable crash reporter
+ retrieveCrashReporterState();
+ if ( !isCrashReporterEnabled() )
+ {
+ osl_setErrorReporting( sal_False );
+ // disable stack trace feature
+ }
+
+ // create title string
+ sal_Bool bCheckOk = sal_False;
+ ::com::sun::star::lang::Locale aLocale;
+ String aMgrName = String::CreateFromAscii( "ofa" );
+ ResMgr* pLabelResMgr = ResMgr::SearchCreateResMgr( "ofa", aLocale );
+ String aTitle = pLabelResMgr ? String( ResId( RID_APPTITLE, *pLabelResMgr ) ) : String();
+ delete pLabelResMgr;
+
+ // Check for StarOffice/Suite specific extensions runs also with OpenOffice installation sets
+ OUString aTitleString( aTitle );
+ bCheckOk = CheckInstallation( aTitleString );
+ if ( !bCheckOk )
+ return EXIT_FAILURE;
+ else
+ aTitle = aTitleString;
+
+#ifdef DBG_UTIL
+ //include version ID in non product builds
+ ::rtl::OUString aDefault;
+ aTitle += DEFINE_CONST_UNICODE(" [");
+ String aVerId( utl::Bootstrap::getBuildIdData( aDefault ));
+ aTitle += aVerId;
+ aTitle += ']';
+#endif
+
+ SetDisplayName( aTitle );
+ SetSplashScreenProgress(35);
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "{ create SvtPathOptions and SvtLanguageOptions" );
+ pExecGlobals->pPathOptions.reset( new SvtPathOptions);
+ SetSplashScreenProgress(40);
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "} create SvtPathOptions and SvtLanguageOptions" );
+
+ // Check special env variable
+ std::vector< String > aUnrestrictedFolders;
+ svt::getUnrestrictedFolders( aUnrestrictedFolders );
+
+ if ( aUnrestrictedFolders.size() > 0 )
+ {
+ // Set different working directory. The first entry is
+ // the new work path.
+ String aWorkPath = aUnrestrictedFolders[0];
+ SvtPathOptions().SetWorkPath( aWorkPath );
+ }
+
+ // create service for loadin SFX (still needed in startup)
+ pExecGlobals->xGlobalBroadcaster = Reference < css::document::XEventListener >
+ ( xSMgr->createInstance(
+ DEFINE_CONST_UNICODE( "com.sun.star.frame.GlobalEventBroadcaster" ) ), UNO_QUERY );
+
+ /* ensure existance of a default window that messages can be dispatched to
+ This is for the benefit of testtool which uses PostUserEvent extensively
+ and else can deadlock while creating this window from another tread while
+ the main thread is not yet in the event loop.
+ */
+ Application::GetDefaultDevice();
+
+ // initialize test-tool library (if available)
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "{ tools::InitTestToolLib" );
+ tools::InitTestToolLib();
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "} tools::InitTestToolLib" );
+
+ // Check if bundled or shared extensions were added /removed
+ // and process those extensions (has to be done before checking
+ // the extension dependencies!
+ SynchronizeExtensionRepositories();
+ bool bAbort = CheckExtensionDependencies();
+ if ( bAbort )
+ return EXIT_FAILURE;
+
+ Migration::migrateSettingsIfNecessary();
+
+ // keep a language options instance...
+ pExecGlobals->pLanguageOptions.reset( new SvtLanguageOptions(sal_True));
+
+ if (pExecGlobals->xGlobalBroadcaster.is())
+ {
+ css::document::EventObject aEvent;
+ aEvent.EventName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("OnStartApp"));
+ pExecGlobals->xGlobalBroadcaster->notifyEvent(aEvent);
+ }
+
+ SetSplashScreenProgress(50);
+
+ // Backing Component
+ sal_Bool bCrashed = sal_False;
+ sal_Bool bExistsRecoveryData = sal_False;
+ sal_Bool bExistsSessionData = sal_False;
+
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "{ impl_checkRecoveryState" );
+ impl_checkRecoveryState(bCrashed, bExistsRecoveryData, bExistsSessionData);
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "} impl_checkRecoveryState" );
+
+ {
+ ::comphelper::ComponentContext aContext( xSMgr );
+ xRestartManager.set( aContext.getSingleton( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.task.OfficeRestartManager" ) ) ), UNO_QUERY );
+ }
+
+ // check whether the shutdown is caused by restart
+ pExecGlobals->bRestartRequested = ( xRestartManager.is() && xRestartManager->isRestartRequested( sal_True ) );
+
+ if ( pCmdLineArgs->IsHeadless() )
+ {
+ // Ensure that we use not the system file dialogs as
+ // headless mode relies on Application::EnableHeadlessMode()
+ // which does only work for VCL dialogs!!
+ SvtMiscOptions aMiscOptions;
+ pExecGlobals->bUseSystemFileDialog = aMiscOptions.UseSystemFileDialog();
+ aMiscOptions.SetUseSystemFileDialog( sal_False );
+ }
+
+ if ( !pExecGlobals->bRestartRequested )
+ {
+ if ((!pCmdLineArgs->WantsToLoadDocument() && !pCmdLineArgs->IsInvisible() && !pCmdLineArgs->IsHeadless() ) &&
+ (SvtModuleOptions().IsModuleInstalled(SvtModuleOptions::E_SSTARTMODULE)) &&
+ (!bExistsRecoveryData ) &&
+ (!bExistsSessionData ) &&
+ (!Application::AnyInput( INPUT_APPEVENT ) ))
+ {
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "{ create BackingComponent" );
+ Reference< XFrame > xDesktopFrame( xSMgr->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.Desktop" ))), UNO_QUERY );
+ if (xDesktopFrame.is())
+ {
+ SetSplashScreenProgress(60);
+ Reference< XFrame > xBackingFrame;
+ Reference< ::com::sun::star::awt::XWindow > xContainerWindow;
+
+ xBackingFrame = xDesktopFrame->findFrame(OUString( RTL_CONSTASCII_USTRINGPARAM( "_blank" )), 0);
+ if (xBackingFrame.is())
+ xContainerWindow = xBackingFrame->getContainerWindow();
+ if (xContainerWindow.is())
+ {
+ SetDocumentExtendedStyle(xContainerWindow);
+ SetSplashScreenProgress(75);
+ Sequence< Any > lArgs(1);
+ lArgs[0] <<= xContainerWindow;
+
+ Reference< XController > xBackingComp(
+ xSMgr->createInstanceWithArguments(OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.StartModule") ), lArgs), UNO_QUERY);
+ if (xBackingComp.is())
+ {
+ Reference< ::com::sun::star::awt::XWindow > xBackingWin(xBackingComp, UNO_QUERY);
+ // Attention: You MUST(!) call setComponent() before you call attachFrame().
+ // Because the backing component set the property "IsBackingMode" of the frame
+ // to true inside attachFrame(). But setComponent() reset this state everytimes ...
+ xBackingFrame->setComponent(xBackingWin, xBackingComp);
+ SetSplashScreenProgress(100);
+ xBackingComp->attachFrame(xBackingFrame);
+ CloseSplashScreen();
+ xContainerWindow->setVisible(sal_True);
+ }
+ }
+ }
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "} create BackingComponent" );
+ }
+ }
+ }
+ catch ( com::sun::star::lang::WrappedTargetException& wte )
+ {
+ com::sun::star::uno::Exception te;
+ wte.TargetException >>= te;
+ FatalError( MakeStartupConfigAccessErrorMessage(wte.Message + te.Message) );
+ return EXIT_FAILURE;
+ }
+ catch ( com::sun::star::uno::Exception& e )
+ {
+ FatalError( MakeStartupErrorMessage(e.Message) );
+ return EXIT_FAILURE;
+ }
+ SetSplashScreenProgress(55);
+
+ SvtFontSubstConfig().Apply();
+
+ SvtTabAppearanceCfg aAppearanceCfg;
+ aAppearanceCfg.SetInitialized();
+ aAppearanceCfg.SetApplicationDefaults( this );
+ SvtAccessibilityOptions aOptions;
+ aOptions.SetVCLSettings();
+ SetSplashScreenProgress(60);
+
+ if ( !pExecGlobals->bRestartRequested )
+ {
+ Application::SetFilterHdl( LINK( this, Desktop, ImplInitFilterHdl ) );
+ sal_Bool bTerminateRequested = sal_False;
+
+ // Preload function depends on an initialized sfx application!
+ SetSplashScreenProgress(75);
+
+ // use system window dialogs
+ Application::SetSystemWindowMode( SYSTEMWINDOW_MODE_DIALOG );
+
+ SetSplashScreenProgress(80);
+
+ if ( !bTerminateRequested && !pCmdLineArgs->IsInvisible() &&
+ !pCmdLineArgs->IsNoQuickstart() )
+ InitializeQuickstartMode( xSMgr );
+
+ RTL_LOGFILE_CONTEXT( aLog2, "desktop (cd100003) createInstance com.sun.star.frame.Desktop" );
+ try
+ {
+ Reference< XDesktop > xDesktop( xSMgr->createInstance(
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.Desktop" ))), UNO_QUERY );
+ if ( xDesktop.is() )
+ xDesktop->addTerminateListener( new OfficeIPCThreadController );
+ SetSplashScreenProgress(100);
+ }
+ catch ( com::sun::star::uno::Exception& e )
+ {
+ FatalError( MakeStartupErrorMessage(e.Message) );
+ return EXIT_FAILURE;
+ }
+
+ // Post user event to startup first application component window
+ // We have to send this OpenClients message short before execute() to
+ // minimize the risk that this message overtakes type detection contruction!!
+ Application::PostUserEvent( LINK( this, Desktop, OpenClients_Impl ) );
+
+ // Post event to enable acceptors
+ Application::PostUserEvent( LINK( this, Desktop, EnableAcceptors_Impl) );
+
+ // The configuration error handler currently is only for startup
+ aConfigErrHandler.deactivate();
+
+ // Acquire solar mutex just before we enter our message loop
+ if ( nAcquireCount )
+ Application::AcquireSolarMutex( nAcquireCount );
+
+ // call Application::Execute to process messages in vcl message loop
+ RTL_LOGFILE_PRODUCT_TRACE( "PERFORMANCE - enter Application::Execute()" );
+
+ try
+ {
+ // The JavaContext contains an interaction handler which is used when
+ // the creation of a Java Virtual Machine fails
+ com::sun::star::uno::ContextLayer layer2(
+ new svt::JavaContext( com::sun::star::uno::getCurrentContext() ) );
+
+ // check whether the shutdown is caused by restart just before entering the Execute
+ pExecGlobals->bRestartRequested = pExecGlobals->bRestartRequested || ( xRestartManager.is() && xRestartManager->isRestartRequested( sal_True ) );
+
+ if ( !pExecGlobals->bRestartRequested )
+ {
+ // if this run of the office is triggered by restart, some additional actions should be done
+ DoRestartActionsIfNecessary( !pCmdLineArgs->IsInvisible() && !pCmdLineArgs->IsNoQuickstart() );
+
+ Execute();
+ }
+ }
+ catch(const com::sun::star::document::CorruptedFilterConfigurationException& exFilterCfg)
+ {
+ OfficeIPCThread::SetDowning();
+ FatalError( MakeStartupErrorMessage(exFilterCfg.Message) );
+ }
+ catch(const com::sun::star::configuration::CorruptedConfigurationException& exAnyCfg)
+ {
+ OfficeIPCThread::SetDowning();
+ FatalError( MakeStartupErrorMessage(exAnyCfg.Message) );
+ }
+ }
+ // CAUTION: you do not necessarily get here e.g. on the Mac.
+ // please put all deinitialization code into doShutdown
+ return doShutdown();
+}
+
+int Desktop::doShutdown()
+{
+ if( ! pExecGlobals )
+ return EXIT_SUCCESS;
+
+ if ( pExecGlobals->bRestartRequested )
+ SetRestartState();
+
+ if (pExecGlobals->xGlobalBroadcaster.is())
+ {
+ css::document::EventObject aEvent;
+ aEvent.EventName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("OnCloseApp"));
+ pExecGlobals->xGlobalBroadcaster->notifyEvent(aEvent);
+ }
+
+ delete pResMgr, pResMgr = NULL;
+ // Restore old value
+ CommandLineArgs* pCmdLineArgs = GetCommandLineArgs();
+ if ( pCmdLineArgs->IsHeadless() )
+ SvtMiscOptions().SetUseSystemFileDialog( pExecGlobals->bUseSystemFileDialog );
+
+ // remove temp directory
+ RemoveTemporaryDirectory();
+ FlushConfiguration();
+ // The acceptors in the AcceptorMap must be released (in DeregisterServices)
+ // with the solar mutex unlocked, to avoid deadlock:
+ sal_uLong nAcquireCount = Application::ReleaseSolarMutex();
+ DeregisterServices();
+ Application::AcquireSolarMutex(nAcquireCount);
+ tools::DeInitTestToolLib();
+ // be sure that path/language options gets destroyed before
+ // UCB is deinitialized
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "-> dispose path/language options" );
+ pExecGlobals->pLanguageOptions.reset( 0 );
+ pExecGlobals->pPathOptions.reset( 0 );
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "<- dispose path/language options" );
+
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "-> deinit ucb" );
+ ::ucbhelper::ContentBroker::deinitialize();
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "<- deinit ucb" );
+
+ sal_Bool bRR = pExecGlobals->bRestartRequested;
+ delete pExecGlobals, pExecGlobals = NULL;
+
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "FINISHED WITH Destop::Main" );
+ if ( bRR )
+ {
+ restartOnMac(true);
+ if ( m_rSplashScreen.is() )
+ m_rSplashScreen->reset();
+
+ return ExitHelper::E_NORMAL_RESTART;
+ }
+ return EXIT_SUCCESS;
+}
+
+IMPL_LINK( Desktop, ImplInitFilterHdl, ConvertData*, pData )
+{
+ return GraphicFilter::GetGraphicFilter()->GetFilterCallback().Call( pData );
+}
+
+sal_Bool Desktop::InitializeConfiguration()
+{
+ sal_Bool bOk = sal_False;
+
+ try
+ {
+ bOk = InitConfiguration();
+ }
+ catch( ::com::sun::star::lang::ServiceNotRegisteredException& )
+ {
+ this->HandleBootstrapErrors( Desktop::BE_UNO_SERVICE_CONFIG_MISSING );
+ }
+ catch( ::com::sun::star::configuration::MissingBootstrapFileException& e )
+ {
+ OUString aMsg( CreateErrorMsgString( utl::Bootstrap::MISSING_BOOTSTRAP_FILE,
+ e.BootstrapFileURL ));
+ HandleBootstrapPathErrors( ::utl::Bootstrap::INVALID_USER_INSTALL, aMsg );
+ }
+ catch( ::com::sun::star::configuration::InvalidBootstrapFileException& e )
+ {
+ OUString aMsg( CreateErrorMsgString( utl::Bootstrap::INVALID_BOOTSTRAP_FILE_ENTRY,
+ e.BootstrapFileURL ));
+ HandleBootstrapPathErrors( ::utl::Bootstrap::INVALID_BASE_INSTALL, aMsg );
+ }
+ catch( ::com::sun::star::configuration::InstallationIncompleteException& )
+ {
+ OUString aVersionFileURL;
+ OUString aMsg;
+ utl::Bootstrap::PathStatus aPathStatus = utl::Bootstrap::locateVersionFile( aVersionFileURL );
+ if ( aPathStatus == utl::Bootstrap::PATH_EXISTS )
+ aMsg = CreateErrorMsgString( utl::Bootstrap::MISSING_VERSION_FILE_ENTRY, aVersionFileURL );
+ else
+ aMsg = CreateErrorMsgString( utl::Bootstrap::MISSING_VERSION_FILE, aVersionFileURL );
+
+ HandleBootstrapPathErrors( ::utl::Bootstrap::MISSING_USER_INSTALL, aMsg );
+ }
+ catch ( com::sun::star::configuration::backend::BackendAccessException& exception)
+ {
+ // [cm122549] It is assumed in this case that the message
+ // coming from InitConfiguration (in fact CreateApplicationConf...)
+ // is suitable for display directly.
+ FatalError( MakeStartupErrorMessage( exception.Message ) );
+ }
+ catch ( com::sun::star::configuration::backend::BackendSetupException& exception)
+ {
+ // [cm122549] It is assumed in this case that the message
+ // coming from InitConfiguration (in fact CreateApplicationConf...)
+ // is suitable for display directly.
+ FatalError( MakeStartupErrorMessage( exception.Message ) );
+ }
+ catch ( ::com::sun::star::configuration::CannotLoadConfigurationException& )
+ {
+ OUString aMsg( CreateErrorMsgString( utl::Bootstrap::INVALID_BOOTSTRAP_DATA,
+ OUString() ));
+ HandleBootstrapPathErrors( ::utl::Bootstrap::INVALID_BASE_INSTALL, aMsg );
+ }
+ catch( ::com::sun::star::uno::Exception& )
+ {
+ OUString aMsg( CreateErrorMsgString( utl::Bootstrap::INVALID_BOOTSTRAP_DATA,
+ OUString() ));
+ HandleBootstrapPathErrors( ::utl::Bootstrap::INVALID_BASE_INSTALL, aMsg );
+ }
+
+ return bOk;
+}
+
+void Desktop::FlushConfiguration()
+{
+ Reference < XFlushable > xCFGFlush( ::utl::ConfigManager::GetConfigManager().GetConfigurationProvider(), UNO_QUERY );
+ if (xCFGFlush.is())
+ {
+ xCFGFlush->flush();
+ }
+ else
+ {
+ // because there is no method to flush the condiguration data, we must dispose the ConfigManager
+ Reference < XComponent > xCFGDispose( ::utl::ConfigManager::GetConfigManager().GetConfigurationProvider(), UNO_QUERY );
+ if (xCFGDispose.is())
+ xCFGDispose->dispose();
+ }
+}
+
+sal_Bool Desktop::shouldLaunchQuickstart()
+{
+ sal_Bool bQuickstart = GetCommandLineArgs()->IsQuickstart();
+ if (!bQuickstart)
+ {
+ const SfxPoolItem* pItem=0;
+ SfxItemSet aQLSet(SFX_APP()->GetPool(), SID_ATTR_QUICKLAUNCHER, SID_ATTR_QUICKLAUNCHER);
+ SFX_APP()->GetOptions(aQLSet);
+ SfxItemState eState = aQLSet.GetItemState(SID_ATTR_QUICKLAUNCHER, sal_False, &pItem);
+ if (SFX_ITEM_SET == eState)
+ bQuickstart = ((SfxBoolItem*)pItem)->GetValue();
+ }
+ return bQuickstart;
+}
+
+
+sal_Bool Desktop::InitializeQuickstartMode( Reference< XMultiServiceFactory >& rSMgr )
+{
+ try
+ {
+ // the shutdown icon sits in the systray and allows the user to keep
+ // the office instance running for quicker restart
+ // this will only be activated if -quickstart was specified on cmdline
+ RTL_LOGFILE_CONTEXT( aLog, "desktop (cd100003) createInstance com.sun.star.office.Quickstart" );
+
+ sal_Bool bQuickstart = shouldLaunchQuickstart();
+
+ // Try to instanciate quickstart service. This service is not mandatory, so
+ // do nothing if service is not available
+
+ // #i105753# the following if was invented for performance
+ // unfortunately this broke the QUARTZ behavior which is to always run
+ // in quickstart mode since Mac applications do not usually quit
+ // when the last document closes
+ #ifndef QUARTZ
+ if ( bQuickstart )
+ #endif
+ {
+ Sequence< Any > aSeq( 1 );
+ aSeq[0] <<= bQuickstart;
+ Reference < XComponent > xQuickstart( rSMgr->createInstanceWithArguments(
+ DEFINE_CONST_UNICODE( "com.sun.star.office.Quickstart" ), aSeq ),
+ UNO_QUERY );
+ }
+ return sal_True;
+ }
+ catch( ::com::sun::star::uno::Exception& )
+ {
+ return sal_False;
+ }
+}
+
+void Desktop::SystemSettingsChanging( AllSettings& rSettings, Window* )
+{
+ if ( !SvtTabAppearanceCfg::IsInitialized () )
+ return;
+
+# define DRAGFULL_OPTION_ALL \
+ ( DRAGFULL_OPTION_WINDOWMOVE | DRAGFULL_OPTION_WINDOWSIZE \
+ | DRAGFULL_OPTION_OBJECTMOVE | DRAGFULL_OPTION_OBJECTSIZE \
+ | DRAGFULL_OPTION_DOCKING | DRAGFULL_OPTION_SPLIT \
+ | DRAGFULL_OPTION_SCROLL )
+# define DRAGFULL_OPTION_NONE ((sal_uInt32)~DRAGFULL_OPTION_ALL)
+
+ StyleSettings hStyleSettings = rSettings.GetStyleSettings();
+ MouseSettings hMouseSettings = rSettings.GetMouseSettings();
+
+ sal_uInt32 nDragFullOptions = hStyleSettings.GetDragFullOptions();
+
+ SvtTabAppearanceCfg aAppearanceCfg;
+ sal_uInt16 nGet = aAppearanceCfg.GetDragMode();
+ switch ( nGet )
+ {
+ case DragFullWindow:
+ nDragFullOptions |= DRAGFULL_OPTION_ALL;
+ break;
+ case DragFrame:
+ nDragFullOptions &= DRAGFULL_OPTION_NONE;
+ break;
+ case DragSystemDep:
+ default:
+ break;
+ }
+
+ sal_uInt32 nFollow = hMouseSettings.GetFollow();
+ hMouseSettings.SetFollow( aAppearanceCfg.IsMenuMouseFollow() ? (nFollow|MOUSE_FOLLOW_MENU) : (nFollow&~MOUSE_FOLLOW_MENU));
+ rSettings.SetMouseSettings(hMouseSettings);
+
+ SvtMenuOptions aMenuOpt;
+ hStyleSettings.SetUseImagesInMenus(aMenuOpt.GetMenuIconsState());
+ hStyleSettings.SetDragFullOptions( nDragFullOptions );
+ rSettings.SetStyleSettings ( hStyleSettings );
+}
+
+// ========================================================================
+IMPL_LINK( Desktop, AsyncInitFirstRun, void*, EMPTYARG )
+{
+ DoFirstRunInitializations();
+ return 0L;
+}
+
+// ========================================================================
+
+class ExitTimer : public Timer
+{
+ public:
+ ExitTimer()
+ {
+ SetTimeout(500);
+ Start();
+ }
+ virtual void Timeout()
+ {
+ exit(42);
+ }
+};
+
+IMPL_LINK( Desktop, OpenClients_Impl, void*, EMPTYARG )
+{
+ RTL_LOGFILE_PRODUCT_CONTEXT( aLog, "PERFORMANCE - DesktopOpenClients_Impl()" );
+
+ OpenClients();
+
+ OfficeIPCThread::SetReady();
+
+ CloseSplashScreen();
+ CheckFirstRun( );
+ EnableOleAutomation();
+
+ if (getenv ("OOO_EXIT_POST_STARTUP"))
+ new ExitTimer();
+ return 0;
+}
+
+// enable acceptos
+IMPL_LINK( Desktop, EnableAcceptors_Impl, void*, EMPTYARG )
+{
+ enableAcceptors();
+ return 0;
+}
+
+
+// Registers a COM class factory of the service manager with the windows operating system.
+void Desktop::EnableOleAutomation()
+{
+ RTL_LOGFILE_CONTEXT( aLog, "desktop (jl97489) ::Desktop::EnableOleAutomation" );
+#ifdef WNT
+ Reference< XMultiServiceFactory > xSMgr= comphelper::getProcessServiceFactory();
+ xSMgr->createInstance(DEFINE_CONST_UNICODE("com.sun.star.bridge.OleApplicationRegistration"));
+ xSMgr->createInstance(DEFINE_CONST_UNICODE("com.sun.star.comp.ole.EmbedServer"));
+#endif
+}
+
+sal_Bool Desktop::CheckOEM()
+{
+ Reference<XMultiServiceFactory> rFactory = ::comphelper::getProcessServiceFactory();
+ Reference<XJob> rOemJob(rFactory->createInstance(
+ OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.office.OEMPreloadJob"))),
+ UNO_QUERY );
+ Sequence<NamedValue> args;
+ sal_Bool bResult = sal_False;
+ if (rOemJob.is()) {
+ Any aResult = rOemJob->execute(args);
+ aResult >>= bResult;
+ return bResult;
+ } else {
+ return sal_True;
+ }
+}
+
+void Desktop::PreloadModuleData( CommandLineArgs* pArgs )
+{
+ Reference< XMultiServiceFactory > rFactory = ::comphelper::getProcessServiceFactory();
+
+ Sequence < com::sun::star::beans::PropertyValue > args(1);
+ args[0].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Hidden"));
+ args[0].Value <<= sal_True;
+ Reference < XComponentLoader > xLoader( ::comphelper::getProcessServiceFactory()->createInstance(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.Desktop")) ), UNO_QUERY );
+
+ if ( !xLoader.is() )
+ return;
+
+ if ( pArgs->IsWriter() )
+ {
+ try
+ {
+ Reference < ::com::sun::star::util::XCloseable > xDoc( xLoader->loadComponentFromURL( DEFINE_CONST_UNICODE("private:factory/swriter"),
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("_blank")), 0, args ), UNO_QUERY_THROW );
+ xDoc->close( sal_False );
+ }
+ catch ( com::sun::star::uno::Exception& )
+ {
+ }
+ }
+ if ( pArgs->IsCalc() )
+ {
+ try
+ {
+ Reference < ::com::sun::star::util::XCloseable > xDoc( xLoader->loadComponentFromURL( DEFINE_CONST_UNICODE("private:factory/scalc"),
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("_blank")), 0, args ), UNO_QUERY_THROW );
+ xDoc->close( sal_False );
+ }
+ catch ( com::sun::star::uno::Exception& )
+ {
+ }
+ }
+ if ( pArgs->IsDraw() )
+ {
+ try
+ {
+ Reference < ::com::sun::star::util::XCloseable > xDoc( xLoader->loadComponentFromURL( DEFINE_CONST_UNICODE("private:factory/sdraw"),
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("_blank")), 0, args ), UNO_QUERY_THROW );
+ xDoc->close( sal_False );
+ }
+ catch ( com::sun::star::uno::Exception& )
+ {
+ }
+ }
+ if ( pArgs->IsImpress() )
+ {
+ try
+ {
+ Reference < ::com::sun::star::util::XCloseable > xDoc( xLoader->loadComponentFromURL( DEFINE_CONST_UNICODE("private:factory/simpress"),
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("_blank")), 0, args ), UNO_QUERY_THROW );
+ xDoc->close( sal_False );
+ }
+ catch ( com::sun::star::uno::Exception& )
+ {
+ }
+ }
+}
+
+void Desktop::PreloadConfigurationData()
+{
+ Reference< XMultiServiceFactory > rFactory = ::comphelper::getProcessServiceFactory();
+ Reference< XNameAccess > xNameAccess( rFactory->createInstance(
+ DEFINE_CONST_UNICODE( "com.sun.star.frame.UICommandDescription" )), UNO_QUERY );
+
+ rtl::OUString aWriterDoc( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.text.TextDocument" ));
+ rtl::OUString aCalcDoc( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sheet.SpreadsheetDocument" ));
+ rtl::OUString aDrawDoc( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.drawing.DrawingDocument" ));
+ rtl::OUString aImpressDoc( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.presentation.PresentationDocument" ));
+
+ // preload commands configuration
+ if ( xNameAccess.is() )
+ {
+ Any a;
+ Reference< XNameAccess > xCmdAccess;
+
+ try
+ {
+ a = xNameAccess->getByName( aWriterDoc );
+ a >>= xCmdAccess;
+ if ( xCmdAccess.is() )
+ {
+ xCmdAccess->getByName( DEFINE_CONST_UNICODE( ".uno:BasicShapes" ));
+ xCmdAccess->getByName( DEFINE_CONST_UNICODE( ".uno:EditGlossary" ));
+ }
+ }
+ catch ( ::com::sun::star::uno::Exception& )
+ {
+ }
+
+ try
+ {
+ a = xNameAccess->getByName( aCalcDoc );
+ a >>= xCmdAccess;
+ if ( xCmdAccess.is() )
+ xCmdAccess->getByName( DEFINE_CONST_UNICODE( ".uno:InsertObjectStarMath" ));
+ }
+ catch ( ::com::sun::star::uno::Exception& )
+ {
+ }
+
+ try
+ {
+ // draw and impress share the same configuration file (DrawImpressCommands.xcu)
+ a = xNameAccess->getByName( aDrawDoc );
+ a >>= xCmdAccess;
+ if ( xCmdAccess.is() )
+ xCmdAccess->getByName( DEFINE_CONST_UNICODE( ".uno:Polygon" ));
+ }
+ catch ( ::com::sun::star::uno::Exception& )
+ {
+ }
+ }
+
+ // preload window state configuration
+ xNameAccess = Reference< XNameAccess >( rFactory->createInstance(
+ DEFINE_CONST_UNICODE( "com.sun.star.ui.WindowStateConfiguration" )), UNO_QUERY );
+ if ( xNameAccess.is() )
+ {
+ Any a;
+ Reference< XNameAccess > xWindowAccess;
+ try
+ {
+ a = xNameAccess->getByName( aWriterDoc );
+ a >>= xWindowAccess;
+ if ( xWindowAccess.is() )
+ xWindowAccess->getByName( DEFINE_CONST_UNICODE( "private:resource/toolbar/standardbar" ));
+ }
+ catch ( ::com::sun::star::uno::Exception& )
+ {
+ }
+ try
+ {
+ a = xNameAccess->getByName( aCalcDoc );
+ a >>= xWindowAccess;
+ if ( xWindowAccess.is() )
+ xWindowAccess->getByName( DEFINE_CONST_UNICODE( "private:resource/toolbar/standardbar" ));
+ }
+ catch ( ::com::sun::star::uno::Exception& )
+ {
+ }
+ try
+ {
+ a = xNameAccess->getByName( aDrawDoc );
+ a >>= xWindowAccess;
+ if ( xWindowAccess.is() )
+ xWindowAccess->getByName( DEFINE_CONST_UNICODE( "private:resource/toolbar/standardbar" ));
+ }
+ catch ( ::com::sun::star::uno::Exception& )
+ {
+ }
+ try
+ {
+ a = xNameAccess->getByName( aImpressDoc );
+ a >>= xWindowAccess;
+ if ( xWindowAccess.is() )
+ xWindowAccess->getByName( DEFINE_CONST_UNICODE( "private:resource/toolbar/standardbar" ));
+ }
+ catch ( ::com::sun::star::uno::Exception& )
+ {
+ }
+ }
+
+ // preload user interface element factories
+ Sequence< Sequence< css::beans::PropertyValue > > aSeqSeqPropValue;
+ Reference< ::com::sun::star::ui::XUIElementFactoryRegistration > xUIElementFactory(
+ rFactory->createInstance(
+ DEFINE_CONST_UNICODE( "com.sun.star.ui.UIElementFactoryManager" )),
+ UNO_QUERY );
+ if ( xUIElementFactory.is() )
+ {
+ try
+ {
+ aSeqSeqPropValue = xUIElementFactory->getRegisteredFactories();
+ }
+ catch ( ::com::sun::star::uno::Exception& )
+ {
+ }
+ }
+
+ // preload popup menu controller factories. As all controllers are in the same
+ // configuration file they also get preloaded!
+ Reference< ::com::sun::star::frame::XUIControllerRegistration > xPopupMenuControllerFactory(
+ rFactory->createInstance(
+ DEFINE_CONST_UNICODE( "com.sun.star.frame.PopupMenuControllerFactory" )),
+ UNO_QUERY );
+ if ( xPopupMenuControllerFactory.is() )
+ {
+ try
+ {
+ xPopupMenuControllerFactory->hasController(
+ DEFINE_CONST_UNICODE( ".uno:CharFontName" ),
+ OUString() );
+ }
+ catch ( ::com::sun::star::uno::Exception& )
+ {
+ }
+ }
+
+ // preload filter configuration
+ Sequence< OUString > aSeq;
+ xNameAccess = Reference< XNameAccess >( rFactory->createInstance(
+ DEFINE_CONST_UNICODE( "com.sun.star.document.FilterFactory" )), UNO_QUERY );
+ if ( xNameAccess.is() )
+ {
+ try
+ {
+ aSeq = xNameAccess->getElementNames();
+ }
+ catch ( ::com::sun::star::uno::Exception& )
+ {
+ }
+ }
+
+ // preload type detection configuration
+ xNameAccess = Reference< XNameAccess >( rFactory->createInstance(
+ DEFINE_CONST_UNICODE( "com.sun.star.document.TypeDetection" )), UNO_QUERY );
+ if ( xNameAccess.is() )
+ {
+ try
+ {
+ aSeq = xNameAccess->getElementNames();
+ }
+ catch ( ::com::sun::star::uno::Exception& )
+ {
+ }
+ }
+
+ static const OUString sConfigSrvc( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.configuration.ConfigurationProvider" ) );
+ static const OUString sAccessSrvc( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.configuration.ConfigurationAccess" ) );
+
+ // get configuration provider
+ Reference< XMultiServiceFactory > xConfigProvider;
+ xConfigProvider = Reference< XMultiServiceFactory > (
+ rFactory->createInstance( sConfigSrvc ),UNO_QUERY );
+
+ if ( xConfigProvider.is() )
+ {
+ // preload writer configuration
+ Sequence< Any > theArgs(1);
+ theArgs[ 0 ] <<= OUString(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.Office.Writer/MailMergeWizard"));
+ try
+ {
+ xNameAccess = Reference< XNameAccess >(
+ xConfigProvider->createInstanceWithArguments( sAccessSrvc, theArgs ), UNO_QUERY );
+ }
+ catch (::com::sun::star::uno::Exception& )
+ {
+ }
+
+ // WriterWeb
+ theArgs[ 0 ] <<= OUString(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.Office.WriterWeb/Content"));
+ try
+ {
+ xNameAccess = Reference< XNameAccess >(
+ xConfigProvider->createInstanceWithArguments( sAccessSrvc, theArgs ), UNO_QUERY );
+ }
+ catch (::com::sun::star::uno::Exception& )
+ {
+ }
+
+ // preload compatibility
+ theArgs[ 0 ] <<= OUString(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.Office.Compatibility/WriterCompatibilityVersion"));
+ try
+ {
+ xNameAccess = Reference< XNameAccess >(
+ xConfigProvider->createInstanceWithArguments( sAccessSrvc, theArgs ), UNO_QUERY );
+ }
+ catch (::com::sun::star::uno::Exception& )
+ {
+ }
+
+ // preload calc configuration
+ theArgs[ 0 ] <<= OUString(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.Office.Calc/Content"));
+ try
+ {
+ xNameAccess = Reference< XNameAccess >(
+ xConfigProvider->createInstanceWithArguments( sAccessSrvc, theArgs ), UNO_QUERY );
+ }
+ catch (::com::sun::star::uno::Exception& )
+ {
+ }
+
+ // preload impress configuration
+ theArgs[ 0 ] <<= OUString(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.Office.UI.Effects/UserInterface"));
+ try
+ {
+ xNameAccess = Reference< XNameAccess >(
+ xConfigProvider->createInstanceWithArguments( sAccessSrvc, theArgs ), UNO_QUERY );
+ }
+ catch (::com::sun::star::uno::Exception& )
+ {
+ }
+
+ theArgs[ 0 ] <<= OUString(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.Office.Impress/Layout"));
+ try
+ {
+ xNameAccess = Reference< XNameAccess >(
+ xConfigProvider->createInstanceWithArguments( sAccessSrvc, theArgs ), UNO_QUERY );
+ }
+ catch (::com::sun::star::uno::Exception& )
+ {
+ }
+
+ // preload draw configuration
+ theArgs[ 0 ] <<= OUString(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.Office.Draw/Layout"));
+ try
+ {
+ xNameAccess = Reference< XNameAccess >(
+ xConfigProvider->createInstanceWithArguments( sAccessSrvc, theArgs ), UNO_QUERY );
+ }
+ catch (::com::sun::star::uno::Exception& )
+ {
+ }
+
+ // preload ui configuration
+ theArgs[ 0 ] <<= OUString(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.Office.UI/FilterClassification"));
+ try
+ {
+ xNameAccess = Reference< XNameAccess >(
+ xConfigProvider->createInstanceWithArguments( sAccessSrvc, theArgs ), UNO_QUERY );
+ }
+ catch (::com::sun::star::uno::Exception& )
+ {
+ }
+
+ // preload addons configuration
+ theArgs[ 0 ] <<= OUString(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.Office.Addons/AddonUI"));
+ try
+ {
+ xNameAccess = Reference< XNameAccess >(
+ xConfigProvider->createInstanceWithArguments( sAccessSrvc, theArgs ), UNO_QUERY );
+ }
+ catch (::com::sun::star::uno::Exception& )
+ {
+ }
+ }
+}
+
+void Desktop::OpenClients()
+{
+
+ // check if a document has been recovered - if there is one of if a document was loaded by cmdline, no default document
+ // should be created
+ Reference < XComponent > xFirst;
+ sal_Bool bLoaded = sal_False;
+
+ CommandLineArgs* pArgs = GetCommandLineArgs();
+ SvtInternalOptions aInternalOptions;
+
+ Reference<XMultiServiceFactory> rFactory = ::comphelper::getProcessServiceFactory();
+
+ if (!pArgs->IsQuickstart()) {
+ sal_Bool bShowHelp = sal_False;
+ ::rtl::OUStringBuffer aHelpURLBuffer;
+ if (pArgs->IsHelpWriter()) {
+ bShowHelp = sal_True;
+ aHelpURLBuffer.appendAscii("vnd.sun.star.help://swriter/start");
+ } else if (pArgs->IsHelpCalc()) {
+ bShowHelp = sal_True;
+ aHelpURLBuffer.appendAscii("vnd.sun.star.help://scalc/start");
+ } else if (pArgs->IsHelpDraw()) {
+ bShowHelp = sal_True;
+ aHelpURLBuffer.appendAscii("vnd.sun.star.help://sdraw/start");
+ } else if (pArgs->IsHelpImpress()) {
+ bShowHelp = sal_True;
+ aHelpURLBuffer.appendAscii("vnd.sun.star.help://simpress/start");
+ } else if (pArgs->IsHelpBase()) {
+ bShowHelp = sal_True;
+ aHelpURLBuffer.appendAscii("vnd.sun.star.help://sdatabase/start");
+ } else if (pArgs->IsHelpBasic()) {
+ bShowHelp = sal_True;
+ aHelpURLBuffer.appendAscii("vnd.sun.star.help://sbasic/start");
+ } else if (pArgs->IsHelpMath()) {
+ bShowHelp = sal_True;
+ aHelpURLBuffer.appendAscii("vnd.sun.star.help://smath/start");
+ }
+ if (bShowHelp) {
+ Help *pHelp = Application::GetHelp();
+
+ Any aRet = ::utl::ConfigManager::GetDirectConfigProperty( ::utl::ConfigManager::LOCALE );
+ rtl::OUString aTmp;
+ aRet >>= aTmp;
+ aHelpURLBuffer.appendAscii("?Language=");
+ aHelpURLBuffer.append(aTmp);
+#if defined UNX
+ aHelpURLBuffer.appendAscii("&System=UNX");
+#elif defined WNT
+ aHelpURLBuffer.appendAscii("&System=WIN");
+#elif defined OS2
+ aHelpURLBuffer.appendAscii("&System=OS2");
+#endif
+ pHelp->Start(aHelpURLBuffer.makeStringAndClear(), NULL);
+ return;
+ }
+ }
+ else
+ {
+ OUString aIniName;
+
+ osl_getExecutableFile( &aIniName.pData );
+ sal_uInt32 lastIndex = aIniName.lastIndexOf('/');
+ if ( lastIndex > 0 )
+ {
+ aIniName = aIniName.copy( 0, lastIndex+1 );
+ aIniName += OUString( RTL_CONSTASCII_USTRINGPARAM( "perftune" ));
+#if defined(WNT) || defined(OS2)
+ aIniName += OUString( RTL_CONSTASCII_USTRINGPARAM( ".ini" ));
+#else
+ aIniName += OUString( RTL_CONSTASCII_USTRINGPARAM( "rc" ));
+#endif
+ }
+
+ rtl::Bootstrap aPerfTuneIniFile( aIniName );
+
+ OUString aDefault( RTL_CONSTASCII_USTRINGPARAM( "0" ));
+ OUString aPreloadData;
+
+ aPerfTuneIniFile.getFrom( OUString( RTL_CONSTASCII_USTRINGPARAM( "QuickstartPreloadConfiguration" )), aPreloadData, aDefault );
+ if ( aPreloadData.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "1" ) ))
+ {
+ if ( pArgs->IsWriter() ||
+ pArgs->IsCalc() ||
+ pArgs->IsDraw() ||
+ pArgs->IsImpress() )
+ {
+ PreloadModuleData( pArgs );
+ }
+
+ PreloadConfigurationData();
+ }
+ }
+
+ // Disable AutoSave feature in case "-norestore" or a similare command line switch is set on the command line.
+ // The reason behind: AutoSave/EmergencySave/AutoRecovery share the same data.
+ // But the require that all documents, which are saved as backup should exists inside
+ // memory. May be this mechanism will be inconsistent if the configuration exists ...
+ // but no document inside memory corrspond to this data.
+ // Furter it's not acceptable to recover such documents without any UI. It can
+ // need some time, where the user wont see any results and wait for finishing the office startup ...
+ sal_Bool bAllowRecoveryAndSessionManagement = (
+ ( !pArgs->IsNoRestore() ) &&
+ ( !pArgs->IsHeadless() ) &&
+ ( !pArgs->IsServer() )
+ );
+
+ if ( ! bAllowRecoveryAndSessionManagement )
+ {
+ try
+ {
+ Reference< XDispatch > xRecovery(
+ ::comphelper::getProcessServiceFactory()->createInstance( OUSTRING(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.AutoRecovery")) ),
+ ::com::sun::star::uno::UNO_QUERY_THROW );
+
+ Reference< XURLTransformer > xParser(
+ ::comphelper::getProcessServiceFactory()->createInstance( OUSTRING(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.util.URLTransformer")) ),
+ ::com::sun::star::uno::UNO_QUERY_THROW );
+
+ css::util::URL aCmd;
+ aCmd.Complete = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("vnd.sun.star.autorecovery:/disableRecovery"));
+ xParser->parseStrict(aCmd);
+
+ xRecovery->dispatch(aCmd, css::uno::Sequence< css::beans::PropertyValue >());
+ }
+ catch(const css::uno::Exception& e)
+ {
+ OUString aMessage = OUString(RTL_CONSTASCII_USTRINGPARAM("Could not disable AutoRecovery.\n"))
+ + e.Message;
+ OSL_FAIL(OUStringToOString(aMessage, RTL_TEXTENCODING_ASCII_US).getStr());
+ }
+ }
+ else
+ {
+ sal_Bool bCrashed = sal_False;
+ sal_Bool bExistsRecoveryData = sal_False;
+ sal_Bool bExistsSessionData = sal_False;
+
+ impl_checkRecoveryState(bCrashed, bExistsRecoveryData, bExistsSessionData);
+
+ if ( !getenv ("OOO_DISABLE_RECOVERY") &&
+ ( ! bLoaded ) &&
+ (
+ ( bExistsRecoveryData ) || // => crash with files => recovery
+ ( bCrashed ) // => crash without files => error report
+ )
+ )
+ {
+ try
+ {
+ impl_callRecoveryUI(
+ sal_False , // false => force recovery instead of emergency save
+ bCrashed ,
+ bExistsRecoveryData);
+ /* TODO we cant be shure, that at least one document could be recovered here successfully
+ So we set bLoaded=sal_True to supress opening of the default document.
+ But we should make it more safe. Otherwhise we have an office without an UI ...
+ ...
+ May be we can check the desktop if some documents are existing there.
+ */
+ Reference< XFramesSupplier > xTasksSupplier(
+ ::comphelper::getProcessServiceFactory()->createInstance( OUSTRING(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.Desktop")) ),
+ ::com::sun::star::uno::UNO_QUERY_THROW );
+ Reference< XElementAccess > xList( xTasksSupplier->getFrames(), UNO_QUERY_THROW );
+ if ( xList->hasElements() )
+ bLoaded = sal_True;
+ }
+ catch(const css::uno::Exception& e)
+ {
+ OUString aMessage = OUString(RTL_CONSTASCII_USTRINGPARAM("Error during recovery\n"))
+ + e.Message;
+ OSL_FAIL(OUStringToOString(aMessage, RTL_TEXTENCODING_ASCII_US).getStr());
+ }
+ }
+
+ Reference< XInitialization > xSessionListener;
+ try
+ {
+ xSessionListener = Reference< XInitialization >(::comphelper::getProcessServiceFactory()->createInstance(
+ OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.SessionListener"))), UNO_QUERY_THROW);
+
+ // specifies whether the UI-interaction on Session shutdown is allowed
+ sal_Bool bAllowUI = isUIOnSessionShutdownAllowed();
+ css::beans::NamedValue aProperty( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "AllowUserInteractionOnQuit" ) ),
+ css::uno::makeAny( bAllowUI ) );
+ css::uno::Sequence< css::uno::Any > aArgs( 1 );
+ aArgs[0] <<= aProperty;
+
+ xSessionListener->initialize( aArgs );
+ }
+ catch(const com::sun::star::uno::Exception& e)
+ {
+ OUString aMessage = OUString(RTL_CONSTASCII_USTRINGPARAM("Registration of session listener failed\n"))
+ + e.Message;
+ OSL_FAIL(OUStringToOString(aMessage, RTL_TEXTENCODING_ASCII_US).getStr());
+ }
+
+ if (
+ ( ! bLoaded ) &&
+ ( bExistsSessionData )
+ )
+ {
+ // session management
+ try
+ {
+ Reference< XSessionManagerListener > r(xSessionListener, UNO_QUERY_THROW);
+ bLoaded = r->doRestore();
+ }
+ catch(const com::sun::star::uno::Exception& e)
+ {
+ OUString aMessage = OUString(RTL_CONSTASCII_USTRINGPARAM("Error in session management\n"))
+ + e.Message;
+ OSL_FAIL(OUStringToOString(aMessage, RTL_TEXTENCODING_ASCII_US).getStr());
+ }
+ }
+ }
+
+ OfficeIPCThread::EnableRequests();
+
+ sal_Bool bShutdown( sal_False );
+ if ( !pArgs->IsServer() )
+ {
+ ProcessDocumentsRequest aRequest(pArgs->getCwdUrl());
+ aRequest.pcProcessed = NULL;
+
+ pArgs->GetOpenList( aRequest.aOpenList );
+ pArgs->GetViewList( aRequest.aViewList );
+ pArgs->GetStartList( aRequest.aStartList );
+ pArgs->GetPrintList( aRequest.aPrintList );
+ pArgs->GetPrintToList( aRequest.aPrintToList );
+ pArgs->GetPrinterName( aRequest.aPrinterName );
+ pArgs->GetForceOpenList( aRequest.aForceOpenList );
+ pArgs->GetForceNewList( aRequest.aForceNewList );
+ pArgs->GetConversionList( aRequest.aConversionList );
+ pArgs->GetConversionParams( aRequest.aConversionParams );
+ pArgs->GetConversionOut( aRequest.aConversionOut );
+ pArgs->GetInFilter( aRequest.aInFilter );
+
+ if ( aRequest.aOpenList.getLength() > 0 ||
+ aRequest.aViewList.getLength() > 0 ||
+ aRequest.aStartList.getLength() > 0 ||
+ aRequest.aPrintList.getLength() > 0 ||
+ aRequest.aForceOpenList.getLength() > 0 ||
+ aRequest.aForceNewList.getLength() > 0 ||
+ ( aRequest.aPrintToList.getLength() > 0 && aRequest.aPrinterName.getLength() > 0 ) ||
+ aRequest.aConversionList.getLength() > 0 )
+ {
+ bLoaded = sal_True;
+
+ if ( pArgs->HasModuleParam() )
+ {
+ SvtModuleOptions aOpt;
+
+ // Support command line parameters to start a module (as preselection)
+ if ( pArgs->IsWriter() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SWRITER ) )
+ aRequest.aModule = aOpt.GetFactoryName( SvtModuleOptions::E_WRITER );
+ else if ( pArgs->IsCalc() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SCALC ) )
+ aRequest.aModule = aOpt.GetFactoryName( SvtModuleOptions::E_CALC );
+ else if ( pArgs->IsImpress() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SIMPRESS ) )
+ aRequest.aModule= aOpt.GetFactoryName( SvtModuleOptions::E_IMPRESS );
+ else if ( pArgs->IsDraw() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SDRAW ) )
+ aRequest.aModule= aOpt.GetFactoryName( SvtModuleOptions::E_DRAW );
+ }
+
+ // check for printing disabled
+ if( ( aRequest.aPrintList.getLength() || aRequest.aPrintToList.getLength() )
+ && Application::GetSettings().GetMiscSettings().GetDisablePrinting() )
+ {
+ aRequest.aPrintList = rtl::OUString();
+ aRequest.aPrintToList = rtl::OUString();
+ ResMgr* pDtResMgr = GetDesktopResManager();
+ if( pDtResMgr )
+ {
+ ErrorBox aBox( NULL, ResId( EBX_ERR_PRINTDISABLED, *pDtResMgr ) );
+ aBox.Execute();
+ }
+ }
+
+ // Process request
+ bShutdown = OfficeIPCThread::ExecuteCmdLineRequests( aRequest );
+ }
+ }
+
+ // Don't do anything if we have successfully called terminate at desktop
+ if ( bShutdown )
+ return;
+
+ // no default document if a document was loaded by recovery or by command line or if soffice is used as server
+ Reference< XFramesSupplier > xTasksSupplier(
+ ::comphelper::getProcessServiceFactory()->createInstance( OUSTRING(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.Desktop")) ),
+ ::com::sun::star::uno::UNO_QUERY_THROW );
+ Reference< XElementAccess > xList( xTasksSupplier->getFrames(), UNO_QUERY_THROW );
+ if ( xList->hasElements() || pArgs->IsServer() )
+ return;
+
+ if ( pArgs->IsQuickstart() || pArgs->IsInvisible() || pArgs->IsBean() || Application::AnyInput( INPUT_APPEVENT ) )
+ // soffice was started as tray icon ...
+ return;
+ {
+ OpenDefault();
+ }
+}
+
+void Desktop::OpenDefault()
+{
+
+ RTL_LOGFILE_CONTEXT( aLog, "desktop (cd100003) ::Desktop::OpenDefault" );
+
+ ::rtl::OUString aName;
+ SvtModuleOptions aOpt;
+
+ CommandLineArgs* pArgs = GetCommandLineArgs();
+ if ( pArgs->IsNoDefault() ) return;
+ if ( pArgs->HasModuleParam() )
+ {
+ // Support new command line parameters to start a module
+ if ( pArgs->IsWriter() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SWRITER ) )
+ aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_WRITER );
+ else if ( pArgs->IsCalc() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SCALC ) )
+ aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_CALC );
+ else if ( pArgs->IsImpress() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SIMPRESS ) )
+ aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_IMPRESS );
+ else if ( pArgs->IsBase() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SDATABASE ) )
+ aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_DATABASE );
+ else if ( pArgs->IsDraw() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SDRAW ) )
+ aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_DRAW );
+ else if ( pArgs->IsMath() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SMATH ) )
+ aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_MATH );
+ else if ( pArgs->IsGlobal() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SWRITER ) )
+ aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_WRITERGLOBAL );
+ else if ( pArgs->IsWeb() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SWRITER ) )
+ aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_WRITERWEB );
+ }
+
+ if ( !aName.getLength() )
+ {
+ // Old way to create a default document
+ if ( aOpt.IsModuleInstalled( SvtModuleOptions::E_SWRITER ) )
+ aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_WRITER );
+ else if ( aOpt.IsModuleInstalled( SvtModuleOptions::E_SCALC ) )
+ aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_CALC );
+ else if ( aOpt.IsModuleInstalled( SvtModuleOptions::E_SIMPRESS ) )
+ aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_IMPRESS );
+ else if ( aOpt.IsModuleInstalled( SvtModuleOptions::E_SDATABASE ) )
+ aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_DATABASE );
+ else if ( aOpt.IsModuleInstalled( SvtModuleOptions::E_SDRAW ) )
+ aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_DRAW );
+ else
+ return;
+ }
+
+ ProcessDocumentsRequest aRequest(pArgs->getCwdUrl());
+ aRequest.pcProcessed = NULL;
+ aRequest.aOpenList = aName;
+ OfficeIPCThread::ExecuteCmdLineRequests( aRequest );
+}
+
+
+String GetURL_Impl(
+ const String& rName, boost::optional< rtl::OUString > const & cwdUrl )
+{
+ // if rName is a vnd.sun.star.script URL do not attempt to parse it
+ // as INetURLObj does not handle handle there URLs
+ if (rName.CompareToAscii("vnd.sun.star.script" , 19) == COMPARE_EQUAL)
+ {
+ return rName;
+ }
+
+ // dont touch file urls, those should already be in internal form
+ // they won't get better here (#112849#)
+ if (rName.CompareToAscii("file:" , 5) == COMPARE_EQUAL)
+ {
+ return rName;
+ }
+
+ if ( rName.CompareToAscii("service:" , 8) == COMPARE_EQUAL )
+ {
+ return rName;
+ }
+
+ // Add path seperator to these directory and make given URL (rName) absolute by using of current working directory
+ // Attention: "setFinalSlash()" is necessary for calling "smartRel2Abs()"!!!
+ // Otherwhise last part will be ignored and wrong result will be returned!!!
+ // "smartRel2Abs()" interpret given URL as file not as path. So he truncate last element to get the base path ...
+ // But if we add a seperator - he doesn't do it anymore.
+ INetURLObject aObj;
+ if (cwdUrl) {
+ aObj.SetURL(*cwdUrl);
+ aObj.setFinalSlash();
+ }
+
+ // Use the provided parameters for smartRel2Abs to support the usage of '%' in system paths.
+ // Otherwise this char won't get encoded and we are not able to load such files later,
+ bool bWasAbsolute;
+ INetURLObject aURL = aObj.smartRel2Abs( rName, bWasAbsolute, false, INetURLObject::WAS_ENCODED,
+ RTL_TEXTENCODING_UTF8, true );
+ String aFileURL = aURL.GetMainURL(INetURLObject::NO_DECODE);
+
+ ::osl::FileStatus aStatus( FileStatusMask_FileURL );
+ ::osl::DirectoryItem aItem;
+ if( ::osl::FileBase::E_None == ::osl::DirectoryItem::get( aFileURL, aItem ) &&
+ ::osl::FileBase::E_None == aItem.getFileStatus( aStatus ) )
+ aFileURL = aStatus.getFileURL();
+
+ return aFileURL;
+}
+
+void Desktop::HandleAppEvent( const ApplicationEvent& rAppEvent )
+{
+ if ( rAppEvent.GetEvent() == "APPEAR" && !GetCommandLineArgs()->IsInvisible() )
+ {
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = ::comphelper::getProcessServiceFactory();
+
+ // find active task - the active task is always a visible task
+ ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFramesSupplier >
+ xDesktop( xSMGR->createInstance( OUSTRING(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.Desktop")) ),
+ ::com::sun::star::uno::UNO_QUERY );
+ ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame > xTask = xDesktop->getActiveFrame();
+ if ( !xTask.is() )
+ {
+ // get any task if there is no active one
+ ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexAccess > xList( xDesktop->getFrames(), ::com::sun::star::uno::UNO_QUERY );
+ if ( xList->getCount()>0 )
+ xList->getByIndex(0) >>= xTask;
+ }
+
+ if ( xTask.is() )
+ {
+ Reference< com::sun::star::awt::XTopWindow > xTop( xTask->getContainerWindow(), UNO_QUERY );
+ xTop->toFront();
+ }
+ else
+ {
+ // no visible task that could be activated found
+ Reference< XFrame > xBackingFrame;
+ Reference< ::com::sun::star::awt::XWindow > xContainerWindow;
+ ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame > xDesktopFrame( xDesktop, UNO_QUERY );
+
+ xBackingFrame = xDesktopFrame->findFrame(OUString( RTL_CONSTASCII_USTRINGPARAM( "_blank" )), 0);
+ if (xBackingFrame.is())
+ xContainerWindow = xBackingFrame->getContainerWindow();
+ if (xContainerWindow.is())
+ {
+ Sequence< Any > lArgs(1);
+ lArgs[0] <<= xContainerWindow;
+ Reference< XController > xBackingComp(
+ xSMGR->createInstanceWithArguments(OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.StartModule") ), lArgs),
+ UNO_QUERY);
+ if (xBackingComp.is())
+ {
+ Reference< ::com::sun::star::awt::XWindow > xBackingWin(xBackingComp, UNO_QUERY);
+ // Attention: You MUST(!) call setComponent() before you call attachFrame().
+ // Because the backing component set the property "IsBackingMode" of the frame
+ // to true inside attachFrame(). But setComponent() reset this state everytimes ...
+ xBackingFrame->setComponent(xBackingWin, xBackingComp);
+ xBackingComp->attachFrame(xBackingFrame);
+ xContainerWindow->setVisible(sal_True);
+
+ Window* pCompWindow = VCLUnoHelper::GetWindow(xBackingFrame->getComponentWindow());
+ if (pCompWindow)
+ pCompWindow->Update();
+ }
+ }
+ }
+ }
+ else if ( rAppEvent.GetEvent() == "QUICKSTART" && !GetCommandLineArgs()->IsInvisible() )
+ {
+ // If the office has been started the second time its command line arguments are sent through a pipe
+ // connection to the first office. We want to reuse the quickstart option for the first office.
+ // NOTICE: The quickstart service must be initialized inside the "main thread", so we use the
+ // application events to do this (they are executed inside main thread)!!!
+ // Don't start quickstart service if the user specified "-invisible" on the command line!
+ sal_Bool bQuickstart( sal_True );
+ Sequence< Any > aSeq( 1 );
+ aSeq[0] <<= bQuickstart;
+
+ Reference < XInitialization > xQuickstart( ::comphelper::getProcessServiceFactory()->createInstance(
+ DEFINE_CONST_UNICODE( "com.sun.star.office.Quickstart" )),
+ UNO_QUERY );
+ if ( xQuickstart.is() )
+ xQuickstart->initialize( aSeq );
+ }
+ else if ( rAppEvent.GetEvent() == "ACCEPT" )
+ {
+ // every time an accept parameter is used we create an acceptor
+ // with the corresponding accept-string
+ OUString aAcceptString(rAppEvent.GetData().GetBuffer());
+ createAcceptor(aAcceptString);
+ }
+ else if ( rAppEvent.GetEvent() == "UNACCEPT" )
+ {
+ // try to remove corresponding acceptor
+ OUString aUnAcceptString(rAppEvent.GetData().GetBuffer());
+ destroyAcceptor(aUnAcceptString);
+ }
+ else if ( rAppEvent.GetEvent() == "SaveDocuments" )
+ {
+ Desktop::_bTasksSaved = sal_False;
+ Desktop::_bTasksSaved = SaveTasks();
+ }
+ else if ( rAppEvent.GetEvent() == "OPENHELPURL" )
+ {
+ // start help for a specific URL
+ OUString aHelpURL(rAppEvent.GetData().GetBuffer());
+ Help *pHelp = Application::GetHelp();
+ pHelp->Start(aHelpURL, NULL);
+ }
+ else if ( rAppEvent.GetEvent() == APPEVENT_OPEN_STRING )
+ {
+ OUString aOpenURL(rAppEvent.GetData().GetBuffer());
+
+ CommandLineArgs* pCmdLine = GetCommandLineArgs();
+ if ( !pCmdLine->IsInvisible() && !pCmdLine->IsTerminateAfterInit() )
+ {
+ ProcessDocumentsRequest* pDocsRequest = new ProcessDocumentsRequest(
+ pCmdLine->getCwdUrl());
+ pDocsRequest->aOpenList = aOpenURL;
+ pDocsRequest->pcProcessed = NULL;
+
+ OfficeIPCThread::ExecuteCmdLineRequests( *pDocsRequest );
+ delete pDocsRequest;
+ }
+ }
+ else if ( rAppEvent.GetEvent() == APPEVENT_PRINT_STRING )
+ {
+ OUString aPrintURL(rAppEvent.GetData().GetBuffer());
+
+ CommandLineArgs* pCmdLine = GetCommandLineArgs();
+ if ( !pCmdLine->IsInvisible() && !pCmdLine->IsTerminateAfterInit() )
+ {
+ ProcessDocumentsRequest* pDocsRequest = new ProcessDocumentsRequest(
+ pCmdLine->getCwdUrl());
+ pDocsRequest->aPrintList = aPrintURL;
+ pDocsRequest->pcProcessed = NULL;
+
+ OfficeIPCThread::ExecuteCmdLineRequests( *pDocsRequest );
+ delete pDocsRequest;
+ }
+ }
+#ifndef UNX
+ else if ( rAppEvent.GetEvent() == "HELP" )
+ {
+ // in non unix version allow showing of cmdline help window
+ displayCmdlineHelp();
+ }
+#endif
+ else if ( rAppEvent.GetEvent() == "SHOWDIALOG" )
+ {
+ // ignore all errors here. It's clicking a menu entry only ...
+ // The user will try it again, in case nothing happens .-)
+ try
+ {
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = ::comphelper::getProcessServiceFactory();
+
+ com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatchProvider >
+ xDesktop( xSMGR->createInstance( OUSTRING(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.Desktop")) ),
+ ::com::sun::star::uno::UNO_QUERY );
+
+ // check provider ... we know it's weak reference only
+ if ( ! xDesktop.is())
+ return;
+
+ css::uno::Reference< css::util::XURLTransformer > xParser(xSMGR->createInstance(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.util.URLTransformer"))), css::uno::UNO_QUERY_THROW);
+ css::util::URL aCommand;
+ if( rAppEvent.GetData().EqualsAscii( "PREFERENCES" ) )
+ aCommand.Complete = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:OptionsTreeDialog" ) );
+ else if( rAppEvent.GetData().EqualsAscii( "ABOUT" ) )
+ aCommand.Complete = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:About" ) );
+ if( aCommand.Complete.getLength() )
+ {
+ xParser->parseStrict(aCommand);
+
+ css::uno::Reference< css::frame::XDispatch > xDispatch = xDesktop->queryDispatch(aCommand, rtl::OUString(), 0);
+ if (xDispatch.is())
+ xDispatch->dispatch(aCommand, css::uno::Sequence< css::beans::PropertyValue >());
+ }
+ }
+ catch(const css::uno::Exception&)
+ {}
+ }
+ else if( rAppEvent.GetEvent() == "PRIVATE:DOSHUTDOWN" )
+ {
+ Desktop* pD = dynamic_cast<Desktop*>(GetpApp());
+ OSL_ENSURE( pD, "no desktop ?!?" );
+ if( pD )
+ pD->doShutdown();
+ }
+}
+
+void Desktop::OpenSplashScreen()
+{
+ ::rtl::OUString aTmpString;
+ CommandLineArgs* pCmdLine = GetCommandLineArgs();
+ sal_Bool bVisible = sal_False;
+ // Show intro only if this is normal start (e.g. no server, no quickstart, no printing )
+ if ( !pCmdLine->IsInvisible() &&
+ !pCmdLine->IsHeadless() &&
+ !pCmdLine->IsQuickstart() &&
+ !pCmdLine->IsMinimized() &&
+ !pCmdLine->IsNoLogo() &&
+ !pCmdLine->IsTerminateAfterInit() &&
+ !pCmdLine->GetPrintList( aTmpString ) &&
+ !pCmdLine->GetPrintToList( aTmpString ) &&
+ !pCmdLine->GetConversionList( aTmpString ))
+ {
+ // Determine application name from command line parameters
+ OUString aAppName;
+ if ( pCmdLine->IsWriter() )
+ aAppName = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "writer" ));
+ else if ( pCmdLine->IsCalc() )
+ aAppName = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "calc" ));
+ else if ( pCmdLine->IsDraw() )
+ aAppName = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "draw" ));
+ else if ( pCmdLine->IsImpress() )
+ aAppName = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "impress" ));
+ else if ( pCmdLine->IsBase() )
+ aAppName = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "base" ));
+ else if ( pCmdLine->IsGlobal() )
+ aAppName = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "global" ));
+ else if ( pCmdLine->IsMath() )
+ aAppName = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "math" ));
+ else if ( pCmdLine->IsWeb() )
+ aAppName = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "web" ));
+
+ // Which splash to use
+ OUString aSplashService( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.office.SplashScreen" ));
+ if ( pCmdLine->GetStringParam( CommandLineArgs::CMD_STRINGPARAM_SPLASHPIPE ).getLength() )
+ aSplashService = OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.office.PipeSplashScreen"));
+
+ bVisible = sal_True;
+ Sequence< Any > aSeq( 2 );
+ aSeq[0] <<= bVisible;
+ aSeq[1] <<= aAppName;
+ m_rSplashScreen = Reference<XStatusIndicator>(
+ comphelper::getProcessServiceFactory()->createInstanceWithArguments(
+ aSplashService, aSeq), UNO_QUERY);
+
+ if(m_rSplashScreen.is())
+ m_rSplashScreen->start(OUString(RTL_CONSTASCII_USTRINGPARAM("SplashScreen")), 100);
+ }
+
+}
+
+void Desktop::SetSplashScreenProgress(sal_Int32 iProgress)
+{
+ if(m_rSplashScreen.is())
+ {
+ m_rSplashScreen->setValue(iProgress);
+ }
+}
+
+void Desktop::SetSplashScreenText( const ::rtl::OUString& rText )
+{
+ if( m_rSplashScreen.is() )
+ {
+ m_rSplashScreen->setText( rText );
+ }
+}
+
+void Desktop::CloseSplashScreen()
+{
+ if(m_rSplashScreen.is())
+ {
+ m_rSplashScreen->end();
+ m_rSplashScreen = NULL;
+ }
+}
+
+// ========================================================================
+void Desktop::DoFirstRunInitializations()
+{
+ try
+ {
+ Reference< XJobExecutor > xExecutor( ::comphelper::getProcessServiceFactory()->createInstance( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.task.JobExecutor")) ), UNO_QUERY );
+ if( xExecutor.is() )
+ xExecutor->trigger( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("onFirstRunInitialization")) );
+ }
+ catch(const ::com::sun::star::uno::Exception&)
+ {
+ OSL_FAIL( "Desktop::DoFirstRunInitializations: caught an exception while trigger job executor ..." );
+ }
+}
+
+// ========================================================================
+void Desktop::CheckFirstRun( )
+{
+ const ::rtl::OUString sCommonMiscNodeName(RTL_CONSTASCII_USTRINGPARAM("/org.openoffice.Office.Common/Misc"));
+ const ::rtl::OUString sFirstRunNodeName(RTL_CONSTASCII_USTRINGPARAM("FirstRun"));
+
+ // --------------------------------------------------------------------
+ // check if this is the first office start
+
+ // for this, open the Common/Misc node where this info is stored
+ ::utl::OConfigurationTreeRoot aCommonMisc = ::utl::OConfigurationTreeRoot::createWithServiceFactory(
+ ::comphelper::getProcessServiceFactory( ),
+ sCommonMiscNodeName,
+ 2,
+ ::utl::OConfigurationTreeRoot::CM_UPDATABLE
+ );
+
+ // read the flag
+ OSL_ENSURE( aCommonMisc.isValid(), "Desktop::CheckFirstRun: could not open the config node needed!" );
+ sal_Bool bIsFirstRun = sal_False;
+ aCommonMisc.getNodeValue( sFirstRunNodeName ) >>= bIsFirstRun;
+
+ if ( !bIsFirstRun )
+ // nothing to do ....
+ return;
+
+ // --------------------------------------------------------------------
+ // it is the first run
+ // this has once been done using a vos timer. this could lead to problems when
+ // the timer would trigger when the app is already going down again, since VCL would
+ // no longer be available. Since the old handler would do a postUserEvent to the main
+ // thread anyway, we can use a vcl timer here to prevent the race contition (#107197#)
+ m_firstRunTimer.SetTimeout(3000); // 3 sec.
+ m_firstRunTimer.SetTimeoutHdl(LINK(this, Desktop, AsyncInitFirstRun));
+ m_firstRunTimer.Start();
+
+ // --------------------------------------------------------------------
+ // reset the config flag
+
+ // set the value
+ aCommonMisc.setNodeValue( sFirstRunNodeName, makeAny( (sal_Bool)sal_False ) );
+ // commit the changes
+ aCommonMisc.commit();
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/app/appfirststart.cxx b/desktop/source/app/appfirststart.cxx
new file mode 100644
index 000000000000..a5a161181efa
--- /dev/null
+++ b/desktop/source/app/appfirststart.cxx
@@ -0,0 +1,116 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include <osl/file.hxx>
+#include <rtl/bootstrap.hxx>
+#include <rtl/ustring.hxx>
+#include <tools/datetime.hxx>
+#include <unotools/configmgr.hxx>
+
+#include <comphelper/processfactory.hxx>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <com/sun/star/util/XChangesBatch.hpp>
+
+#include "app.hxx"
+
+using ::rtl::OUString;
+using namespace ::desktop;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::beans;
+
+static const OUString sConfigSrvc( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.configuration.ConfigurationProvider" ) );
+static const OUString sAccessSrvc( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.configuration.ConfigurationUpdateAccess" ) );
+
+/* Local function - get access to the configuration */
+static Reference< XPropertySet > impl_getConfigurationAccess( const OUString& rPath )
+{
+ Reference < XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory();
+
+ // get configuration provider
+ Reference< XMultiServiceFactory > xConfigProvider = Reference< XMultiServiceFactory >(
+ xFactory->createInstance( sConfigSrvc ), UNO_QUERY_THROW );
+
+ Sequence< Any > aArgs( 1 );
+ NamedValue aValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "NodePath" ) ), makeAny( rPath ) );
+ aArgs[0] <<= aValue;
+ return Reference< XPropertySet >(
+ xConfigProvider->createInstanceWithArguments( sAccessSrvc, aArgs ), UNO_QUERY_THROW );
+}
+
+void Desktop::DoRestartActionsIfNecessary( sal_Bool bQuickStart )
+{
+ if ( bQuickStart )
+ {
+ try
+ {
+ Reference< XPropertySet > xPSet = impl_getConfigurationAccess( OUString( RTL_CONSTASCII_USTRINGPARAM( "org.openoffice.Setup/Office" ) ) );
+
+ OUString sPropName( RTL_CONSTASCII_USTRINGPARAM( "OfficeRestartInProgress" ) );
+ Any aRestart = xPSet->getPropertyValue( sPropName );
+ sal_Bool bRestart = sal_False;
+ if ( ( aRestart >>= bRestart ) && bRestart )
+ {
+ xPSet->setPropertyValue( sPropName, makeAny( sal_False ) );
+ Reference< util::XChangesBatch >( xPSet, UNO_QUERY_THROW )->commitChanges();
+
+ Sequence< Any > aSeq( 1 );
+ sal_Bool bQuickstart = shouldLaunchQuickstart();
+ aSeq[0] <<= bQuickstart;
+
+ Reference < XInitialization > xQuickstart( ::comphelper::getProcessServiceFactory()->createInstance(
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.office.Quickstart" ) ) ),UNO_QUERY_THROW );
+ xQuickstart->initialize( aSeq );
+ }
+ }
+ catch( uno::Exception& )
+ {
+ // this is no critical operation so it should not prevent office from starting
+ }
+ }
+}
+
+void Desktop::SetRestartState()
+{
+ try
+ {
+ Reference< XPropertySet > xPSet = impl_getConfigurationAccess( OUString( RTL_CONSTASCII_USTRINGPARAM( "org.openoffice.Setup/Office" ) ) );
+ OUString sPropName( RTL_CONSTASCII_USTRINGPARAM( "OfficeRestartInProgress" ) );
+ xPSet->setPropertyValue( sPropName, makeAny( sal_True ) );
+ Reference< util::XChangesBatch >( xPSet, UNO_QUERY_THROW )->commitChanges();
+ }
+ catch( uno::Exception& )
+ {
+ // this is no critical operation, ignore the exception
+ }
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/app/appinit.cxx b/desktop/source/app/appinit.cxx
new file mode 100644
index 000000000000..38d425ed703c
--- /dev/null
+++ b/desktop/source/app/appinit.cxx
@@ -0,0 +1,464 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include <algorithm>
+
+#include "app.hxx"
+#include "cmdlineargs.hxx"
+#include "desktopresid.hxx"
+#include "desktop.hrc"
+#include <com/sun/star/registry/XSimpleRegistry.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/uno/Exception.hpp>
+#include <com/sun/star/uno/XCurrentContext.hpp>
+#include <com/sun/star/packages/zip/ZipIOException.hpp>
+
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/container/XContentEnumerationAccess.hpp>
+#include <com/sun/star/ucb/XContentProviderManager.hpp>
+#include <com/sun/star/ucb/XContentProviderFactory.hpp>
+#include <uno/current_context.hxx>
+#include <cppuhelper/servicefactory.hxx>
+#include <cppuhelper/bootstrap.hxx>
+#include <osl/file.hxx>
+#include <osl/module.h>
+#include <osl/security.hxx>
+#include <rtl/uri.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <rtl/bootstrap.hxx>
+#include <comphelper/regpathhelper.hxx>
+#include <tools/debug.hxx>
+#include <tools/tempfile.hxx>
+#include <ucbhelper/configurationkeys.hxx>
+
+#include <cppuhelper/bootstrap.hxx>
+#include <tools/urlobj.hxx>
+#include <tools/rcid.h>
+
+#include <rtl/logfile.hxx>
+#include <rtl/instance.hxx>
+#include <comphelper/processfactory.hxx>
+#include <unotools/localfilehelper.hxx>
+#include <unotools/ucbhelper.hxx>
+#include <unotools/tempfile.hxx>
+#include <ucbhelper/contentbroker.hxx>
+#include <vcl/svapp.hxx>
+#include <unotools/startoptions.hxx>
+#include <unotools/pathoptions.hxx>
+#include <unotools/internaloptions.hxx>
+
+
+#define DEFINE_CONST_OUSTRING(CONSTASCII) OUString(RTL_CONSTASCII_USTRINGPARAM(CONSTASCII))
+
+#define DESKTOP_TEMPDIRNAME "soffice.tmp"
+
+using namespace desktop;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::registry;
+using namespace ::com::sun::star::ucb;
+
+using ::rtl::OUString;
+
+namespace desktop
+{
+
+// -----------------------------------------------------------------------------
+
+static bool configureUcb(bool bServer, rtl::OUString const & rPortalConnect)
+{
+ RTL_LOGFILE_CONTEXT( aLog, "desktop (sb93797) ::configureUcb" );
+ Reference< XMultiServiceFactory >
+ xServiceFactory( comphelper::getProcessServiceFactory() );
+ if (!xServiceFactory.is())
+ {
+ OSL_FAIL("configureUcb(): No XMultiServiceFactory");
+ return false;
+ }
+
+ rtl::OUString aPipe;
+ osl::Security().getUserIdent(aPipe);
+
+ rtl::OUStringBuffer aPortal;
+ if (rPortalConnect.getLength() != 0)
+ {
+ aPortal.append(sal_Unicode(','));
+ aPortal.append(rPortalConnect);
+ }
+
+ Sequence< Any > aArgs(6);
+ aArgs[0]
+ <<= bServer ? rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(UCB_CONFIGURATION_KEY1_SERVER)) :
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(UCB_CONFIGURATION_KEY1_LOCAL));
+ aArgs[1]
+ <<= rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(UCB_CONFIGURATION_KEY2_OFFICE));
+ aArgs[2] <<= rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("PIPE"));
+ aArgs[3] <<= aPipe;
+ aArgs[4] <<= rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("PORTAL"));
+ aArgs[5] <<= aPortal.makeStringAndClear();
+
+ bool ret =
+ ::ucbhelper::ContentBroker::initialize( xServiceFactory, aArgs ) != false;
+
+#ifdef GNOME_VFS_ENABLED
+ // register GnomeUCP if necessary
+ ::ucbhelper::ContentBroker* cb = ::ucbhelper::ContentBroker::get();
+ if(cb) {
+ try {
+ Reference< XCurrentContext > xCurrentContext(
+ getCurrentContext());
+ if (xCurrentContext.is())
+ {
+ Any aValue = xCurrentContext->getValueByName(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "system.desktop-environment" ) )
+ );
+ rtl::OUString aDesktopEnvironment;
+ if ((aValue >>= aDesktopEnvironment)
+ && aDesktopEnvironment.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("GNOME")))
+ {
+ Reference<XContentProviderManager> xCPM =
+ cb->getContentProviderManagerInterface();
+
+
+ //Instanciate GNOME-VFS-UCP in the thread that initialized
+ // GNOME in order to avoid a deadlock that may occure in case UCP gets initialized from
+ // a different thread. The latter may happen when calling the Office remotely via UNO.
+ // THIS IS NOT A FIX, JUST A WORKAROUND!
+
+ try
+ {
+ Reference<XContentProvider> xCP(
+ xServiceFactory->createInstance(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.ucb.GnomeVFSContentProvider"))),
+ UNO_QUERY);
+ if(xCP.is())
+ xCPM->registerContentProvider(
+ xCP,
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".*")),
+ false);
+ } catch (...)
+ {
+ }
+ }
+ }
+ } catch (RuntimeException &e) {
+ }
+ }
+#endif // GNOME_VFS_ENABLED
+
+ return ret;;
+}
+
+Reference< XMultiServiceFactory > Desktop::CreateApplicationServiceManager()
+{
+ RTL_LOGFILE_CONTEXT( aLog, "desktop (cd100003) ::createApplicationServiceManager" );
+
+ try
+ {
+ Reference<XComponentContext> xComponentContext = ::cppu::defaultBootstrap_InitialComponentContext();
+ Reference<XMultiServiceFactory> xMS(xComponentContext->getServiceManager(), UNO_QUERY);
+
+ return xMS;
+ }
+ catch( ::com::sun::star::uno::Exception& )
+ {
+ }
+
+ return Reference< XMultiServiceFactory >();
+}
+
+void Desktop::DestroyApplicationServiceManager( Reference< XMultiServiceFactory >& xSMgr )
+{
+ Reference< XPropertySet > xProps( xSMgr, UNO_QUERY );
+ if ( xProps.is() )
+ {
+ try
+ {
+ Reference< XComponent > xComp;
+ if (xProps->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ))) >>= xComp )
+ {
+ xComp->dispose();
+ }
+ }
+ catch ( UnknownPropertyException& )
+ {
+ }
+ }
+}
+
+void Desktop::RegisterServices( Reference< XMultiServiceFactory >& xSMgr )
+{
+ if( !m_bServicesRegistered )
+ {
+ RTL_LOGFILE_CONTEXT( aLog, "desktop (cd100003) ::registerServices" );
+
+ // read command line parameters
+ ::rtl::OUString conDcp;
+ ::rtl::OUString aClientDisplay;
+ ::rtl::OUString aTmpString;
+ sal_Bool bHeadlessMode = sal_False;
+
+ // interpret command line arguments
+ CommandLineArgs* pCmdLine = GetCommandLineArgs();
+
+ // read accept string from configuration
+ conDcp = SvtStartOptions().GetConnectionURL();
+
+ if ( pCmdLine->GetAcceptString( aTmpString ))
+ conDcp = aTmpString;
+
+ // Headless mode for FAT Office
+ bHeadlessMode = pCmdLine->IsHeadless();
+ if ( bHeadlessMode )
+ Application::EnableHeadlessMode();
+
+ if ( conDcp.getLength() > 0 )
+ {
+ // accept incoming connections (scripting and one rvp)
+ RTL_LOGFILE_CONTEXT( aLog, "desktop (lo119109) desktop::Desktop::createAcceptor()" );
+ createAcceptor(conDcp);
+ }
+
+ // improves parallel processing on Sun ONE Webtop
+ // servicemanager up -> copy user installation
+ if ( pCmdLine->IsServer() )
+ {
+ // Check some mandatory environment states if "-server" is possible. Otherwise ignore
+ // this parameter.
+ Reference< com::sun::star::container::XContentEnumerationAccess > rContent( xSMgr , UNO_QUERY );
+ if( rContent.is() )
+ {
+ OUString sPortalService = OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.portal.InstallUser" ) );
+ Reference < com::sun::star::container::XEnumeration > rEnum = rContent->createContentEnumeration( sPortalService );
+ if ( !rEnum.is() )
+ {
+ // Reset server parameter so it is ignored in the furthermore startup process
+ pCmdLine->SetBoolParam( CommandLineArgs::CMD_BOOLPARAM_SERVER, sal_False );
+ }
+ }
+ }
+
+ ::rtl::OUString aPortalConnect;
+ bool bServer = (bool)pCmdLine->IsServer();
+
+ pCmdLine->GetPortalConnectString( aPortalConnect );
+ if ( !configureUcb( bServer, aPortalConnect ) )
+ {
+ OSL_FAIL( "Can't configure UCB" );
+ throw com::sun::star::uno::Exception(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("RegisterServices, configureUcb")), NULL);
+ }
+
+ CreateTemporaryDirectory();
+ m_bServicesRegistered = true;
+ }
+}
+
+namespace
+{
+ struct acceptorMap : public rtl::Static< AcceptorMap, acceptorMap > {};
+ struct CurrentTempURL : public rtl::Static< String, CurrentTempURL > {};
+}
+
+static sal_Bool bAccept = sal_False;
+
+void Desktop::createAcceptor(const OUString& aAcceptString)
+{
+ // check whether the requested acceptor already exists
+ AcceptorMap &rMap = acceptorMap::get();
+ AcceptorMap::const_iterator pIter = rMap.find(aAcceptString);
+ if (pIter == rMap.end() ) {
+
+ Sequence< Any > aSeq( 2 );
+ aSeq[0] <<= aAcceptString;
+ aSeq[1] <<= bAccept;
+ Reference<XInitialization> rAcceptor(
+ ::comphelper::getProcessServiceFactory()->createInstance(
+ OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.office.Acceptor" ))), UNO_QUERY );
+ if ( rAcceptor.is() ) {
+ try{
+ rAcceptor->initialize( aSeq );
+ rMap.insert(AcceptorMap::value_type(aAcceptString, rAcceptor));
+ } catch (com::sun::star::uno::Exception&) {
+ // no error handling needed...
+ // acceptor just won't come up
+ OSL_FAIL("Acceptor could not be created.");
+ }
+ } else {
+ // there is already an acceptor with this description
+ OSL_FAIL("Acceptor already exists.");
+ }
+
+ }
+}
+
+class enable
+{
+ private:
+ Sequence<Any> m_aSeq;
+ public:
+ enable() : m_aSeq(1) {
+ m_aSeq[0] <<= sal_True;
+ }
+ void operator() (const AcceptorMap::value_type& val) {
+ if (val.second.is()) {
+ val.second->initialize(m_aSeq);
+ }
+ }
+};
+
+void Desktop::enableAcceptors()
+{
+ RTL_LOGFILE_CONTEXT(aLog, "desktop (lo119109) Desktop::enableAcceptors");
+ if (!bAccept)
+ {
+ // from now on, all new acceptors are enabled
+ bAccept = sal_True;
+ // enable existing acceptors by calling initialize(true)
+ // on all existing acceptors
+ AcceptorMap &rMap = acceptorMap::get();
+ std::for_each(rMap.begin(), rMap.end(), enable());
+ }
+}
+
+void Desktop::destroyAcceptor(const OUString& aAcceptString)
+{
+ // special case stop all acceptors
+ AcceptorMap &rMap = acceptorMap::get();
+ if (aAcceptString.compareToAscii("all") == 0) {
+ rMap.clear();
+
+ } else {
+ // try to remove acceptor from map
+ AcceptorMap::const_iterator pIter = rMap.find(aAcceptString);
+ if (pIter != rMap.end() ) {
+ // remove reference from map
+ // this is the last reference and the acceptor will be destructed
+ rMap.erase(aAcceptString);
+ } else {
+ OSL_FAIL("Found no acceptor to remove");
+ }
+ }
+}
+
+
+void Desktop::DeregisterServices()
+{
+ // stop all acceptors by clearing the map
+ acceptorMap::get().clear();
+}
+
+void Desktop::CreateTemporaryDirectory()
+{
+ RTL_LOGFILE_CONTEXT( aLog, "desktop (cd100003) ::createTemporaryDirectory" );
+
+ ::rtl::OUString aTempBaseURL;
+ try
+ {
+ SvtPathOptions aOpt;
+ aTempBaseURL = aOpt.GetTempPath();
+ }
+ catch ( RuntimeException& e )
+ {
+ // Catch runtime exception here: We have to add language dependent info
+ // to the exception message. Fallback solution uses hard coded string.
+ OUString aMsg;
+ DesktopResId aResId( STR_BOOTSTRAP_ERR_NO_PATHSET_SERVICE );
+ aResId.SetRT( RSC_STRING );
+ if ( aResId.GetResMgr()->IsAvailable( aResId ))
+ aMsg = String( aResId );
+ else
+ aMsg = OUString( RTL_CONSTASCII_USTRINGPARAM( "The path manager is not available.\n" ));
+ e.Message = aMsg + e.Message;
+ throw e;
+ }
+
+ // remove possible old directory and base directory
+ SvtInternalOptions aInternalOpt;
+
+ // set temp base directory
+ sal_Int32 nLength = aTempBaseURL.getLength();
+ if ( aTempBaseURL.matchAsciiL( "/", 1, nLength-1 ) )
+ aTempBaseURL = aTempBaseURL.copy( 0, nLength - 1 );
+
+ String aOldTempURL = aInternalOpt.GetCurrentTempURL();
+ if ( aOldTempURL.Len() > 0 )
+ {
+ // remove old temporary directory
+ ::utl::UCBContentHelper::Kill( aOldTempURL );
+ }
+
+ String aRet;
+ ::rtl::OUString aTempPath( aTempBaseURL );
+
+ // create new current temporary directory
+ ::utl::LocalFileHelper::ConvertURLToPhysicalName( aTempBaseURL, aRet );
+ ::osl::FileBase::getFileURLFromSystemPath( aRet, aTempPath );
+ aTempPath = ::utl::TempFile::SetTempNameBaseDirectory( aTempPath );
+ if ( !aTempPath.getLength() )
+ {
+ ::osl::File::getTempDirURL( aTempBaseURL );
+
+ nLength = aTempBaseURL.getLength();
+ if ( aTempBaseURL.matchAsciiL( "/", 1, nLength-1 ) )
+ aTempBaseURL = aTempBaseURL.copy( 0, nLength - 1 );
+
+ aTempPath = aTempBaseURL;
+ ::osl::FileBase::getFileURLFromSystemPath( aRet, aTempPath );
+ aTempPath = ::utl::TempFile::SetTempNameBaseDirectory( aTempPath );
+ }
+
+ // set new current temporary directory
+ ::utl::LocalFileHelper::ConvertPhysicalNameToURL( aTempPath, aRet );
+ aInternalOpt.SetCurrentTempURL( aRet );
+ CurrentTempURL::get() = aRet;
+}
+
+void Desktop::RemoveTemporaryDirectory()
+{
+ RTL_LOGFILE_CONTEXT( aLog, "desktop (cd100003) ::removeTemporaryDirectory" );
+
+ // remove current temporary directory
+ String &rCurrentTempURL = CurrentTempURL::get();
+ if ( rCurrentTempURL.Len() > 0 )
+ {
+ if ( ::utl::UCBContentHelper::Kill( rCurrentTempURL ) )
+ SvtInternalOptions().SetCurrentTempURL( String() );
+ }
+}
+
+} // namespace desktop
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/app/appinit.hxx b/desktop/source/app/appinit.hxx
new file mode 100644
index 000000000000..b4a756aa31ee
--- /dev/null
+++ b/desktop/source/app/appinit.hxx
@@ -0,0 +1,53 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _DESKTOP_APPINIT_HXX_
+#define _DESKTOP_APPINIT_HXX_
+
+#include <com/sun/star/uno/Reference.h>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+
+namespace desktop
+{
+
+::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > createApplicationServiceManager();
+
+sal_Bool InitializeInstallation( const rtl::OUString& rAppFilename );
+void registerServices( ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xSMgr );
+void deregisterServices();
+
+void destroyApplicationServiceManager( ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xSMgr );
+
+void createTemporaryDirectory();
+void removeTemporaryDirectory();
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/app/appsys.cxx b/desktop/source/app/appsys.cxx
new file mode 100644
index 000000000000..47c7778e56e1
--- /dev/null
+++ b/desktop/source/app/appsys.cxx
@@ -0,0 +1,70 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include "appsys.hxx"
+
+#ifdef WNT
+
+#include <rtl/ustring.hxx>
+#include <tools/solar.h>
+#include <tools/urlobj.hxx>
+
+#include <windows.h>
+
+
+#define U2S(STRING) ::rtl::OUStringToOString(STRING, RTL_TEXTENCODING_UTF8)
+
+namespace desktop
+{
+
+void FATToVFat_Impl( String& aName )
+{
+ INetURLObject aObj( aName );
+ if ( aObj.GetProtocol() == INET_PROT_FILE )
+ {
+ WIN32_FIND_DATA aData;
+ HANDLE h = FindFirstFile( U2S(aName).getStr(), &aData );
+ if ( h )
+ {
+ // Change FAT short filename into VFAT long filename
+ aObj.removeSegment();
+ aObj.insertName( String::CreateFromAscii( aData.cFileName ) );
+ aName = aObj.PathToFileName();
+ FindClose( h );
+ }
+ }
+}
+
+}
+
+#endif // WNT
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/app/appsys.hxx b/desktop/source/app/appsys.hxx
new file mode 100644
index 000000000000..d2f13ff0aace
--- /dev/null
+++ b/desktop/source/app/appsys.hxx
@@ -0,0 +1,45 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _DESKTOP_APPSYS_HXX_
+#define _DESKTOP_APPSYS_HXX_
+
+#include <tools/string.hxx>
+
+namespace desktop
+{
+
+#ifdef WNT
+void FATToVFat_Impl( String& aName );
+#endif
+
+}
+
+#endif // _DESKTOP_APPSYS_HXX_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/app/check_ext_deps.cxx b/desktop/source/app/check_ext_deps.cxx
new file mode 100644
index 000000000000..fbc5136518c3
--- /dev/null
+++ b/desktop/source/app/check_ext_deps.cxx
@@ -0,0 +1,432 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include "osl/file.hxx"
+#include "osl/mutex.hxx"
+
+#include <rtl/bootstrap.hxx>
+#include <rtl/ustring.hxx>
+#include <rtl/logfile.hxx>
+#include "cppuhelper/compbase3.hxx"
+
+#include "vcl/wrkwin.hxx"
+#include "vcl/timer.hxx"
+
+#include <unotools/configmgr.hxx>
+#include "toolkit/helper/vclunohelper.hxx"
+
+#include <comphelper/processfactory.hxx>
+#include <comphelper/sequence.hxx>
+#include <cppuhelper/bootstrap.hxx>
+#include <com/sun/star/ucb/XCommandEnvironment.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/NamedValue.hpp>
+#include "com/sun/star/deployment/XPackage.hpp"
+#include "com/sun/star/deployment/ExtensionManager.hpp"
+#include "com/sun/star/deployment/LicenseException.hpp"
+#include "com/sun/star/deployment/ui/LicenseDialog.hpp"
+#include <com/sun/star/task/XJob.hpp>
+#include <com/sun/star/task/XJobExecutor.hpp>
+#include <com/sun/star/task/XInteractionApprove.hpp>
+#include <com/sun/star/task/XInteractionAbort.hpp>
+#include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
+#include "com/sun/star/ui/dialogs/ExecutableDialogResults.hpp"
+#include <com/sun/star/util/XChangesBatch.hpp>
+
+#include "app.hxx"
+
+#include "../deployment/inc/dp_misc.h"
+
+using rtl::OUString;
+using namespace desktop;
+using namespace com::sun::star;
+
+#define UNISTRING(s) OUString(RTL_CONSTASCII_USTRINGPARAM(s))
+
+namespace
+{
+//For use with XExtensionManager.synchronize
+class SilentCommandEnv
+ : public ::cppu::WeakImplHelper3< ucb::XCommandEnvironment,
+ task::XInteractionHandler,
+ ucb::XProgressHandler >
+{
+ Desktop *mpDesktop;
+ sal_Int32 mnLevel;
+ sal_Int32 mnProgress;
+
+public:
+ SilentCommandEnv( Desktop* pDesktop );
+ virtual ~SilentCommandEnv();
+
+ // XCommandEnvironment
+ virtual uno::Reference<task::XInteractionHandler > SAL_CALL
+ getInteractionHandler() throw (uno::RuntimeException);
+ virtual uno::Reference<ucb::XProgressHandler >
+ SAL_CALL getProgressHandler() throw (uno::RuntimeException);
+
+ // XInteractionHandler
+ virtual void SAL_CALL handle(
+ uno::Reference<task::XInteractionRequest > const & xRequest )
+ throw (uno::RuntimeException);
+
+ // XProgressHandler
+ virtual void SAL_CALL push( uno::Any const & Status )
+ throw (uno::RuntimeException);
+ virtual void SAL_CALL update( uno::Any const & Status )
+ throw (uno::RuntimeException);
+ virtual void SAL_CALL pop() throw (uno::RuntimeException);
+};
+
+//-----------------------------------------------------------------------------
+SilentCommandEnv::SilentCommandEnv( Desktop* pDesktop )
+{
+ mpDesktop = pDesktop;
+ mnLevel = 0;
+ mnProgress = 25;
+}
+
+//-----------------------------------------------------------------------------
+SilentCommandEnv::~SilentCommandEnv()
+{
+ mpDesktop->SetSplashScreenText( OUString() );
+}
+
+//-----------------------------------------------------------------------------
+Reference<task::XInteractionHandler> SilentCommandEnv::getInteractionHandler()
+ throw (uno::RuntimeException)
+{
+ return this;
+}
+
+//-----------------------------------------------------------------------------
+Reference<ucb::XProgressHandler> SilentCommandEnv::getProgressHandler()
+ throw (uno::RuntimeException)
+{
+ return this;
+}
+
+//-----------------------------------------------------------------------------
+// XInteractionHandler
+void SilentCommandEnv::handle( Reference< task::XInteractionRequest> const & xRequest )
+ throw (uno::RuntimeException)
+{
+ deployment::LicenseException licExc;
+
+ uno::Any request( xRequest->getRequest() );
+ bool bApprove = true;
+
+ if ( request >>= licExc )
+ {
+ uno::Reference< uno::XComponentContext > xContext = comphelper_getProcessComponentContext();
+ uno::Reference< ui::dialogs::XExecutableDialog > xDialog(
+ deployment::ui::LicenseDialog::create(
+ xContext, VCLUnoHelper::GetInterface( NULL ),
+ licExc.ExtensionName, licExc.Text ) );
+ sal_Int16 res = xDialog->execute();
+ if ( res == ui::dialogs::ExecutableDialogResults::CANCEL )
+ bApprove = false;
+ else if ( res == ui::dialogs::ExecutableDialogResults::OK )
+ bApprove = true;
+ else
+ {
+ OSL_ASSERT(0);
+ }
+ }
+
+ // We approve everything here
+ uno::Sequence< Reference< task::XInteractionContinuation > > conts( xRequest->getContinuations() );
+ Reference< task::XInteractionContinuation > const * pConts = conts.getConstArray();
+ sal_Int32 len = conts.getLength();
+
+ for ( sal_Int32 pos = 0; pos < len; ++pos )
+ {
+ if ( bApprove )
+ {
+ uno::Reference< task::XInteractionApprove > xInteractionApprove( pConts[ pos ], uno::UNO_QUERY );
+ if ( xInteractionApprove.is() )
+ xInteractionApprove->select();
+ }
+ else
+ {
+ uno::Reference< task::XInteractionAbort > xInteractionAbort( pConts[ pos ], uno::UNO_QUERY );
+ if ( xInteractionAbort.is() )
+ xInteractionAbort->select();
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// XProgressHandler
+void SilentCommandEnv::push( uno::Any const & rStatus )
+ throw (uno::RuntimeException)
+{
+ OUString sText;
+ mnLevel += 1;
+
+ if ( rStatus.hasValue() && ( rStatus >>= sText) )
+ {
+ if ( mnLevel <= 3 )
+ mpDesktop->SetSplashScreenText( sText );
+ else
+ mpDesktop->SetSplashScreenProgress( ++mnProgress );
+ }
+}
+
+//-----------------------------------------------------------------------------
+void SilentCommandEnv::update( uno::Any const & rStatus )
+ throw (uno::RuntimeException)
+{
+ OUString sText;
+ if ( rStatus.hasValue() && ( rStatus >>= sText) )
+ {
+ mpDesktop->SetSplashScreenText( sText );
+ }
+}
+
+//-----------------------------------------------------------------------------
+void SilentCommandEnv::pop() throw (uno::RuntimeException)
+{
+ mnLevel -= 1;
+}
+
+} // end namespace
+
+//-----------------------------------------------------------------------------
+static const OUString sConfigSrvc( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.configuration.ConfigurationProvider" ) );
+static const OUString sAccessSrvc( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.configuration.ConfigurationUpdateAccess" ) );
+//------------------------------------------------------------------------------
+static sal_Int16 impl_showExtensionDialog( uno::Reference< uno::XComponentContext > &xContext )
+{
+ rtl::OUString sServiceName = UNISTRING("com.sun.star.deployment.ui.UpdateRequiredDialog");
+ uno::Reference< uno::XInterface > xService;
+ sal_Int16 nRet = 0;
+
+ uno::Reference< lang::XMultiComponentFactory > xServiceManager( xContext->getServiceManager() );
+ if( !xServiceManager.is() )
+ throw uno::RuntimeException(
+ UNISTRING( "impl_showExtensionDialog(): unable to obtain service manager from component context" ), uno::Reference< uno::XInterface > () );
+
+ xService = xServiceManager->createInstanceWithContext( sServiceName, xContext );
+ uno::Reference< ui::dialogs::XExecutableDialog > xExecuteable( xService, uno::UNO_QUERY );
+ if ( xExecuteable.is() )
+ nRet = xExecuteable->execute();
+
+ return nRet;
+}
+
+//------------------------------------------------------------------------------
+// Check dependencies of all packages
+//------------------------------------------------------------------------------
+static bool impl_checkDependencies( const uno::Reference< uno::XComponentContext > &xContext )
+{
+ uno::Sequence< uno::Sequence< uno::Reference< deployment::XPackage > > > xAllPackages;
+ uno::Reference< deployment::XExtensionManager > xExtensionManager = deployment::ExtensionManager::get( xContext );
+
+ if ( !xExtensionManager.is() )
+ {
+ OSL_FAIL( "Could not get the Extension Manager!" );
+ return true;
+ }
+
+ try {
+ xAllPackages = xExtensionManager->getAllExtensions( uno::Reference< task::XAbortChannel >(),
+ uno::Reference< ucb::XCommandEnvironment >() );
+ }
+ catch ( deployment::DeploymentException & ) { return true; }
+ catch ( ucb::CommandFailedException & ) { return true; }
+ catch ( ucb::CommandAbortedException & ) { return true; }
+ catch ( lang::IllegalArgumentException & e ) {
+ throw uno::RuntimeException( e.Message, e.Context );
+ }
+
+ sal_Int32 nMax = 2;
+#ifdef DEBUG
+ nMax = 3;
+#endif
+
+ for ( sal_Int32 i = 0; i < xAllPackages.getLength(); ++i )
+ {
+ uno::Sequence< uno::Reference< deployment::XPackage > > xPackageList = xAllPackages[i];
+
+ for ( sal_Int32 j = 0; (j<nMax) && (j < xPackageList.getLength()); ++j )
+ {
+ uno::Reference< deployment::XPackage > xPackage = xPackageList[j];
+ if ( xPackage.is() )
+ {
+ bool bRegistered = false;
+ try {
+ beans::Optional< beans::Ambiguous< sal_Bool > > option( xPackage->isRegistered( uno::Reference< task::XAbortChannel >(),
+ uno::Reference< ucb::XCommandEnvironment >() ) );
+ if ( option.IsPresent )
+ {
+ ::beans::Ambiguous< sal_Bool > const & reg = option.Value;
+ if ( reg.IsAmbiguous )
+ bRegistered = false;
+ else
+ bRegistered = reg.Value ? true : false;
+ }
+ else
+ bRegistered = false;
+ }
+ catch ( uno::RuntimeException & ) { throw; }
+ catch ( uno::Exception & exc) {
+ (void) exc;
+ OSL_FAIL( ::rtl::OUStringToOString( exc.Message, RTL_TEXTENCODING_UTF8 ).getStr() );
+ }
+
+ if ( bRegistered )
+ {
+ bool bDependenciesValid = false;
+ try {
+ bDependenciesValid = xPackage->checkDependencies( uno::Reference< ucb::XCommandEnvironment >() );
+ }
+ catch ( deployment::DeploymentException & ) {}
+ if ( ! bDependenciesValid )
+ {
+ return false;
+ }
+ }
+ }
+ }
+ }
+ return true;
+}
+
+//------------------------------------------------------------------------------
+// resets the 'check needed' flag (needed, if aborted)
+//------------------------------------------------------------------------------
+static void impl_setNeedsCompatCheck()
+{
+ try {
+ Reference < XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory();
+ // get configuration provider
+ Reference< XMultiServiceFactory > theConfigProvider = Reference< XMultiServiceFactory >(
+ xFactory->createInstance(sConfigSrvc), UNO_QUERY_THROW);
+
+ Sequence< Any > theArgs(1);
+ beans::NamedValue v( OUString(RTL_CONSTASCII_USTRINGPARAM("NodePath")),
+ makeAny( OUString(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.Setup/Office")) ) );
+ theArgs[0] <<= v;
+ Reference< beans::XPropertySet > pset = Reference< beans::XPropertySet >(
+ theConfigProvider->createInstanceWithArguments( sAccessSrvc, theArgs ), UNO_QUERY_THROW );
+
+ Any value = makeAny( OUString(RTL_CONSTASCII_USTRINGPARAM("never")) );
+
+ pset->setPropertyValue( OUString(RTL_CONSTASCII_USTRINGPARAM("LastCompatibilityCheckID")), value );
+ Reference< util::XChangesBatch >( pset, UNO_QUERY_THROW )->commitChanges();
+ }
+ catch (const Exception&) {}
+}
+
+//------------------------------------------------------------------------------
+static bool impl_check()
+{
+ uno::Reference< uno::XComponentContext > xContext = comphelper_getProcessComponentContext();
+
+ bool bDependenciesValid = impl_checkDependencies( xContext );
+
+ short nRet = 0;
+
+ if ( !bDependenciesValid )
+ nRet = impl_showExtensionDialog( xContext );
+
+ if ( nRet == -1 )
+ {
+ impl_setNeedsCompatCheck();
+ return true;
+ }
+ else
+ return false;
+}
+
+//------------------------------------------------------------------------------
+// to check if we need checking the dependencies of the extensions again, we compare
+// the build id of the office with the one of the last check
+//------------------------------------------------------------------------------
+static bool impl_needsCompatCheck()
+{
+ bool bNeedsCheck = false;
+ rtl::OUString aLastCheckBuildID;
+ rtl::OUString aCurrentBuildID( UNISTRING( "${$OOO_BASE_DIR/program/" SAL_CONFIGFILE("version") ":buildid}" ) );
+ rtl::Bootstrap::expandMacros( aCurrentBuildID );
+
+ try {
+ Reference < XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory();
+ // get configuration provider
+ Reference< XMultiServiceFactory > theConfigProvider = Reference< XMultiServiceFactory >(
+ xFactory->createInstance(sConfigSrvc), UNO_QUERY_THROW);
+
+ Sequence< Any > theArgs(1);
+ beans::NamedValue v( OUString(RTL_CONSTASCII_USTRINGPARAM("NodePath")),
+ makeAny( OUString(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.Setup/Office")) ) );
+ theArgs[0] <<= v;
+ Reference< beans::XPropertySet > pset = Reference< beans::XPropertySet >(
+ theConfigProvider->createInstanceWithArguments( sAccessSrvc, theArgs ), UNO_QUERY_THROW );
+
+ Any result = pset->getPropertyValue( OUString(RTL_CONSTASCII_USTRINGPARAM("LastCompatibilityCheckID")) );
+
+ result >>= aLastCheckBuildID;
+ if ( aLastCheckBuildID != aCurrentBuildID )
+ {
+ bNeedsCheck = true;
+ result <<= aCurrentBuildID;
+ pset->setPropertyValue( OUString(RTL_CONSTASCII_USTRINGPARAM("LastCompatibilityCheckID")), result );
+ Reference< util::XChangesBatch >( pset, UNO_QUERY_THROW )->commitChanges();
+ }
+#ifdef DEBUG
+ bNeedsCheck = true;
+#endif
+ }
+ catch (const Exception&) {}
+
+ return bNeedsCheck;
+}
+
+//------------------------------------------------------------------------------
+// Do we need to check the dependencies of the extensions?
+// When there are unresolved issues, we can't continue with startup
+sal_Bool Desktop::CheckExtensionDependencies()
+{
+ sal_Bool bAbort = false;
+
+ if ( impl_needsCompatCheck() )
+ bAbort = impl_check();
+
+ return bAbort;
+}
+
+void Desktop::SynchronizeExtensionRepositories()
+{
+ RTL_LOGFILE_CONTEXT(aLog,"desktop (jl) ::Desktop::SynchronizeExtensionRepositories");
+ dp_misc::syncRepositories( new SilentCommandEnv( this ) );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/app/checkinstall.cxx b/desktop/source/app/checkinstall.cxx
new file mode 100644
index 000000000000..c0e853d9eef5
--- /dev/null
+++ b/desktop/source/app/checkinstall.cxx
@@ -0,0 +1,122 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include "checkinstall.hxx"
+#include <com/sun/star/beans/XExactName.hpp>
+#include <com/sun/star/beans/XMaterialHolder.hpp>
+#include <com/sun/star/container/XContentEnumerationAccess.hpp>
+#include <com/sun/star/util/Date.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <comphelper/processfactory.hxx>
+#include <vcl/msgbox.hxx>
+#include <tools/date.hxx>
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::beans;
+
+using ::rtl::OUString;
+
+namespace desktop
+{
+
+sal_Bool CheckInstallation( OUString& rTitle )
+{
+ try
+ {
+ Reference< XMultiServiceFactory > xSMgr = ::comphelper::getProcessServiceFactory();
+ Reference< XExactName > xExactName( xSMgr->createInstance(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.comp.desktop.Evaluation" ))),
+ UNO_QUERY );
+ if ( xExactName.is() )
+ {
+ try
+ {
+ rTitle = xExactName->getExactName( rTitle );
+ Reference< XMaterialHolder > xMaterialHolder( xExactName, UNO_QUERY );
+ if ( xMaterialHolder.is() )
+ {
+ com::sun::star::util::Date aExpirationDate;
+ Any a = xMaterialHolder->getMaterial();
+ if ( a >>= aExpirationDate )
+ {
+ Date aToday;
+ Date aTimeBombDate( aExpirationDate.Day, aExpirationDate.Month, aExpirationDate.Year );
+ if ( aToday > aTimeBombDate )
+ {
+ InfoBox aInfoBox( NULL, String::CreateFromAscii( "This version has expired" ) );
+ aInfoBox.Execute();
+ return sal_False;
+ }
+ }
+
+ return sal_True;
+ }
+ else
+ {
+ InfoBox aInfoBox( NULL, rTitle );
+ aInfoBox.Execute();
+ return sal_False;
+ }
+ }
+ catch ( RuntimeException& )
+ {
+ // Evaluation version expired!
+ return sal_False;
+ }
+ }
+ else
+ {
+ Reference< com::sun::star::container::XContentEnumerationAccess > rContent( xSMgr , UNO_QUERY );
+ if( rContent.is() )
+ {
+ OUString sEvalService = OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.office.Evaluation" ) );
+ Reference < com::sun::star::container::XEnumeration > rEnum = rContent->createContentEnumeration( sEvalService );
+ if ( rEnum.is() )
+ {
+ InfoBox aInfoBox( NULL, rTitle );
+ aInfoBox.Execute();
+ return sal_False;
+ }
+ }
+ }
+ }
+ catch(Exception)
+ {
+ }
+
+ return sal_True;
+}
+
+} // namespace desktop
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/app/checkinstall.hxx b/desktop/source/app/checkinstall.hxx
new file mode 100644
index 000000000000..a4ee8c05c9ef
--- /dev/null
+++ b/desktop/source/app/checkinstall.hxx
@@ -0,0 +1,45 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _DESKTOP_CHECKINSTALL_HXX_
+#define _DESKTOP_CHECKINSTALL_HXX_
+
+#include <sal/types.h>
+#include <rtl/ustring.hxx>
+
+
+namespace desktop
+{
+
+sal_Bool CheckInstallation( rtl::OUString& rTitle );
+
+}
+
+#endif // _DESKTOP_CHECKINSTALL_HXX_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/app/cmdlineargs.cxx b/desktop/source/app/cmdlineargs.cxx
new file mode 100644
index 000000000000..6885021718bc
--- /dev/null
+++ b/desktop/source/app/cmdlineargs.cxx
@@ -0,0 +1,1008 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+#include <cmdlineargs.hxx>
+#include <vcl/svapp.hxx>
+#include <rtl/uri.hxx>
+#include <rtl/ustring.hxx>
+#include "rtl/process.h"
+#include <comphelper/processfactory.hxx>
+#include <com/sun/star/uri/XExternalUriReferenceTranslator.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/uno/Reference.hxx>
+#include "tools/getprocessworkingdir.hxx"
+
+#include <svl/documentlockfile.hxx>
+
+#include <cstdio>
+
+using namespace com::sun::star::lang;
+using namespace com::sun::star::uri;
+using namespace com::sun::star::uno;
+
+using ::rtl::OUString;
+
+namespace desktop
+{
+
+namespace {
+
+class ExtCommandLineSupplier: public CommandLineArgs::Supplier {
+public:
+ explicit ExtCommandLineSupplier():
+ m_count(rtl_getAppCommandArgCount()),
+ m_index(0)
+ {
+ rtl::OUString url;
+ if (tools::getProcessWorkingDir(url)) {
+ m_cwdUrl.reset(url);
+ }
+ }
+
+ virtual ~ExtCommandLineSupplier() {}
+
+ virtual boost::optional< rtl::OUString > getCwdUrl() { return m_cwdUrl; }
+
+ virtual bool next(rtl::OUString * argument) {
+ OSL_ASSERT(argument != NULL);
+ if (m_index < m_count) {
+ rtl_getAppCommandArg(m_index++, &argument->pData);
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+private:
+ boost::optional< rtl::OUString > m_cwdUrl;
+ sal_uInt32 m_count;
+ sal_uInt32 m_index;
+};
+
+}
+
+static CommandLineArgs::BoolParam aModuleGroupDefinition[] =
+{
+ CommandLineArgs::CMD_BOOLPARAM_WRITER,
+ CommandLineArgs::CMD_BOOLPARAM_CALC,
+ CommandLineArgs::CMD_BOOLPARAM_DRAW,
+ CommandLineArgs::CMD_BOOLPARAM_IMPRESS,
+ CommandLineArgs::CMD_BOOLPARAM_GLOBAL,
+ CommandLineArgs::CMD_BOOLPARAM_MATH,
+ CommandLineArgs::CMD_BOOLPARAM_WEB,
+ CommandLineArgs::CMD_BOOLPARAM_BASE
+};
+
+CommandLineArgs::GroupDefinition CommandLineArgs::m_pGroupDefinitions[ CommandLineArgs::CMD_GRPID_COUNT ] =
+{
+ { 8, aModuleGroupDefinition }
+};
+
+CommandLineArgs::Supplier::Exception::Exception() {}
+
+CommandLineArgs::Supplier::Exception::Exception(Exception const &) {}
+
+CommandLineArgs::Supplier::Exception::~Exception() {}
+
+CommandLineArgs::Supplier::Exception &
+CommandLineArgs::Supplier::Exception::operator =(Exception const &)
+{ return *this; }
+
+CommandLineArgs::Supplier::~Supplier() {}
+
+// intialize class with command line parameters from process environment
+CommandLineArgs::CommandLineArgs()
+{
+ ResetParamValues();
+ ExtCommandLineSupplier s;
+ ParseCommandLine_Impl( s );
+}
+
+CommandLineArgs::CommandLineArgs( Supplier& supplier )
+{
+ ResetParamValues();
+ ParseCommandLine_Impl( supplier );
+}
+
+// ----------------------------------------------------------------------------
+
+void CommandLineArgs::ParseCommandLine_Impl( Supplier& supplier )
+{
+ m_cwdUrl = supplier.getCwdUrl();
+ Reference<XMultiServiceFactory> xMS(comphelper::getProcessServiceFactory(), UNO_QUERY);
+ OSL_ENSURE(xMS.is(), "CommandLineArgs: no ProcessServiceFactory.");
+
+ Reference< XExternalUriReferenceTranslator > xTranslator(
+ xMS->createInstance(
+ OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.uri.ExternalUriReferenceTranslator"))),
+ UNO_QUERY);
+
+ // parse command line arguments
+ bool bOpenEvent(true);
+ bool bPrintEvent(false);
+ bool bViewEvent(false);
+ bool bStartEvent(false);
+ bool bPrintToEvent(false);
+ bool bPrinterName(false);
+ bool bForceOpenEvent(false);
+ bool bForceNewEvent(false);
+ bool bDisplaySpec(false);
+ bool bOpenDoc(false);
+ bool bConversionEvent(false);
+ bool bConversionParamsEvent(false);
+ bool bBatchPrintEvent(false);
+ bool bBatchPrinterNameEvent(false);
+ bool bConversionOutEvent(false);
+
+ m_eArgumentCount = NONE;
+
+ for (;;)
+ {
+ ::rtl::OUString aArg;
+ if ( !supplier.next( &aArg ) )
+ {
+ break;
+ }
+ // convert file URLs to internal form
+ if (aArg.indexOfAsciiL(RTL_CONSTASCII_STRINGPARAM("file:"))==0 &&
+ xTranslator.is())
+ {
+ OUString tmp(xTranslator->translateToInternal(aArg));
+ if (tmp.getLength() > 0)
+ aArg = tmp;
+ }
+
+ if ( aArg.getLength() > 0 )
+ {
+ m_eArgumentCount = m_eArgumentCount == NONE ? ONE : MANY;
+ ::rtl::OUString oArg;
+ if ( !InterpretCommandLineParameter( aArg, oArg ))
+ {
+ if ( aArg.toChar() == '-' )
+ {
+ // handle this argument as an option
+ if ( aArg.equalsIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM("-n")))
+ {
+ // force new documents based on the following documents
+ bForceNewEvent = true;
+ bOpenEvent = false;
+ bForceOpenEvent = false;
+ bPrintToEvent = false;
+ bPrintEvent = false;
+ bViewEvent = false;
+ bStartEvent = false;
+ bDisplaySpec = false;
+ }
+ else if ( aArg.equalsIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM( "-o" )))
+ {
+ // force open documents regardless if they are templates or not
+ bForceOpenEvent = true;
+ bOpenEvent = false;
+ bForceNewEvent = false;
+ bPrintToEvent = false;
+ bPrintEvent = false;
+ bViewEvent = false;
+ bStartEvent = false;
+ bDisplaySpec = false;
+ }
+ else if ( aArg.equalsIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM( "-pt" )))
+ {
+ // Print to special printer
+ bPrintToEvent = true;
+ bPrinterName = true;
+ bPrintEvent = false;
+ bOpenEvent = false;
+ bForceNewEvent = false;
+ bViewEvent = false;
+ bStartEvent = false;
+ bDisplaySpec = false;
+ bForceOpenEvent = false;
+ }
+ else if ( aArg.equalsIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM( "-p" )))
+ {
+ // Print to default printer
+ bPrintEvent = true;
+ bPrintToEvent = false;
+ bOpenEvent = false;
+ bForceNewEvent = false;
+ bForceOpenEvent = false;
+ bViewEvent = false;
+ bStartEvent = false;
+ bDisplaySpec = false;
+ }
+ else if ( aArg.equalsIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM( "-view" )))
+ {
+ // open in viewmode
+ bOpenEvent = false;
+ bPrintEvent = false;
+ bPrintToEvent = false;
+ bForceNewEvent = false;
+ bForceOpenEvent = false;
+ bViewEvent = true;
+ bStartEvent = false;
+ bDisplaySpec = false;
+ }
+ else if ( aArg.equalsIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM( "-show" )))
+ {
+ // open in viewmode
+ bOpenEvent = false;
+ bViewEvent = false;
+ bStartEvent = true;
+ bPrintEvent = false;
+ bPrintToEvent = false;
+ bForceNewEvent = false;
+ bForceOpenEvent = false;
+ bDisplaySpec = false;
+ }
+ else if ( oArg.equalsIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM("display")))
+ {
+ // set display
+ bOpenEvent = false;
+ bPrintEvent = false;
+ bForceOpenEvent = false;
+ bPrintToEvent = false;
+ bForceNewEvent = false;
+ bViewEvent = false;
+ bStartEvent = false;
+ bDisplaySpec = true;
+ }
+ else if ( oArg.equalsIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM("language")))
+ {
+ bOpenEvent = false;
+ bPrintEvent = false;
+ bForceOpenEvent = false;
+ bPrintToEvent = false;
+ bForceNewEvent = false;
+ bViewEvent = false;
+ bStartEvent = false;
+ bDisplaySpec = false;
+ }
+ else if ( oArg.equalsIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM("convert-to")))
+ {
+ bOpenEvent = false;
+ bConversionEvent = true;
+ bConversionParamsEvent = true;
+ }
+ else if ( oArg.equalsIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM("print-to-file")))
+ {
+ bOpenEvent = false;
+ bBatchPrintEvent = true;
+ }
+ else if ( oArg.equalsIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM("printer-name")) &&
+ bBatchPrintEvent )
+ {
+ bBatchPrinterNameEvent = true;
+ }
+ else if ( oArg.equalsIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM("outdir")) &&
+ (bConversionEvent || bBatchPrintEvent) )
+ {
+ bConversionOutEvent = true;
+ }
+ }
+ else
+ {
+ if ( bPrinterName && bPrintToEvent )
+ {
+ // first argument after "-pt" this must be the printer name
+ AddStringListParam_Impl( CMD_STRINGPARAM_PRINTERNAME, aArg );
+ bPrinterName = false;
+ }
+ else if ( bConversionParamsEvent && bConversionEvent )
+ {
+ // first argument must be the the params
+ AddStringListParam_Impl( CMD_STRINGPARAM_CONVERSIONPARAMS, aArg );
+ bConversionParamsEvent = false;
+ }
+ else if ( bBatchPrinterNameEvent && bBatchPrintEvent )
+ {
+ // first argument is the printer name
+ AddStringListParam_Impl( CMD_STRINGPARAM_PRINTERNAME, aArg );
+ bBatchPrinterNameEvent = false;
+ }
+ else if ( (bConversionEvent || bBatchPrintEvent) && bConversionOutEvent )
+ {
+ AddStringListParam_Impl( CMD_STRINGPARAM_CONVERSIONOUT, aArg );
+ bConversionOutEvent = false;
+ }
+ else
+ {
+ if( bOpenEvent || bViewEvent || bForceNewEvent || bForceOpenEvent )
+ {
+ if( aArg.matchIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM("::ODMA")) )
+ {
+ ::rtl::OUString sArg(RTL_CONSTASCII_USTRINGPARAM("vnd.sun.star.odma:/"));
+ sArg += aArg;
+ aArg = sArg;
+ }
+ }
+ // handle this argument as a filename
+ if ( bOpenEvent )
+ {
+ AddStringListParam_Impl( CMD_STRINGPARAM_OPENLIST, aArg );
+ bOpenDoc = true;
+ }
+ else if ( bViewEvent )
+ {
+ AddStringListParam_Impl( CMD_STRINGPARAM_VIEWLIST, aArg );
+ bOpenDoc = true;
+ }
+ else if ( bStartEvent )
+ {
+ AddStringListParam_Impl( CMD_STRINGPARAM_STARTLIST, aArg );
+ bOpenDoc = true;
+ }
+ else if ( bPrintEvent )
+ {
+ AddStringListParam_Impl( CMD_STRINGPARAM_PRINTLIST, aArg );
+ bOpenDoc = true;
+ }
+ else if ( bPrintToEvent )
+ {
+ AddStringListParam_Impl( CMD_STRINGPARAM_PRINTTOLIST, aArg );
+ bOpenDoc = true;
+ }
+ else if ( bForceNewEvent )
+ {
+ AddStringListParam_Impl( CMD_STRINGPARAM_FORCENEWLIST, aArg );
+ bOpenDoc = true;
+ }
+ else if ( bForceOpenEvent )
+ {
+ AddStringListParam_Impl( CMD_STRINGPARAM_FORCEOPENLIST, aArg );
+ bOpenDoc = true;
+ }
+ else if ( bDisplaySpec )
+ {
+ AddStringListParam_Impl( CMD_STRINGPARAM_DISPLAY, aArg );
+ bDisplaySpec = false; // only one display, not a lsit
+ bOpenEvent = true; // set back to standard
+ }
+ else if ( bConversionEvent || bBatchPrintEvent )
+ AddStringListParam_Impl( CMD_STRINGPARAM_CONVERSIONLIST, aArg );
+ }
+ }
+ }
+ }
+ }
+
+ if ( bOpenDoc )
+ m_bDocumentArgs = true;
+}
+
+void CommandLineArgs::AddStringListParam_Impl( StringParam eParam, const rtl::OUString& aParam )
+{
+ OSL_ASSERT( eParam >= 0 && eParam < CMD_STRINGPARAM_COUNT );
+ if ( m_aStrParams[eParam].getLength() )
+ m_aStrParams[eParam] += ::rtl::OUString::valueOf( (sal_Unicode)APPEVENT_PARAM_DELIMITER );
+ m_aStrParams[eParam] += aParam;
+ m_aStrSetParams[eParam] = sal_True;
+}
+
+void CommandLineArgs::SetBoolParam_Impl( BoolParam eParam, sal_Bool bValue )
+{
+ OSL_ASSERT( eParam >= 0 && eParam < CMD_BOOLPARAM_COUNT );
+ m_aBoolParams[eParam] = bValue;
+}
+
+sal_Bool CommandLineArgs::InterpretCommandLineParameter( const ::rtl::OUString& aArg, ::rtl::OUString& oArg )
+{
+ bool bDeprecated = false;
+ if (aArg.matchIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM("--")))
+ {
+ oArg = ::rtl::OUString(aArg.getStr()+2, aArg.getLength()-2);
+ }
+ else if (aArg.toChar() == '-')
+ {
+ bDeprecated = true;
+ oArg = ::rtl::OUString(aArg.getStr()+1, aArg.getLength()-1);
+ }
+ else
+ {
+ return sal_False;
+ }
+
+ if ( oArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "minimized" )) == sal_True )
+ {
+ SetBoolParam_Impl( CMD_BOOLPARAM_MINIMIZED, sal_True );
+ }
+ else if ( oArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "invisible" )) == sal_True )
+ {
+ SetBoolParam_Impl( CMD_BOOLPARAM_INVISIBLE, sal_True );
+ }
+ else if ( oArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "norestore" )) == sal_True )
+ {
+ SetBoolParam_Impl( CMD_BOOLPARAM_NORESTORE, sal_True );
+ }
+ else if ( oArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "nodefault" )) == sal_True )
+ {
+ SetBoolParam_Impl( CMD_BOOLPARAM_NODEFAULT, sal_True );
+ }
+ else if ( oArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "bean" )) == sal_True )
+ {
+ SetBoolParam_Impl( CMD_BOOLPARAM_BEAN, sal_True );
+ }
+ else if ( oArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "plugin" )) == sal_True )
+ {
+ SetBoolParam_Impl( CMD_BOOLPARAM_PLUGIN, sal_True );
+ }
+ else if ( oArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "server" )) == sal_True )
+ {
+ SetBoolParam_Impl( CMD_BOOLPARAM_SERVER, sal_True );
+ }
+ else if ( oArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "headless" )) == sal_True )
+ {
+ // Headless means also invisibile, so set this parameter to true!
+ SetBoolParam_Impl( CMD_BOOLPARAM_HEADLESS, sal_True );
+ SetBoolParam_Impl( CMD_BOOLPARAM_INVISIBLE, sal_True );
+ }
+ else if ( oArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "quickstart" )) == sal_True )
+ {
+#if defined(ENABLE_QUICKSTART_APPLET)
+ SetBoolParam_Impl( CMD_BOOLPARAM_QUICKSTART, sal_True );
+#endif
+ SetBoolParam_Impl( CMD_BOOLPARAM_NOQUICKSTART, sal_False );
+ }
+ else if ( oArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "quickstart=no" )))
+ {
+ SetBoolParam_Impl( CMD_BOOLPARAM_NOQUICKSTART, sal_True );
+ SetBoolParam_Impl( CMD_BOOLPARAM_QUICKSTART, sal_False );
+ }
+ else if ( oArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "terminate_after_init" )) == sal_True )
+ {
+ SetBoolParam_Impl( CMD_BOOLPARAM_TERMINATEAFTERINIT, sal_True );
+ }
+ else if ( oArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "nofirststartwizard" )) == sal_True )
+ {
+ SetBoolParam_Impl( CMD_BOOLPARAM_NOFIRSTSTARTWIZARD, sal_True );
+ }
+ else if ( oArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "nologo" )) == sal_True )
+ {
+ SetBoolParam_Impl( CMD_BOOLPARAM_NOLOGO, sal_True );
+ }
+ else if ( oArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "nolockcheck" )) == sal_True )
+ {
+ SetBoolParam_Impl( CMD_BOOLPARAM_NOLOCKCHECK, sal_True );
+ // Workaround for automated testing
+ ::svt::DocumentLockFile::AllowInteraction( sal_False );
+ }
+ else if ( oArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "help" ))
+ || aArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "-h" ))
+ || aArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "-?" )))
+ {
+ SetBoolParam_Impl( CMD_BOOLPARAM_HELP, sal_True );
+ }
+ else if ( oArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "helpwriter" )) == sal_True )
+ {
+ SetBoolParam_Impl( CMD_BOOLPARAM_HELPWRITER, sal_True );
+ }
+ else if ( oArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "helpcalc" )) == sal_True )
+ {
+ SetBoolParam_Impl( CMD_BOOLPARAM_HELPCALC, sal_True );
+ }
+ else if ( oArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "helpdraw" )) == sal_True )
+ {
+ SetBoolParam_Impl( CMD_BOOLPARAM_HELPDRAW, sal_True );
+ }
+ else if ( oArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "helpimpress" )) == sal_True )
+ {
+ SetBoolParam_Impl( CMD_BOOLPARAM_HELPIMPRESS, sal_True );
+ }
+ else if ( oArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "helpbase" )) == sal_True )
+ {
+ SetBoolParam_Impl( CMD_BOOLPARAM_HELPBASE, sal_True );
+ }
+ else if ( oArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "helpbasic" )) == sal_True )
+ {
+ SetBoolParam_Impl( CMD_BOOLPARAM_HELPBASIC, sal_True );
+ }
+ else if ( oArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "helpmath" )) == sal_True )
+ {
+ SetBoolParam_Impl( CMD_BOOLPARAM_HELPMATH, sal_True );
+ }
+ else if ( oArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "version" )) == sal_True )
+ {
+ SetBoolParam_Impl( CMD_BOOLPARAM_VERSION, sal_True );
+ }
+ else if ( oArg.matchIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM("splash-pipe=")) )
+ {
+ AddStringListParam_Impl( CMD_STRINGPARAM_SPLASHPIPE, oArg.copy(RTL_CONSTASCII_LENGTH("splash-pipe=")) );
+ }
+#ifdef MACOSX
+ /* #i84053# ignore -psn on Mac
+ Platform dependent #ifdef here is ugly, however this is currently
+ the only platform dependent parameter. Should more appear
+ we should find a better solution
+ */
+ else if ( aArg.matchAsciiL(RTL_CONSTASCII_STRINGPARAM("-psn")) )
+ {
+ SetBoolParam_Impl( CMD_BOOLPARAM_PSN, sal_True );
+ return sal_True;
+ }
+#endif
+ else if ( oArg.matchIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM("infilter=")))
+ {
+ AddStringListParam_Impl( CMD_STRINGPARAM_INFILTER, oArg.copy(RTL_CONSTASCII_LENGTH("infilter=")) );
+ }
+ else if ( oArg.matchIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM("accept=")))
+ {
+ AddStringListParam_Impl( CMD_STRINGPARAM_ACCEPT, oArg.copy(RTL_CONSTASCII_LENGTH("accept=")) );
+ }
+ else if ( oArg.matchIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM("unaccept=")))
+ {
+ AddStringListParam_Impl( CMD_STRINGPARAM_UNACCEPT, oArg.copy(RTL_CONSTASCII_LENGTH("unaccept=")) );
+ }
+ else if ( oArg.matchIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM("portal,")))
+ {
+ AddStringListParam_Impl( CMD_STRINGPARAM_PORTAL, oArg.copy(RTL_CONSTASCII_LENGTH("portal,")) );
+ }
+ else if ( oArg.matchIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM("userid")))
+ {
+ if ( oArg.getLength() > RTL_CONSTASCII_LENGTH("userid")+1 )
+ {
+ AddStringListParam_Impl(
+ CMD_STRINGPARAM_USERDIR,
+ ::rtl::Uri::decode( oArg.copy(RTL_CONSTASCII_LENGTH("userid")+1),
+ rtl_UriDecodeWithCharset,
+ RTL_TEXTENCODING_UTF8 ) );
+ }
+ }
+ else if ( oArg.matchIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM("clientdisplay=")))
+ {
+ AddStringListParam_Impl( CMD_STRINGPARAM_CLIENTDISPLAY, oArg.copy(RTL_CONSTASCII_LENGTH("clientdisplay=")) );
+ }
+ else if ( oArg.matchIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM("version=")))
+ {
+ AddStringListParam_Impl( CMD_STRINGPARAM_VERSION, oArg.copy(RTL_CONSTASCII_LENGTH("version=")) );
+ }
+ else if ( oArg.matchIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM("language=")))
+ {
+ AddStringListParam_Impl( CMD_STRINGPARAM_LANGUAGE, oArg.copy(RTL_CONSTASCII_LENGTH("language=")) );
+ }
+ else if ( oArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "writer" )) == sal_True )
+ {
+ sal_Bool bAlreadySet = CheckGroupMembers( CMD_GRPID_MODULE, CMD_BOOLPARAM_WRITER );
+ if ( !bAlreadySet )
+ SetBoolParam_Impl( CMD_BOOLPARAM_WRITER, sal_True );
+ m_bDocumentArgs = true;
+ }
+ else if ( oArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "calc" )) == sal_True )
+ {
+ sal_Bool bAlreadySet = CheckGroupMembers( CMD_GRPID_MODULE, CMD_BOOLPARAM_CALC );
+ if ( !bAlreadySet )
+ SetBoolParam_Impl( CMD_BOOLPARAM_CALC, sal_True );
+ m_bDocumentArgs = true;
+ }
+ else if ( oArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "draw" )) == sal_True )
+ {
+ sal_Bool bAlreadySet = CheckGroupMembers( CMD_GRPID_MODULE, CMD_BOOLPARAM_DRAW );
+ if ( !bAlreadySet )
+ SetBoolParam_Impl( CMD_BOOLPARAM_DRAW, sal_True );
+ m_bDocumentArgs = true;
+ }
+ else if ( oArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "impress" )) == sal_True )
+ {
+ sal_Bool bAlreadySet = CheckGroupMembers( CMD_GRPID_MODULE, CMD_BOOLPARAM_IMPRESS );
+ if ( !bAlreadySet )
+ SetBoolParam_Impl( CMD_BOOLPARAM_IMPRESS, sal_True );
+ m_bDocumentArgs = true;
+ }
+ else if ( oArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "base" )) == sal_True )
+ {
+ sal_Bool bAlreadySet = CheckGroupMembers( CMD_GRPID_MODULE, CMD_BOOLPARAM_BASE );
+ if ( !bAlreadySet )
+ SetBoolParam_Impl( CMD_BOOLPARAM_BASE, sal_True );
+ m_bDocumentArgs = true;
+ }
+ else if ( oArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "global" )) == sal_True )
+ {
+ sal_Bool bAlreadySet = CheckGroupMembers( CMD_GRPID_MODULE, CMD_BOOLPARAM_GLOBAL );
+ if ( !bAlreadySet )
+ SetBoolParam_Impl( CMD_BOOLPARAM_GLOBAL, sal_True );
+ m_bDocumentArgs = true;
+ }
+ else if ( oArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "math" )) == sal_True )
+ {
+ sal_Bool bAlreadySet = CheckGroupMembers( CMD_GRPID_MODULE, CMD_BOOLPARAM_MATH );
+ if ( !bAlreadySet )
+ SetBoolParam_Impl( CMD_BOOLPARAM_MATH, sal_True );
+ m_bDocumentArgs = true;
+ }
+ else if ( oArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "web" )) == sal_True )
+ {
+ sal_Bool bAlreadySet = CheckGroupMembers( CMD_GRPID_MODULE, CMD_BOOLPARAM_WEB );
+ if ( !bAlreadySet )
+ SetBoolParam_Impl( CMD_BOOLPARAM_WEB, sal_True );
+ m_bDocumentArgs = true;
+ }
+ else
+ return sal_False;
+
+ if (bDeprecated)
+ {
+ rtl::OString sArg(rtl::OUStringToOString(aArg, RTL_TEXTENCODING_UTF8));
+ fprintf(stderr, "Warning: %s is deprecated. Use -%s instead.\n", sArg.getStr(), sArg.getStr());
+ }
+ return sal_True;
+}
+
+sal_Bool CommandLineArgs::CheckGroupMembers( GroupParamId nGroupId, BoolParam nExcludeMember ) const
+{
+ // Check if at least one bool param out of a group is set. An exclude member can be provided.
+ for ( int i = 0; i < m_pGroupDefinitions[nGroupId].nCount; i++ )
+ {
+ BoolParam nParam = m_pGroupDefinitions[nGroupId].pGroupMembers[i];
+ if ( nParam != nExcludeMember && m_aBoolParams[nParam] )
+ return sal_True;
+ }
+
+ return sal_False;
+}
+
+void CommandLineArgs::ResetParamValues()
+{
+ int i;
+ for ( i = 0; i < CMD_BOOLPARAM_COUNT; i++ )
+ m_aBoolParams[i] = sal_False;
+ for ( i = 0; i < CMD_STRINGPARAM_COUNT; i++ )
+ m_aStrSetParams[i] = sal_False;
+ m_eArgumentCount = NONE;
+ m_bDocumentArgs = false;
+}
+
+void CommandLineArgs::SetBoolParam( BoolParam eParam, sal_Bool bNewValue )
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+
+ OSL_ASSERT( ( eParam >= 0 && eParam < CMD_BOOLPARAM_COUNT ) );
+ m_aBoolParams[eParam] = bNewValue;
+}
+
+const rtl::OUString& CommandLineArgs::GetStringParam( StringParam eParam ) const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+
+ OSL_ASSERT( ( eParam >= 0 && eParam < CMD_STRINGPARAM_COUNT ) );
+ return m_aStrParams[eParam];
+}
+
+sal_Bool CommandLineArgs::IsMinimized() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_aBoolParams[ CMD_BOOLPARAM_MINIMIZED ];
+}
+
+sal_Bool CommandLineArgs::IsInvisible() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_aBoolParams[ CMD_BOOLPARAM_INVISIBLE ];
+}
+
+sal_Bool CommandLineArgs::IsNoRestore() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_aBoolParams[ CMD_BOOLPARAM_NORESTORE ];
+}
+
+sal_Bool CommandLineArgs::IsNoDefault() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_aBoolParams[ CMD_BOOLPARAM_NODEFAULT ];
+}
+
+sal_Bool CommandLineArgs::IsBean() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_aBoolParams[ CMD_BOOLPARAM_BEAN ];
+}
+
+sal_Bool CommandLineArgs::IsServer() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_aBoolParams[ CMD_BOOLPARAM_SERVER ];
+}
+
+sal_Bool CommandLineArgs::IsHeadless() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_aBoolParams[ CMD_BOOLPARAM_HEADLESS ];
+}
+
+sal_Bool CommandLineArgs::IsQuickstart() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_aBoolParams[ CMD_BOOLPARAM_QUICKSTART ];
+}
+
+sal_Bool CommandLineArgs::IsNoQuickstart() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_aBoolParams[ CMD_BOOLPARAM_NOQUICKSTART ];
+}
+
+sal_Bool CommandLineArgs::IsTerminateAfterInit() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_aBoolParams[ CMD_BOOLPARAM_TERMINATEAFTERINIT ];
+}
+
+sal_Bool CommandLineArgs::IsNoLogo() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_aBoolParams[ CMD_BOOLPARAM_NOLOGO ];
+}
+
+sal_Bool CommandLineArgs::IsNoLockcheck() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_aBoolParams[ CMD_BOOLPARAM_NOLOCKCHECK ];
+}
+
+sal_Bool CommandLineArgs::IsHelp() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_aBoolParams[ CMD_BOOLPARAM_HELP ];
+}
+sal_Bool CommandLineArgs::IsHelpWriter() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_aBoolParams[ CMD_BOOLPARAM_HELPWRITER ];
+}
+
+sal_Bool CommandLineArgs::IsHelpCalc() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_aBoolParams[ CMD_BOOLPARAM_HELPCALC ];
+}
+
+sal_Bool CommandLineArgs::IsHelpDraw() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_aBoolParams[ CMD_BOOLPARAM_HELPDRAW ];
+}
+
+sal_Bool CommandLineArgs::IsHelpImpress() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_aBoolParams[ CMD_BOOLPARAM_HELPIMPRESS ];
+}
+
+sal_Bool CommandLineArgs::IsHelpBase() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_aBoolParams[ CMD_BOOLPARAM_HELPBASE ];
+}
+sal_Bool CommandLineArgs::IsHelpMath() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_aBoolParams[ CMD_BOOLPARAM_HELPMATH ];
+}
+sal_Bool CommandLineArgs::IsHelpBasic() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_aBoolParams[ CMD_BOOLPARAM_HELPBASIC ];
+}
+
+sal_Bool CommandLineArgs::IsWriter() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_aBoolParams[ CMD_BOOLPARAM_WRITER ];
+}
+
+sal_Bool CommandLineArgs::IsCalc() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_aBoolParams[ CMD_BOOLPARAM_CALC ];
+}
+
+sal_Bool CommandLineArgs::IsDraw() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_aBoolParams[ CMD_BOOLPARAM_DRAW ];
+}
+
+sal_Bool CommandLineArgs::IsImpress() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_aBoolParams[ CMD_BOOLPARAM_IMPRESS ];
+}
+
+sal_Bool CommandLineArgs::IsBase() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_aBoolParams[ CMD_BOOLPARAM_BASE ];
+}
+
+sal_Bool CommandLineArgs::IsGlobal() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_aBoolParams[ CMD_BOOLPARAM_GLOBAL ];
+}
+
+sal_Bool CommandLineArgs::IsMath() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_aBoolParams[ CMD_BOOLPARAM_MATH ];
+}
+
+sal_Bool CommandLineArgs::IsWeb() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_aBoolParams[ CMD_BOOLPARAM_WEB ];
+}
+
+sal_Bool CommandLineArgs::IsVersion() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_aBoolParams[ CMD_BOOLPARAM_VERSION ];
+}
+
+sal_Bool CommandLineArgs::HasModuleParam() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return CheckGroupMembers( CMD_GRPID_MODULE, CMD_BOOLPARAM_COUNT );
+}
+
+sal_Bool CommandLineArgs::GetPortalConnectString( ::rtl::OUString& rPara ) const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ rPara = m_aStrParams[ CMD_STRINGPARAM_PORTAL ];
+ return m_aStrSetParams[ CMD_STRINGPARAM_PORTAL ];
+}
+
+sal_Bool CommandLineArgs::GetAcceptString( ::rtl::OUString& rPara ) const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ rPara = m_aStrParams[ CMD_STRINGPARAM_ACCEPT ];
+ return m_aStrSetParams[ CMD_STRINGPARAM_ACCEPT ];
+}
+
+sal_Bool CommandLineArgs::GetUnAcceptString( ::rtl::OUString& rPara ) const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ rPara = m_aStrParams[ CMD_STRINGPARAM_UNACCEPT ];
+ return m_aStrSetParams[ CMD_STRINGPARAM_UNACCEPT ];
+}
+
+sal_Bool CommandLineArgs::GetOpenList( ::rtl::OUString& rPara) const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ rPara = m_aStrParams[ CMD_STRINGPARAM_OPENLIST ];
+ return m_aStrSetParams[ CMD_STRINGPARAM_OPENLIST ];
+}
+
+sal_Bool CommandLineArgs::GetViewList( ::rtl::OUString& rPara) const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ rPara = m_aStrParams[ CMD_STRINGPARAM_VIEWLIST ];
+ return m_aStrSetParams[ CMD_STRINGPARAM_VIEWLIST ];
+}
+
+sal_Bool CommandLineArgs::GetStartList( ::rtl::OUString& rPara) const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ rPara = m_aStrParams[ CMD_STRINGPARAM_STARTLIST ];
+ return m_aStrSetParams[ CMD_STRINGPARAM_STARTLIST ];
+}
+
+sal_Bool CommandLineArgs::GetForceOpenList( ::rtl::OUString& rPara) const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ rPara = m_aStrParams[ CMD_STRINGPARAM_FORCEOPENLIST ];
+ return m_aStrSetParams[ CMD_STRINGPARAM_FORCEOPENLIST ];
+}
+
+sal_Bool CommandLineArgs::GetForceNewList( ::rtl::OUString& rPara) const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ rPara = m_aStrParams[ CMD_STRINGPARAM_FORCENEWLIST ];
+ return m_aStrSetParams[ CMD_STRINGPARAM_FORCENEWLIST ];
+}
+
+sal_Bool CommandLineArgs::GetPrintList( ::rtl::OUString& rPara) const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ rPara = m_aStrParams[ CMD_STRINGPARAM_PRINTLIST ];
+ return m_aStrSetParams[ CMD_STRINGPARAM_PRINTLIST ];
+}
+
+sal_Bool CommandLineArgs::GetPrintToList( ::rtl::OUString& rPara ) const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ rPara = m_aStrParams[ CMD_STRINGPARAM_PRINTTOLIST ];
+ return m_aStrSetParams[ CMD_STRINGPARAM_PRINTTOLIST ];
+}
+
+sal_Bool CommandLineArgs::GetPrinterName( ::rtl::OUString& rPara ) const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ rPara = m_aStrParams[ CMD_STRINGPARAM_PRINTERNAME ];
+ return m_aStrSetParams[ CMD_STRINGPARAM_PRINTERNAME ];
+}
+
+sal_Bool CommandLineArgs::GetLanguage( ::rtl::OUString& rPara ) const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ rPara = m_aStrParams[ CMD_STRINGPARAM_LANGUAGE ];
+ return m_aStrSetParams[ CMD_STRINGPARAM_LANGUAGE ];
+}
+
+sal_Bool CommandLineArgs::GetInFilter( ::rtl::OUString& rPara ) const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ rPara = m_aStrParams[ CMD_STRINGPARAM_INFILTER ];
+ return m_aStrSetParams[ CMD_STRINGPARAM_INFILTER ];
+}
+
+sal_Bool CommandLineArgs::GetConversionList( ::rtl::OUString& rPara ) const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ rPara = m_aStrParams[ CMD_STRINGPARAM_CONVERSIONLIST ];
+ return m_aStrSetParams[ CMD_STRINGPARAM_CONVERSIONLIST ];
+}
+
+sal_Bool CommandLineArgs::GetConversionParams( ::rtl::OUString& rPara ) const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ rPara = m_aStrParams[ CMD_STRINGPARAM_CONVERSIONPARAMS ];
+ return m_aStrSetParams[ CMD_STRINGPARAM_CONVERSIONPARAMS ];
+}
+sal_Bool CommandLineArgs::GetConversionOut( ::rtl::OUString& rPara ) const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ rPara = m_aStrParams[ CMD_STRINGPARAM_CONVERSIONOUT ];
+ return m_aStrSetParams[ CMD_STRINGPARAM_CONVERSIONOUT ];
+}
+
+sal_Bool CommandLineArgs::IsEmpty() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_eArgumentCount == NONE;
+}
+
+sal_Bool CommandLineArgs::IsEmptyOrAcceptOnly() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+
+ return m_eArgumentCount == NONE ||
+ ( ( m_eArgumentCount == ONE ) && ( m_aStrParams[ CMD_STRINGPARAM_SPLASHPIPE ].getLength() )) ||
+ ( ( m_eArgumentCount == ONE ) && ( m_aStrParams[ CMD_STRINGPARAM_ACCEPT ].getLength() )) ||
+ ( ( m_eArgumentCount == ONE ) && m_aBoolParams[ CMD_BOOLPARAM_PSN ] );
+}
+
+sal_Bool CommandLineArgs::WantsToLoadDocument() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_bDocumentArgs;
+}
+
+} // namespace desktop
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/app/cmdlineargs.hxx b/desktop/source/app/cmdlineargs.hxx
new file mode 100644
index 000000000000..bd7e24a81147
--- /dev/null
+++ b/desktop/source/app/cmdlineargs.hxx
@@ -0,0 +1,230 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _DESKTOP_COMMANDLINEARGS_HXX_
+#define _DESKTOP_COMMANDLINEARGS_HXX_
+
+#include <rtl/ustring.hxx>
+#include <osl/mutex.hxx>
+#include "boost/optional.hpp"
+
+namespace desktop
+{
+
+class CommandLineArgs
+{
+ public:
+ enum BoolParam // must be zero based!
+ {
+ CMD_BOOLPARAM_MINIMIZED = 0,
+ CMD_BOOLPARAM_INVISIBLE,
+ CMD_BOOLPARAM_NORESTORE,
+ CMD_BOOLPARAM_BEAN,
+ CMD_BOOLPARAM_PLUGIN,
+ CMD_BOOLPARAM_SERVER,
+ CMD_BOOLPARAM_HEADLESS,
+ CMD_BOOLPARAM_QUICKSTART,
+ CMD_BOOLPARAM_NOQUICKSTART,
+ CMD_BOOLPARAM_TERMINATEAFTERINIT,
+ CMD_BOOLPARAM_NOFIRSTSTARTWIZARD,
+ CMD_BOOLPARAM_NOLOGO,
+ CMD_BOOLPARAM_NOLOCKCHECK,
+ CMD_BOOLPARAM_NODEFAULT,
+ CMD_BOOLPARAM_HELP,
+ CMD_BOOLPARAM_WRITER,
+ CMD_BOOLPARAM_CALC,
+ CMD_BOOLPARAM_DRAW,
+ CMD_BOOLPARAM_IMPRESS,
+ CMD_BOOLPARAM_GLOBAL,
+ CMD_BOOLPARAM_MATH,
+ CMD_BOOLPARAM_WEB,
+ CMD_BOOLPARAM_BASE,
+ CMD_BOOLPARAM_HELPWRITER,
+ CMD_BOOLPARAM_HELPCALC,
+ CMD_BOOLPARAM_HELPDRAW,
+ CMD_BOOLPARAM_HELPBASIC,
+ CMD_BOOLPARAM_HELPMATH,
+ CMD_BOOLPARAM_HELPIMPRESS,
+ CMD_BOOLPARAM_HELPBASE,
+ CMD_BOOLPARAM_PSN,
+ CMD_BOOLPARAM_VERSION,
+ CMD_BOOLPARAM_COUNT // must be last element!
+ };
+
+ enum StringParam // must be zero based!
+ {
+ CMD_STRINGPARAM_PORTAL = 0,
+ CMD_STRINGPARAM_SPLASHPIPE,
+ CMD_STRINGPARAM_ACCEPT,
+ CMD_STRINGPARAM_UNACCEPT,
+ CMD_STRINGPARAM_USERDIR,
+ CMD_STRINGPARAM_CLIENTDISPLAY,
+ CMD_STRINGPARAM_OPENLIST,
+ CMD_STRINGPARAM_VIEWLIST,
+ CMD_STRINGPARAM_STARTLIST,
+ CMD_STRINGPARAM_FORCEOPENLIST,
+ CMD_STRINGPARAM_FORCENEWLIST,
+ CMD_STRINGPARAM_PRINTLIST,
+ CMD_STRINGPARAM_VERSION,
+ CMD_STRINGPARAM_PRINTTOLIST,
+ CMD_STRINGPARAM_PRINTERNAME,
+ CMD_STRINGPARAM_CONVERSIONLIST,
+ CMD_STRINGPARAM_CONVERSIONPARAMS,
+ CMD_STRINGPARAM_CONVERSIONOUT,
+ CMD_STRINGPARAM_INFILTER,
+ CMD_STRINGPARAM_DISPLAY,
+ CMD_STRINGPARAM_LANGUAGE,
+ CMD_STRINGPARAM_COUNT // must be last element!
+ };
+
+ enum GroupParamId
+ {
+ CMD_GRPID_MODULE = 0,
+ CMD_GRPID_COUNT
+ };
+
+ struct Supplier
+ {
+ // Thrown from constructors and next:
+ class Exception {
+ public:
+ Exception();
+ Exception(Exception const &);
+ virtual ~Exception();
+ Exception & operator =(Exception const &);
+ };
+
+ virtual ~Supplier();
+ virtual boost::optional< rtl::OUString > getCwdUrl() = 0;
+ virtual bool next(rtl::OUString * argument) = 0;
+ };
+
+ CommandLineArgs();
+ CommandLineArgs( Supplier& supplier );
+
+ boost::optional< rtl::OUString > getCwdUrl() const { return m_cwdUrl; }
+
+ // generic methods to access parameter
+ void SetBoolParam( BoolParam eParam, sal_Bool bNewValue );
+
+ const rtl::OUString& GetStringParam( StringParam eParam ) const;
+
+ // Access to bool parameters
+ sal_Bool IsMinimized() const;
+ sal_Bool IsInvisible() const;
+ sal_Bool IsNoRestore() const;
+ sal_Bool IsNoDefault() const;
+ sal_Bool IsBean() const;
+ sal_Bool IsServer() const;
+ sal_Bool IsHeadless() const;
+ sal_Bool IsQuickstart() const;
+ sal_Bool IsNoQuickstart() const;
+ sal_Bool IsTerminateAfterInit() const;
+ sal_Bool IsNoLogo() const;
+ sal_Bool IsNoLockcheck() const;
+ sal_Bool IsHelp() const;
+ sal_Bool IsHelpWriter() const;
+ sal_Bool IsHelpCalc() const;
+ sal_Bool IsHelpDraw() const;
+ sal_Bool IsHelpImpress() const;
+ sal_Bool IsHelpBase() const;
+ sal_Bool IsHelpMath() const;
+ sal_Bool IsHelpBasic() const;
+ sal_Bool IsWriter() const;
+ sal_Bool IsCalc() const;
+ sal_Bool IsDraw() const;
+ sal_Bool IsImpress() const;
+ sal_Bool IsBase() const;
+ sal_Bool IsGlobal() const;
+ sal_Bool IsMath() const;
+ sal_Bool IsWeb() const;
+ sal_Bool IsVersion() const;
+ sal_Bool HasModuleParam() const;
+ sal_Bool WantsToLoadDocument() const;
+
+ // Access to string parameters
+ sal_Bool GetPortalConnectString( ::rtl::OUString& rPara) const;
+ sal_Bool GetAcceptString( ::rtl::OUString& rPara) const;
+ sal_Bool GetUnAcceptString( ::rtl::OUString& rPara) const;
+ sal_Bool GetOpenList( ::rtl::OUString& rPara) const;
+ sal_Bool GetViewList( ::rtl::OUString& rPara) const;
+ sal_Bool GetStartList( ::rtl::OUString& rPara) const;
+ sal_Bool GetForceOpenList( ::rtl::OUString& rPara) const;
+ sal_Bool GetForceNewList( ::rtl::OUString& rPara) const;
+ sal_Bool GetPrintList( ::rtl::OUString& rPara) const;
+ sal_Bool GetPrintToList( ::rtl::OUString& rPara ) const;
+ sal_Bool GetPrinterName( ::rtl::OUString& rPara ) const;
+ sal_Bool GetLanguage( ::rtl::OUString& rPara ) const;
+ sal_Bool GetInFilter( ::rtl::OUString& rPara ) const;
+ sal_Bool GetConversionList( ::rtl::OUString& rPara ) const;
+ sal_Bool GetConversionParams( ::rtl::OUString& rPara ) const;
+ sal_Bool GetConversionOut( ::rtl::OUString& rPara ) const;
+
+ // Special analyzed states (does not match directly to a command line parameter!)
+ sal_Bool IsPrinting() const;
+ sal_Bool IsEmpty() const;
+ sal_Bool IsEmptyOrAcceptOnly() const;
+
+ private:
+ enum Count { NONE, ONE, MANY };
+
+ struct GroupDefinition
+ {
+ sal_Int32 nCount;
+ BoolParam* pGroupMembers;
+ };
+
+ // no copy and operator=
+ CommandLineArgs( const CommandLineArgs& );
+ CommandLineArgs operator=( const CommandLineArgs& );
+
+ sal_Bool InterpretCommandLineParameter( const ::rtl::OUString&, ::rtl::OUString& );
+ void ParseCommandLine_Impl( Supplier& supplier );
+ void ResetParamValues();
+ sal_Bool CheckGroupMembers( GroupParamId nGroup, BoolParam nExcludeMember ) const;
+
+ void AddStringListParam_Impl( StringParam eParam, const rtl::OUString& aParam );
+ void SetBoolParam_Impl( BoolParam eParam, sal_Bool bValue );
+
+ boost::optional< rtl::OUString > m_cwdUrl;
+ sal_Bool m_aBoolParams[ CMD_BOOLPARAM_COUNT ]; // Stores boolean parameters
+ rtl::OUString m_aStrParams[ CMD_STRINGPARAM_COUNT ]; // Stores string parameters
+ sal_Bool m_aStrSetParams[ CMD_STRINGPARAM_COUNT ]; // Stores if string parameters are provided on cmdline
+ Count m_eArgumentCount; // Number of Args
+ bool m_bDocumentArgs; // A document creation/open/load arg is used
+ mutable ::osl::Mutex m_aMutex;
+
+ // static definition for groups where only one member can be true
+ static GroupDefinition m_pGroupDefinitions[ CMD_GRPID_COUNT ];
+};
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/app/cmdlinehelp.cxx b/desktop/source/app/cmdlinehelp.cxx
new file mode 100644
index 000000000000..00754d91631e
--- /dev/null
+++ b/desktop/source/app/cmdlinehelp.cxx
@@ -0,0 +1,214 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include <stdlib.h>
+#ifdef UNX
+#include <stdio.h>
+#endif
+#include <sal/types.h>
+#include <tools/string.hxx>
+#include <vcl/msgbox.hxx>
+#include <rtl/bootstrap.hxx>
+#include <app.hxx>
+
+#include "desktopresid.hxx"
+#include "desktop.hrc"
+#include "cmdlinehelp.hxx"
+
+namespace desktop
+{
+ // to be able to display the help nicely in a dialog box with propotional font,
+ // we need to split it in chunks...
+ // ___HEAD___
+ // LEFT RIGHT
+ // LEFT RIGHT
+ // LEFT RIGHT
+ // __BOTTOM__
+ // [OK]
+
+ const char *aCmdLineHelp_version =
+ "%PRODUCTNAME %PRODUCTVERSION %PRODUCTEXTENSION %BUILDID\n"\
+ "\n";
+ const char *aCmdLineHelp_head =
+ "Usage: %CMDNAME [options] [documents...]\n"\
+ "\n"\
+ "Options:\n";
+ const char *aCmdLineHelp_left =
+ "--minimized \n"\
+ "--invisible \n"\
+ "--norestore \n"\
+ "--quickstart \n"\
+ "--nologo \n"\
+ "--nolockcheck \n"\
+ "--nodefault \n"\
+ "--headless \n"\
+ "--help/-h/-? \n"\
+ "--version \n"\
+ "--writer \n"\
+ "--calc \n"\
+ "--draw \n"\
+ "--impress \n"\
+ "--base \n"\
+ "--math \n"\
+ "--global \n"\
+ "--web \n"\
+ "-o \n"\
+ "-n \n";
+ const char *aCmdLineHelp_right =
+ "keep startup bitmap minimized.\n"\
+ "no startup screen, no default document and no UI.\n"\
+ "suppress restart/restore after fatal errors.\n"\
+ "starts the quickstart service\n"\
+ "don't show startup screen.\n"\
+ "don't check for remote instances using the installation\n"\
+ "don't start with an empty document\n"\
+ "like invisible but no userinteraction at all.\n"\
+ "show this message and exit.\n"\
+ "display the version information.\n"\
+ "create new text document.\n"\
+ "create new spreadsheet document.\n"\
+ "create new drawing.\n"\
+ "create new presentation.\n"\
+ "create new database.\n"\
+ "create new formula.\n"\
+ "create new global document.\n"\
+ "create new HTML document.\n"\
+ "open documents regardless whether they are templates or not.\n"\
+ "always open documents as new files (use as template).\n";
+ const char *aCmdLineHelp_bottom =
+ "--display <display>\n"\
+ " Specify X-Display to use in Unix/X11 versions.\n"
+ "-p <documents...>\n"\
+ " print the specified documents on the default printer.\n"\
+ "--pt <printer> <documents...>\n"\
+ " print the specified documents on the specified printer.\n"\
+ "--view <documents...>\n"\
+ " open the specified documents in viewer-(readonly-)mode.\n"\
+ "--show <presentation>\n"\
+ " open the specified presentation and start it immediately\n"\
+ "--accept=<accept-string>\n"\
+ " Specify an UNO connect-string to create an UNO acceptor through which\n"\
+ " other programs can connect to access the API\n"\
+ "--unaccept=<accept-string>\n"\
+ " Close an acceptor that was created with -accept=<accept-string>\n"\
+ " Use -unnaccept=all to close all open acceptors\n"\
+ "--infilter=<filter>\n"\
+ " Force an input filter type if possible\n"\
+ " Eg. -infilter=\"Calc Office Open XML\"\n"\
+ "--convert-to output_file_extension[:output_filter_name] [-outdir ouput_dir] files\n"\
+ " Batch convert files.\n"\
+ " If -outdir is not specified then current working dir is used as output_dir.\n"\
+ " Eg. -convert-to pdf *.doc\n"\
+ " -convert-to pdf:writer_pdf_Export -outdir /home/user *.doc\n"\
+ "--print-to-file [-printer-name printer_name] [-outdir ouput_dir] files\n"\
+ " Batch print files to file.\n"\
+ " If -outdir is not specified then current working dir is used as output_dir.\n"\
+ " Eg. -print-to-file *.doc\n"\
+ " -print-to-file -printer-name nasty_lowres_printer -outdir /home/user *.doc\n"\
+ "\nRemaining arguments will be treated as filenames or URLs of documents to open.\n\n";
+
+ void ReplaceStringHookProc( UniString& rStr );
+
+ void displayCmdlineHelp()
+ {
+ // if you put variables in other chunks don't forget to call the replace routines
+ // for those chunks...
+ String aHelpMessage_version(aCmdLineHelp_version, RTL_TEXTENCODING_ASCII_US);
+ String aHelpMessage_head(aCmdLineHelp_head, RTL_TEXTENCODING_ASCII_US);
+ String aHelpMessage_left(aCmdLineHelp_left, RTL_TEXTENCODING_ASCII_US);
+ String aHelpMessage_right(aCmdLineHelp_right, RTL_TEXTENCODING_ASCII_US);
+ String aHelpMessage_bottom(aCmdLineHelp_bottom, RTL_TEXTENCODING_ASCII_US);
+ ReplaceStringHookProc(aHelpMessage_version);
+ ::rtl::OUString aDefault;
+ String aVerId( ::utl::Bootstrap::getBuildIdData( aDefault ));
+ aHelpMessage_version.SearchAndReplaceAscii( "%BUILDID", aVerId );
+ aHelpMessage_head.SearchAndReplaceAscii( "%CMDNAME", String( "soffice", RTL_TEXTENCODING_ASCII_US) );
+#ifdef UNX
+ // on unix use console for output
+ fprintf(stdout, "%s%s",
+ ByteString(aHelpMessage_version, RTL_TEXTENCODING_ASCII_US).GetBuffer(),
+ ByteString(aHelpMessage_head, RTL_TEXTENCODING_ASCII_US).GetBuffer());
+ // merge left and right column
+ int n = aHelpMessage_left.GetTokenCount ('\n');
+ ByteString bsLeft(aHelpMessage_left, RTL_TEXTENCODING_ASCII_US);
+ ByteString bsRight(aHelpMessage_right, RTL_TEXTENCODING_ASCII_US);
+ for ( int i = 0; i < n; i++ )
+ {
+ fprintf(stdout, "%s", bsLeft.GetToken(i, '\n').GetBuffer());
+ fprintf(stdout, "%s\n", bsRight.GetToken(i, '\n').GetBuffer());
+ }
+ fprintf(stdout, "%s", ByteString(aHelpMessage_bottom,
+ RTL_TEXTENCODING_ASCII_US).GetBuffer());
+#else
+ // rest gets a dialog box
+ CmdlineHelpDialog aDlg;
+ String head = aHelpMessage_version;
+ head.Append(aHelpMessage_head);
+ aDlg.m_ftHead.SetText(head);
+ aDlg.m_ftLeft.SetText(aHelpMessage_left);
+ aDlg.m_ftRight.SetText(aHelpMessage_right);
+ aDlg.m_ftBottom.SetText(aHelpMessage_bottom);
+ aDlg.Execute();
+#endif
+ }
+
+ void displayVersion()
+ {
+ String aVersionMsg(aCmdLineHelp_version, RTL_TEXTENCODING_ASCII_US);
+ ReplaceStringHookProc(aVersionMsg);
+ ::rtl::OUString aDefault;
+ String aVerId = ::utl::Bootstrap::getBuildIdData(aDefault);
+ aVersionMsg.SearchAndReplaceAscii("%BUILDID", aVerId);
+#ifdef UNX
+ fprintf(stdout, "%s", ByteString(aVersionMsg, RTL_TEXTENCODING_ASCII_US).GetBuffer());
+#else
+ // Just re-use the help dialog for now.
+ CmdlineHelpDialog aDlg;
+ aDlg.m_ftHead.SetText(aVersionMsg);
+ aDlg.Execute();
+#endif
+ }
+
+#ifndef UNX
+ CmdlineHelpDialog::CmdlineHelpDialog (void)
+ : ModalDialog( NULL, DesktopResId( DLG_CMDLINEHELP ) )
+ , m_ftHead( this, DesktopResId( TXT_DLG_CMDLINEHELP_HEADER ) )
+ , m_ftLeft( this, DesktopResId( TXT_DLG_CMDLINEHELP_LEFT ) )
+ , m_ftRight( this, DesktopResId( TXT_DLG_CMDLINEHELP_RIGHT ) )
+ , m_ftBottom( this, DesktopResId( TXT_DLG_CMDLINEHELP_BOTTOM ) )
+ , m_btOk( this, DesktopResId( BTN_DLG_CMDLINEHELP_OK ) )
+ {
+ FreeResource();
+ }
+#endif
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/app/cmdlinehelp.hxx b/desktop/source/app/cmdlinehelp.hxx
new file mode 100644
index 000000000000..5c92512ea1e9
--- /dev/null
+++ b/desktop/source/app/cmdlinehelp.hxx
@@ -0,0 +1,25 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+#include <vcl/dialog.hxx>
+#include <vcl/fixed.hxx>
+#include <vcl/button.hxx>
+
+namespace desktop
+{
+ void displayCmdlineHelp( void );
+ void displayVersion();
+#ifndef UNX
+ class CmdlineHelpDialog : public ModalDialog
+ {
+ public:
+ CmdlineHelpDialog ( void );
+
+ FixedText m_ftHead;
+ FixedText m_ftLeft;
+ FixedText m_ftRight;
+ FixedText m_ftBottom;
+ OKButton m_btOk;
+ };
+#endif
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/app/configinit.cxx b/desktop/source/app/configinit.cxx
new file mode 100644
index 000000000000..16ef67f3b3d7
--- /dev/null
+++ b/desktop/source/app/configinit.cxx
@@ -0,0 +1,304 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include "configinit.hxx"
+
+#include "desktop.hrc"
+#include "app.hxx"
+#include <comphelper/processfactory.hxx>
+#include <uno/current_context.hxx>
+#include <cppuhelper/implbase1.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <osl/diagnose.h>
+#include <stdio.h>
+#include <map>
+#include <com/sun/star/lang/ServiceNotRegisteredException.hpp>
+#include <com/sun/star/configuration/CannotLoadConfigurationException.hpp>
+#include <com/sun/star/configuration/InvalidBootstrapFileException.hpp>
+#include <com/sun/star/configuration/backend/BackendSetupException.hpp>
+#include <com/sun/star/configuration/backend/CannotConnectException.hpp>
+
+// ----------------------------------------------------------------------------
+
+namespace uno = ::com::sun::star::uno;
+namespace lang = ::com::sun::star::lang;
+namespace configuration = ::com::sun::star::configuration;
+namespace backend = ::com::sun::star::configuration::backend;
+using rtl::OUString;
+using uno::UNO_QUERY;
+using desktop::Desktop;
+
+// ----------------------------------------------------------------------------
+static char const CONFIGURATION_PROVIDER[] = "com.sun.star.configuration.ConfigurationProvider";
+
+static char const CONFIGURATION_ERROR_HANDLER[] = "com.sun.star.configuration.backend.InteractionHandler";
+
+// must be aligned with configmgr/source/misc/configinteractionhandler
+static char const CONFIG_ERROR_HANDLER[] = "configuration.interaction-handler";
+// ----------------------------------------------------------------------------
+
+// ----------------------------------------------------------------------------
+#define arraysize( arr ) ( sizeof (arr)/sizeof *(arr) )
+
+typedef uno::Reference< lang::XMultiServiceFactory > ConfigurationProvider;
+
+#define OUSTRING( constascii ) OUString( RTL_CONSTASCII_USTRINGPARAM( constascii ) )
+
+#define OU2O( ustr, enc ) rtl::OUStringToOString( (ustr), RTL_TEXTENCODING_ ## enc )
+
+#define k_PROVIDER OUSTRING( CONFIGURATION_PROVIDER )
+#define k_ERRORHANDLER OUSTRING( CONFIGURATION_ERROR_HANDLER )
+// ----------------------------------------------------------------------------
+// Get a message string securely. There is a fallback string if the resource
+// is not available. Adapted from Desktop::GetMsgString()
+
+OUString getMsgString( sal_uInt16 nId, char const * aFallBackMsg )
+{
+ ResMgr* pResMgr = Desktop::GetDesktopResManager();
+ if ( !pResMgr || !nId )
+ return OUString::createFromAscii(aFallBackMsg);
+ else
+ return OUString( String(ResId( nId, *pResMgr )));
+}
+// ----------------------------------------------------------------------------
+/** Creates the normal configuration provider.
+
+*/
+static
+ConfigurationProvider createDefaultConfigurationProvider( )
+{
+ uno::Reference< lang::XMultiServiceFactory > xServiceManager = ::comphelper::getProcessServiceFactory();
+
+ OSL_ENSURE( xServiceManager.is(),"No ServiceManager set for CreateApplicationConfigurationProvider");
+
+ ConfigurationProvider xProvider;
+
+ if (xServiceManager.is())
+ {
+
+ xProvider.set( xServiceManager->createInstance(k_PROVIDER), UNO_QUERY);
+ }
+
+ if (!xProvider.is())
+ {
+ OUString const sMsg = OUSTRING("Service \"") + k_PROVIDER +
+ OUSTRING("\" is not available at the service manager.");
+
+ throw lang::ServiceNotRegisteredException(sMsg, xServiceManager);
+ }
+
+ return xProvider;
+}
+// ----------------------------------------------------------------------------
+/// @attention this method must be called from a catch statement!
+static void handleGeneralException(uno::Exception& aException,
+ const rtl::OUString& aMessage)
+{
+ aException.Message = aMessage ;
+ throw ;
+}
+// ----------------------------------------------------------------------------
+
+uno::Reference< lang::XMultiServiceFactory > CreateApplicationConfigurationProvider( )
+{
+ uno::Reference< lang::XMultiServiceFactory > xProvider;
+
+ try
+ {
+ xProvider = createDefaultConfigurationProvider( );
+ }
+ catch (configuration::InvalidBootstrapFileException & exception)
+ {
+ handleGeneralException(exception,
+ getMsgString( STR_CONFIG_ERR_SETTINGS_INCOMPLETE,
+ "The startup settings for your configuration settings are incomplete. "));
+ }
+ catch (backend::CannotConnectException & exception)
+ {
+ handleGeneralException(exception,
+ getMsgString( STR_CONFIG_ERR_CANNOT_CONNECT,
+ "A connection to your configuration settings could not be established. "));
+ }
+ catch (backend::BackendSetupException & exception)
+ {
+ handleGeneralException(exception,
+ getMsgString( STR_CONFIG_ERR_CANNOT_CONNECT,
+ "A connection to your configuration settings could not be established. "));
+ }
+ catch (configuration::CannotLoadConfigurationException & exception)
+ {
+ handleGeneralException(exception,
+ getMsgString( STR_CONFIG_ERR_CANNOT_CONNECT,
+ "A connection to your configuration settings could not be established. "));
+ }
+ catch (uno::Exception & exception)
+ {
+ handleGeneralException(exception,
+ getMsgString( STR_CONFIG_ERR_ACCESS_GENERAL,
+ "A general error occurred while accessing your configuration settings."));
+ }
+
+
+ return xProvider ;
+}
+// ----------------------------------------------------------------------------
+
+
+
+
+// ----------------------------------------------------------------------------
+// ConfigurationErrorHandler
+// ----------------------------------------------------------------------------
+
+namespace
+{
+ typedef uno::Reference< uno::XCurrentContext > CurrentContext;
+ class SimpleCurrentContext : public cppu::WeakImplHelper1< uno::XCurrentContext >
+ {
+ CurrentContext m_xChainedContext;
+ public:
+ explicit
+ SimpleCurrentContext(const CurrentContext & xChainedContext)
+ : m_xChainedContext(xChainedContext)
+ {}
+
+ void install() { uno::setCurrentContext(this); }
+ void deinstall() { uno::setCurrentContext(m_xChainedContext); }
+
+ uno::Any getChainedValueByName( OUString const & aName) const
+ {
+ return m_xChainedContext.is()
+ ? m_xChainedContext->getValueByName(aName)
+ : uno::Any();
+ }
+
+ // XCurrentContext
+ virtual uno::Any SAL_CALL
+ getValueByName( OUString const & aName)
+ throw (uno::RuntimeException);
+ };
+
+ uno::Any SAL_CALL
+ SimpleCurrentContext::getValueByName( OUString const & aName)
+ throw (uno::RuntimeException)
+ {
+ return getChainedValueByName(aName);
+ }
+
+}
+
+// ----------------------------------------------------------------------------
+class ConfigurationErrorHandler::Context : public SimpleCurrentContext
+{
+public:
+ Context()
+ : SimpleCurrentContext( uno::getCurrentContext() )
+ {
+ }
+
+ ~Context()
+ {
+ }
+
+ // XCurrentContext
+ virtual uno::Any SAL_CALL
+ getValueByName( OUString const & aName)
+ throw (uno::RuntimeException);
+
+private:
+ InteractionHandler m_xHandler;
+};
+
+//------------------------------------------------------------------------------
+uno::Any SAL_CALL ConfigurationErrorHandler::Context::getValueByName( OUString const & aName)
+ throw (uno::RuntimeException)
+{
+ if ( aName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(CONFIG_ERROR_HANDLER)) )
+ {
+ if ( !m_xHandler.is() )
+ m_xHandler = ConfigurationErrorHandler::getDefaultInteractionHandler();
+ return uno::Any( m_xHandler );
+ }
+ return SimpleCurrentContext::getValueByName( aName );
+}
+
+//------------------------------------------------------------------------------
+ConfigurationErrorHandler::~ConfigurationErrorHandler()
+{
+ deactivate();
+}
+
+//------------------------------------------------------------------------------
+/// installs the handler into the current context
+void ConfigurationErrorHandler::activate()
+{
+ if (!m_pContext)
+ {
+ m_pContext = new Context;
+ m_pContext->acquire();
+ }
+ m_pContext->install();
+}
+
+//------------------------------------------------------------------------------
+/// deinstalls the handler from the current context, restoring the previous context
+void ConfigurationErrorHandler::deactivate()
+{
+ if (m_pContext)
+ {
+ m_pContext->deinstall();
+ m_pContext->release();
+ m_pContext = 0;
+ }
+}
+//------------------------------------------------------------------------------
+
+ConfigurationErrorHandler::InteractionHandler ConfigurationErrorHandler::getDefaultInteractionHandler()
+{
+ uno::Reference< lang::XMultiServiceFactory > xServiceManager = ::comphelper::getProcessServiceFactory();
+
+ OSL_ENSURE( xServiceManager.is(),"No ServiceManager set for ConfigurationErrorHandler");
+
+ InteractionHandler xHandler;
+
+ if (xServiceManager.is())
+ {
+ xHandler.set( xServiceManager->createInstance(k_ERRORHANDLER), UNO_QUERY );
+ }
+
+ return xHandler;
+}
+//------------------------------------------------------------------------------
+
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/app/configinit.hxx b/desktop/source/app/configinit.hxx
new file mode 100644
index 000000000000..24fb01881396
--- /dev/null
+++ b/desktop/source/app/configinit.hxx
@@ -0,0 +1,74 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+#ifndef _DESKTOP_CONFIGINIT_HXX_
+#define _DESKTOP_CONFIGINIT_HXX_
+
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <rtl/ustring.hxx>
+
+/** creates a ConfigurationProvider instance
+Important: exceptions thrown from that method will contain a readily
+displayable message.
+
+ @return
+ The default configuration provider for the application or<br/>
+ <NULL/>, if startup was canceled
+
+ @throw com::sun::star::configuration::CannotLoadConfigurationException
+ if the configuration provider can't be created
+
+ @throw com::sun::star::lang::ServiceNotRegisteredException
+ if the ConfigurationProvider service is unknwon
+
+ @throw com::sun::star::lang::WrappedTargetException
+ if the configuration backend could be created,
+ but incurred a failure later
+
+*/
+extern
+com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >
+ CreateApplicationConfigurationProvider( );
+
+//-----------------------------------------------------------------------------
+#include <com/sun/star/task/XInteractionHandler.hpp>
+
+/**
+ sets an InteractionHandler for configuration errors in the current context.
+
+ */
+ class ConfigurationErrorHandler
+ {
+ public:
+ typedef com::sun::star::uno::Reference< com::sun::star::task::XInteractionHandler > InteractionHandler;
+
+ /// Constructor: Uses the default interaction handler
+ ConfigurationErrorHandler()
+ : m_pContext(0), m_xHandler()
+ {}
+
+ /// Constructor: Uses an externally provided interaction handler
+ ConfigurationErrorHandler(const InteractionHandler & xHandler)
+ : m_pContext(0), m_xHandler( xHandler )
+ {}
+
+ ~ConfigurationErrorHandler();
+
+ static InteractionHandler getDefaultInteractionHandler();
+
+ /// installs the handler into the current context
+ void activate();
+ /// deinstalls the handler from the current context, restoring the previous context
+ void deactivate();
+ private:
+ class Context;
+ Context * m_pContext;
+ InteractionHandler m_xHandler;
+ private:
+ // not implemented - suppress copy
+ ConfigurationErrorHandler(const ConfigurationErrorHandler&);
+ void operator=(const ConfigurationErrorHandler&);
+ };
+
+//-----------------------------------------------------------------------------
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/app/copyright_ascii_ooo.c b/desktop/source/app/copyright_ascii_ooo.c
new file mode 100755
index 000000000000..3984a81f26e5
--- /dev/null
+++ b/desktop/source/app/copyright_ascii_ooo.c
@@ -0,0 +1,12 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+
+ /*
+ * copyright text to see as text in the soffice binary
+ *
+ */
+
+extern const char copyright_text_1[];
+
+const char copyright_text_1[] = "Copyright © 2000, 2010 Oracle and/or its affiliates, All rights reserved.";
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/app/copyright_ascii_sun.c b/desktop/source/app/copyright_ascii_sun.c
new file mode 100755
index 000000000000..c7d6e7e3c08d
--- /dev/null
+++ b/desktop/source/app/copyright_ascii_sun.c
@@ -0,0 +1,10 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+
+ /*
+ * copyright text to see as text in the soffice binary
+ *
+ */
+
+const char copyright_text_1[] = "Copyright © 2000, 2010 Oracle and/or its affiliates, All rights reserved.";
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/app/desktop.hrc b/desktop/source/app/desktop.hrc
new file mode 100755
index 000000000000..9c68d7b9fd2d
--- /dev/null
+++ b/desktop/source/app/desktop.hrc
@@ -0,0 +1,91 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _DESKTOP_HRC_
+#define _DESKTOP_HRC_
+
+#ifndef _SOLAR_HRC
+#include <svl/solar.hrc>
+#endif
+
+#define RID_DESKTOP_DIALOG_START 2000
+#define RID_FIRSTSTSTART_START 3000
+#define RID_DESKTOP_STRING_START 10000
+
+
+#define INFOBOX_CMDLINEHELP (RID_DESKTOP_DIALOG_START+51)
+#define INFOBOX_EXPIRED (RID_DESKTOP_DIALOG_START+52)
+
+#define QBX_USERDATALOCKED (RID_DESKTOP_DIALOG_START+100)
+
+#define DLG_CMDLINEHELP (RID_DESKTOP_DIALOG_START+101)
+#define TXT_DLG_CMDLINEHELP_HEADER (RID_DESKTOP_DIALOG_START+102)
+#define TXT_DLG_CMDLINEHELP_LEFT (RID_DESKTOP_DIALOG_START+103)
+#define TXT_DLG_CMDLINEHELP_RIGHT (RID_DESKTOP_DIALOG_START+104)
+#define TXT_DLG_CMDLINEHELP_BOTTOM (RID_DESKTOP_DIALOG_START+105)
+#define BTN_DLG_CMDLINEHELP_OK (RID_DESKTOP_DIALOG_START+106)
+
+#define QBX_CONFIG_IMPORTSETTINGS (RID_DESKTOP_DIALOG_START+180)
+
+#define EBX_ERR_PRINTDISABLED (RID_DESKTOP_DIALOG_START+190)
+
+#define STR_RECOVER_QUERY (RID_DESKTOP_STRING_START+0)
+#define STR_RECOVER_TITLE (RID_DESKTOP_STRING_START+1)
+#define STR_RECOVER_PREPARED (RID_DESKTOP_STRING_START+2)
+
+#define STR_BOOTSTRAP_ERR_CANNOT_START (RID_DESKTOP_STRING_START+100)
+#define STR_BOOTSTRAP_ERR_DIR_MISSING (RID_DESKTOP_STRING_START+101)
+#define STR_BOOTSTRAP_ERR_PATH_INVALID (RID_DESKTOP_STRING_START+102)
+#define STR_BOOTSTRAP_ERR_NO_PATH (RID_DESKTOP_STRING_START+103)
+#define STR_BOOTSTRAP_ERR_INTERNAL (RID_DESKTOP_STRING_START+104)
+#define STR_BOOTSTRAP_ERR_FILE_CORRUPT (RID_DESKTOP_STRING_START+105)
+#define STR_BOOTSTRAP_ERR_FILE_MISSING (RID_DESKTOP_STRING_START+106)
+#define STR_BOOTSTRAP_ERR_NO_SUPPORT (RID_DESKTOP_STRING_START+107)
+#define STR_BOOTSTRAP_ERR_LANGUAGE_MISSING (RID_DESKTOP_STRING_START+108)
+
+#define STR_BOOTSTRAP_ERR_NO_SERVICE (RID_DESKTOP_STRING_START+120)
+#define STR_BOOTSTRAP_ERR_NO_CFG_SERVICE (RID_DESKTOP_STRING_START+121)
+#define STR_BOOTSTRAP_ERR_CFG_DATAACCESS (RID_DESKTOP_STRING_START+122)
+#define STR_BOOTSTRAP_ERR_NO_PATHSET_SERVICE (RID_DESKTOP_STRING_START+123)
+
+#define STR_ASK_START_SETUP_MANUALLY (RID_DESKTOP_STRING_START+152)
+
+#define STR_INTERNAL_ERRMSG (RID_DESKTOP_STRING_START+161)
+
+#define STR_CONFIG_ERR_SETTINGS_INCOMPLETE (RID_DESKTOP_STRING_START+182)
+#define STR_CONFIG_ERR_CANNOT_CONNECT (RID_DESKTOP_STRING_START+183)
+#define STR_CONFIG_ERR_RIGHTS_MISSING (RID_DESKTOP_STRING_START+184)
+#define STR_CONFIG_ERR_ACCESS_GENERAL (RID_DESKTOP_STRING_START+187)
+#define STR_CONFIG_ERR_NO_WRITE_ACCESS (RID_DESKTOP_STRING_START+188)
+
+#define STR_BOOSTRAP_ERR_NOTENOUGHDISKSPACE (RID_DESKTOP_STRING_START+189)
+#define STR_BOOSTRAP_ERR_NOACCESSRIGHTS (RID_DESKTOP_STRING_START+190)
+
+#define STR_TITLE_USERDATALOCKED (RID_DESKTOP_STRING_START+206)
+#define STR_TITLE_EXPIRED (RID_DESKTOP_STRING_START+207)
+
+#endif // _DESKTOP_HRC_
diff --git a/desktop/source/app/desktop.src b/desktop/source/app/desktop.src
new file mode 100644
index 000000000000..98ee68685917
--- /dev/null
+++ b/desktop/source/app/desktop.src
@@ -0,0 +1,235 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "desktop.hrc"
+
+
+String STR_RECOVER_QUERY
+{
+ Text [ en-US ] = "Should the file \"$1\" be restored?" ;
+};
+
+String STR_RECOVER_TITLE
+{
+ Text [ en-US ] = "File Recovery" ;
+};
+
+WarningBox STR_RECOVER_PREPARED
+{
+ Message [ en-US ] = "An unrecoverable error has occurred.\n\nAll modified files have been saved and can\nprobably be recovered at program restart." ;
+};
+
+String STR_BOOTSTRAP_ERR_CANNOT_START
+{
+ Text [ en-US ] = "The application cannot be started. ";
+};
+
+String STR_BOOTSTRAP_ERR_DIR_MISSING
+{
+ Text [ en-US ] = "The configuration directory \"$1\" could not be found.";
+};
+
+String STR_BOOTSTRAP_ERR_PATH_INVALID
+{
+ Text [ en-US ] = "The installation path is invalid.";
+};
+
+String STR_BOOTSTRAP_ERR_NO_PATH
+{
+ Text [ en-US ] = "The installation path is not available.";
+};
+
+String STR_BOOTSTRAP_ERR_INTERNAL
+{
+ Text [ en-US ] = "An internal error occurred.";
+};
+
+String STR_BOOTSTRAP_ERR_FILE_CORRUPT
+{
+ Text [ en-US ] = "The configuration file \"$1\" is corrupt.";
+};
+
+String STR_BOOTSTRAP_ERR_FILE_MISSING
+{
+ Text [ en-US ] = "The configuration file \"$1\" was not found.";
+};
+
+String STR_BOOTSTRAP_ERR_NO_SUPPORT
+{
+ Text [ en-US ] = "The configuration file \"$1\" does not support the current version.";
+};
+
+String STR_BOOTSTRAP_ERR_LANGUAGE_MISSING
+{
+ Text [ en-US ] = "The user interface language cannot be determined.";
+};
+
+String STR_BOOTSTRAP_ERR_NO_SERVICE
+{
+ Text [ en-US ] = "The component manager is not available.";
+};
+
+String STR_BOOTSTRAP_ERR_NO_CFG_SERVICE
+{
+ Text [ en-US ] = "The configuration service is not available.";
+};
+
+String STR_ASK_START_SETUP_MANUALLY
+{
+ Text [ en-US ] = "Start the setup application to repair the installation from the CD or the folder containing the installation packages.";
+};
+
+String STR_CONFIG_ERR_SETTINGS_INCOMPLETE
+{
+ Text [ en-US ] = "The startup settings for accessing the central configuration are incomplete. ";
+};
+
+String STR_CONFIG_ERR_CANNOT_CONNECT
+{
+ Text [ en-US ] = "A connection to the central configuration could not be established. ";
+};
+
+String STR_CONFIG_ERR_RIGHTS_MISSING
+{
+ Text [ en-US ] = "You cannot access the central configuration because of missing access rights. ";
+};
+
+String STR_CONFIG_ERR_ACCESS_GENERAL
+{
+ Text [ en-US ] = "A general error occurred while accessing your central configuration. ";
+};
+
+String STR_CONFIG_ERR_NO_WRITE_ACCESS
+{
+ Text [ en-US ] = "The changes to your personal settings cannot be stored centrally because of missing access rights. ";
+};
+
+String STR_BOOTSTRAP_ERR_CFG_DATAACCESS
+{
+ Text [ en-US ] = "%PRODUCTNAME cannot be started due to an error in accessing the %PRODUCTNAME configuration data.\n\nPlease contact your system administrator." ;
+};
+
+String STR_INTERNAL_ERRMSG
+{
+ Text [ en-US ] = "The following internal error has occurred: " ;
+};
+
+QueryBox QBX_USERDATALOCKED
+{
+ Buttons = WB_YES_NO ;
+ DefButton = WB_DEF_NO ;
+ Message [ en-US ] = "Either another instance of %PRODUCTNAME is accessing your personal settings or your personal settings are locked.\nSimultaneous access can lead to inconsistencies in your personal settings. Before continuing, you should make sure user '$u' closes %PRODUCTNAME on host '$h'.\n\nDo you really want to continue?";
+};
+
+String STR_TITLE_USERDATALOCKED
+{
+ Text [ en-US ] = "%PRODUCTNAME %PRODUCTVERSION";
+};
+
+InfoBox INFOBOX_CMDLINEHELP
+{
+ Buttons = WB_OK ;
+ DefButton = WB_DEF_OK ;
+ Message = "";
+};
+
+ModalDialog DLG_CMDLINEHELP
+{
+ HelpID = "desktop:ModalDialog:DLG_CMDLINEHELP";
+ Text = "Help Message...";
+ Size = MAP_APPFONT(250, 365);
+ Border = True;
+ SVLook = True;
+ Moveable = True;
+
+ FixedText TXT_DLG_CMDLINEHELP_HEADER
+ {
+ Size = MAP_APPFONT(240, 50);
+ Pos = MAP_APPFONT(5, 5);
+ Text = "HEADER";
+ };
+ FixedText TXT_DLG_CMDLINEHELP_LEFT
+ {
+ Size = MAP_APPFONT(50, 150);
+ Pos = MAP_APPFONT(5, 50);
+ Text = "LEFT";
+ };
+ FixedText TXT_DLG_CMDLINEHELP_RIGHT
+ {
+ Size = MAP_APPFONT(190, 150);
+ Pos = MAP_APPFONT(60, 50);
+ Text = "RIGHT";
+ };
+ FixedText TXT_DLG_CMDLINEHELP_BOTTOM
+ {
+ Size = MAP_APPFONT(240, 145);
+ Pos = MAP_APPFONT(5, 200);
+ Text = "BOTTOM";
+ };
+ OKButton BTN_DLG_CMDLINEHELP_OK
+ {
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ Pos = MAP_APPFONT(95, 345);
+ TabStop = TRUE ;
+ DefButton = TRUE ;
+ };
+};
+
+ErrorBox EBX_ERR_PRINTDISABLED
+{
+ Buttons = WB_OK ;
+ DefButton = WB_DEF_OK ;
+ Message [ en-US ] = "Printing is disabled. No documents can be printed.";
+};
+
+InfoBox INFOBOX_EXPIRED
+{
+ Buttons = WB_OK ;
+ DefButton = WB_DEF_OK ;
+ Message [ en-US ] = "This Evaluation Version has expired. To find out more about %PRODUCTNAME,\nvisit http://www.oracle.com/us/products/applications/open-office.";
+};
+
+String STR_TITLE_EXPIRED
+{
+ Text [ en-US ] = "%PRODUCTNAME %PRODUCTVERSION";
+};
+
+String STR_BOOTSTRAP_ERR_NO_PATHSET_SERVICE
+{
+ Text [ en-US ] = "The path manager is not available.\n";
+};
+
+String STR_BOOSTRAP_ERR_NOTENOUGHDISKSPACE
+{
+ Text [ en-US ] = "%PRODUCTNAME user installation could not be completed due to insufficient free disk space. Please free more disc space at the following location and restart %PRODUCTNAME:\n\n";
+};
+
+String STR_BOOSTRAP_ERR_NOACCESSRIGHTS
+{
+ Text [ en-US ] = "%PRODUCTNAME user installation could not be processed due to missing access rights. Please make sure that you have sufficient access rights for the following location and restart %PRODUCTNAME:\n\n";
+};
+
diff --git a/desktop/source/app/desktopcontext.cxx b/desktop/source/app/desktopcontext.cxx
new file mode 100644
index 000000000000..2a8ed7ef628c
--- /dev/null
+++ b/desktop/source/app/desktopcontext.cxx
@@ -0,0 +1,67 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+#include "desktopcontext.hxx"
+
+#include <vcl/svapp.hxx>
+#include <svtools/javainteractionhandler.hxx>
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::task;
+
+using ::rtl::OUString;
+
+namespace desktop
+{
+
+DesktopContext::DesktopContext( const Reference< XCurrentContext > & ctx )
+ : m_xNextContext( ctx )
+{
+}
+
+Any SAL_CALL DesktopContext::getValueByName( const OUString& Name) throw (RuntimeException)
+{
+ Any retVal;
+
+ if (Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(JAVA_INTERACTION_HANDLER_NAME)))
+ {
+ retVal = makeAny( Reference< XInteractionHandler >( new svt::JavaInteractionHandler()) );
+ }
+ else if( m_xNextContext.is() )
+ {
+ // Call next context in chain if found
+ retVal = m_xNextContext->getValueByName( Name );
+ }
+ return retVal;
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/app/desktopcontext.hxx b/desktop/source/app/desktopcontext.hxx
new file mode 100644
index 000000000000..b68a73cd9cf9
--- /dev/null
+++ b/desktop/source/app/desktopcontext.hxx
@@ -0,0 +1,53 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _DESKTOP_DESKTOPCONTEXT_HXX_
+#define _DESKTOP_DESKTOPCONTEXT_HXX_
+
+#include <cppuhelper/implbase1.hxx>
+#include <uno/current_context.hxx>
+
+namespace desktop
+{
+ class DesktopContext: public cppu::WeakImplHelper1< com::sun::star::uno::XCurrentContext >
+ {
+ public:
+ DesktopContext( const com::sun::star::uno::Reference< com::sun::star::uno::XCurrentContext > & ctx);
+
+ // XCurrentContext
+ virtual com::sun::star::uno::Any SAL_CALL getValueByName( const rtl::OUString& Name )
+ throw (com::sun::star::uno::RuntimeException);
+
+ private:
+ com::sun::star::uno::Reference< com::sun::star::uno::XCurrentContext > m_xNextContext;
+ };
+}
+
+#endif // _DESKTOP_DESKTOPCONTEXT_HXX_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/app/desktopresid.cxx b/desktop/source/app/desktopresid.cxx
new file mode 100644
index 000000000000..ac8799a95a23
--- /dev/null
+++ b/desktop/source/app/desktopresid.cxx
@@ -0,0 +1,47 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+
+#include "desktopresid.hxx"
+#include "app.hxx"
+
+// -----------------------------------------------------------------------
+namespace desktop
+{
+
+DesktopResId::DesktopResId( sal_uInt16 nId ) :
+ ResId( nId, *Desktop::GetDesktopResManager() )
+{
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/app/desktopresid.hxx b/desktop/source/app/desktopresid.hxx
new file mode 100644
index 000000000000..14d45a493f0c
--- /dev/null
+++ b/desktop/source/app/desktopresid.hxx
@@ -0,0 +1,47 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _DESKTOP_RESID_HXX_
+#define _DESKTOP_RESID_HXX_
+
+#include <tools/resid.hxx>
+
+namespace desktop
+{
+
+class DesktopResId : public ResId
+{
+ public:
+ DesktopResId( sal_uInt16 nId );
+};
+
+}
+
+#endif // _DESKTOP_RESID_HXX_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/app/dispatchwatcher.cxx b/desktop/source/app/dispatchwatcher.cxx
new file mode 100644
index 000000000000..e575ea8f3727
--- /dev/null
+++ b/desktop/source/app/dispatchwatcher.cxx
@@ -0,0 +1,666 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include <sfx2/docfile.hxx>
+#include <sfx2/docfilt.hxx>
+#include <sfx2/fcontnr.hxx>
+#include "osl/file.hxx"
+#include <svl/fstathelper.hxx>
+
+#include "dispatchwatcher.hxx"
+#include <rtl/ustring.hxx>
+#include <tools/string.hxx>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/synchronousdispatch.hxx>
+#include <com/sun/star/util/XCloseable.hpp>
+#include <com/sun/star/util/CloseVetoException.hpp>
+#include <com/sun/star/task/XInteractionHandler.hpp>
+#include <com/sun/star/util/URL.hpp>
+#include <com/sun/star/frame/XDesktop.hpp>
+#include <com/sun/star/container/XEnumeration.hpp>
+#include <com/sun/star/frame/XFramesSupplier.hpp>
+#include <com/sun/star/frame/XDispatch.hpp>
+#include <com/sun/star/frame/XComponentLoader.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/view/XPrintable.hpp>
+#include <com/sun/star/frame/XDispatchProvider.hpp>
+#include <com/sun/star/util/XURLTransformer.hpp>
+#include <com/sun/star/document/MacroExecMode.hpp>
+#include <com/sun/star/document/UpdateDocMode.hpp>
+#include <com/sun/star/frame/XStorable.hpp>
+
+#include <tools/urlobj.hxx>
+#include <comphelper/mediadescriptor.hxx>
+
+#include <vector>
+#include <osl/thread.hxx>
+
+using ::rtl::OUString;
+using namespace ::osl;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::util;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::view;
+
+namespace desktop
+{
+
+String GetURL_Impl(
+ const String& rName, boost::optional< rtl::OUString > const & cwdUrl );
+
+struct DispatchHolder
+{
+ DispatchHolder( const URL& rURL, Reference< XDispatch >& rDispatch ) :
+ aURL( rURL ), xDispatch( rDispatch ) {}
+
+ URL aURL;
+ rtl::OUString cwdUrl;
+ Reference< XDispatch > xDispatch;
+};
+
+static String impl_GetFilterFromExt( OUString aUrl, SfxFilterFlags nFlags,
+ String aAppl )
+{
+ String aFilter;
+ SfxMedium* pMedium = new SfxMedium( aUrl,
+ STREAM_STD_READ, sal_False );
+ const SfxFilter *pSfxFilter = NULL;
+ SfxFilterMatcher aMatcher;
+ if( nFlags == SFX_FILTER_EXPORT )
+ aMatcher = SfxFilterMatcher( aAppl );
+ aMatcher.GuessFilterIgnoringContent( *pMedium, &pSfxFilter, nFlags, 0 );
+ if( pSfxFilter )
+ aFilter = ( nFlags == SFX_FILTER_EXPORT ) ? pSfxFilter->GetFilterName() :
+ pSfxFilter->GetServiceName();
+
+ delete pMedium;
+ return aFilter;
+}
+static OUString impl_GuessFilter( OUString aUrlIn, OUString aUrlOut )
+{
+ /* aAppl can also be set to Factory like scalc, swriter... */
+ String aAppl;
+ aAppl = impl_GetFilterFromExt( aUrlIn, SFX_FILTER_IMPORT, aAppl );
+ return impl_GetFilterFromExt( aUrlOut, SFX_FILTER_EXPORT, aAppl );
+}
+
+Mutex* DispatchWatcher::pWatcherMutex = NULL;
+
+Mutex& DispatchWatcher::GetMutex()
+{
+ if ( !pWatcherMutex )
+ {
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ if ( !pWatcherMutex )
+ pWatcherMutex = new osl::Mutex();
+ }
+
+ return *pWatcherMutex;
+}
+
+// Create or get the dispatch watcher implementation. This implementation must be
+// a singleton to prevent access to the framework after it wants to terminate.
+DispatchWatcher* DispatchWatcher::GetDispatchWatcher()
+{
+ static Reference< XInterface > xDispatchWatcher;
+ static DispatchWatcher* pDispatchWatcher = NULL;
+
+ if ( !xDispatchWatcher.is() )
+ {
+ ::osl::MutexGuard aGuard( GetMutex() );
+
+ if ( !xDispatchWatcher.is() )
+ {
+ pDispatchWatcher = new DispatchWatcher();
+
+ // We have to hold a reference to ourself forever to prevent our own destruction.
+ xDispatchWatcher = static_cast< cppu::OWeakObject *>( pDispatchWatcher );
+ }
+ }
+
+ return pDispatchWatcher;
+}
+
+
+DispatchWatcher::DispatchWatcher()
+ : m_nRequestCount(0)
+{
+}
+
+
+DispatchWatcher::~DispatchWatcher()
+{
+}
+
+
+sal_Bool DispatchWatcher::executeDispatchRequests( const DispatchList& aDispatchRequestsList, bool bNoTerminate )
+{
+ Reference< XComponentLoader > xDesktop( ::comphelper::getProcessServiceFactory()->createInstance(
+ OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.Desktop")) ),
+ UNO_QUERY );
+
+ DispatchList::const_iterator p;
+ std::vector< DispatchHolder > aDispatches;
+ ::rtl::OUString aAsTemplateArg( RTL_CONSTASCII_USTRINGPARAM( "AsTemplate"));
+ sal_Bool bSetInputFilter = sal_False;
+ ::rtl::OUString aForcedInputFilter;
+
+ for ( p = aDispatchRequestsList.begin(); p != aDispatchRequestsList.end(); ++p )
+ {
+ const DispatchRequest& aDispatchRequest = *p;
+
+ // create parameter array
+ sal_Int32 nCount = 4;
+ if ( aDispatchRequest.aPreselectedFactory.getLength() )
+ nCount++;
+
+ // Set Input Filter
+ if ( aDispatchRequest.aRequestType == REQUEST_INFILTER )
+ {
+ bSetInputFilter = sal_True;
+ aForcedInputFilter = aDispatchRequest.aURL;
+ OfficeIPCThread::RequestsCompleted( 1 );
+ continue;
+ }
+
+ // we need more properties for a print/print to request
+ if ( aDispatchRequest.aRequestType == REQUEST_PRINT ||
+ aDispatchRequest.aRequestType == REQUEST_PRINTTO ||
+ aDispatchRequest.aRequestType == REQUEST_BATCHPRINT ||
+ aDispatchRequest.aRequestType == REQUEST_CONVERSION)
+ nCount++;
+
+ Sequence < PropertyValue > aArgs( nCount );
+
+ // mark request as user interaction from outside
+ aArgs[0].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Referer"));
+ aArgs[0].Value <<= ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("private:OpenEvent"));
+
+ if ( aDispatchRequest.aRequestType == REQUEST_PRINT ||
+ aDispatchRequest.aRequestType == REQUEST_PRINTTO ||
+ aDispatchRequest.aRequestType == REQUEST_BATCHPRINT ||
+ aDispatchRequest.aRequestType == REQUEST_CONVERSION)
+ {
+ aArgs[1].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ReadOnly"));
+ aArgs[2].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("OpenNewView"));
+ aArgs[3].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Hidden"));
+ aArgs[4].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Silent"));
+ }
+ else
+ {
+ Reference < com::sun::star::task::XInteractionHandler > xInteraction(
+ ::comphelper::getProcessServiceFactory()->createInstance( OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.task.InteractionHandler")) ),
+ com::sun::star::uno::UNO_QUERY );
+
+ aArgs[1].Name = OUString(RTL_CONSTASCII_USTRINGPARAM( "InteractionHandler" ));
+ aArgs[1].Value <<= xInteraction;
+
+ sal_Int16 nMacroExecMode = ::com::sun::star::document::MacroExecMode::USE_CONFIG;
+ aArgs[2].Name = OUString(RTL_CONSTASCII_USTRINGPARAM( "MacroExecutionMode" ));
+ aArgs[2].Value <<= nMacroExecMode;
+
+ sal_Int16 nUpdateDoc = ::com::sun::star::document::UpdateDocMode::ACCORDING_TO_CONFIG;
+ aArgs[3].Name = OUString(RTL_CONSTASCII_USTRINGPARAM( "UpdateDocMode" ));
+ aArgs[3].Value <<= nUpdateDoc;
+ }
+
+ if ( aDispatchRequest.aPreselectedFactory.getLength() )
+ {
+ aArgs[nCount-1].Name = ::comphelper::MediaDescriptor::PROP_DOCUMENTSERVICE();
+ aArgs[nCount-1].Value <<= aDispatchRequest.aPreselectedFactory;
+ }
+
+ String aName( GetURL_Impl( aDispatchRequest.aURL, aDispatchRequest.aCwdUrl ) );
+ ::rtl::OUString aTarget( RTL_CONSTASCII_USTRINGPARAM("_default") );
+
+ if ( aDispatchRequest.aRequestType == REQUEST_PRINT ||
+ aDispatchRequest.aRequestType == REQUEST_PRINTTO ||
+ aDispatchRequest.aRequestType == REQUEST_BATCHPRINT ||
+ aDispatchRequest.aRequestType == REQUEST_CONVERSION)
+ {
+ // documents opened for printing are opened readonly because they must be opened as a new document and this
+ // document could be open already
+ aArgs[1].Value <<= sal_True;
+
+ // always open a new document for printing, because it must be disposed afterwards
+ aArgs[2].Value <<= sal_True;
+
+ // printing is done in a hidden view
+ aArgs[3].Value <<= sal_True;
+
+ // load document for printing without user interaction
+ aArgs[4].Value <<= sal_True;
+
+ // hidden documents should never be put into open tasks
+ aTarget = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("_blank") );
+ }
+ // load the document ... if they are loadable!
+ // Otherwise try to dispatch it ...
+ Reference < XPrintable > xDoc;
+ if(
+ ( aName.CompareToAscii( ".uno" , 4 ) == COMPARE_EQUAL ) ||
+ ( aName.CompareToAscii( "slot:" , 5 ) == COMPARE_EQUAL ) ||
+ ( aName.CompareToAscii( "macro:", 6 ) == COMPARE_EQUAL ) ||
+ ( aName.CompareToAscii("vnd.sun.star.script", 19) == COMPARE_EQUAL)
+ )
+ {
+ // Attention: URL must be parsed full. Otherwise some detections on it will fail!
+ // It doesnt matter, if parser isn't available. Because; We try loading of URL then ...
+ URL aURL ;
+ aURL.Complete = aName;
+
+ Reference < XDispatch > xDispatcher ;
+ Reference < XDispatchProvider > xProvider ( xDesktop, UNO_QUERY );
+ Reference < XURLTransformer > xParser ( ::comphelper::getProcessServiceFactory()->createInstance( OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.util.URLTransformer")) ), ::com::sun::star::uno::UNO_QUERY );
+
+ if( xParser.is() == sal_True )
+ xParser->parseStrict( aURL );
+
+ if( xProvider.is() == sal_True )
+ xDispatcher = xProvider->queryDispatch( aURL, ::rtl::OUString(), 0 );
+
+ if( xDispatcher.is() == sal_True )
+ {
+ {
+ ::osl::ClearableMutexGuard aGuard( GetMutex() );
+ // Remember request so we can find it in statusChanged!
+ m_aRequestContainer.insert( DispatchWatcherHashMap::value_type( aURL.Complete, (sal_Int32)1 ) );
+ m_nRequestCount++;
+ }
+
+ // Use local vector to store dispatcher because we have to fill our request container before
+ // we can dispatch. Otherwise it would be possible that statusChanged is called before we dispatched all requests!!
+ aDispatches.push_back( DispatchHolder( aURL, xDispatcher ));
+ }
+ }
+ else if ( ( aName.CompareToAscii( "service:" , 8 ) == COMPARE_EQUAL ) )
+ {
+ // TODO: the dispatch has to be done for loadComponentFromURL as well. Please ask AS for more details.
+ URL aURL ;
+ aURL.Complete = aName;
+
+ Reference < XDispatch > xDispatcher ;
+ Reference < XDispatchProvider > xProvider ( xDesktop, UNO_QUERY );
+ Reference < XURLTransformer > xParser ( ::comphelper::getProcessServiceFactory()->createInstance( OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.util.URLTransformer")) ), ::com::sun::star::uno::UNO_QUERY );
+
+ if( xParser.is() == sal_True )
+ xParser->parseStrict( aURL );
+
+ if( xProvider.is() == sal_True )
+ xDispatcher = xProvider->queryDispatch( aURL, ::rtl::OUString(), 0 );
+
+ if( xDispatcher.is() == sal_True )
+ {
+ try
+ {
+ // We have to be listener to catch errors during dispatching URLs.
+ // Otherwise it would be possible to have an office running without an open
+ // window!!
+ Sequence < PropertyValue > aArgs2(1);
+ aArgs2[0].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SynchronMode"));
+ aArgs2[0].Value <<= sal_True;
+ Reference < XNotifyingDispatch > xDisp( xDispatcher, UNO_QUERY );
+ if ( xDisp.is() )
+ xDisp->dispatchWithNotification( aURL, aArgs2, DispatchWatcher::GetDispatchWatcher() );
+ else
+ xDispatcher->dispatch( aURL, aArgs2 );
+ }
+ catch ( ::com::sun::star::uno::Exception& )
+ {
+ OUString aMsg = OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "Desktop::OpenDefault() IllegalArgumentException while calling XNotifyingDispatch: "));
+ OSL_FAIL( OUStringToOString(aMsg, RTL_TEXTENCODING_ASCII_US).getStr());
+ }
+ }
+ }
+ else
+ {
+ INetURLObject aObj( aName );
+ if ( aObj.GetProtocol() == INET_PROT_PRIVATE )
+ aTarget = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("_default") );
+
+ // Set "AsTemplate" argument according to request type
+ if ( aDispatchRequest.aRequestType == REQUEST_FORCENEW ||
+ aDispatchRequest.aRequestType == REQUEST_FORCEOPEN )
+ {
+ sal_Int32 nIndex = aArgs.getLength();
+ aArgs.realloc( nIndex+1 );
+ aArgs[nIndex].Name = aAsTemplateArg;
+ if ( aDispatchRequest.aRequestType == REQUEST_FORCENEW )
+ aArgs[nIndex].Value <<= sal_True;
+ else
+ aArgs[nIndex].Value <<= sal_False;
+ }
+
+ // if we are called in viewmode, open document read-only
+ if(aDispatchRequest.aRequestType == REQUEST_VIEW) {
+ sal_Int32 nIndex = aArgs.getLength();
+ aArgs.realloc(nIndex+1);
+ aArgs[nIndex].Name = OUString(RTL_CONSTASCII_USTRINGPARAM("ReadOnly"));
+ aArgs[nIndex].Value <<= sal_True;
+ }
+
+ // if we are called with -start set Start in mediadescriptor
+ if(aDispatchRequest.aRequestType == REQUEST_START) {
+ sal_Int32 nIndex = aArgs.getLength();
+ aArgs.realloc(nIndex+1);
+ aArgs[nIndex].Name = OUString(RTL_CONSTASCII_USTRINGPARAM("StartPresentation"));
+ aArgs[nIndex].Value <<= sal_True;
+ }
+
+ // Force input filter, if possible
+ if( bSetInputFilter )
+ {
+ sal_Int32 nIndex = aArgs.getLength();
+ aArgs.realloc(nIndex+1);
+ aArgs[nIndex].Name = OUString(RTL_CONSTASCII_USTRINGPARAM("FilterName"));
+ aArgs[nIndex].Value <<= aForcedInputFilter;
+ }
+
+ // This is a synchron loading of a component so we don't have to deal with our statusChanged listener mechanism.
+ try
+ {
+ xDoc = Reference < XPrintable >( ::comphelper::SynchronousDispatch::dispatch( xDesktop, aName, aTarget, 0, aArgs ), UNO_QUERY );
+ }
+ catch ( ::com::sun::star::lang::IllegalArgumentException& iae)
+ {
+ OUString aMsg = OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "Dispatchwatcher IllegalArgumentException while calling loadComponentFromURL: "))
+ + iae.Message;
+ OSL_FAIL( OUStringToOString(aMsg, RTL_TEXTENCODING_ASCII_US).getStr());
+ }
+ catch (com::sun::star::io::IOException& ioe)
+ {
+ OUString aMsg = OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "Dispatchwatcher IOException while calling loadComponentFromURL: "))
+ + ioe.Message;
+ OSL_FAIL( OUStringToOString(aMsg, RTL_TEXTENCODING_ASCII_US).getStr());
+ }
+ if ( aDispatchRequest.aRequestType == REQUEST_OPEN ||
+ aDispatchRequest.aRequestType == REQUEST_VIEW ||
+ aDispatchRequest.aRequestType == REQUEST_START ||
+ aDispatchRequest.aRequestType == REQUEST_FORCEOPEN ||
+ aDispatchRequest.aRequestType == REQUEST_FORCENEW )
+ {
+ // request is completed
+ OfficeIPCThread::RequestsCompleted( 1 );
+ }
+ else if ( aDispatchRequest.aRequestType == REQUEST_PRINT ||
+ aDispatchRequest.aRequestType == REQUEST_PRINTTO ||
+ aDispatchRequest.aRequestType == REQUEST_BATCHPRINT ||
+ aDispatchRequest.aRequestType == REQUEST_CONVERSION )
+ {
+ if ( xDoc.is() )
+ {
+ if ( aDispatchRequest.aRequestType == REQUEST_CONVERSION ) {
+ Reference< XStorable > xStorable( xDoc, UNO_QUERY );
+ if ( xStorable.is() ) {
+ rtl::OUString aParam = aDispatchRequest.aPrinterName;
+ sal_Int32 nPathIndex = aParam.lastIndexOfAsciiL( ";", 1 );
+ sal_Int32 nFilterIndex = aParam.indexOfAsciiL( ":", 1 );
+ if( nPathIndex < nFilterIndex )
+ nFilterIndex = -1;
+ rtl::OUString aFilterOut=aParam.copy( nPathIndex+1 );
+ rtl::OUString aFilter;
+ rtl::OUString aFilterExt;
+ sal_Bool bGuess = sal_False;
+
+ if( nFilterIndex >= 0 )
+ {
+ aFilter = aParam.copy( nFilterIndex+1, nPathIndex-nFilterIndex-1 );
+ aFilterExt = aParam.copy( 0, nFilterIndex );
+ }
+ else
+ {
+ // Guess
+ bGuess = sal_True;
+ aFilterExt = aParam.copy( 0, nPathIndex );
+ }
+ INetURLObject aOutFilename( aObj );
+ aOutFilename.SetExtension( aFilterExt );
+ FileBase::getFileURLFromSystemPath( aFilterOut, aFilterOut );
+ rtl::OUString aOutFile = aFilterOut+
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "/" ))+
+ aOutFilename.getName();
+
+ if ( bGuess )
+ {
+ aFilter = impl_GuessFilter( aName, aOutFile );
+ }
+
+ Sequence<PropertyValue> conversionProperties( 2 );
+ conversionProperties[0].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "Overwrite" ));
+ conversionProperties[0].Value <<= sal_True;
+
+ conversionProperties[1].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "FilterName" ));
+ conversionProperties[1].Value <<= aFilter;
+
+ rtl::OUString aTempName;
+ FileBase::getSystemPathFromFileURL( aName, aTempName );
+ rtl::OString aSource8 = ::rtl::OUStringToOString ( aTempName, RTL_TEXTENCODING_UTF8 );
+ FileBase::getSystemPathFromFileURL( aOutFile, aTempName );
+ rtl::OString aTargetURL8 = ::rtl::OUStringToOString(aTempName, RTL_TEXTENCODING_UTF8 );
+ printf("convert %s -> %s using %s\n", aSource8.getStr(), aTargetURL8.getStr(),
+ ::rtl::OUStringToOString( aFilter, RTL_TEXTENCODING_UTF8 ).getStr());
+ if( FStatHelper::IsDocument(aOutFile) )
+ printf("Overwriting: %s\n",::rtl::OUStringToOString( aTempName, RTL_TEXTENCODING_UTF8 ).getStr() );
+ try
+ {
+ xStorable->storeToURL( aOutFile, conversionProperties );
+ }
+ catch ( Exception& e )
+ {
+ fprintf( stderr, "Error: Please reverify input parameters...\n" );
+ }
+ }
+ } else if ( aDispatchRequest.aRequestType == REQUEST_BATCHPRINT ) {
+ rtl::OUString aParam = aDispatchRequest.aPrinterName;
+ sal_Int32 nPathIndex = aParam.lastIndexOfAsciiL( ";", 1 );
+
+ rtl::OUString aFilterOut;
+ rtl::OUString aPrinterName;
+ if( nPathIndex != -1 )
+ aFilterOut=aParam.copy( nPathIndex+1 );
+ if( nPathIndex != 0 )
+ aPrinterName=aParam.copy( 0, nPathIndex );
+
+ INetURLObject aOutFilename( aObj );
+ aOutFilename.SetExtension( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ps")) );
+ FileBase::getFileURLFromSystemPath( aFilterOut, aFilterOut );
+ rtl::OUString aOutFile = aFilterOut+
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "/" ))+
+ aOutFilename.getName();
+
+ rtl::OUString aTempName;
+ FileBase::getSystemPathFromFileURL( aName, aTempName );
+ rtl::OString aSource8 = ::rtl::OUStringToOString ( aTempName, RTL_TEXTENCODING_UTF8 );
+ FileBase::getSystemPathFromFileURL( aOutFile, aTempName );
+ rtl::OString aTargetURL8 = ::rtl::OUStringToOString(aTempName, RTL_TEXTENCODING_UTF8 );
+ printf("print %s -> %s using %s\n", aSource8.getStr(), aTargetURL8.getStr(),
+ aPrinterName.getLength() ?
+ ::rtl::OUStringToOString( aPrinterName, RTL_TEXTENCODING_UTF8 ).getStr() : "<default_printer>");
+
+ // create the custom printer, if given
+ Sequence < PropertyValue > aPrinterArgs( 1 );
+ if( aPrinterName.getLength() )
+ {
+ aPrinterArgs[0].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Name"));
+ aPrinterArgs[0].Value <<= aPrinterName;
+ xDoc->setPrinter( aPrinterArgs );
+ }
+
+ // print ( also without user interaction )
+ aPrinterArgs.realloc(2);
+ aPrinterArgs[0].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("FileName"));
+ aPrinterArgs[0].Value <<= aOutFile;
+ aPrinterArgs[1].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Wait"));
+ aPrinterArgs[1].Value <<= ( sal_Bool ) sal_True;
+ xDoc->print( aPrinterArgs );
+ } else {
+ if ( aDispatchRequest.aRequestType == REQUEST_PRINTTO )
+ {
+ // create the printer
+ Sequence < PropertyValue > aPrinterArgs( 1 );
+ aPrinterArgs[0].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Name"));
+ aPrinterArgs[0].Value <<= ::rtl::OUString( aDispatchRequest.aPrinterName );
+ xDoc->setPrinter( aPrinterArgs );
+ }
+
+ // print ( also without user interaction )
+ Sequence < PropertyValue > aPrinterArgs( 1 );
+ aPrinterArgs[0].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Wait"));
+ aPrinterArgs[0].Value <<= ( sal_Bool ) sal_True;
+ xDoc->print( aPrinterArgs );
+ }
+ }
+ else
+ {
+ // place error message here ...
+ }
+
+ // remove the document
+ try
+ {
+ Reference < XCloseable > xClose( xDoc, UNO_QUERY );
+ if ( xClose.is() )
+ xClose->close( sal_True );
+ else
+ {
+ Reference < XComponent > xComp( xDoc, UNO_QUERY );
+ if ( xComp.is() )
+ xComp->dispose();
+ }
+ }
+ catch ( com::sun::star::util::CloseVetoException& )
+ {
+ }
+
+ // request is completed
+ OfficeIPCThread::RequestsCompleted( 1 );
+ }
+ }
+ }
+
+ if ( aDispatches.size() > 0 )
+ {
+ // Execute all asynchronous dispatches now after we placed them into our request container!
+ Sequence < PropertyValue > aArgs( 2 );
+ aArgs[0].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Referer"));
+ aArgs[0].Value <<= ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("private:OpenEvent"));
+ aArgs[1].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SynchronMode"));
+ aArgs[1].Value <<= sal_True;
+
+ for ( sal_uInt32 n = 0; n < aDispatches.size(); n++ )
+ {
+ Reference< XDispatch > xDispatch = aDispatches[n].xDispatch;
+ Reference < XNotifyingDispatch > xDisp( xDispatch, UNO_QUERY );
+ if ( xDisp.is() )
+ xDisp->dispatchWithNotification( aDispatches[n].aURL, aArgs, this );
+ else
+ {
+ ::osl::ClearableMutexGuard aGuard( GetMutex() );
+ m_nRequestCount--;
+ aGuard.clear();
+ xDispatch->dispatch( aDispatches[n].aURL, aArgs );
+ }
+ }
+ }
+
+ ::osl::ClearableMutexGuard aGuard( GetMutex() );
+ bool bEmpty = (m_nRequestCount == 0);
+ aGuard.clear();
+
+ // No more asynchronous requests?
+ // The requests are removed from the request container after they called back to this
+ // implementation via statusChanged!!
+ if ( bEmpty && !bNoTerminate /*m_aRequestContainer.empty()*/ )
+ {
+ // We have to check if we have an open task otherwise we have to shutdown the office.
+ Reference< XFramesSupplier > xTasksSupplier( xDesktop, UNO_QUERY );
+ aGuard.clear();
+ Reference< XElementAccess > xList( xTasksSupplier->getFrames(), UNO_QUERY );
+
+ if ( !xList->hasElements() )
+ {
+ // We don't have any task open so we have to shutdown ourself!!
+ Reference< XDesktop > xDesktop2( xTasksSupplier, UNO_QUERY );
+ if ( xDesktop2.is() )
+ return xDesktop2->terminate();
+ }
+ }
+
+ return sal_False;
+}
+
+
+void SAL_CALL DispatchWatcher::disposing( const ::com::sun::star::lang::EventObject& )
+throw(::com::sun::star::uno::RuntimeException)
+{
+}
+
+
+void SAL_CALL DispatchWatcher::dispatchFinished( const DispatchResultEvent& ) throw( RuntimeException )
+{
+ osl::ClearableMutexGuard aGuard( GetMutex() );
+ sal_Int16 nCount = --m_nRequestCount;
+ aGuard.clear();
+ OfficeIPCThread::RequestsCompleted( 1 );
+ if ( !nCount && !OfficeIPCThread::AreRequestsPending() )
+ {
+ // We have to check if we have an open task otherwise we have to shutdown the office.
+ Reference< XFramesSupplier > xTasksSupplier( ::comphelper::getProcessServiceFactory()->createInstance(
+ OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.Desktop")) ),
+ UNO_QUERY );
+ Reference< XElementAccess > xList( xTasksSupplier->getFrames(), UNO_QUERY );
+
+ if ( !xList->hasElements() )
+ {
+ // We don't have any task open so we have to shutdown ourself!!
+ Reference< XDesktop > xDesktop( xTasksSupplier, UNO_QUERY );
+ if ( xDesktop.is() )
+ xDesktop->terminate();
+ }
+ }
+}
+
+}
+
+
+
+
+
+
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/app/dispatchwatcher.hxx b/desktop/source/app/dispatchwatcher.hxx
new file mode 100644
index 000000000000..0fde60da603f
--- /dev/null
+++ b/desktop/source/app/dispatchwatcher.hxx
@@ -0,0 +1,130 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _DESKTOP_DISPATCHWATCHER_HXX
+#define _DESKTOP_DISPATCHWATCHER_HXX
+
+#include <cppuhelper/implbase1.hxx>
+#include <com/sun/star/frame/XNotifyingDispatch.hpp>
+#include <com/sun/star/frame/XDispatchResultListener.hpp>
+
+#include "officeipcthread.hxx"
+#include <boost/unordered_map.hpp>
+#include <vector>
+
+namespace desktop
+{
+
+/*
+ Class for controlls dispatching of command URL through office command line. There
+ are "dangerous" command URLs, that can result in a running office without UI. To prevent
+ this situation the implementation surveile all dispatches and looks for an open task if
+ there is arose a problem. If there is none the office will be shutdown to prevent a
+ running office without UI.
+*/
+
+struct OUStringHashCode
+{
+ size_t operator()( const ::rtl::OUString& sString ) const
+ {
+ return sString.hashCode();
+ }
+};
+
+class DispatchWatcherHashMap : public ::boost::unordered_map< ::rtl::OUString, sal_Int32, OUStringHashCode, ::std::equal_to< ::rtl::OUString > >
+{
+ public:
+ inline void free()
+ {
+ DispatchWatcherHashMap().swap( *this );
+ }
+};
+
+class DispatchWatcher : public ::cppu::WeakImplHelper1< ::com::sun::star::frame::XDispatchResultListener >
+{
+ public:
+ enum RequestType
+ {
+ REQUEST_OPEN,
+ REQUEST_VIEW,
+ REQUEST_START,
+ REQUEST_PRINT,
+ REQUEST_PRINTTO,
+ REQUEST_FORCEOPEN,
+ REQUEST_FORCENEW,
+ REQUEST_CONVERSION,
+ REQUEST_INFILTER,
+ REQUEST_BATCHPRINT
+ };
+
+ struct DispatchRequest
+ {
+ DispatchRequest( RequestType aType, const ::rtl::OUString& aFile, boost::optional< rtl::OUString > const & cwdUrl, const ::rtl::OUString& aPrinter, const ::rtl::OUString& aFact ) :
+ aRequestType( aType ), aURL( aFile ), aCwdUrl( cwdUrl ), aPrinterName( aPrinter ), aPreselectedFactory( aFact ) {}
+
+ RequestType aRequestType;
+ rtl::OUString aURL;
+ boost::optional< rtl::OUString > aCwdUrl;
+ rtl::OUString aPrinterName; // also conversion params
+ rtl::OUString aPreselectedFactory;
+ };
+
+ typedef std::vector< DispatchRequest > DispatchList;
+
+ virtual ~DispatchWatcher();
+
+ // XEventListener
+ virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source )
+ throw(::com::sun::star::uno::RuntimeException);
+
+ // XDispachResultListener
+ virtual void SAL_CALL dispatchFinished( const com::sun::star::frame::DispatchResultEvent& aEvent ) throw( com::sun::star::uno::RuntimeException );
+
+ // Access function to get a dispatcher watcher reference. There must be a global reference holder
+ static DispatchWatcher* GetDispatchWatcher();
+
+ // execute new dispatch request
+ sal_Bool executeDispatchRequests( const DispatchList& aDispatches, bool bNoTerminate = false );
+
+ private:
+ DispatchWatcher();
+
+ static ::osl::Mutex& GetMutex();
+
+ DispatchWatcherHashMap m_aRequestContainer;
+
+ static ::osl::Mutex* pWatcherMutex;
+
+ sal_Int16 m_nRequestCount;
+};
+
+}
+
+#endif // _DESKTOP_DISPATCHWATCHER_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/app/exports.dxp b/desktop/source/app/exports.dxp
new file mode 100755
index 000000000000..f0e1c69934bc
--- /dev/null
+++ b/desktop/source/app/exports.dxp
@@ -0,0 +1,2 @@
+component_getImplementationEnvironment
+component_getFactory
diff --git a/desktop/source/app/langselect.cxx b/desktop/source/app/langselect.cxx
new file mode 100644
index 000000000000..13421d3cde7d
--- /dev/null
+++ b/desktop/source/app/langselect.cxx
@@ -0,0 +1,563 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include "app.hxx"
+#include "langselect.hxx"
+#include "cmdlineargs.hxx"
+#include <stdio.h>
+
+#include <rtl/string.hxx>
+#include <rtl/bootstrap.hxx>
+#include <unotools/pathoptions.hxx>
+#include <tools/resid.hxx>
+#include <tools/config.hxx>
+#include <i18npool/mslangid.hxx>
+#include <comphelper/processfactory.hxx>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <com/sun/star/util/XChangesBatch.hpp>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/lang/XLocalizable.hpp>
+#include <com/sun/star/lang/Locale.hpp>
+#include "com/sun/star/util/XFlushable.hpp"
+#include <rtl/locale.hxx>
+#include <rtl/instance.hxx>
+#include <osl/process.h>
+#include <osl/file.hxx>
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::container;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::util;
+
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+using ::rtl::OString;
+
+namespace desktop {
+
+static char const SOFFICE_BOOTSTRAP[] = "Bootstrap";
+static char const SOFFICE_STARTLANG[] = "STARTLANG";
+
+sal_Bool LanguageSelection::bFoundLanguage = sal_False;
+OUString LanguageSelection::aFoundLanguage;
+LanguageSelection::LanguageSelectionStatus LanguageSelection::m_eStatus = LS_STATUS_OK;
+
+const OUString LanguageSelection::usFallbackLanguage(RTL_CONSTASCII_USTRINGPARAM("en-US"));
+
+static sal_Bool existsURL( OUString const& sURL )
+{
+ using namespace osl;
+ DirectoryItem aDirItem;
+
+ if (sURL.getLength() != 0)
+ return ( DirectoryItem::get( sURL, aDirItem ) == DirectoryItem::E_None );
+
+ return sal_False;
+}
+
+// locate soffice.ini/.rc file
+static OUString locateSofficeIniFile()
+{
+ OUString aUserDataPath;
+ OUString aSofficeIniFileURL;
+
+ // Retrieve the default file URL for the soffice.ini/rc
+ rtl::Bootstrap().getIniName( aSofficeIniFileURL );
+
+ if ( utl::Bootstrap::locateUserData( aUserDataPath ) == utl::Bootstrap::PATH_EXISTS )
+ {
+ const char CONFIG_DIR[] = "/config";
+
+ sal_Int32 nIndex = aSofficeIniFileURL.lastIndexOf( '/');
+ if ( nIndex > 0 )
+ {
+ OUString aUserSofficeIniFileURL;
+ OUStringBuffer aBuffer( aUserDataPath );
+ aBuffer.appendAscii( CONFIG_DIR );
+ aBuffer.append( aSofficeIniFileURL.copy( nIndex ));
+ aUserSofficeIniFileURL = aBuffer.makeStringAndClear();
+
+ if ( existsURL( aUserSofficeIniFileURL ))
+ return aUserSofficeIniFileURL;
+ }
+ }
+ // Fallback try to use the soffice.ini/rc from program folder
+ return aSofficeIniFileURL;
+}
+
+Locale LanguageSelection::IsoStringToLocale(const OUString& str)
+{
+ Locale l;
+ sal_Int32 index=0;
+ l.Language = str.getToken(0, '-', index);
+ if (index >= 0) l.Country = str.getToken(0, '-', index);
+ if (index >= 0) l.Variant = str.getToken(0, '-', index);
+ return l;
+}
+
+bool LanguageSelection::prepareLanguage()
+{
+ m_eStatus = LS_STATUS_OK;
+ OUString sConfigSrvc = OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.configuration.ConfigurationProvider"));
+ Reference< XMultiServiceFactory > theMSF = comphelper::getProcessServiceFactory();
+ Reference< XLocalizable > theConfigProvider;
+ try
+ {
+ theConfigProvider = Reference< XLocalizable >(theMSF->createInstance( sConfigSrvc ),UNO_QUERY_THROW );
+ }
+ catch(const Exception&)
+ {
+ m_eStatus = LS_STATUS_CONFIGURATIONACCESS_BROKEN;
+ }
+
+ if(!theConfigProvider.is())
+ return false;
+
+ sal_Bool bSuccess = sal_False;
+
+ // #i42730#get the windows 16Bit locale - it should be preferred over the UI language
+ try
+ {
+ Reference< XPropertySet > xProp(getConfigAccess("org.openoffice.System/L10N/", sal_False), UNO_QUERY_THROW);
+ Any aWin16SysLocale = xProp->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("SystemLocale")));
+ ::rtl::OUString sWin16SysLocale;
+ aWin16SysLocale >>= sWin16SysLocale;
+ if( sWin16SysLocale.getLength())
+ setDefaultLanguage(sWin16SysLocale);
+ }
+ catch(const Exception&)
+ {
+ m_eStatus = LS_STATUS_CONFIGURATIONACCESS_BROKEN;
+ }
+
+ // #i32939# use system locale to set document default locale
+ try
+ {
+ OUString usLocale;
+ Reference< XPropertySet > xLocaleProp(getConfigAccess(
+ "org.openoffice.System/L10N", sal_True), UNO_QUERY_THROW);
+ xLocaleProp->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("Locale"))) >>= usLocale;
+ setDefaultLanguage(usLocale);
+ }
+ catch (Exception&)
+ {
+ m_eStatus = LS_STATUS_CONFIGURATIONACCESS_BROKEN;
+ }
+
+ // get the selected UI language as string
+ bool bCmdLanguage( false );
+ bool bIniLanguage( false );
+ OUString aEmpty;
+ OUString aLocaleString = getUserUILanguage();
+
+ if ( aLocaleString.getLength() == 0 )
+ {
+ CommandLineArgs* pCmdLineArgs = Desktop::GetCommandLineArgs();
+ if ( pCmdLineArgs )
+ {
+ pCmdLineArgs->GetLanguage(aLocaleString);
+ if (isInstalledLanguage(aLocaleString, sal_False))
+ {
+ bCmdLanguage = true;
+ bFoundLanguage = true;
+ aFoundLanguage = aLocaleString;
+ }
+ else
+ aLocaleString = aEmpty;
+ }
+
+ if ( !bCmdLanguage )
+ {
+ OUString aSOfficeIniURL = locateSofficeIniFile();
+ Config aConfig(aSOfficeIniURL);
+ aConfig.SetGroup( SOFFICE_BOOTSTRAP );
+ OString sLang = aConfig.ReadKey( SOFFICE_STARTLANG );
+ aLocaleString = OUString( sLang.getStr(), sLang.getLength(), RTL_TEXTENCODING_ASCII_US );
+ if (isInstalledLanguage(aLocaleString, sal_False))
+ {
+ bIniLanguage = true;
+ bFoundLanguage = true;
+ aFoundLanguage = aLocaleString;
+ }
+ else
+ aLocaleString = aEmpty;
+ }
+ }
+
+ // user further fallbacks for the UI language
+ if ( aLocaleString.getLength() == 0 )
+ aLocaleString = getLanguageString();
+
+ if ( aLocaleString.getLength() > 0 )
+ {
+ try
+ {
+ // prepare default config provider by localizing it to the selected locale
+ // this will ensure localized configuration settings to be selected accoring to the
+ // UI language.
+ Locale loc = LanguageSelection::IsoStringToLocale(aLocaleString);
+ // flush any data already written to the configuration (which
+ // currently uses independent caches for different locales and thus
+ // would ignore data written to another cache):
+ Reference< XFlushable >(theConfigProvider, UNO_QUERY_THROW)->
+ flush();
+ theConfigProvider->setLocale(loc);
+
+ Reference< XPropertySet > xProp(getConfigAccess("org.openoffice.Setup/L10N/", sal_True), UNO_QUERY_THROW);
+ if ( !bCmdLanguage )
+ {
+ // Store language only
+ xProp->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("ooLocale")), makeAny(aLocaleString));
+ Reference< XChangesBatch >(xProp, UNO_QUERY_THROW)->commitChanges();
+ }
+
+ if ( bIniLanguage )
+ {
+ // Store language only
+ Reference< XPropertySet > xProp2(getConfigAccess("org.openoffice.Office.Linguistic/General/", sal_True), UNO_QUERY_THROW);
+ xProp2->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("UILocale")), makeAny(aLocaleString));
+ Reference< XChangesBatch >(xProp2, UNO_QUERY_THROW)->commitChanges();
+ }
+
+ MsLangId::setConfiguredSystemUILanguage( MsLangId::convertLocaleToLanguage(loc) );
+
+ OUString sLocale;
+ xProp->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("ooSetupSystemLocale"))) >>= sLocale;
+ if ( sLocale.getLength() )
+ {
+ loc = LanguageSelection::IsoStringToLocale(sLocale);
+ MsLangId::setConfiguredSystemLanguage( MsLangId::convertLocaleToLanguage(loc) );
+ }
+ else
+ MsLangId::setConfiguredSystemLanguage( MsLangId::getSystemLanguage() );
+
+ bSuccess = sal_True;
+ }
+ catch ( PropertyVetoException& )
+ {
+ // we are not allowed to change this
+ }
+ catch (Exception& e)
+ {
+ OString aMsg = OUStringToOString(e.Message, RTL_TEXTENCODING_ASCII_US);
+ OSL_FAIL(aMsg.getStr());
+
+ }
+ }
+
+ // #i32939# setting of default document locale
+ // #i32939# this should not be based on the UI language
+ setDefaultLanguage(aLocaleString);
+
+ return bSuccess;
+}
+
+void LanguageSelection::setDefaultLanguage(const OUString& sLocale)
+{
+ // #i32939# setting of default document language
+ // See #i42730# for rules for determining source of settings
+
+ // determine script type of locale
+ LanguageType nLang = MsLangId::convertIsoStringToLanguage(sLocale);
+ sal_uInt16 nScriptType = SvtLanguageOptions::GetScriptTypeOfLanguage(nLang);
+
+ switch (nScriptType)
+ {
+ case SCRIPTTYPE_ASIAN:
+ MsLangId::setConfiguredAsianFallback( nLang );
+ break;
+ case SCRIPTTYPE_COMPLEX:
+ MsLangId::setConfiguredComplexFallback( nLang );
+ break;
+ default:
+ MsLangId::setConfiguredWesternFallback( nLang );
+ break;
+ }
+}
+
+OUString LanguageSelection::getUserUILanguage()
+{
+ // check whether the user has selected a specific language
+ OUString aUserLanguage = getUserLanguage();
+ if (aUserLanguage.getLength() > 0 )
+ {
+ if (isInstalledLanguage(aUserLanguage))
+ {
+ // all is well
+ bFoundLanguage = sal_True;
+ aFoundLanguage = aUserLanguage;
+ return aFoundLanguage;
+ }
+ else
+ {
+ // selected language is not/no longer installed
+ resetUserLanguage();
+ }
+ }
+
+ return aUserLanguage;
+}
+
+OUString LanguageSelection::getLanguageString()
+{
+ // did we already find a language?
+ if (bFoundLanguage)
+ return aFoundLanguage;
+
+ // check whether the user has selected a specific language
+ OUString aUserLanguage = getUserUILanguage();
+ if (aUserLanguage.getLength() > 0 )
+ return aUserLanguage ;
+
+ // try to use system default
+ aUserLanguage = getSystemLanguage();
+ if (aUserLanguage.getLength() > 0 )
+ {
+ if (isInstalledLanguage(aUserLanguage, sal_False))
+ {
+ // great, system default language is available
+ bFoundLanguage = sal_True;
+ aFoundLanguage = aUserLanguage;
+ return aFoundLanguage;
+ }
+ }
+ // fallback 1: en-US
+ OUString usFB = usFallbackLanguage;
+ if (isInstalledLanguage(usFB))
+ {
+ bFoundLanguage = sal_True;
+ aFoundLanguage = usFallbackLanguage;
+ return aFoundLanguage;
+ }
+
+ // fallback didn't work use first installed language
+ aUserLanguage = getFirstInstalledLanguage();
+
+ bFoundLanguage = sal_True;
+ aFoundLanguage = aUserLanguage;
+ return aFoundLanguage;
+}
+
+Reference< XNameAccess > LanguageSelection::getConfigAccess(const sal_Char* pPath, sal_Bool bUpdate)
+{
+ Reference< XNameAccess > xNameAccess;
+ try{
+ OUString sConfigSrvc(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.configuration.ConfigurationProvider"));
+ OUString sAccessSrvc;
+ if (bUpdate)
+ sAccessSrvc = OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.configuration.ConfigurationUpdateAccess"));
+ else
+ sAccessSrvc = OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.configuration.ConfigurationAccess"));
+
+ OUString sConfigURL = OUString::createFromAscii(pPath);
+
+ // get configuration provider
+ Reference< XMultiServiceFactory > theMSF = comphelper::getProcessServiceFactory();
+ if (theMSF.is()) {
+ Reference< XMultiServiceFactory > theConfigProvider = Reference< XMultiServiceFactory > (
+ theMSF->createInstance( sConfigSrvc ),UNO_QUERY_THROW );
+
+ // access the provider
+ Sequence< Any > theArgs(1);
+ theArgs[ 0 ] <<= sConfigURL;
+ xNameAccess = Reference< XNameAccess > (
+ theConfigProvider->createInstanceWithArguments(
+ sAccessSrvc, theArgs ), UNO_QUERY_THROW );
+ }
+ } catch (com::sun::star::uno::Exception& e)
+ {
+ OString aMsg = OUStringToOString(e.Message, RTL_TEXTENCODING_ASCII_US);
+ OSL_FAIL(aMsg.getStr());
+ }
+ return xNameAccess;
+}
+
+Sequence< OUString > LanguageSelection::getInstalledLanguages()
+{
+ Sequence< OUString > seqLanguages;
+ Reference< XNameAccess > xAccess = getConfigAccess("org.openoffice.Setup/Office/InstalledLocales", sal_False);
+ if (!xAccess.is()) return seqLanguages;
+ seqLanguages = xAccess->getElementNames();
+ return seqLanguages;
+}
+
+// FIXME
+// it's not very clever to handle language fallbacks here, but
+// right now, there is no place that handles those fallbacks globally
+static Sequence< OUString > _getFallbackLocales(const OUString& aIsoLang)
+{
+ Sequence< OUString > seqFallbacks;
+ if (aIsoLang.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("zh-HK"))) {
+ seqFallbacks = Sequence< OUString >(1);
+ seqFallbacks[0] = OUString(RTL_CONSTASCII_USTRINGPARAM("zh-TW"));
+ }
+ return seqFallbacks;
+}
+
+sal_Bool LanguageSelection::isInstalledLanguage(OUString& usLocale, sal_Bool bExact)
+{
+ sal_Bool bInstalled = sal_False;
+ Sequence< OUString > seqLanguages = getInstalledLanguages();
+ for (sal_Int32 i=0; i<seqLanguages.getLength(); i++)
+ {
+ if (usLocale.equals(seqLanguages[i]))
+ {
+ bInstalled = sal_True;
+ break;
+ }
+ }
+
+ if (!bInstalled && !bExact)
+ {
+ // try fallback locales
+ Sequence< OUString > seqFallbacks = _getFallbackLocales(usLocale);
+ for (sal_Int32 j=0; j<seqFallbacks.getLength(); j++)
+ {
+ for (sal_Int32 i=0; i<seqLanguages.getLength(); i++)
+ {
+ if (seqFallbacks[j].equals(seqLanguages[i]))
+ {
+ bInstalled = sal_True;
+ usLocale = seqFallbacks[j];
+ break;
+ }
+ }
+ }
+ }
+
+ if (!bInstalled && !bExact)
+ {
+ // no exact match was found, well try to find a substitute
+ OUString aInstalledLocale;
+ for (sal_Int32 i=0; i<seqLanguages.getLength(); i++)
+ {
+ if (usLocale.indexOf(seqLanguages[i]) == 0)
+ {
+ // requested locale starts with the installed locale
+ // (i.e. installed locale has index 0 in requested locale)
+ bInstalled = sal_True;
+ usLocale = seqLanguages[i];
+ break;
+ }
+ }
+ }
+ return bInstalled;
+}
+
+OUString LanguageSelection::getFirstInstalledLanguage()
+{
+ OUString aLanguage;
+ Sequence< OUString > seqLanguages = getInstalledLanguages();
+ if (seqLanguages.getLength() > 0)
+ aLanguage = seqLanguages[0];
+ return aLanguage;
+}
+
+OUString LanguageSelection::getUserLanguage()
+{
+ OUString aUserLanguage;
+ Reference< XNameAccess > xAccess(getConfigAccess("org.openoffice.Office.Linguistic/General", sal_False));
+ if (xAccess.is())
+ {
+ try
+ {
+ xAccess->getByName(OUString(RTL_CONSTASCII_USTRINGPARAM("UILocale"))) >>= aUserLanguage;
+ }
+ catch ( NoSuchElementException const & )
+ {
+ m_eStatus = LS_STATUS_CONFIGURATIONACCESS_BROKEN;
+ return OUString();
+ }
+ catch ( WrappedTargetException const & )
+ {
+ m_eStatus = LS_STATUS_CONFIGURATIONACCESS_BROKEN;
+ return OUString();
+ }
+ }
+ return aUserLanguage;
+}
+
+OUString LanguageSelection::getSystemLanguage()
+{
+ OUString aUserLanguage;
+ Reference< XNameAccess > xAccess(getConfigAccess("org.openoffice.System/L10N", sal_False));
+ if (xAccess.is())
+ {
+ try
+ {
+ xAccess->getByName(OUString(RTL_CONSTASCII_USTRINGPARAM("UILocale"))) >>= aUserLanguage;
+ }
+ catch ( NoSuchElementException const & )
+ {
+ m_eStatus = LS_STATUS_CONFIGURATIONACCESS_BROKEN;
+ return OUString();
+ }
+ catch ( WrappedTargetException const & )
+ {
+ m_eStatus = LS_STATUS_CONFIGURATIONACCESS_BROKEN;
+ return OUString();
+ }
+ }
+ return aUserLanguage;
+}
+
+
+void LanguageSelection::resetUserLanguage()
+{
+ try
+ {
+ Reference< XPropertySet > xProp(getConfigAccess("org.openoffice.Office.Linguistic/General", sal_True), UNO_QUERY_THROW);
+ xProp->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("UILocale")), makeAny(OUString()));
+ Reference< XChangesBatch >(xProp, UNO_QUERY_THROW)->commitChanges();
+ }
+ catch ( PropertyVetoException& )
+ {
+ // we are not allowed to change this
+ }
+ catch ( Exception& e)
+ {
+ OString aMsg = OUStringToOString(e.Message, RTL_TEXTENCODING_ASCII_US);
+ OSL_FAIL(aMsg.getStr());
+ m_eStatus = LS_STATUS_CONFIGURATIONACCESS_BROKEN;
+ }
+}
+
+LanguageSelection::LanguageSelectionStatus LanguageSelection::getStatus()
+{
+ return m_eStatus;
+}
+
+} // namespace desktop
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/app/langselect.hxx b/desktop/source/app/langselect.hxx
new file mode 100644
index 000000000000..fdb229a47956
--- /dev/null
+++ b/desktop/source/app/langselect.hxx
@@ -0,0 +1,77 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <list>
+#include <sal/types.h>
+#include <tools/string.hxx>
+#include <rtl/ustring.hxx>
+#include <tools/resid.hxx>
+#include <com/sun/star/lang/Locale.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <svl/languageoptions.hxx>
+
+namespace desktop
+{
+
+class LanguageSelection
+{
+public:
+ enum LanguageSelectionStatus
+ {
+ LS_STATUS_OK,
+ LS_STATUS_CANNOT_DETERMINE_LANGUAGE,
+ LS_STATUS_CONFIGURATIONACCESS_BROKEN
+ };
+
+ static com::sun::star::lang::Locale IsoStringToLocale(const rtl::OUString& str);
+ static rtl::OUString getLanguageString();
+ static bool prepareLanguage();
+ static LanguageSelectionStatus getStatus();
+
+private:
+ static const rtl::OUString usFallbackLanguage;
+ static rtl::OUString aFoundLanguage;
+ static sal_Bool bFoundLanguage;
+ static LanguageSelectionStatus m_eStatus;
+
+ static com::sun::star::uno::Reference< com::sun::star::container::XNameAccess >
+ getConfigAccess(const sal_Char* pPath, sal_Bool bUpdate=sal_False);
+ static com::sun::star::uno::Sequence< rtl::OUString > getInstalledLanguages();
+ static sal_Bool isInstalledLanguage(rtl::OUString& usLocale, sal_Bool bExact=sal_False);
+ static rtl::OUString getFirstInstalledLanguage();
+ static rtl::OUString getUserUILanguage();
+ static rtl::OUString getUserLanguage();
+ static rtl::OUString getSystemLanguage();
+ static void resetUserLanguage();
+ static void setDefaultLanguage(const rtl::OUString&);
+};
+
+} //namespace desktop
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/app/lockfile.cxx b/desktop/source/app/lockfile.cxx
new file mode 100644
index 000000000000..72632bdb5e27
--- /dev/null
+++ b/desktop/source/app/lockfile.cxx
@@ -0,0 +1,238 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+#include <stdlib.h>
+#include <time.h>
+#ifndef WNT
+#include <unistd.h>
+#else
+#include <windows.h>
+#endif
+#include <sal/types.h>
+#include <osl/file.hxx>
+#include <osl/socket.hxx>
+#include <osl/security.hxx>
+#include <unotools/bootstrap.hxx>
+#include <tools/string.hxx>
+#include <tools/config.hxx>
+
+#include "lockfile.hxx"
+
+
+using namespace ::osl;
+using namespace ::rtl;
+using namespace ::utl;
+
+
+static rtl::OString impl_getHostname()
+{
+ rtl::OString aHost;
+#ifdef WNT
+ /*
+ prevent windows from connecting to the net to get it's own
+ hostname by using the netbios name
+ */
+ sal_Int32 sz = MAX_COMPUTERNAME_LENGTH + 1;
+ char* szHost = new char[sz];
+ if (GetComputerName(szHost, (LPDWORD)&sz))
+ aHost = OString(szHost);
+ else
+ aHost = OString("UNKNOWN");
+ delete[] szHost;
+#else
+ /* Don't do dns lookup on Linux either */
+ sal_Char pHostName[1024];
+
+ if ( gethostname( pHostName, sizeof( pHostName ) - 1 ) == 0 )
+ {
+ pHostName[sizeof( pHostName ) - 1] = '\0';
+ aHost = OString( pHostName );
+ }
+ else
+ aHost = OString("UNKNOWN");
+#endif
+
+ return aHost;
+}
+
+namespace desktop {
+
+ Lockfile::Lockfile( bool bIPCserver )
+ :m_bIPCserver(bIPCserver)
+ ,m_bRemove(sal_False)
+ ,m_bIsLocked(sal_False)
+ {
+ // build the file-url to use for the lock
+ OUString aUserPath;
+ utl::Bootstrap::locateUserInstallation( aUserPath );
+ m_aLockname = aUserPath + LOCKFILE_SUFFIX;
+
+ // generate ID
+ const int nIdBytes = 16;
+ char tmpId[nIdBytes*2+1];
+ time_t t;
+ srand( (unsigned)(t = time( NULL )) );
+ int tmpByte = 0;
+ for (int i = 0; i<nIdBytes; i++) {
+ tmpByte = rand( ) % 0xFF;
+ sprintf( tmpId+i*2, "%02X", tmpByte );
+ }
+ tmpId[nIdBytes*2]=0x00;
+ m_aId = OUString::createFromAscii( tmpId );
+
+ // generate date string
+ char *tmpTime = ctime( &t );
+ if (tmpTime != NULL) {
+ m_aDate = OUString::createFromAscii( tmpTime );
+ sal_Int32 i = m_aDate.indexOf('\n');
+ if (i > 0)
+ m_aDate = m_aDate.copy(0, i);
+ }
+
+
+ // try to create file
+ File aFile(m_aLockname);
+ if (aFile.open( osl_File_OpenFlag_Create ) == File::E_EXIST) {
+ m_bIsLocked = sal_True;
+ } else {
+ // new lock created
+ aFile.close( );
+ syncToFile( );
+ m_bRemove = sal_True;
+ }
+ }
+
+ sal_Bool Lockfile::check( fpExecWarning execWarning )
+ {
+
+ if (m_bIsLocked) {
+ // lock existed, ask user what to do
+ if (isStale() ||
+ (execWarning != 0 && (*execWarning)( this ))) {
+ // remove file and create new
+ File::remove( m_aLockname );
+ File aFile(m_aLockname);
+ aFile.open( osl_File_OpenFlag_Create );
+ aFile.close( );
+ syncToFile( );
+ m_bRemove = sal_True;
+ return sal_True;
+ } else {
+ //leave alone and return false
+ m_bRemove = sal_False;
+ return sal_False;
+ }
+ } else {
+ // lock was created by us
+ return sal_True;
+ }
+ }
+
+ sal_Bool Lockfile::isStale( void ) const
+ {
+ // this checks whether the lockfile was created on the same
+ // host by the same user. Should this be the case it is safe
+ // to assume that it is a stale lockfile which can be overwritten
+ String aLockname = m_aLockname;
+ Config aConfig(aLockname);
+ aConfig.SetGroup(LOCKFILE_GROUP);
+ rtl::OString aIPCserver = aConfig.ReadKey( LOCKFILE_IPCKEY );
+ if (!aIPCserver.equalsIgnoreAsciiCase(rtl::OString("true")))
+ return false;
+
+ rtl::OString aHost = aConfig.ReadKey( LOCKFILE_HOSTKEY );
+ rtl::OString aUser = aConfig.ReadKey( LOCKFILE_USERKEY );
+
+ // lockfile from same host?
+ rtl::OString myHost( impl_getHostname() );
+ if (aHost == myHost) {
+ // lockfile by same UID
+ OUString myUserName;
+ Security aSecurity;
+ aSecurity.getUserName( myUserName );
+ rtl::OString myUser(rtl::OUStringToOString(myUserName, RTL_TEXTENCODING_ASCII_US));
+ if (aUser == myUser)
+ return sal_True;
+ }
+ return sal_False;
+ }
+
+ void Lockfile::syncToFile( void ) const
+ {
+ String aLockname = m_aLockname;
+ Config aConfig(aLockname);
+ aConfig.SetGroup(LOCKFILE_GROUP);
+
+ // get information
+ rtl::OString aHost( impl_getHostname() );
+ OUString aUserName;
+ Security aSecurity;
+ aSecurity.getUserName( aUserName );
+ rtl::OString aUser = OUStringToOString( aUserName, RTL_TEXTENCODING_ASCII_US );
+ rtl::OString aTime = OUStringToOString( m_aDate, RTL_TEXTENCODING_ASCII_US );
+ rtl::OString aStamp = OUStringToOString( m_aId, RTL_TEXTENCODING_ASCII_US );
+
+ // write information
+ aConfig.WriteKey( LOCKFILE_USERKEY, aUser );
+ aConfig.WriteKey( LOCKFILE_HOSTKEY, aHost );
+ aConfig.WriteKey( LOCKFILE_STAMPKEY, aStamp );
+ aConfig.WriteKey( LOCKFILE_TIMEKEY, aTime );
+ aConfig.WriteKey(
+ LOCKFILE_IPCKEY,
+ m_bIPCserver ? rtl::OString("true") : rtl::OString("false") );
+ aConfig.Flush( );
+ }
+
+ void Lockfile::clean( void )
+ {
+ if ( m_bRemove )
+ {
+ File::remove( m_aLockname );
+ m_bRemove = sal_False;
+ }
+ }
+
+ Lockfile::~Lockfile( void )
+ {
+ // unlock userdata by removing file
+ if ( m_bRemove )
+ File::remove( m_aLockname );
+ }
+}
+
+
+
+
+
+
+
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/app/lockfile.hxx b/desktop/source/app/lockfile.hxx
new file mode 100644
index 000000000000..5444714ec88c
--- /dev/null
+++ b/desktop/source/app/lockfile.hxx
@@ -0,0 +1,101 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+/* Information:
+ * This class implements a mechanism to lock a users installation directory,
+ * which is necessesary because instances of staroffice could be running on
+ * different hosts while using the same directory thus causing data
+ * inconsistency.
+ * When an existing lock is detected, the user will be asked whether he wants
+ * to continue anyway, thus removing the lock and replacing it with a new one
+ *
+ * ideas:
+ * - store information about user and host and time in the lockfile and display
+ * these when asking whether to remove the lockfile.
+ * - periodically check the lockfile and warn the user when it gets replaced
+ *
+ */
+
+#include "sal/types.h"
+#include "rtl/ustring.hxx"
+
+class ByteString;
+
+#define LOCKFILE_SUFFIX rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/.lock" ) )
+#define LOCKFILE_GROUP ByteString( "Lockdata" )
+#define LOCKFILE_USERKEY ByteString( "User" )
+#define LOCKFILE_HOSTKEY ByteString( "Host" )
+#define LOCKFILE_STAMPKEY ByteString( "Stamp" )
+#define LOCKFILE_TIMEKEY ByteString( "Time" )
+#define LOCKFILE_IPCKEY ByteString( "IPCServer" )
+
+namespace desktop {
+
+ class Lockfile;
+ bool Lockfile_execWarning( Lockfile * that );
+
+ class Lockfile
+ {
+ public:
+
+ // contructs a new lockfile onject
+ Lockfile( bool bIPCserver = true );
+
+ // separating GUI code:
+ typedef bool (* fpExecWarning)( Lockfile * that );
+
+ // checks the lockfile, asks user when lockfile is
+ // found (iff gui) and returns false when we may not continue
+ sal_Bool check( fpExecWarning execWarning );
+
+ // removes the lockfile. should only be called in exceptional situations
+ void clean(void);
+
+ // removes the lockfile
+ ~Lockfile(void);
+
+ private:
+ bool m_bIPCserver;
+ // full qualified name (file://-url) of the lockfile
+ rtl::OUString m_aLockname;
+ // flag whether the d'tor should delete the lock
+ sal_Bool m_bRemove;
+ sal_Bool m_bIsLocked;
+ // ID
+ rtl::OUString m_aId;
+ rtl::OUString m_aDate;
+ // access to data in file
+ void syncToFile(void) const;
+ sal_Bool isStale(void) const;
+ friend bool Lockfile_execWarning( Lockfile * that );
+
+ };
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/app/lockfile2.cxx b/desktop/source/app/lockfile2.cxx
new file mode 100644
index 000000000000..619102b70c2b
--- /dev/null
+++ b/desktop/source/app/lockfile2.cxx
@@ -0,0 +1,72 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include "vcl/msgbox.hxx"
+#include "desktopresid.hxx"
+#include "desktop.hrc"
+#include "tools/config.hxx"
+#include "lockfile.hxx"
+
+
+namespace desktop {
+
+bool Lockfile_execWarning( Lockfile * that )
+{
+ // read information from lock
+ String aLockname = that->m_aLockname;
+ Config aConfig(aLockname);
+ aConfig.SetGroup( LOCKFILE_GROUP );
+ ByteString aHost = aConfig.ReadKey( LOCKFILE_HOSTKEY );
+ ByteString aUser = aConfig.ReadKey( LOCKFILE_USERKEY );
+ ByteString aStamp = aConfig.ReadKey( LOCKFILE_STAMPKEY );
+ ByteString aTime = aConfig.ReadKey( LOCKFILE_TIMEKEY );
+
+ // display warning and return response
+ QueryBox aBox( NULL, DesktopResId( QBX_USERDATALOCKED ) );
+ // set box title
+ String aTitle = String( DesktopResId( STR_TITLE_USERDATALOCKED ));
+ aBox.SetText( aTitle );
+ // insert values...
+ String aMsgText = aBox.GetMessText( );
+ aMsgText.SearchAndReplaceAscii(
+ "$u", String( aUser, RTL_TEXTENCODING_ASCII_US) );
+ aMsgText.SearchAndReplaceAscii(
+ "$h", String( aHost, RTL_TEXTENCODING_ASCII_US) );
+ aMsgText.SearchAndReplaceAscii(
+ "$t", String( aTime, RTL_TEXTENCODING_ASCII_US) );
+ aBox.SetMessText(aMsgText);
+ // do it
+ return aBox.Execute( ) == RET_YES;
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/app/main.c b/desktop/source/app/main.c
new file mode 100755
index 000000000000..88610ba18ef9
--- /dev/null
+++ b/desktop/source/app/main.c
@@ -0,0 +1,39 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "sal/config.h"
+
+#include "sal/main.h"
+
+#include "sofficemain.h"
+
+SAL_IMPLEMENT_MAIN() {
+ return soffice_main();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/app/makefile.mk b/desktop/source/app/makefile.mk
new file mode 100755
index 000000000000..e7c30a2ca70f
--- /dev/null
+++ b/desktop/source/app/makefile.mk
@@ -0,0 +1,119 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+PRJNAME=desktop
+TARGET=dkt
+AUTOSEG=true
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE : ../deployment/inc/dp_misc.mk
+
+.IF "$(ENABLE_GNOMEVFS)"=="TRUE"
+CFLAGS+=-DGNOME_VFS_ENABLED
+.ENDIF
+
+# .IF "$(OS)" == "WNT"
+# .IF "$(COM)" == "GCC"
+# DEPLOYMENTMISCLIB = -ldeploymentmisc$(DLLPOSTFIX)
+# .ELSE
+# DEPLOYMENTMISCLIB = ideploymentmisc$(DLLPOSTFIX).lib
+# .ENDIF
+# .ELIF "$(OS)" == "OS2"
+# DEPLOYMENTMISCLIB = ideploymentmisc$(DLLPOSTFIX).lib
+# .ELSE
+# DEPLOYMENTMISCLIB = -ldeploymentmisc$(DLLPOSTFIX)
+# .ENDIF
+
+.IF "$(GUI)"=="WNT" || "$(GUI)"=="OS2" || "$(GUIBASE)"=="aqua" || "$(ENABLE_SYSTRAY_GTK)"=="TRUE"
+CFLAGS+=-DENABLE_QUICKSTART_APPLET
+.ENDIF
+
+SHL1TARGET = sofficeapp
+SHL1OBJS = \
+ $(SLO)$/app.obj \
+ $(SLO)$/appfirststart.obj \
+ $(SLO)$/appinit.obj \
+ $(SLO)$/appsys.obj \
+ $(SLO)$/checkinstall.obj \
+ $(SLO)$/check_ext_deps.obj \
+ $(SLO)$/cmdlineargs.obj \
+ $(SLO)$/cmdlinehelp.obj \
+ $(SLO)$/configinit.obj \
+ $(SLO)$/desktopcontext.obj \
+ $(SLO)$/desktopresid.obj \
+ $(SLO)$/dispatchwatcher.obj \
+ $(SLO)$/langselect.obj \
+ $(SLO)$/lockfile.obj \
+ $(SLO)$/lockfile2.obj \
+ $(SLO)$/officeipcthread.obj \
+ $(SLO)$/sofficemain.obj \
+ $(SLO)$/userinstall.obj
+
+SHL1LIBS = $(SLB)$/mig.lib
+
+SHL1STDLIBS = \
+ $(COMPHELPERLIB) \
+ $(CPPUHELPERLIB) \
+ $(CPPULIB) \
+ $(DEPLOYMENTMISCLIB) \
+ $(I18NISOLANGLIB) \
+ $(SALLIB) \
+ $(SFXLIB) \
+ $(SVLLIB) \
+ $(SVTOOLLIB) \
+ $(TKLIB) \
+ $(TOOLSLIB) \
+ $(UCBHELPERLIB) \
+ $(UNOTOOLSLIB) \
+ $(VCLLIB) \
+
+SHL1VERSIONMAP = version.map
+SHL1IMPLIB = i$(SHL1TARGET)
+DEF1NAME = $(SHL1TARGET)
+
+OBJFILES = \
+ $(OBJ)$/copyright_ascii_ooo.obj \
+ $(OBJ)$/main.obj
+.IF "$(GUI)" != "OS2"
+OBJFILES += \
+ $(OBJ)$/copyright_ascii_sun.obj
+.ENDIF
+
+SLOFILES = $(SHL1OBJS)
+
+SRS1NAME= desktop
+SRC1FILES= desktop.src
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/desktop/source/app/officeipcthread.cxx b/desktop/source/app/officeipcthread.cxx
new file mode 100644
index 000000000000..652d4c8dd416
--- /dev/null
+++ b/desktop/source/app/officeipcthread.cxx
@@ -0,0 +1,1043 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include "app.hxx"
+#include "officeipcthread.hxx"
+#include "cmdlineargs.hxx"
+#include "dispatchwatcher.hxx"
+#include <memory>
+#include <stdio.h>
+#include <osl/process.h>
+#include <unotools/bootstrap.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/help.hxx>
+#include <unotools/configmgr.hxx>
+#include <osl/thread.hxx>
+#include <rtl/digest.h>
+#include <rtl/ustrbuf.hxx>
+#include <rtl/instance.hxx>
+#include <osl/conditn.hxx>
+#include <unotools/moduleoptions.hxx>
+#include <rtl/bootstrap.hxx>
+#include <rtl/strbuf.hxx>
+#include <comphelper/processfactory.hxx>
+#include <osl/file.hxx>
+#include "rtl/process.h"
+#include "tools/getprocessworkingdir.hxx"
+
+using namespace desktop;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::frame;
+
+using ::rtl::OString;
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+
+const char *OfficeIPCThread::sc_aTerminationSequence = "InternalIPC::TerminateThread";
+const int OfficeIPCThread::sc_nTSeqLength = 28;
+const char *OfficeIPCThread::sc_aShowSequence = "-tofront";
+const int OfficeIPCThread::sc_nShSeqLength = 5;
+const char *OfficeIPCThread::sc_aConfirmationSequence = "InternalIPC::ProcessingDone";
+const int OfficeIPCThread::sc_nCSeqLength = 27;
+
+namespace { static char const ARGUMENT_PREFIX[] = "InternalIPC::Arguments"; }
+
+// Type of pipe we use
+enum PipeMode
+{
+ PIPEMODE_DONTKNOW,
+ PIPEMODE_CREATED,
+ PIPEMODE_CONNECTED
+};
+
+namespace desktop
+{
+
+namespace {
+
+class Parser: public CommandLineArgs::Supplier {
+public:
+ explicit Parser(rtl::OString const & input): m_input(input) {
+ if (!m_input.match(ARGUMENT_PREFIX) ||
+ m_input.getLength() == RTL_CONSTASCII_LENGTH(ARGUMENT_PREFIX))
+ {
+ throw CommandLineArgs::Supplier::Exception();
+ }
+ m_index = RTL_CONSTASCII_LENGTH(ARGUMENT_PREFIX);
+ switch (m_input[m_index++]) {
+ case '0':
+ break;
+ case '1':
+ {
+ rtl::OUString url;
+ if (!next(&url, false)) {
+ throw CommandLineArgs::Supplier::Exception();
+ }
+ m_cwdUrl.reset(url);
+ break;
+ }
+ case '2':
+ {
+ rtl::OUString path;
+ if (!next(&path, false)) {
+ throw CommandLineArgs::Supplier::Exception();
+ }
+ rtl::OUString url;
+ if (osl::FileBase::getFileURLFromSystemPath(path, url) ==
+ osl::FileBase::E_None)
+ {
+ m_cwdUrl.reset(url);
+ }
+ break;
+ }
+ default:
+ throw CommandLineArgs::Supplier::Exception();
+ }
+ }
+
+ virtual ~Parser() {}
+
+ virtual boost::optional< rtl::OUString > getCwdUrl() { return m_cwdUrl; }
+
+ virtual bool next(rtl::OUString * argument) { return next(argument, true); }
+
+private:
+ virtual bool next(rtl::OUString * argument, bool prefix) {
+ OSL_ASSERT(argument != NULL);
+ if (m_index < m_input.getLength()) {
+ if (prefix) {
+ if (m_input[m_index] != ',') {
+ throw CommandLineArgs::Supplier::Exception();
+ }
+ ++m_index;
+ }
+ rtl::OStringBuffer b;
+ while (m_index < m_input.getLength()) {
+ char c = m_input[m_index];
+ if (c == ',') {
+ break;
+ }
+ ++m_index;
+ if (c == '\\') {
+ if (m_index < m_input.getLength()) {
+ c = m_input[m_index++];
+ switch (c) {
+ case '0':
+ c = '\0';
+ break;
+ case ',':
+ case '\\':
+ break;
+ default:
+ throw CommandLineArgs::Supplier::Exception();
+ }
+ } else {
+ throw CommandLineArgs::Supplier::Exception();
+ }
+ }
+ b.append(c);
+ }
+ rtl::OString b2(b.makeStringAndClear());
+ if (!rtl_convertStringToUString(
+ &argument->pData, b2.getStr(), b2.getLength(),
+ RTL_TEXTENCODING_UTF8,
+ (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR |
+ RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR |
+ RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR)))
+ {
+ throw CommandLineArgs::Supplier::Exception();
+ }
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ boost::optional< rtl::OUString > m_cwdUrl;
+ rtl::OString m_input;
+ sal_Int32 m_index;
+};
+
+bool addArgument(
+ ByteString * arguments, char prefix, rtl::OUString const & argument)
+{
+ rtl::OString utf8;
+ if (!argument.convertToString(
+ &utf8, RTL_TEXTENCODING_UTF8,
+ (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR |
+ RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR)))
+ {
+ return false;
+ }
+ *arguments += prefix;
+ for (sal_Int32 i = 0; i < utf8.getLength(); ++i) {
+ char c = utf8[i];
+ switch (c) {
+ case '\0':
+ *arguments += "\\0";
+ break;
+ case ',':
+ *arguments += "\\,";
+ break;
+ case '\\':
+ *arguments += "\\\\";
+ break;
+ default:
+ *arguments += c;
+ break;
+ }
+ }
+ return true;
+}
+
+}
+
+OfficeIPCThread* OfficeIPCThread::pGlobalOfficeIPCThread = 0;
+ namespace { struct Security : public rtl::Static<osl::Security, Security> {}; }
+::osl::Mutex* OfficeIPCThread::pOfficeIPCThreadMutex = 0;
+
+// Turns a string in aMsg such as file:///home/foo/.libreoffice/3
+// Into a hex string of well known length ff132a86...
+String CreateMD5FromString( const OUString& aMsg )
+{
+#if (OSL_DEBUG_LEVEL > 1) || defined DBG_UTIL
+ fprintf (stderr, "create md5 frim '%s'\n",
+ (const sal_Char *)rtl::OUStringToOString (aMsg, RTL_TEXTENCODING_UTF8));
+#endif
+
+ rtlDigest handle = rtl_digest_create( rtl_Digest_AlgorithmMD5 );
+ if ( handle > 0 )
+ {
+ const sal_uInt8* pData = (const sal_uInt8*)aMsg.getStr();
+ sal_uInt32 nSize = ( aMsg.getLength() * sizeof( sal_Unicode ));
+ sal_uInt32 nMD5KeyLen = rtl_digest_queryLength( handle );
+ sal_uInt8* pMD5KeyBuffer = new sal_uInt8[ nMD5KeyLen ];
+
+ rtl_digest_init( handle, pData, nSize );
+ rtl_digest_update( handle, pData, nSize );
+ rtl_digest_get( handle, pMD5KeyBuffer, nMD5KeyLen );
+ rtl_digest_destroy( handle );
+
+ // Create hex-value string from the MD5 value to keep the string size minimal
+ OUStringBuffer aBuffer( nMD5KeyLen * 2 + 1 );
+ for ( sal_uInt32 i = 0; i < nMD5KeyLen; i++ )
+ aBuffer.append( (sal_Int32)pMD5KeyBuffer[i], 16 );
+
+ delete [] pMD5KeyBuffer;
+ return aBuffer.makeStringAndClear();
+ }
+
+ return String();
+}
+
+class ProcessEventsClass_Impl
+{
+public:
+ DECL_STATIC_LINK( ProcessEventsClass_Impl, CallEvent, void* pEvent );
+ DECL_STATIC_LINK( ProcessEventsClass_Impl, ProcessDocumentsEvent, void* pEvent );
+};
+
+IMPL_STATIC_LINK_NOINSTANCE( ProcessEventsClass_Impl, CallEvent, void*, pEvent )
+{
+ // Application events are processed by the Desktop::HandleAppEvent implementation.
+ Desktop::HandleAppEvent( *((ApplicationEvent*)pEvent) );
+ delete (ApplicationEvent*)pEvent;
+ return 0;
+}
+
+IMPL_STATIC_LINK_NOINSTANCE( ProcessEventsClass_Impl, ProcessDocumentsEvent, void*, pEvent )
+{
+ // Documents requests are processed by the OfficeIPCThread implementation
+ ProcessDocumentsRequest* pDocsRequest = (ProcessDocumentsRequest*)pEvent;
+
+ if ( pDocsRequest )
+ {
+ OfficeIPCThread::ExecuteCmdLineRequests( *pDocsRequest );
+ delete pDocsRequest;
+ }
+ return 0;
+}
+
+void ImplPostForeignAppEvent( ApplicationEvent* pEvent )
+{
+ Application::PostUserEvent( STATIC_LINK( NULL, ProcessEventsClass_Impl, CallEvent ), pEvent );
+}
+
+void ImplPostProcessDocumentsEvent( ProcessDocumentsRequest* pEvent )
+{
+ Application::PostUserEvent( STATIC_LINK( NULL, ProcessEventsClass_Impl, ProcessDocumentsEvent ), pEvent );
+}
+
+oslSignalAction SAL_CALL SalMainPipeExchangeSignal_impl(void* /*pData*/, oslSignalInfo* pInfo)
+{
+ if( pInfo->Signal == osl_Signal_Terminate )
+ OfficeIPCThread::DisableOfficeIPCThread();
+ return osl_Signal_ActCallNextHdl;
+}
+
+// ----------------------------------------------------------------------------
+
+// The OfficeIPCThreadController implementation is a bookkeeper for all pending requests
+// that were created by the OfficeIPCThread. The requests are waiting to be processed by
+// our framework loadComponentFromURL function (e.g. open/print request).
+// During shutdown the framework is asking OfficeIPCThreadController about pending requests.
+// If there are pending requests framework has to stop the shutdown process. It is waiting
+// for these requests because framework is not able to handle shutdown and open a document
+// concurrently.
+
+
+// XServiceInfo
+OUString SAL_CALL OfficeIPCThreadController::getImplementationName()
+throw ( RuntimeException )
+{
+ return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.OfficeIPCThreadController" ));
+}
+
+sal_Bool SAL_CALL OfficeIPCThreadController::supportsService( const OUString& )
+throw ( RuntimeException )
+{
+ return sal_False;
+}
+
+Sequence< OUString > SAL_CALL OfficeIPCThreadController::getSupportedServiceNames()
+throw ( RuntimeException )
+{
+ Sequence< OUString > aSeq( 0 );
+ return aSeq;
+}
+
+// XEventListener
+void SAL_CALL OfficeIPCThreadController::disposing( const EventObject& )
+throw( RuntimeException )
+{
+}
+
+// XTerminateListener
+void SAL_CALL OfficeIPCThreadController::queryTermination( const EventObject& )
+throw( TerminationVetoException, RuntimeException )
+{
+ // Desktop ask about pending request through our office ipc pipe. We have to
+ // be sure that no pending request is waiting because framework is not able to
+ // handle shutdown and open a document concurrently.
+
+ if ( OfficeIPCThread::AreRequestsPending() )
+ throw TerminationVetoException();
+ else
+ OfficeIPCThread::SetDowning();
+}
+
+void SAL_CALL OfficeIPCThreadController::notifyTermination( const EventObject& )
+throw( RuntimeException )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+::osl::Mutex& OfficeIPCThread::GetMutex()
+{
+ // Get or create our mutex for thread-saftey
+ if ( !pOfficeIPCThreadMutex )
+ {
+ ::osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex() );
+ if ( !pOfficeIPCThreadMutex )
+ pOfficeIPCThreadMutex = new osl::Mutex;
+ }
+
+ return *pOfficeIPCThreadMutex;
+}
+
+void OfficeIPCThread::SetDowning()
+{
+ // We have the order to block all incoming requests. Framework
+ // wants to shutdown and we have to make sure that no loading/printing
+ // requests are executed anymore.
+ ::osl::MutexGuard aGuard( GetMutex() );
+
+ if ( pGlobalOfficeIPCThread )
+ pGlobalOfficeIPCThread->mbDowning = true;
+}
+
+static bool s_bInEnableRequests = false;
+
+void OfficeIPCThread::EnableRequests( bool i_bEnable )
+{
+ // switch between just queueing the requests and executing them
+ ::osl::MutexGuard aGuard( GetMutex() );
+
+ if ( pGlobalOfficeIPCThread )
+ {
+ s_bInEnableRequests = true;
+ pGlobalOfficeIPCThread->mbRequestsEnabled = i_bEnable;
+ if( i_bEnable )
+ {
+ // hit the compiler over the head
+ ProcessDocumentsRequest aEmptyReq = ProcessDocumentsRequest( boost::optional< rtl::OUString >() );
+ // trigger already queued requests
+ OfficeIPCThread::ExecuteCmdLineRequests( aEmptyReq );
+ }
+ s_bInEnableRequests = false;
+ }
+}
+
+sal_Bool OfficeIPCThread::AreRequestsPending()
+{
+ // Give info about pending requests
+ ::osl::MutexGuard aGuard( GetMutex() );
+ if ( pGlobalOfficeIPCThread )
+ return ( pGlobalOfficeIPCThread->mnPendingRequests > 0 );
+ else
+ return sal_False;
+}
+
+void OfficeIPCThread::RequestsCompleted( int nCount )
+{
+ // Remove nCount pending requests from our internal counter
+ ::osl::MutexGuard aGuard( GetMutex() );
+ if ( pGlobalOfficeIPCThread )
+ {
+ if ( pGlobalOfficeIPCThread->mnPendingRequests > 0 )
+ pGlobalOfficeIPCThread->mnPendingRequests -= nCount;
+ }
+}
+
+OfficeIPCThread::Status OfficeIPCThread::EnableOfficeIPCThread()
+{
+ ::osl::MutexGuard aGuard( GetMutex() );
+
+ if( pGlobalOfficeIPCThread )
+ return IPC_STATUS_OK;
+
+ ::rtl::OUString aUserInstallPath;
+ ::rtl::OUString aDummy;
+
+ OfficeIPCThread* pThread = new OfficeIPCThread;
+
+ pThread->maPipeIdent = OUString( RTL_CONSTASCII_USTRINGPARAM( "SingleOfficeIPC_" ) );
+
+ // The name of the named pipe is created with the hashcode of the user installation directory (without /user). We have to retrieve
+ // this information from a unotools implementation.
+ ::utl::Bootstrap::PathStatus aLocateResult = ::utl::Bootstrap::locateUserInstallation( aUserInstallPath );
+ if ( aLocateResult == ::utl::Bootstrap::PATH_EXISTS || aLocateResult == ::utl::Bootstrap::PATH_VALID)
+ aDummy = aUserInstallPath;
+ else
+ {
+ delete pThread;
+ return IPC_STATUS_BOOTSTRAP_ERROR;
+ }
+
+ // Try to determine if we are the first office or not! This should prevent multiple
+ // access to the user directory !
+ // First we try to create our pipe if this fails we try to connect. We have to do this
+ // in a loop because the the other office can crash or shutdown between createPipe
+ // and connectPipe!!
+
+ OUString aIniName;
+
+ osl_getExecutableFile( &aIniName.pData );
+
+ sal_uInt32 lastIndex = aIniName.lastIndexOf('/');
+ if ( lastIndex > 0 )
+ {
+ aIniName = aIniName.copy( 0, lastIndex+1 );
+ aIniName += OUString( RTL_CONSTASCII_USTRINGPARAM( "perftune" ));
+#if defined(WNT) || defined(OS2)
+ aIniName += OUString( RTL_CONSTASCII_USTRINGPARAM( ".ini" ));
+#else
+ aIniName += OUString( RTL_CONSTASCII_USTRINGPARAM( "rc" ));
+#endif
+ }
+
+ ::rtl::Bootstrap aPerfTuneIniFile( aIniName );
+
+ OUString aDefault( RTL_CONSTASCII_USTRINGPARAM( "0" ));
+ OUString aPreloadData;
+
+ aPerfTuneIniFile.getFrom( OUString( RTL_CONSTASCII_USTRINGPARAM( "FastPipeCommunication" )), aPreloadData, aDefault );
+
+
+ OUString aUserInstallPathHashCode;
+
+ if ( aPreloadData.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "1" ) ))
+ {
+ sal_Char szBuffer[32];
+ sprintf( szBuffer, "%d", SUPD );
+ aUserInstallPathHashCode = OUString( szBuffer, strlen(szBuffer), osl_getThreadTextEncoding() );
+ }
+ else
+ aUserInstallPathHashCode = CreateMD5FromString( aDummy );
+
+
+ // Check result to create a hash code from the user install path
+ if ( aUserInstallPathHashCode.getLength() == 0 )
+ return IPC_STATUS_BOOTSTRAP_ERROR; // Something completely broken, we cannot create a valid hash code!
+
+ pThread->maPipeIdent = pThread->maPipeIdent + aUserInstallPathHashCode;
+
+ PipeMode nPipeMode = PIPEMODE_DONTKNOW;
+ do
+ {
+ osl::Security &rSecurity = Security::get();
+ // Try to create pipe
+ if ( pThread->maPipe.create( pThread->maPipeIdent.getStr(), osl_Pipe_CREATE, rSecurity ))
+ {
+ // Pipe created
+ nPipeMode = PIPEMODE_CREATED;
+ }
+ else if( pThread->maPipe.create( pThread->maPipeIdent.getStr(), osl_Pipe_OPEN, rSecurity )) // Creation not successfull, now we try to connect
+ {
+ // Pipe connected to first office
+ nPipeMode = PIPEMODE_CONNECTED;
+ }
+ else
+ {
+ oslPipeError eReason = pThread->maPipe.getError();
+ if ((eReason == osl_Pipe_E_ConnectionRefused) || (eReason == osl_Pipe_E_invalidError))
+ return IPC_STATUS_BOOTSTRAP_ERROR;
+
+ // Wait for second office to be ready
+ TimeValue aTimeValue;
+ aTimeValue.Seconds = 0;
+ aTimeValue.Nanosec = 10000000; // 10ms
+ osl::Thread::wait( aTimeValue );
+ }
+
+ } while ( nPipeMode == PIPEMODE_DONTKNOW );
+
+ if ( nPipeMode == PIPEMODE_CREATED )
+ {
+ // Seems we are the one and only, so start listening thread
+ pGlobalOfficeIPCThread = pThread;
+ pThread->create(); // starts thread
+ }
+ else
+ {
+ // Seems another office is running. Pipe arguments to it and self terminate
+ osl::StreamPipe aStreamPipe(pThread->maPipe.getHandle());
+
+ ByteString aArguments(RTL_CONSTASCII_STRINGPARAM(ARGUMENT_PREFIX));
+ rtl::OUString cwdUrl;
+ if (!(tools::getProcessWorkingDir(cwdUrl) &&
+ addArgument(&aArguments, '1', cwdUrl)))
+ {
+ aArguments += '0';
+ }
+ sal_uInt32 nCount = rtl_getAppCommandArgCount();
+ for( sal_uInt32 i=0; i < nCount; i++ )
+ {
+ rtl_getAppCommandArg( i, &aDummy.pData );
+ if (!addArgument(&aArguments, ',', aDummy)) {
+ return IPC_STATUS_BOOTSTRAP_ERROR;
+ }
+ }
+ // finally, write the string onto the pipe
+ aStreamPipe.write( aArguments.GetBuffer(), aArguments.Len() );
+ aStreamPipe.write( "\0", 1 );
+
+ ByteString aToken(sc_aConfirmationSequence);
+ char *aReceiveBuffer = new char[aToken.Len()+1];
+ int n = aStreamPipe.read( aReceiveBuffer, aToken.Len() );
+ aReceiveBuffer[n]='\0';
+
+ delete pThread;
+ if (aToken.CompareTo(aReceiveBuffer)!= COMPARE_EQUAL) {
+ // something went wrong
+ delete[] aReceiveBuffer;
+ return IPC_STATUS_BOOTSTRAP_ERROR;
+ } else {
+ delete[] aReceiveBuffer;
+ return IPC_STATUS_2ND_OFFICE;
+ }
+ }
+
+ return IPC_STATUS_OK;
+}
+
+void OfficeIPCThread::DisableOfficeIPCThread()
+{
+ osl::ClearableMutexGuard aMutex( GetMutex() );
+
+ if( pGlobalOfficeIPCThread )
+ {
+ OfficeIPCThread *pOfficeIPCThread = pGlobalOfficeIPCThread;
+ pGlobalOfficeIPCThread = 0;
+
+ // send thread a termination message
+ // this is done so the subsequent join will not hang
+ // because the thread hangs in accept of pipe
+ osl::StreamPipe aPipe ( pOfficeIPCThread->maPipeIdent, osl_Pipe_OPEN, Security::get() );
+ if (aPipe.is())
+ {
+ aPipe.send( sc_aTerminationSequence, sc_nTSeqLength+1 ); // also send 0-byte
+
+ // close the pipe so that the streampipe on the other
+ // side produces EOF
+ aPipe.close();
+ }
+
+ // release mutex to avoid deadlocks
+ aMutex.clear();
+
+ OfficeIPCThread::SetReady(pOfficeIPCThread);
+
+ // exit gracefully and join
+ pOfficeIPCThread->join();
+ delete pOfficeIPCThread;
+
+
+ }
+}
+
+OfficeIPCThread::OfficeIPCThread() :
+ mbDowning( false ),
+ mbRequestsEnabled( false ),
+ mnPendingRequests( 0 ),
+ mpDispatchWatcher( 0 )
+{
+}
+
+OfficeIPCThread::~OfficeIPCThread()
+{
+ ::osl::ClearableMutexGuard aGuard( GetMutex() );
+
+ if ( mpDispatchWatcher )
+ mpDispatchWatcher->release();
+ maPipe.close();
+ maStreamPipe.close();
+ pGlobalOfficeIPCThread = 0;
+}
+
+static void AddURLToStringList( const rtl::OUString& aURL, rtl::OUString& aStringList )
+{
+ if ( aStringList.getLength() )
+ aStringList += ::rtl::OUString::valueOf( (sal_Unicode)APPEVENT_PARAM_DELIMITER );
+ aStringList += aURL;
+}
+
+void OfficeIPCThread::SetReady(OfficeIPCThread* pThread)
+{
+ if (pThread == NULL) pThread = pGlobalOfficeIPCThread;
+ if (pThread != NULL)
+ {
+ pThread->cReady.set();
+ }
+}
+
+void SAL_CALL OfficeIPCThread::run()
+{
+ do
+ {
+ oslPipeError nError = maPipe.accept( maStreamPipe );
+
+
+ if( nError == osl_Pipe_E_None )
+ {
+ // if we receive a request while the office is displaying some dialog or error during
+ // bootstrap, that dialogs event loop might get events that are dispatched by this thread
+ // we have to wait for cReady to be set by the real main loop.
+ // only reqests that dont dispatch events may be processed before cReady is set.
+ cReady.wait();
+
+ // we might have decided to shutdown while we were sleeping
+ if (!pGlobalOfficeIPCThread) return;
+
+ // only lock the mutex when processing starts, othewise we deadlock when the office goes
+ // down during wait
+ osl::ClearableMutexGuard aGuard( GetMutex() );
+
+ ByteString aArguments;
+ // test byte by byte
+ const int nBufSz = 2048;
+ char pBuf[nBufSz];
+ int nBytes = 0;
+ int nResult = 0;
+ // read into pBuf until '\0' is read or read-error
+ while ((nResult=maStreamPipe.recv( pBuf+nBytes, nBufSz-nBytes))>0) {
+ nBytes += nResult;
+ if (pBuf[nBytes-1]=='\0') {
+ aArguments += pBuf;
+ break;
+ }
+ }
+ // don't close pipe ...
+
+ // Is this a lookup message from another application? if so, ignore
+ if ( aArguments.Len() == 0 )
+ continue;
+
+ // is this a termination message ? if so, terminate
+ if(( aArguments.CompareTo( sc_aTerminationSequence, sc_nTSeqLength ) == COMPARE_EQUAL ) ||
+ mbDowning ) return;
+ String aEmpty;
+ std::auto_ptr< CommandLineArgs > aCmdLineArgs;
+ try
+ {
+ Parser p( aArguments );
+ aCmdLineArgs.reset( new CommandLineArgs( p ) );
+ }
+ catch ( CommandLineArgs::Supplier::Exception & )
+ {
+#if (OSL_DEBUG_LEVEL > 1) || defined DBG_UTIL
+ fprintf( stderr, "Error in received command line arguments\n" );
+#endif
+ continue;
+ }
+ CommandLineArgs *pCurrentCmdLineArgs = Desktop::GetCommandLineArgs();
+
+ if ( aCmdLineArgs->IsQuickstart() )
+ {
+ // we have to use application event, because we have to start quickstart service in main thread!!
+ ApplicationEvent* pAppEvent =
+ new ApplicationEvent( aEmpty, aEmpty,
+ "QUICKSTART", aEmpty );
+ ImplPostForeignAppEvent( pAppEvent );
+ }
+
+ // handle request for acceptor
+ OUString aAcceptString;
+ if ( aCmdLineArgs->GetAcceptString(aAcceptString) && Desktop::CheckOEM()) {
+ ApplicationEvent* pAppEvent =
+ new ApplicationEvent( aEmpty, aEmpty,
+ "ACCEPT", aAcceptString );
+ ImplPostForeignAppEvent( pAppEvent );
+ }
+ // handle acceptor removal
+ OUString aUnAcceptString;
+ if ( aCmdLineArgs->GetUnAcceptString(aUnAcceptString) ) {
+ ApplicationEvent* pAppEvent =
+ new ApplicationEvent( aEmpty, aEmpty,
+ "UNACCEPT", aUnAcceptString );
+ ImplPostForeignAppEvent( pAppEvent );
+ }
+
+#ifndef UNX
+ // only in non-unix version, we need to handle a -help request
+ // in a running instance in order to display the command line help
+ if ( aCmdLineArgs->IsHelp() ) {
+ ApplicationEvent* pAppEvent =
+ new ApplicationEvent( aEmpty, aEmpty, "HELP", aEmpty );
+ ImplPostForeignAppEvent( pAppEvent );
+ }
+#endif
+
+ sal_Bool bDocRequestSent = sal_False;
+ ProcessDocumentsRequest* pRequest = new ProcessDocumentsRequest(
+ aCmdLineArgs->getCwdUrl());
+ cProcessed.reset();
+ pRequest->pcProcessed = &cProcessed;
+
+ // Print requests are not dependent on the -invisible cmdline argument as they are
+ // loaded with the "hidden" flag! So they are always checked.
+ bDocRequestSent |= aCmdLineArgs->GetPrintList( pRequest->aPrintList );
+ bDocRequestSent |= ( aCmdLineArgs->GetPrintToList( pRequest->aPrintToList ) &&
+ aCmdLineArgs->GetPrinterName( pRequest->aPrinterName ) );
+
+ if ( !pCurrentCmdLineArgs->IsInvisible() )
+ {
+ // Read cmdline args that can open/create documents. As they would open a window
+ // they are only allowed if the "-invisible" is currently not used!
+ bDocRequestSent |= aCmdLineArgs->GetOpenList( pRequest->aOpenList );
+ bDocRequestSent |= aCmdLineArgs->GetViewList( pRequest->aViewList );
+ bDocRequestSent |= aCmdLineArgs->GetStartList( pRequest->aStartList );
+ bDocRequestSent |= aCmdLineArgs->GetForceOpenList( pRequest->aForceOpenList );
+ bDocRequestSent |= aCmdLineArgs->GetForceNewList( pRequest->aForceNewList );
+
+ // Special command line args to create an empty document for a given module
+
+ // #i18338# (lo)
+ // we only do this if no document was specified on the command line,
+ // since this would be inconsistent with the the behaviour of
+ // the first process, see OpenClients() (call to OpenDefault()) in app.cxx
+ if ( aCmdLineArgs->HasModuleParam() && Desktop::CheckOEM() && (!bDocRequestSent))
+ {
+ SvtModuleOptions aOpt;
+ SvtModuleOptions::EFactory eFactory = SvtModuleOptions::E_WRITER;
+ if ( aCmdLineArgs->IsWriter() )
+ eFactory = SvtModuleOptions::E_WRITER;
+ else if ( aCmdLineArgs->IsCalc() )
+ eFactory = SvtModuleOptions::E_CALC;
+ else if ( aCmdLineArgs->IsDraw() )
+ eFactory = SvtModuleOptions::E_DRAW;
+ else if ( aCmdLineArgs->IsImpress() )
+ eFactory = SvtModuleOptions::E_IMPRESS;
+ else if ( aCmdLineArgs->IsBase() )
+ eFactory = SvtModuleOptions::E_DATABASE;
+ else if ( aCmdLineArgs->IsMath() )
+ eFactory = SvtModuleOptions::E_MATH;
+ else if ( aCmdLineArgs->IsGlobal() )
+ eFactory = SvtModuleOptions::E_WRITERGLOBAL;
+ else if ( aCmdLineArgs->IsWeb() )
+ eFactory = SvtModuleOptions::E_WRITERWEB;
+
+ if ( pRequest->aOpenList.getLength() )
+ pRequest->aModule = aOpt.GetFactoryName( eFactory );
+ else
+ AddURLToStringList( aOpt.GetFactoryEmptyDocumentURL( eFactory ), pRequest->aOpenList );
+ bDocRequestSent = sal_True;
+ }
+ }
+
+ if (!aCmdLineArgs->IsQuickstart() && Desktop::CheckOEM()) {
+ sal_Bool bShowHelp = sal_False;
+ rtl::OUStringBuffer aHelpURLBuffer;
+ if (aCmdLineArgs->IsHelpWriter()) {
+ bShowHelp = sal_True;
+ aHelpURLBuffer.appendAscii("vnd.sun.star.help://swriter/start");
+ } else if (aCmdLineArgs->IsHelpCalc()) {
+ bShowHelp = sal_True;
+ aHelpURLBuffer.appendAscii("vnd.sun.star.help://scalc/start");
+ } else if (aCmdLineArgs->IsHelpDraw()) {
+ bShowHelp = sal_True;
+ aHelpURLBuffer.appendAscii("vnd.sun.star.help://sdraw/start");
+ } else if (aCmdLineArgs->IsHelpImpress()) {
+ bShowHelp = sal_True;
+ aHelpURLBuffer.appendAscii("vnd.sun.star.help://simpress/start");
+ } else if (aCmdLineArgs->IsHelpBase()) {
+ bShowHelp = sal_True;
+ aHelpURLBuffer.appendAscii("vnd.sun.star.help://sdatabase/start");
+ } else if (aCmdLineArgs->IsHelpBasic()) {
+ bShowHelp = sal_True;
+ aHelpURLBuffer.appendAscii("vnd.sun.star.help://sbasic/start");
+ } else if (aCmdLineArgs->IsHelpMath()) {
+ bShowHelp = sal_True;
+ aHelpURLBuffer.appendAscii("vnd.sun.star.help://smath/start");
+ }
+ if (bShowHelp) {
+ Any aRet = ::utl::ConfigManager::GetDirectConfigProperty( ::utl::ConfigManager::LOCALE );
+ rtl::OUString aTmp;
+ aRet >>= aTmp;
+ aHelpURLBuffer.appendAscii("?Language=");
+ aHelpURLBuffer.append(aTmp);
+#if defined UNX
+ aHelpURLBuffer.appendAscii("&System=UNX");
+#elif defined WNT
+ aHelpURLBuffer.appendAscii("&System=WIN");
+#elif defined OS2
+ aHelpURLBuffer.appendAscii("&System=OS2");
+#endif
+ ApplicationEvent* pAppEvent =
+ new ApplicationEvent( aEmpty, aEmpty,
+ "OPENHELPURL", aHelpURLBuffer.makeStringAndClear());
+ ImplPostForeignAppEvent( pAppEvent );
+ }
+ }
+
+ if ( bDocRequestSent && Desktop::CheckOEM())
+ {
+ // Send requests to dispatch watcher if we have at least one. The receiver
+ // is responsible to delete the request after processing it.
+ if ( aCmdLineArgs->HasModuleParam() )
+ {
+ SvtModuleOptions aOpt;
+
+ // Support command line parameters to start a module (as preselection)
+ if ( aCmdLineArgs->IsWriter() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SWRITER ) )
+ pRequest->aModule = aOpt.GetFactoryName( SvtModuleOptions::E_WRITER );
+ else if ( aCmdLineArgs->IsCalc() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SCALC ) )
+ pRequest->aModule = aOpt.GetFactoryName( SvtModuleOptions::E_CALC );
+ else if ( aCmdLineArgs->IsImpress() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SIMPRESS ) )
+ pRequest->aModule= aOpt.GetFactoryName( SvtModuleOptions::E_IMPRESS );
+ else if ( aCmdLineArgs->IsDraw() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SDRAW ) )
+ pRequest->aModule= aOpt.GetFactoryName( SvtModuleOptions::E_DRAW );
+ }
+
+
+ ImplPostProcessDocumentsEvent( pRequest );
+ }
+ else
+ {
+ // delete not used request again
+ delete pRequest;
+ pRequest = NULL;
+ }
+ if (( aArguments.CompareTo( sc_aShowSequence, sc_nShSeqLength ) == COMPARE_EQUAL ) ||
+ aCmdLineArgs->IsEmpty() )
+ {
+ // no document was sent, just bring Office to front
+ ApplicationEvent* pAppEvent =
+ new ApplicationEvent( aEmpty, aEmpty, "APPEAR", aEmpty );
+ ImplPostForeignAppEvent( pAppEvent );
+ }
+
+ // we don't need the mutex any longer...
+ aGuard.clear();
+ // wait for processing to finish
+ if (bDocRequestSent)
+ cProcessed.wait();
+ // processing finished, inform the requesting end
+ nBytes = 0;
+ while (
+ (nResult = maStreamPipe.send(sc_aConfirmationSequence+nBytes, sc_nCSeqLength-nBytes))>0 &&
+ ((nBytes += nResult) < sc_nCSeqLength) ) ;
+ }
+ else
+ {
+#if (OSL_DEBUG_LEVEL > 1) || defined DBG_UTIL
+ fprintf( stderr, "Error on accept: %d\n", (int)nError );
+#endif
+ TimeValue tval;
+ tval.Seconds = 1;
+ tval.Nanosec = 0;
+ wait( tval );
+ }
+ } while( schedule() );
+}
+
+static void AddToDispatchList(
+ DispatchWatcher::DispatchList& rDispatchList,
+ boost::optional< rtl::OUString > const & cwdUrl,
+ const OUString& aRequestList,
+ DispatchWatcher::RequestType nType,
+ const OUString& aParam,
+ const OUString& aFactory )
+{
+ if ( aRequestList.getLength() > 0 )
+ {
+ sal_Int32 nIndex = 0;
+ do
+ {
+ OUString aToken = aRequestList.getToken( 0, APPEVENT_PARAM_DELIMITER, nIndex );
+ if ( aToken.getLength() > 0 )
+ rDispatchList.push_back(
+ DispatchWatcher::DispatchRequest( nType, aToken, cwdUrl, aParam, aFactory ));
+ }
+ while ( nIndex >= 0 );
+ }
+}
+
+static void AddConversionsToDispatchList(
+ DispatchWatcher::DispatchList& rDispatchList,
+ boost::optional< rtl::OUString > const & cwdUrl,
+ const OUString& rRequestList,
+ const OUString& rParam,
+ const OUString& rPrinterName,
+ const OUString& rFactory,
+ const OUString& rParamOut )
+{
+ DispatchWatcher::RequestType nType;
+ OUString aParam( rParam );
+
+ if( rParam.getLength() )
+ {
+ nType = DispatchWatcher::REQUEST_CONVERSION;
+ aParam = rParam;
+ }
+ else
+ {
+ nType = DispatchWatcher::REQUEST_BATCHPRINT;
+ aParam = rPrinterName;
+ }
+
+ OUString aOutDir( rParamOut.trim() );
+ ::rtl::OUString aPWD;
+ ::tools::getProcessWorkingDir( aPWD );
+
+ if( !::osl::FileBase::getAbsoluteFileURL( aPWD, rParamOut, aOutDir ) )
+ ::osl::FileBase::getSystemPathFromFileURL( aOutDir, aOutDir );
+
+ if( rParamOut.trim().getLength() )
+ {
+ aParam += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(";"));
+ aParam += aOutDir;
+ }
+ else
+ {
+ ::osl::FileBase::getSystemPathFromFileURL( aPWD, aPWD );
+ aParam += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( ";" )) + aPWD;
+ }
+
+ if ( rRequestList.getLength() > 0 )
+ {
+ sal_Int32 nIndex = 0;
+ do
+ {
+ OUString aToken = rRequestList.getToken( 0, APPEVENT_PARAM_DELIMITER, nIndex );
+ if ( aToken.getLength() > 0 )
+ rDispatchList.push_back(
+ DispatchWatcher::DispatchRequest( nType, aToken, cwdUrl, aParam, rFactory ));
+ }
+ while ( nIndex >= 0 );
+ }
+}
+
+
+sal_Bool OfficeIPCThread::ExecuteCmdLineRequests( ProcessDocumentsRequest& aRequest )
+{
+ // protect the dispatch list
+ osl::ClearableMutexGuard aGuard( GetMutex() );
+
+ static DispatchWatcher::DispatchList aDispatchList;
+
+ rtl::OUString aEmpty;
+ // Create dispatch list for dispatch watcher
+ AddToDispatchList( aDispatchList, aRequest.aCwdUrl, aRequest.aInFilter, DispatchWatcher::REQUEST_INFILTER, aEmpty, aRequest.aModule );
+ AddToDispatchList( aDispatchList, aRequest.aCwdUrl, aRequest.aOpenList, DispatchWatcher::REQUEST_OPEN, aEmpty, aRequest.aModule );
+ AddToDispatchList( aDispatchList, aRequest.aCwdUrl, aRequest.aViewList, DispatchWatcher::REQUEST_VIEW, aEmpty, aRequest.aModule );
+ AddToDispatchList( aDispatchList, aRequest.aCwdUrl, aRequest.aStartList, DispatchWatcher::REQUEST_START, aEmpty, aRequest.aModule );
+ AddToDispatchList( aDispatchList, aRequest.aCwdUrl, aRequest.aPrintList, DispatchWatcher::REQUEST_PRINT, aEmpty, aRequest.aModule );
+ AddToDispatchList( aDispatchList, aRequest.aCwdUrl, aRequest.aPrintToList, DispatchWatcher::REQUEST_PRINTTO, aRequest.aPrinterName, aRequest.aModule );
+ AddToDispatchList( aDispatchList, aRequest.aCwdUrl, aRequest.aForceOpenList, DispatchWatcher::REQUEST_FORCEOPEN, aEmpty, aRequest.aModule );
+ AddToDispatchList( aDispatchList, aRequest.aCwdUrl, aRequest.aForceNewList, DispatchWatcher::REQUEST_FORCENEW, aEmpty, aRequest.aModule );
+ AddConversionsToDispatchList( aDispatchList, aRequest.aCwdUrl, aRequest.aConversionList, aRequest.aConversionParams, aRequest.aPrinterName, aRequest.aModule, aRequest.aConversionOut );
+ sal_Bool bShutdown( sal_False );
+
+ if ( pGlobalOfficeIPCThread )
+ {
+ if( ! pGlobalOfficeIPCThread->AreRequestsEnabled() )
+ return bShutdown;
+
+ pGlobalOfficeIPCThread->mnPendingRequests += aDispatchList.size();
+ if ( !pGlobalOfficeIPCThread->mpDispatchWatcher )
+ {
+ pGlobalOfficeIPCThread->mpDispatchWatcher = DispatchWatcher::GetDispatchWatcher();
+ pGlobalOfficeIPCThread->mpDispatchWatcher->acquire();
+ }
+
+ // copy for execute
+ DispatchWatcher::DispatchList aTempList( aDispatchList );
+ aDispatchList.clear();
+
+ aGuard.clear();
+
+ // Execute dispatch requests
+ bShutdown = pGlobalOfficeIPCThread->mpDispatchWatcher->executeDispatchRequests( aTempList, s_bInEnableRequests );
+
+ // set processed flag
+ if (aRequest.pcProcessed != NULL)
+ aRequest.pcProcessed->set();
+ }
+
+ return bShutdown;
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/app/officeipcthread.hxx b/desktop/source/app/officeipcthread.hxx
new file mode 100644
index 000000000000..e50e46c280ea
--- /dev/null
+++ b/desktop/source/app/officeipcthread.hxx
@@ -0,0 +1,167 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _DESKTOP_OFFICEIPCTHREAD_HXX_
+#define _DESKTOP_OFFICEIPCTHREAD_HXX_
+
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/frame/XTerminateListener.hpp>
+#include <osl/pipe.hxx>
+#include <osl/security.hxx>
+#include <osl/signal.h>
+#include <rtl/ustring.hxx>
+#include <cppuhelper/implbase2.hxx>
+#include <osl/conditn.hxx>
+#include <osl/thread.hxx>
+#include "boost/optional.hpp"
+
+namespace desktop
+{
+
+oslSignalAction SAL_CALL SalMainPipeExchangeSignal_impl(void* /*pData*/, oslSignalInfo* pInfo);
+
+// A request for the current office
+// that was given by command line or by IPC pipe communication.
+struct ProcessDocumentsRequest
+{
+ ProcessDocumentsRequest(boost::optional< rtl::OUString > const & cwdUrl):
+ aCwdUrl(cwdUrl), pcProcessed( NULL ) {}
+
+ boost::optional< ::rtl::OUString > aCwdUrl;
+ ::rtl::OUString aModule;
+ ::rtl::OUString aOpenList; // Documents that should be opened in the default way
+ ::rtl::OUString aViewList; // Documents that should be opened in viewmode
+ ::rtl::OUString aStartList; // Documents/Presentations that should be started
+ ::rtl::OUString aPrintList; // Documents that should be printed on default printer
+ ::rtl::OUString aForceOpenList; // Documents that should be forced to open for editing (even templates)
+ ::rtl::OUString aForceNewList; // Documents that should be forced to create a new document
+ ::rtl::OUString aPrinterName; // The printer name that should be used for printing
+ ::rtl::OUString aPrintToList; // Documents that should be printed on the given printer
+ ::rtl::OUString aConversionList;
+ ::rtl::OUString aConversionParams;
+ ::rtl::OUString aConversionOut;
+ ::rtl::OUString aInFilter;
+ ::osl::Condition *pcProcessed; // pointer condition to be set when the request has been processed
+};
+
+class DispatchWatcher;
+class OfficeIPCThread : public osl::Thread
+{
+ private:
+ static OfficeIPCThread* pGlobalOfficeIPCThread;
+ static ::osl::Mutex* pOfficeIPCThreadMutex;
+
+ osl::Pipe maPipe;
+ osl::StreamPipe maStreamPipe;
+ rtl::OUString maPipeIdent;
+ bool mbDowning;
+ bool mbRequestsEnabled;
+ int mnPendingRequests;
+ DispatchWatcher* mpDispatchWatcher;
+
+ /* condition to be set when the request has been processed */
+ ::osl::Condition cProcessed;
+
+ /* condition to be set when the main event loop is ready
+ otherwise an error dialogs event loop could eat away
+ requests from a 2nd office */
+ ::osl::Condition cReady;
+
+ static ::osl::Mutex& GetMutex();
+ static const char *sc_aTerminationSequence;
+ static const int sc_nTSeqLength;
+ static const char *sc_aShowSequence;
+ static const int sc_nShSeqLength;
+ static const char *sc_aConfirmationSequence;
+ static const int sc_nCSeqLength;
+
+ OfficeIPCThread();
+
+ protected:
+ /// Working method which should be overridden
+ virtual void SAL_CALL run();
+
+ public:
+ enum Status
+ {
+ IPC_STATUS_OK,
+ IPC_STATUS_2ND_OFFICE,
+ IPC_STATUS_BOOTSTRAP_ERROR
+ };
+
+ virtual ~OfficeIPCThread();
+
+ // controlling pipe communication during shutdown
+ static void SetDowning();
+ static void EnableRequests( bool i_bEnable = true );
+ static sal_Bool AreRequestsPending();
+ static void RequestsCompleted( int n = 1 );
+ static sal_Bool ExecuteCmdLineRequests( ProcessDocumentsRequest& );
+
+ // return sal_False if second office
+ static Status EnableOfficeIPCThread();
+ static void DisableOfficeIPCThread();
+ // start dispatching events...
+ static void SetReady(OfficeIPCThread* pThread = NULL);
+
+ bool AreRequestsEnabled() const { return mbRequestsEnabled && ! mbDowning; }
+};
+
+
+class OfficeIPCThreadController : public ::cppu::WeakImplHelper2<
+ ::com::sun::star::lang::XServiceInfo,
+ ::com::sun::star::frame::XTerminateListener >
+{
+ public:
+ OfficeIPCThreadController() {}
+ virtual ~OfficeIPCThreadController() {}
+
+ // XServiceInfo
+ virtual ::rtl::OUString SAL_CALL getImplementationName()
+ throw ( ::com::sun::star::uno::RuntimeException );
+ virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName )
+ throw ( ::com::sun::star::uno::RuntimeException );
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames()
+ throw ( ::com::sun::star::uno::RuntimeException );
+
+ // XEventListener
+ virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source )
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ // XTerminateListener
+ virtual void SAL_CALL queryTermination( const ::com::sun::star::lang::EventObject& aEvent )
+ throw( ::com::sun::star::frame::TerminationVetoException, ::com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL notifyTermination( const ::com::sun::star::lang::EventObject& aEvent )
+ throw( ::com::sun::star::uno::RuntimeException );
+};
+
+}
+
+#endif // _DESKTOP_OFFICEIPCTHREAD_HXX_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/app/omutexmember.hxx b/desktop/source/app/omutexmember.hxx
new file mode 100644
index 000000000000..175eae09fe93
--- /dev/null
+++ b/desktop/source/app/omutexmember.hxx
@@ -0,0 +1,64 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef __FRAMEWORK_OMUTEXMEMBER_HXX_
+#define __FRAMEWORK_OMUTEXMEMBER_HXX_
+
+//_________________________________________________________________________________________________________________
+// includes
+//_________________________________________________________________________________________________________________
+
+#include <osl/mutex.hxx>
+
+//_________________________________________________________________________________________________________________
+// namespace
+//_________________________________________________________________________________________________________________
+
+//_________________________________________________________________________________________________________________
+// definitions
+//_________________________________________________________________________________________________________________
+
+/*-************************************************************************************************************//**
+ @short definition of a public mutex member
+ @descr You can use this struct as baseclass to get a public mutex member for right initialization.
+ Don't use it as member. You can't guarantee the right order of initialization of baseclasses then!
+ And some other helper classes share the mutex with an implementation and must have a valid one.
+
+ @seealso See implementation of constructors in derived classes for further informations!
+
+ @devstatus ready
+*//*-*************************************************************************************************************/
+
+struct OMutexMember
+{
+ ::osl::Mutex m_aMutex;
+};
+
+#endif // #ifndef __FRAMEWORK_OMUTEXMEMBER_HXX_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/app/sofficemain.cxx b/desktop/source/app/sofficemain.cxx
new file mode 100644
index 000000000000..a4207ef97bfd
--- /dev/null
+++ b/desktop/source/app/sofficemain.cxx
@@ -0,0 +1,71 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include "app.hxx"
+#include "cmdlineargs.hxx"
+#include "cmdlinehelp.hxx"
+
+#include <rtl/logfile.hxx>
+#include <tools/extendapplicationenvironment.hxx>
+
+int SVMain();
+
+// -=-= main() -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+extern "C" int soffice_main()
+{
+ tools::extendApplicationEnvironment();
+
+ RTL_LOGFILE_PRODUCT_TRACE( "PERFORMANCE - enter Main()" );
+
+ desktop::Desktop aDesktop;
+ // This string is used during initialization of the Gtk+ VCL module
+ aDesktop.SetAppName( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("soffice")) );
+ aDesktop.CreateProcessServiceFactory();
+#ifdef UNX
+ // handle --version and --help already here, otherwise they would be handled
+ // after VCL initialization that might fail if $DISPLAY is not set
+ desktop::CommandLineArgs* pCmdLineArgs = aDesktop.GetCommandLineArgs();
+ if ( pCmdLineArgs->IsHelp() )
+ {
+ desktop::displayCmdlineHelp();
+ return EXIT_SUCCESS;
+ }
+ else if ( pCmdLineArgs->IsVersion() )
+ {
+ desktop::displayVersion();
+ return EXIT_SUCCESS;
+ }
+#endif
+ return SVMain();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/app/sofficemain.h b/desktop/source/app/sofficemain.h
new file mode 100755
index 000000000000..539988834a02
--- /dev/null
+++ b/desktop/source/app/sofficemain.h
@@ -0,0 +1,46 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_DESKTOP_SOURCE_APP_SOFFICEMAIN_H
+#define INCLUDED_DESKTOP_SOURCE_APP_SOFFICEMAIN_H
+
+#include "sal/config.h"
+
+#if defined __cplusplus
+extern "C" {
+#endif
+
+int soffice_main(void);
+
+#if defined __cplusplus
+}
+#endif
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/app/userinstall.cxx b/desktop/source/app/userinstall.cxx
new file mode 100644
index 000000000000..0c55c6db4aff
--- /dev/null
+++ b/desktop/source/app/userinstall.cxx
@@ -0,0 +1,297 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+
+#include "userinstall.hxx"
+#include "langselect.hxx"
+
+#include <stdio.h>
+#include <rtl/ustring.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <osl/file.hxx>
+#include <osl/mutex.hxx>
+#include <osl/process.h>
+#include <osl/diagnose.h>
+#include <osl/security.hxx>
+#include <rtl/ref.hxx>
+
+#include <tools/resmgr.hxx>
+#include <unotools/bootstrap.hxx>
+#include <svl/languageoptions.hxx>
+#include <unotools/syslocaleoptions.hxx>
+#include <comphelper/processfactory.hxx>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <i18npool/mslangid.hxx>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/util/XChangesBatch.hpp>
+#include <com/sun/star/beans/XHierarchicalPropertySet.hpp>
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/lang/XLocalizable.hpp>
+#include <com/sun/star/lang/Locale.hpp>
+
+#include "app.hxx"
+
+using rtl::OString;
+using rtl::OUString;
+using namespace osl;
+using namespace utl;
+using namespace com::sun::star::container;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::util;
+
+
+namespace desktop {
+
+ static UserInstall::UserInstallError create_user_install(OUString&);
+
+ static bool is_user_install()
+ {
+ try
+ {
+ OUString sConfigSrvc(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.configuration.ConfigurationProvider" ) );
+ OUString sAccessSrvc(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.configuration.ConfigurationAccess" ) );
+
+ // get configuration provider
+ Reference< XMultiServiceFactory > theMSF
+ = comphelper::getProcessServiceFactory();
+ Reference< XMultiServiceFactory > theConfigProvider
+ = Reference< XMultiServiceFactory >(
+ theMSF->createInstance(sConfigSrvc), UNO_QUERY_THROW);
+
+ // localize the provider to user selection
+ Reference< XLocalizable > localizable(theConfigProvider, UNO_QUERY_THROW);
+ OUString aUserLanguage = LanguageSelection::getLanguageString();
+ Locale aLocale = LanguageSelection::IsoStringToLocale(aUserLanguage);
+ localizable->setLocale(aLocale);
+
+ Sequence< Any > theArgs(1);
+ NamedValue v;
+ v.Name = OUString(RTL_CONSTASCII_USTRINGPARAM("NodePath"));
+ v.Value = makeAny(OUString(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.Setup")));
+ theArgs[0] <<= v;
+ Reference< XHierarchicalNameAccess> hnacc(
+ theConfigProvider->createInstanceWithArguments(
+ sAccessSrvc, theArgs), UNO_QUERY_THROW);
+
+ try
+ {
+ sal_Bool bValue = sal_False;
+ hnacc->getByHierarchicalName(
+ OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "Office/ooSetupInstCompleted" ) ) ) >>= bValue;
+
+ return bValue ? true : false;
+ }
+ catch ( NoSuchElementException const & )
+ {
+ // just return false in this case.
+ }
+ }
+ catch (Exception const & e)
+ {
+ OString msg(OUStringToOString(e.Message, RTL_TEXTENCODING_ASCII_US));
+ OSL_FAIL(msg.getStr());
+ }
+
+ return false;
+ }
+
+ UserInstall::UserInstallError UserInstall::finalize()
+ {
+ OUString aUserInstallPath;
+ utl::Bootstrap::PathStatus aLocateResult =
+ utl::Bootstrap::locateUserInstallation(aUserInstallPath);
+
+ switch (aLocateResult) {
+
+ case utl::Bootstrap::DATA_INVALID:
+ case utl::Bootstrap::DATA_MISSING:
+ case utl::Bootstrap::DATA_UNKNOWN:
+ // cannot find a valid path or path is missing
+ return E_Unknown;
+
+ case utl::Bootstrap::PATH_EXISTS:
+ {
+ // path exists, check if an installation lives there
+ if ( is_user_install() )
+ {
+ return E_None;
+ }
+ // Note: fall-thru intended.
+ }
+ case utl::Bootstrap::PATH_VALID:
+ // found a path but need to create user install
+ return create_user_install(aUserInstallPath);
+ default:
+ return E_Unknown;
+ }
+ }
+
+ static osl::FileBase::RC copy_recursive( const rtl::OUString& srcUnqPath, const rtl::OUString& dstUnqPath)
+ {
+
+ FileBase::RC err;
+ DirectoryItem aDirItem;
+ DirectoryItem::get(srcUnqPath, aDirItem);
+ FileStatus aFileStatus(FileStatusMask_All);
+ aDirItem.getFileStatus(aFileStatus);
+
+ if( aFileStatus.getFileType() == FileStatus::Directory)
+ {
+ // create directory if not already there
+ err = Directory::create( dstUnqPath );
+ if (err == osl::FileBase::E_EXIST)
+ err = osl::FileBase::E_None;
+
+ FileBase::RC next = err;
+ if (err == osl::FileBase::E_None)
+ {
+ // iterate through directory contents
+ Directory aDir( srcUnqPath );
+ aDir.open();
+ while (err == osl::FileBase::E_None &&
+ (next = aDir.getNextItem( aDirItem )) == osl::FileBase::E_None)
+ {
+ aDirItem.getFileStatus(aFileStatus);
+ // generate new src/dst pair and make recursive call
+ rtl::OUString newSrcUnqPath = aFileStatus.getFileURL();
+ rtl::OUString newDstUnqPath = dstUnqPath;
+ rtl::OUString itemname = aFileStatus.getFileName();
+ // append trailing '/' if needed
+ if (newDstUnqPath.lastIndexOf(sal_Unicode('/')) != newDstUnqPath.getLength()-1)
+ newDstUnqPath += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/"));
+ newDstUnqPath += itemname;
+ // recursion
+ err = copy_recursive(newSrcUnqPath, newDstUnqPath);
+ }
+ aDir.close();
+
+ if ( err != osl::FileBase::E_None )
+ return err;
+ if( next != FileBase::E_NOENT )
+ err = FileBase::E_INVAL;
+ }
+ }
+ else
+ {
+ // copy single file - foldback
+ err = File::copy( srcUnqPath,dstUnqPath );
+ }
+ return err;
+ }
+
+ static const char *pszSrcList[] = {
+ "/presets",
+ NULL
+ };
+ static const char *pszDstList[] = {
+ "/user",
+ NULL
+ };
+
+
+ static UserInstall::UserInstallError create_user_install(OUString& aUserPath)
+ {
+ OUString aBasePath;
+ if (utl::Bootstrap::locateBaseInstallation(aBasePath) != utl::Bootstrap::PATH_EXISTS)
+ return UserInstall::E_InvalidBaseinstall;
+
+ // create the user directory
+ FileBase::RC rc = Directory::createPath(aUserPath);
+ if ((rc != FileBase::E_None) && (rc != FileBase::E_EXIST)) return UserInstall::E_Creation;
+
+#ifdef UNIX
+ // set safer permissions for the user directory by default
+ File::setAttributes(aUserPath, Attribute_OwnWrite| Attribute_OwnRead| Attribute_OwnExe);
+#endif
+
+ // copy data from shared data directory of base installation
+ for (sal_Int32 i=0; pszSrcList[i]!=NULL && pszDstList[i]!=NULL; i++)
+ {
+ rc = copy_recursive(
+ aBasePath + OUString::createFromAscii(pszSrcList[i]),
+ aUserPath + OUString::createFromAscii(pszDstList[i]));
+ if ((rc != FileBase::E_None) && (rc != FileBase::E_EXIST))
+ {
+ if ( rc == FileBase::E_NOSPC )
+ return UserInstall::E_NoDiskSpace;
+ else if ( rc == FileBase::E_ACCES )
+ return UserInstall::E_NoWriteAccess;
+ else
+ return UserInstall::E_Creation;
+ }
+ }
+ try
+ {
+ OUString sConfigSrvc(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.configuration.ConfigurationProvider"));
+ OUString sAccessSrvc(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.configuration.ConfigurationUpdateAccess"));
+
+ // get configuration provider
+ Reference< XMultiServiceFactory > theMSF = comphelper::getProcessServiceFactory();
+ Reference< XMultiServiceFactory > theConfigProvider = Reference< XMultiServiceFactory >(
+ theMSF->createInstance(sConfigSrvc), UNO_QUERY_THROW);
+ Sequence< Any > theArgs(1);
+ NamedValue v(OUString(RTL_CONSTASCII_USTRINGPARAM("NodePath")), makeAny(OUString(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.Setup"))));
+ theArgs[0] <<= v;
+ Reference< XHierarchicalPropertySet> hpset(
+ theConfigProvider->createInstanceWithArguments(sAccessSrvc, theArgs), UNO_QUERY_THROW);
+ hpset->setHierarchicalPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("Office/ooSetupInstCompleted")), makeAny(sal_True));
+ Reference< XChangesBatch >(hpset, UNO_QUERY_THROW)->commitChanges();
+ }
+ catch ( PropertyVetoException& )
+ {
+ // we are not allowed to change this
+ }
+ catch (Exception& e)
+ {
+ OString aMsg("create_user_install(): ");
+ aMsg += OUStringToOString(e.Message, RTL_TEXTENCODING_ASCII_US);
+ OSL_FAIL(aMsg.getStr());
+ return UserInstall::E_Creation;
+ }
+
+ return UserInstall::E_None;
+
+ }
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/app/userinstall.hxx b/desktop/source/app/userinstall.hxx
new file mode 100644
index 000000000000..6dcb5e91db41
--- /dev/null
+++ b/desktop/source/app/userinstall.hxx
@@ -0,0 +1,55 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+#include <sal/types.h>
+#include <rtl/ustring.hxx>
+
+namespace desktop
+{
+
+class UserInstall
+{
+public:
+ enum UserInstallError {
+ E_None, // no error
+ E_Creation, // error while creating user install
+ E_InvalidBaseinstall, // corrupt base installation
+ E_SetupFailed, // external setup did not run correctly
+ E_Configuration, // error while accessing configuration
+ E_License, // License not accepted
+ E_NoDiskSpace, // not enough disk space
+ E_NoWriteAccess, // no write access
+ E_Unknown // unknown error
+ };
+
+ static UserInstallError finalize();
+};
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/app/version.map b/desktop/source/app/version.map
new file mode 100755
index 000000000000..0ffffcd58635
--- /dev/null
+++ b/desktop/source/app/version.map
@@ -0,0 +1,34 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+UDK_3_0_0 {
+ global:
+ soffice_main;
+
+ local:
+ *;
+};
diff --git a/desktop/source/deployment/deployment.component b/desktop/source/deployment/deployment.component
new file mode 100755
index 000000000000..11385c7aa8d9
--- /dev/null
+++ b/desktop/source/deployment/deployment.component
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--**********************************************************************
+*
+* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+*
+* Copyright 2000, 2010 Oracle and/or its affiliates.
+*
+* OpenOffice.org - a multi-platform office productivity suite
+*
+* This file is part of OpenOffice.org.
+*
+* OpenOffice.org is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License version 3
+* only, as published by the Free Software Foundation.
+*
+* OpenOffice.org is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Lesser General Public License version 3 for more details
+* (a copy is included in the LICENSE file that accompanied this code).
+*
+* You should have received a copy of the GNU Lesser General Public License
+* version 3 along with OpenOffice.org. If not, see
+* <http://www.openoffice.org/license.html>
+* for a copy of the LGPLv3 License.
+*
+**********************************************************************-->
+
+<component loader="com.sun.star.loader.SharedLibrary"
+ xmlns="http://openoffice.org/2010/uno-components">
+ <implementation name="com.sun.star.comp.deployment.ExtensionManager">
+ <service name="com.sun.star.comp.deployment.ExtensionManager"/>
+ <singleton name="com.sun.star.deployment.ExtensionManager"/>
+ </implementation>
+ <implementation name="com.sun.star.comp.deployment.PackageInformationProvider">
+ <service name="com.sun.star.comp.deployment.PackageInformationProvider"/>
+ <singleton name="com.sun.star.deployment.PackageInformationProvider"/>
+ </implementation>
+ <implementation name="com.sun.star.comp.deployment.PackageManagerFactory">
+ <service name="com.sun.star.comp.deployment.PackageManagerFactory"/>
+ <singleton name="com.sun.star.deployment.thePackageManagerFactory"/>
+ </implementation>
+ <implementation name="com.sun.star.comp.deployment.ProgressLog">
+ <service name="com.sun.star.comp.deployment.ProgressLog"/>
+ </implementation>
+ <implementation name="com.sun.star.comp.deployment.component.PackageRegistryBackend">
+ <service name="com.sun.star.deployment.PackageRegistryBackend"/>
+ </implementation>
+ <implementation name="com.sun.star.comp.deployment.configuration.PackageRegistryBackend">
+ <service name="com.sun.star.deployment.PackageRegistryBackend"/>
+ </implementation>
+ <implementation name="com.sun.star.comp.deployment.executable.PackageRegistryBackend">
+ <service name="com.sun.star.deployment.PackageRegistryBackend"/>
+ </implementation>
+ <implementation name="com.sun.star.comp.deployment.help.PackageRegistryBackend">
+ <service name="com.sun.star.deployment.PackageRegistryBackend"/>
+ </implementation>
+ <implementation name="com.sun.star.comp.deployment.script.PackageRegistryBackend">
+ <service name="com.sun.star.deployment.PackageRegistryBackend"/>
+ </implementation>
+ <implementation name="com.sun.star.comp.deployment.sfwk.PackageRegistryBackend">
+ <service name="com.sun.star.deployment.PackageRegistryBackend"/>
+ </implementation>
+</component>
diff --git a/desktop/source/deployment/dp_log.cxx b/desktop/source/deployment/dp_log.cxx
new file mode 100644
index 000000000000..24a8b7b40c0d
--- /dev/null
+++ b/desktop/source/deployment/dp_log.cxx
@@ -0,0 +1,213 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include "dp_misc.h"
+#include "rtl/strbuf.hxx"
+#include "osl/time.h"
+#include "osl/thread.h"
+#include "cppuhelper/compbase1.hxx"
+#include "comphelper/anytostring.hxx"
+#include "comphelper/servicedecl.hxx"
+#include "comphelper/unwrapargs.hxx"
+#include "com/sun/star/deployment/DeploymentException.hpp"
+#include "com/sun/star/ucb/XProgressHandler.hpp"
+#include "com/sun/star/ucb/XSimpleFileAccess.hpp"
+#include "com/sun/star/io/XSeekable.hpp"
+#include <stdio.h>
+
+
+using namespace ::rtl;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+
+namespace dp_log {
+
+typedef ::cppu::WeakComponentImplHelper1<ucb::XProgressHandler> t_log_helper;
+
+//==============================================================================
+class ProgressLogImpl : public ::dp_misc::MutexHolder, public t_log_helper
+{
+ Reference<io::XOutputStream> m_xLogFile;
+ sal_Int32 m_log_level;
+ void log_write( OString const & text );
+
+protected:
+ virtual void SAL_CALL disposing();
+ virtual ~ProgressLogImpl();
+
+public:
+ ProgressLogImpl( Sequence<Any> const & args,
+ Reference<XComponentContext> const & xContext );
+
+ // XProgressHandler
+ virtual void SAL_CALL push( Any const & Status ) throw (RuntimeException);
+ virtual void SAL_CALL update( Any const & Status ) throw (RuntimeException);
+ virtual void SAL_CALL pop() throw (RuntimeException);
+};
+
+//______________________________________________________________________________
+ProgressLogImpl::~ProgressLogImpl()
+{
+}
+
+//______________________________________________________________________________
+void ProgressLogImpl::disposing()
+{
+ try {
+ if (m_xLogFile.is()) {
+ m_xLogFile->closeOutput();
+ m_xLogFile.clear();
+ }
+ }
+ catch (Exception & exc) {
+ (void) exc;
+ OSL_FAIL( OUStringToOString(
+ exc.Message, RTL_TEXTENCODING_UTF8 ).getStr() );
+ }
+}
+
+//______________________________________________________________________________
+ProgressLogImpl::ProgressLogImpl(
+ Sequence<Any> const & args,
+ Reference<XComponentContext> const & xContext )
+ : t_log_helper( getMutex() ),
+ m_log_level( 0 )
+{
+ OUString log_file;
+ boost::optional< Reference<task::XInteractionHandler> > interactionHandler;
+ comphelper::unwrapArgs( args, log_file, interactionHandler );
+
+ Reference<ucb::XSimpleFileAccess> xSimpleFileAccess(
+ xContext->getServiceManager()->createInstanceWithContext(
+ OUSTR("com.sun.star.ucb.SimpleFileAccess"),
+ xContext ), UNO_QUERY_THROW );
+ // optional ia handler:
+ if (interactionHandler)
+ xSimpleFileAccess->setInteractionHandler( *interactionHandler );
+
+ m_xLogFile.set(
+ xSimpleFileAccess->openFileWrite( log_file ), UNO_QUERY_THROW );
+ Reference<io::XSeekable> xSeekable( m_xLogFile, UNO_QUERY_THROW );
+ xSeekable->seek( xSeekable->getLength() );
+
+ // write log stamp
+ OStringBuffer buf;
+ buf.append(
+ RTL_CONSTASCII_STRINGPARAM("###### Progress log entry ") );
+ TimeValue m_start_time, tLocal;
+ oslDateTime date_time;
+ if (osl_getSystemTime( &m_start_time ) &&
+ osl_getLocalTimeFromSystemTime( &m_start_time, &tLocal ) &&
+ osl_getDateTimeFromTimeValue( &tLocal, &date_time ))
+ {
+ char ar[ 128 ];
+ snprintf(
+ ar, sizeof (ar),
+ "%04d-%02d-%02d %02d:%02d:%02d ",
+ date_time.Year, date_time.Month, date_time.Day,
+ date_time.Hours, date_time.Minutes, date_time.Seconds );
+ buf.append( ar );
+ }
+ buf.append( RTL_CONSTASCII_STRINGPARAM("######\n") );
+ log_write( buf.makeStringAndClear() );
+}
+
+//______________________________________________________________________________
+void ProgressLogImpl::log_write( OString const & text )
+{
+ try {
+ if (m_xLogFile.is()) {
+ m_xLogFile->writeBytes(
+ Sequence< sal_Int8 >(
+ reinterpret_cast< sal_Int8 const * >(text.getStr()),
+ text.getLength() ) );
+ }
+ }
+ catch (io::IOException & exc) {
+ (void) exc;
+ OSL_FAIL( OUStringToOString(
+ exc.Message, RTL_TEXTENCODING_UTF8 ).getStr() );
+ }
+}
+
+// XProgressHandler
+//______________________________________________________________________________
+void ProgressLogImpl::push( Any const & Status )
+ throw (RuntimeException)
+{
+ update( Status );
+ OSL_ASSERT( m_log_level >= 0 );
+ ++m_log_level;
+}
+
+//______________________________________________________________________________
+void ProgressLogImpl::update( Any const & Status )
+ throw (RuntimeException)
+{
+ if (! Status.hasValue())
+ return;
+
+ OUStringBuffer buf;
+ OSL_ASSERT( m_log_level >= 0 );
+ for ( sal_Int32 n = 0; n < m_log_level; ++n )
+ buf.append( static_cast<sal_Unicode>(' ') );
+
+ OUString msg;
+ if (Status >>= msg) {
+ buf.append( msg );
+ }
+ else {
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("ERROR: ") );
+ buf.append( ::comphelper::anyToString(Status) );
+ }
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\n") );
+ log_write( OUStringToOString(
+ buf.makeStringAndClear(), osl_getThreadTextEncoding() ) );
+}
+
+//______________________________________________________________________________
+void ProgressLogImpl::pop() throw (RuntimeException)
+{
+ OSL_ASSERT( m_log_level > 0 );
+ --m_log_level;
+}
+
+namespace sdecl = comphelper::service_decl;
+sdecl::class_<ProgressLogImpl, sdecl::with_args<true> > servicePLI;
+extern sdecl::ServiceDecl const serviceDecl(
+ servicePLI,
+ // a private one:
+ "com.sun.star.comp.deployment.ProgressLog",
+ "com.sun.star.comp.deployment.ProgressLog" );
+
+} // namespace dp_log
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/dp_persmap.cxx b/desktop/source/deployment/dp_persmap.cxx
new file mode 100644
index 000000000000..92e4080063f9
--- /dev/null
+++ b/desktop/source/deployment/dp_persmap.cxx
@@ -0,0 +1,254 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include "dp_misc.h"
+#include "dp_ucb.h"
+#include "dp_persmap.h"
+#include "rtl/strbuf.hxx"
+#include "rtl/ustrbuf.hxx"
+#include "osl/file.hxx"
+#include "osl/thread.h"
+
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::rtl;
+using ::osl::File;
+
+namespace dp_misc
+{
+
+//______________________________________________________________________________
+void PersistentMap::throw_rtexc( int err, char const * pmsg ) const
+{
+ OUStringBuffer buf;
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[") );
+ buf.append( m_sysPath );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] Berkeley Db error (") );
+ buf.append( static_cast<sal_Int32>(err) );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("): ") );
+ if (pmsg == 0)
+ pmsg = DbEnv::strerror(err);
+ const OString msg(pmsg);
+ buf.append( OUString( msg.getStr(), msg.getLength(),
+ osl_getThreadTextEncoding() ) );
+ const OUString msg_(buf.makeStringAndClear());
+ OSL_FAIL( rtl::OUStringToOString(
+ msg_, RTL_TEXTENCODING_UTF8 ).getStr() );
+ throw RuntimeException( msg_, Reference<XInterface>() );
+}
+
+//______________________________________________________________________________
+PersistentMap::~PersistentMap()
+{
+ try {
+ m_db.close(0);
+ }
+ catch (DbException & exc) {
+ (void) exc; // avoid warnings
+ OSL_FAIL( DbEnv::strerror( exc.get_errno() ) );
+ }
+}
+
+//______________________________________________________________________________
+PersistentMap::PersistentMap( OUString const & url_, bool readOnly )
+ : m_db( 0, 0 )
+{
+ try {
+ OUString url( expandUnoRcUrl(url_) );
+ if ( File::getSystemPathFromFileURL( url, m_sysPath ) != File::E_None )
+ {
+ OSL_ASSERT( false );
+ }
+ OString cstr_sysPath(
+ OUStringToOString( m_sysPath, RTL_TEXTENCODING_UTF8 ) );
+ char const * pcstr_sysPath = cstr_sysPath.getStr();
+
+ u_int32_t flags = DB_CREATE;
+ if (readOnly) {
+ flags = DB_RDONLY;
+ if (! create_ucb_content(
+ 0, url,
+ Reference<com::sun::star::ucb::XCommandEnvironment>(),
+ false /* no throw */ )) {
+ // ignore non-existent file in read-only mode: simulate empty db
+ pcstr_sysPath = 0;
+ flags = DB_CREATE;
+ }
+ }
+
+ int err = m_db.open(
+ // xxx todo: DB_THREAD, DB_DBT_MALLOC currently not used
+ 0, pcstr_sysPath, 0, DB_HASH, flags/* | DB_THREAD*/, 0664 /* fs mode */ );
+ if (err != 0)
+ throw_rtexc(err);
+ }
+ catch (DbException & exc) {
+ throw_rtexc( exc.get_errno(), exc.what() );
+ }
+}
+
+//______________________________________________________________________________
+PersistentMap::PersistentMap()
+ : m_db( 0, 0 )
+{
+ try {
+ // xxx todo: DB_THREAD, DB_DBT_MALLOC currently not used
+ int err = m_db.open( 0, 0, 0, DB_HASH, DB_CREATE/* | DB_THREAD*/, 0 );
+ if (err != 0)
+ throw_rtexc(err);
+ }
+ catch (DbException & exc) {
+ throw_rtexc( exc.get_errno(), exc.what() );
+ }
+}
+
+//______________________________________________________________________________
+bool PersistentMap::has( OString const & key ) const
+{
+ return get( 0, key );
+}
+
+//______________________________________________________________________________
+bool PersistentMap::get( OString * value, OString const & key ) const
+{
+ try {
+ Dbt dbKey( const_cast< sal_Char * >(key.getStr()), key.getLength() );
+ Dbt dbData;
+ int err = m_db.get( 0, &dbKey, &dbData, 0 );
+ if (err == DB_NOTFOUND)
+ return false;
+ if (err == 0) {
+ if (value != 0) {
+ *value = OString(
+ static_cast< sal_Char const * >(dbData.get_data()),
+ dbData.get_size() );
+ }
+ return true;
+ }
+ throw_rtexc(err);
+ }
+ catch (DbException & exc) {
+ throw_rtexc( exc.get_errno(), exc.what() );
+ }
+ return false; // avoiding warning
+}
+
+//______________________________________________________________________________
+void PersistentMap::put( OString const & key, OString const & value )
+{
+ try {
+ Dbt dbKey( const_cast< sal_Char * >(key.getStr()), key.getLength() );
+ Dbt dbData( const_cast< sal_Char * >(
+ value.getStr()), value.getLength() );
+ int err = m_db.put( 0, &dbKey, &dbData, 0 );
+ if (err == 0) {
+#if OSL_DEBUG_LEVEL > 0
+ OString v;
+ OSL_ASSERT( get( &v, key ) );
+ OSL_ASSERT( v.equals( value ) );
+#endif
+ err = m_db.sync(0);
+ }
+ if (err != 0)
+ throw_rtexc(err);
+ }
+ catch (DbException & exc) {
+ throw_rtexc( exc.get_errno(), exc.what() );
+ }
+}
+
+//______________________________________________________________________________
+bool PersistentMap::erase( OString const & key, bool flush_immediately )
+{
+ try {
+ Dbt dbKey( const_cast< sal_Char * >(key.getStr()), key.getLength() );
+ int err = m_db.del( &dbKey, 0 );
+ if (err == 0) {
+ if (flush_immediately) {
+ err = m_db.sync(0);
+ if (err != 0)
+ throw_rtexc(err);
+ }
+ return true;
+ }
+ if (err == DB_NOTFOUND)
+ return false;
+ throw_rtexc(err);
+ }
+ catch (DbException & exc) {
+ throw_rtexc( exc.get_errno(), exc.what() );
+ }
+ return false; // avoiding warning
+}
+
+//______________________________________________________________________________
+t_string2string_map PersistentMap::getEntries() const
+{
+ try {
+ Dbc * pcurs = 0;
+ int err = m_db.cursor( 0, &pcurs, 0 );
+ if (err != 0)
+ throw_rtexc(err);
+
+ t_string2string_map ret;
+ for (;;) {
+ Dbt dbKey, dbData;
+ err = pcurs->get( &dbKey, &dbData, DB_NEXT );
+ if (err == DB_NOTFOUND)
+ break;
+ if (err != 0)
+ throw_rtexc(err);
+
+#if OSL_DEBUG_LEVEL > 0
+ ::std::pair<t_string2string_map::iterator, bool> insertion =
+#endif
+ ret.insert(
+ t_string2string_map::value_type(
+ OString( static_cast<sal_Char const*>(dbKey.get_data()), dbKey.get_size() ),
+ OString( static_cast<sal_Char const*>(dbData.get_data()), dbData.get_size() )
+ ) );
+ OSL_ASSERT( insertion.second );
+ }
+ err = pcurs->close();
+ if (err != 0)
+ throw_rtexc(err);
+ return ret;
+ }
+ catch (DbException & exc) {
+ throw_rtexc( exc.get_errno(), exc.what() );
+ }
+ return t_string2string_map(); // avoiding warning
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/dp_services.cxx b/desktop/source/deployment/dp_services.cxx
new file mode 100644
index 000000000000..16372bfbe0b9
--- /dev/null
+++ b/desktop/source/deployment/dp_services.cxx
@@ -0,0 +1,117 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#define COMPHELPER_SERVICEDECL_COMPONENT_HELPER_MAX_ARGS 12
+#include "comphelper/servicedecl.hxx"
+
+using namespace com::sun::star;
+namespace sdecl = comphelper::service_decl;
+
+namespace dp_registry {
+namespace backend {
+
+namespace configuration {
+extern sdecl::ServiceDecl const serviceDecl;
+}
+
+namespace component {
+extern sdecl::ServiceDecl const serviceDecl;
+}
+
+namespace script {
+extern sdecl::ServiceDecl const serviceDecl;
+}
+
+namespace sfwk {
+extern sdecl::ServiceDecl const serviceDecl;
+}
+
+namespace help {
+extern sdecl::ServiceDecl const serviceDecl;
+}
+
+namespace executable {
+extern sdecl::ServiceDecl const serviceDecl;
+}
+
+} // namespace backend
+} // namespace dp_registry
+
+namespace dp_manager {
+namespace factory {
+extern sdecl::ServiceDecl const serviceDecl;
+bool singleton_entries( uno::Reference<registry::XRegistryKey> const& );
+}
+extern sdecl::ServiceDecl const serviceDecl;
+bool singleton_entries( uno::Reference<registry::XRegistryKey> const& );
+}
+
+namespace dp_log {
+extern sdecl::ServiceDecl const serviceDecl;
+}
+
+namespace dp_info {
+extern sdecl::ServiceDecl const serviceDecl;
+bool singleton_entries( uno::Reference<registry::XRegistryKey> const& );
+}
+
+extern "C" {
+
+struct uno_Environment;
+
+void SAL_CALL component_getImplementationEnvironment(
+ const sal_Char ** ppEnvTypeName, uno_Environment ** )
+{
+ *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
+}
+
+void * SAL_CALL component_getFactory(
+ sal_Char const * pImplName,
+ lang::XMultiServiceFactory * pServiceManager,
+ registry::XRegistryKey * pRegistryKey )
+{
+ return component_getFactoryHelper(
+ pImplName, pServiceManager, pRegistryKey,
+ dp_registry::backend::configuration::serviceDecl,
+ dp_registry::backend::component::serviceDecl,
+ dp_registry::backend::help::serviceDecl,
+ dp_registry::backend::script::serviceDecl,
+ dp_registry::backend::sfwk::serviceDecl,
+ dp_registry::backend::executable::serviceDecl,
+ dp_manager::factory::serviceDecl,
+ dp_log::serviceDecl,
+ dp_info::serviceDecl,
+ dp_manager::serviceDecl);
+}
+
+} // extern "C"
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/dp_xml.cxx b/desktop/source/deployment/dp_xml.cxx
new file mode 100644
index 000000000000..b46d9835548c
--- /dev/null
+++ b/desktop/source/deployment/dp_xml.cxx
@@ -0,0 +1,67 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include "dp_misc.h"
+#include "dp_xml.h"
+#include "rtl/ustrbuf.hxx"
+#include "ucbhelper/content.hxx"
+#include "com/sun/star/xml/sax/XParser.hpp"
+
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using ::rtl::OUString;
+
+namespace dp_misc
+{
+
+//==============================================================================
+void xml_parse(
+ Reference<xml::sax::XDocumentHandler> const & xDocHandler,
+ ::ucbhelper::Content & ucb_content,
+ Reference<XComponentContext> const & xContext )
+{
+ // raise sax parser:
+ Reference<xml::sax::XParser> xParser(
+ xContext->getServiceManager()->createInstanceWithContext(
+ OUSTR("com.sun.star.xml.sax.Parser"), xContext ), UNO_QUERY_THROW );
+
+ // error handler, entity resolver omitted
+ xParser->setDocumentHandler( xDocHandler );
+ xml::sax::InputSource source;
+ source.aInputStream = ucb_content.openStream();
+ source.sSystemId = ucb_content.getURL();
+ xParser->parseStream( source );
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/gui/deploymentgui.component b/desktop/source/deployment/gui/deploymentgui.component
new file mode 100755
index 000000000000..d613f482e791
--- /dev/null
+++ b/desktop/source/deployment/gui/deploymentgui.component
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--**********************************************************************
+*
+* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+*
+* Copyright 2000, 2010 Oracle and/or its affiliates.
+*
+* OpenOffice.org - a multi-platform office productivity suite
+*
+* This file is part of OpenOffice.org.
+*
+* OpenOffice.org is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License version 3
+* only, as published by the Free Software Foundation.
+*
+* OpenOffice.org is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Lesser General Public License version 3 for more details
+* (a copy is included in the LICENSE file that accompanied this code).
+*
+* You should have received a copy of the GNU Lesser General Public License
+* version 3 along with OpenOffice.org. If not, see
+* <http://www.openoffice.org/license.html>
+* for a copy of the LGPLv3 License.
+*
+**********************************************************************-->
+
+<component loader="com.sun.star.loader.SharedLibrary"
+ xmlns="http://openoffice.org/2010/uno-components">
+ <implementation name="com.sun.star.comp.deployment.ui.LicenseDialog">
+ <service name="com.sun.star.deployment.ui.LicenseDialog"/>
+ </implementation>
+ <implementation name="com.sun.star.comp.deployment.ui.PackageManagerDialog">
+ <service name="com.sun.star.deployment.ui.PackageManagerDialog"/>
+ </implementation>
+ <implementation name="com.sun.star.comp.deployment.ui.UpdateRequiredDialog">
+ <service name="com.sun.star.deployment.ui.UpdateRequiredDialog"/>
+ </implementation>
+</component>
diff --git a/desktop/source/deployment/gui/descedit.cxx b/desktop/source/deployment/gui/descedit.cxx
new file mode 100644
index 000000000000..1faaa9f9bae4
--- /dev/null
+++ b/desktop/source/deployment/gui/descedit.cxx
@@ -0,0 +1,102 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include <vcl/scrbar.hxx>
+#include <svtools/txtattr.hxx>
+#include <svtools/xtextedt.hxx>
+
+#include "descedit.hxx"
+
+#include "dp_gui.hrc"
+
+using dp_gui::DescriptionEdit;
+
+// DescriptionEdit -------------------------------------------------------
+
+DescriptionEdit::DescriptionEdit( Window* pParent, const ResId& rResId ) :
+
+ ExtMultiLineEdit( pParent, rResId ),
+
+ m_bIsVerticalScrollBarHidden( true )
+
+{
+ Init();
+}
+
+// -----------------------------------------------------------------------
+
+void DescriptionEdit::Init()
+{
+ Clear();
+ // no tabstop
+ SetStyle( ( GetStyle() & ~WB_TABSTOP ) | WB_NOTABSTOP );
+ // read-only
+ SetReadOnly();
+ // no cursor
+ EnableCursor( sal_False );
+}
+
+// -----------------------------------------------------------------------
+
+void DescriptionEdit::UpdateScrollBar()
+{
+ if ( m_bIsVerticalScrollBarHidden )
+ {
+ ScrollBar* pVScrBar = GetVScrollBar();
+ if ( pVScrBar && pVScrBar->GetVisibleSize() < pVScrBar->GetRangeMax() )
+ {
+ pVScrBar->Show();
+ m_bIsVerticalScrollBarHidden = false;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void DescriptionEdit::Clear()
+{
+ SetText( String() );
+
+ m_bIsVerticalScrollBarHidden = true;
+ ScrollBar* pVScrBar = GetVScrollBar();
+ if ( pVScrBar )
+ pVScrBar->Hide();
+}
+
+// -----------------------------------------------------------------------
+
+void DescriptionEdit::SetDescription( const String& rDescription )
+{
+ SetText( rDescription );
+ UpdateScrollBar();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/gui/descedit.hxx b/desktop/source/deployment/gui/descedit.hxx
new file mode 100644
index 000000000000..ed8b8f9c333f
--- /dev/null
+++ b/desktop/source/deployment/gui/descedit.hxx
@@ -0,0 +1,59 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_DESKTOP_SOURCE_DEPLOYMENT_GUI_DP_GUI_DESCEDIT_HXX
+#define INCLUDED_DESKTOP_SOURCE_DEPLOYMENT_GUI_DP_GUI_DESCEDIT_HXX
+
+#include "svtools/svmedit2.hxx"
+
+/// @HTML
+
+namespace dp_gui
+{
+
+ class DescriptionEdit : public ExtMultiLineEdit
+ {
+ private:
+ bool m_bIsVerticalScrollBarHidden;
+
+ void Init();
+ void UpdateScrollBar();
+
+ public:
+ DescriptionEdit( Window* pParent, const ResId& rResId );
+ inline ~DescriptionEdit() {}
+
+ void Clear();
+ void SetDescription( const String& rDescription );
+ };
+
+} // namespace dp_gui
+
+#endif // INCLUDED_DESKTOP_SOURCE_DEPLOYMENT_GUI_DP_GUI_DESCEDIT_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/gui/dp_gui.h b/desktop/source/deployment/gui/dp_gui.h
new file mode 100755
index 000000000000..1c57aa5b800e
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui.h
@@ -0,0 +1,101 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#if ! defined INCLUDED_DP_GUI_H
+#define INCLUDED_DP_GUI_H
+
+#include "dp_gui_updatedata.hxx"
+#include "dp_misc.h"
+#include "dp_gui.hrc"
+#include "rtl/ref.hxx"
+#include "rtl/instance.hxx"
+#include "osl/thread.hxx"
+#include "cppuhelper/implbase2.hxx"
+#include "vcl/svapp.hxx"
+#include "vcl/dialog.hxx"
+#include "vcl/button.hxx"
+#include "vcl/fixed.hxx"
+#include "salhelper/simplereferenceobject.hxx"
+#include "svtools/svtabbx.hxx"
+#include "svtools/headbar.hxx"
+#include "com/sun/star/ucb/XContentEventListener.hpp"
+#include "osl/mutex.hxx"
+#include <list>
+#include <memory>
+#include <queue>
+
+namespace com { namespace sun { namespace star {
+ namespace container {
+ class XNameAccess;
+ }
+ namespace frame {
+ class XDesktop;
+ }
+ namespace awt {
+ class XWindow;
+ }
+ namespace uno {
+ class XComponentContext;
+ }
+ namespace deployment {
+ class XPackageManagerFactory;
+ }
+} } }
+
+namespace svt {
+ class FixedHyperlink;
+}
+
+namespace dp_gui {
+
+enum PackageState { REGISTERED, NOT_REGISTERED, AMBIGUOUS, NOT_AVAILABLE };
+
+//==============================================================================
+
+class SelectedPackage: public salhelper::SimpleReferenceObject {
+public:
+ SelectedPackage() {}
+ SelectedPackage( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage> &xPackage)
+ : m_xPackage( xPackage )
+ {}
+
+ virtual ~SelectedPackage();
+ ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage> getPackage() const { return m_xPackage; }
+
+private:
+ SelectedPackage(SelectedPackage &); // not defined
+ void operator =(SelectedPackage &); // not defined
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage> m_xPackage;
+};
+
+} // namespace dp_gui
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/gui/dp_gui.hrc b/desktop/source/deployment/gui/dp_gui.hrc
new file mode 100755
index 000000000000..492405164aa2
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui.hrc
@@ -0,0 +1,181 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#if ! defined INCLUDED_DP_GUI_HRC
+#define INCLUDED_DP_GUI_HRC
+
+#include "deployment.hrc"
+#include "helpid.hrc"
+
+// Package Manager Dialog:
+#define RID_DLG_EXTENSION_MANAGER RID_DEPLOYMENT_GUI_START
+#define RID_DLG_UPDATE_REQUIRED (RID_DEPLOYMENT_GUI_START + 11)
+
+#define RID_EM_BTN_CLOSE 10
+#define RID_EM_BTN_HELP 11
+#define RID_EM_BTN_ADD 12
+#define RID_EM_BTN_CHECK_UPDATES 13
+#define RID_EM_BTN_OPTIONS 14
+#define RID_EM_BTN_CANCEL 15
+#define RID_EM_FT_GET_EXTENSIONS 20
+#define RID_EM_FT_PROGRESS 21
+#define RID_EM_FT_MSG 22
+
+// local RIDs:
+#define PB_LICENSE_DOWN 50
+#define ML_LICENSE 51
+#define BTN_LICENSE_DECLINE 53
+#define FT_LICENSE_HEADER 54
+#define FT_LICENSE_BODY_1 55
+#define FT_LICENSE_BODY_1_TXT 56
+#define FT_LICENSE_BODY_2 57
+#define FT_LICENSE_BODY_2_TXT 58
+#define FL_LICENSE 69
+#define FI_LICENSE_ARROW1 60
+#define FI_LICENSE_ARROW2 61
+#define BTN_LICENSE_ACCEPT 63
+
+// local RIDs for "Download and Install" dialog
+
+#define RID_DLG_UPDATE_INSTALL_ABORT 2
+#define RID_DLG_UPDATE_INSTALL_OK 3
+#define RID_DLG_UPDATE_INSTALL_DOWNLOADING 4
+#define RID_DLG_UPDATE_INSTALL_INSTALLING 5
+#define RID_DLG_UPDATE_INSTALL_FINISHED 6
+#define RID_DLG_UPDATE_INSTALL_LINE 7
+#define RID_DLG_UPDATE_INSTALL_HELP 8
+#define RID_DLG_UPDATE_INSTALL_STATUSBAR 9
+#define RID_DLG_UPDATE_INSTALL_EXTENSION_NAME 10
+#define RID_DLG_UPDATE_INSTALL_RESULTS 11
+#define RID_DLG_UPDATE_INSTALL_INFO 12
+#define RID_DLG_UPDATE_INSTALL_NO_ERRORS 13
+#define RID_DLG_UPDATE_INSTALL_THIS_ERROR_OCCURRED 14
+#define RID_DLG_UPDATE_INSTALL_ERROR_DOWNLOAD 15
+#define RID_DLG_UPDATE_INSTALL_ERROR_INSTALLATION 16
+#define RID_DLG_UPDATE_INSTALL_ERROR_LIC_DECLINED 17
+#define RID_DLG_UPDATE_INSTALL_EXTENSION_NOINSTALL 18
+
+#define RID_DLG_DEPENDENCIES (RID_DEPLOYMENT_GUI_START + 1)
+#define RID_DLG_DEPENDENCIES_TEXT 1
+#define RID_DLG_DEPENDENCIES_LIST 2
+#define RID_DLG_DEPENDENCIES_OK 3
+
+#define RID_QUERYBOX_INSTALL_FOR_ALL (RID_DEPLOYMENT_GUI_START + 2)
+#define RID_WARNINGBOX_VERSION_LESS (RID_DEPLOYMENT_GUI_START + 3)
+#define RID_STR_WARNINGBOX_VERSION_LESS_DIFFERENT_NAMES (RID_DEPLOYMENT_GUI_START + 4)
+#define RID_WARNINGBOX_VERSION_EQUAL (RID_DEPLOYMENT_GUI_START + 5)
+#define RID_STR_WARNINGBOX_VERSION_EQUAL_DIFFERENT_NAMES (RID_DEPLOYMENT_GUI_START + 6)
+#define RID_WARNINGBOX_VERSION_GREATER (RID_DEPLOYMENT_GUI_START + 7)
+#define RID_STR_WARNINGBOX_VERSION_GREATER_DIFFERENT_NAMES (RID_DEPLOYMENT_GUI_START + 8)
+#define RID_WARNINGBOX_INSTALL_EXTENSION (RID_DEPLOYMENT_GUI_START + 9)
+
+#define RID_DLG_UPDATE (RID_DEPLOYMENT_GUI_START + 10)
+
+#define RID_DLG_UPDATE_CHECKING 1
+#define RID_DLG_UPDATE_THROBBER 2
+#define RID_DLG_UPDATE_UPDATE 3
+#define RID_DLG_UPDATE_UPDATES 4
+#define RID_DLG_UPDATE_ALL 5
+#define RID_DLG_UPDATE_DESCRIPTION 6
+#define RID_DLG_UPDATE_DESCRIPTIONS 7
+#define RID_DLG_UPDATE_LINE 8
+#define RID_DLG_UPDATE_HELP 9
+#define RID_DLG_UPDATE_OK 10
+#define RID_DLG_UPDATE_CLOSE 11
+#define RID_DLG_UPDATE_NORMALALERT 12
+#define RID_DLG_UPDATE_ERROR 14
+#define RID_DLG_UPDATE_NONE 15
+#define RID_DLG_UPDATE_NOINSTALLABLE 16
+#define RID_DLG_UPDATE_FAILURE 17
+#define RID_DLG_UPDATE_UNKNOWNERROR 18
+#define RID_DLG_UPDATE_NODESCRIPTION 19
+#define RID_DLG_UPDATE_NOINSTALL 20
+#define RID_DLG_UPDATE_NODEPENDENCY 21
+#define RID_DLG_UPDATE_NODEPENDENCY_CUR_VER 22
+#define RID_DLG_UPDATE_NOPERMISSION 23
+#define RID_DLG_UPDATE_NOPERMISSION_VISTA 24
+#define RID_DLG_UPDATE_BROWSERBASED 25
+#define RID_DLG_UPDATE_PUBLISHER_LABEL 26
+#define RID_DLG_UPDATE_PUBLISHER_LINK 27
+#define RID_DLG_UPDATE_RELEASENOTES_LABEL 28
+#define RID_DLG_UPDATE_RELEASENOTES_LINK 29
+#define RID_DLG_UPDATE_NOUPDATE 30
+#define RID_DLG_UPDATE_VERSION 31
+#define RID_DLG_UPDATE_IGNORE 32
+#define RID_DLG_UPDATE_ENABLE 33
+#define RID_DLG_UPDATE_IGNORE_ALL 34
+#define RID_DLG_UPDATE_IGNORED_UPDATE 35
+
+
+
+#define RID_DLG_UPDATEINSTALL (RID_DEPLOYMENT_GUI_START + 20)
+#define RID_INFOBOX_UPDATE_SHARED_EXTENSION (RID_DEPLOYMENT_GUI_START + 21)
+
+#define RID_IMG_WARNING (RID_DEPLOYMENT_GUI_START+56)
+#define RID_IMG_LOCKED (RID_DEPLOYMENT_GUI_START+58)
+#define RID_IMG_EXTENSION (RID_DEPLOYMENT_GUI_START+60)
+#define RID_IMG_SHARED (RID_DEPLOYMENT_GUI_START+62)
+
+#define RID_STR_ADD_PACKAGES (RID_DEPLOYMENT_GUI_START+70)
+
+#define RID_CTX_ITEM_REMOVE (RID_DEPLOYMENT_GUI_START+80)
+#define RID_CTX_ITEM_ENABLE (RID_DEPLOYMENT_GUI_START+81)
+#define RID_CTX_ITEM_DISABLE (RID_DEPLOYMENT_GUI_START+82)
+#define RID_CTX_ITEM_CHECK_UPDATE (RID_DEPLOYMENT_GUI_START+83)
+#define RID_CTX_ITEM_OPTIONS (RID_DEPLOYMENT_GUI_START+84)
+
+#define RID_STR_ADDING_PACKAGES (RID_DEPLOYMENT_GUI_START+85)
+#define RID_STR_REMOVING_PACKAGES (RID_DEPLOYMENT_GUI_START+86)
+#define RID_STR_ENABLING_PACKAGES (RID_DEPLOYMENT_GUI_START+87)
+#define RID_STR_DISABLING_PACKAGES (RID_DEPLOYMENT_GUI_START+88)
+#define RID_STR_ACCEPT_LICENSE (RID_DEPLOYMENT_GUI_START+89)
+
+#define RID_STR_INSTALL_FOR_ALL (RID_DEPLOYMENT_GUI_START+90)
+#define RID_STR_INSTALL_FOR_ME (RID_DEPLOYMENT_GUI_START+91)
+#define RID_STR_ERROR_UNKNOWN_STATUS (RID_DEPLOYMENT_GUI_START+92)
+#define RID_STR_CLOSE_BTN (RID_DEPLOYMENT_GUI_START+93)
+#define RID_STR_EXIT_BTN (RID_DEPLOYMENT_GUI_START+94)
+#define RID_STR_NO_ADMIN_PRIVILEGE (RID_DEPLOYMENT_GUI_START+95)
+#define RID_STR_ERROR_MISSING_DEPENDENCIES (RID_DEPLOYMENT_GUI_START+96)
+#define RID_STR_ERROR_MISSING_LICENSE (RID_DEPLOYMENT_GUI_START+97)
+#define RID_STR_SHOW_LICENSE_CMD (RID_DEPLOYMENT_GUI_START+98)
+
+#define WARNINGBOX_CONCURRENTINSTANCE (RID_DEPLOYMENT_GUI_START+100)
+
+#define RID_STR_UNSUPPORTED_PLATFORM (RID_DEPLOYMENT_GUI_START+101)
+#define RID_WARNINGBOX_UPDATE_SHARED_EXTENSION (RID_DEPLOYMENT_GUI_START+102)
+#define RID_WARNINGBOX_REMOVE_EXTENSION (RID_DEPLOYMENT_GUI_START+103)
+#define RID_WARNINGBOX_REMOVE_SHARED_EXTENSION (RID_DEPLOYMENT_GUI_START+104)
+#define RID_WARNINGBOX_ENABLE_SHARED_EXTENSION (RID_DEPLOYMENT_GUI_START+105)
+#define RID_WARNINGBOX_DISABLE_SHARED_EXTENSION (RID_DEPLOYMENT_GUI_START+106)
+#define RID_DLG_SHOW_LICENSE (RID_DEPLOYMENT_GUI_START+107)
+
+#define RID_DLG_LICENSE RID_DEPLOYMENT_LICENSE_START
+
+
+
+#endif
diff --git a/desktop/source/deployment/gui/dp_gui_autoscrolledit.cxx b/desktop/source/deployment/gui/dp_gui_autoscrolledit.cxx
new file mode 100644
index 000000000000..5e766b9470cb
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_autoscrolledit.cxx
@@ -0,0 +1,75 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+
+#include "svtools/svmedit2.hxx"
+#include "svl/lstner.hxx"
+#include "svtools/xtextedt.hxx"
+#include "vcl/scrbar.hxx"
+
+#include "dp_gui_autoscrolledit.hxx"
+
+
+namespace dp_gui {
+
+
+AutoScrollEdit::AutoScrollEdit( Window* pParent, const ResId& rResId )
+ : ExtMultiLineEdit( pParent, rResId )
+{
+ ScrollBar* pScroll = GetVScrollBar();
+ if (pScroll)
+ pScroll->Hide();
+ StartListening( *GetTextEngine() );
+}
+
+AutoScrollEdit::~AutoScrollEdit()
+{
+ EndListeningAll();
+}
+
+void AutoScrollEdit::Notify( SfxBroadcaster&, const SfxHint& rHint )
+{
+ if ( rHint.IsA( TYPE(TextHint) ) )
+ {
+ sal_uLong nId = ((const TextHint&)rHint).GetId();
+ if ( nId == TEXT_HINT_VIEWSCROLLED )
+ {
+ ScrollBar* pScroll = GetVScrollBar();
+ if ( pScroll )
+ pScroll->Show();
+ }
+ }
+}
+
+
+} // namespace dp_gui
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/gui/dp_gui_autoscrolledit.hxx b/desktop/source/deployment/gui/dp_gui_autoscrolledit.hxx
new file mode 100644
index 000000000000..c49477358c1b
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_autoscrolledit.hxx
@@ -0,0 +1,54 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef INCLUDED_DESKTOP_SOURCE_DEPLOYMENT_GUI_DP_GUI_AUTOSCROLLEDIT_HXX
+#define INCLUDED_DESKTOP_SOURCE_DEPLOYMENT_GUI_DP_GUI_AUTOSCROLLEDIT_HXX
+
+#include "svtools/svmedit2.hxx"
+#include "svl/lstner.hxx"
+
+namespace dp_gui {
+
+/** This control shows automatically the vertical scroll bar if text is inserted,
+ that does not fit into the text area. In the resource one uses MultiLineEdit
+ and needs to set VScroll = TRUE
+*/
+class AutoScrollEdit : public ExtMultiLineEdit, public SfxListener
+{
+public:
+ AutoScrollEdit( Window* pParent, const ResId& rResId );
+ ~AutoScrollEdit();
+
+ using ExtMultiLineEdit::Notify;
+ virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint );
+};
+
+} // namespace dp_gui
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/gui/dp_gui_backend.src b/desktop/source/deployment/gui/dp_gui_backend.src
new file mode 100644
index 000000000000..e5adb84ba596
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_backend.src
@@ -0,0 +1,86 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "dp_gui.hrc"
+
+// package bundle:
+Image RID_IMG_DEF_PACKAGE_BUNDLE
+{
+ ImageBitmap = Bitmap { File = "sx03256.bmp"; };
+ MASKCOLOR
+};
+
+// script, dialog:
+Image RID_IMG_SCRIPTLIB
+{
+ ImageBitmap = Bitmap { File = "im30820.bmp"; };
+ MASKCOLOR
+};
+
+Image RID_IMG_DIALOGLIB
+{
+ ImageBitmap = Bitmap { File = "dialogfolder_16.bmp"; };
+ MASKCOLOR
+};
+
+// configuration:
+Image RID_IMG_CONF_XML
+{
+ ImageBitmap = Bitmap { File = "xml_16.bmp"; };
+ MASKCOLOR
+};
+
+// component, typelib:
+Image RID_IMG_COMPONENT
+{
+ ImageBitmap = Bitmap { File = "component_16.bmp"; };
+ MASKCOLOR
+};
+
+Image RID_IMG_JAVA_COMPONENT
+{
+ ImageBitmap = Bitmap { File = "javacomponent_16.bmp"; };
+ MASKCOLOR
+};
+
+Image RID_IMG_TYPELIB
+{
+ ImageBitmap = Bitmap { File = "library_16.bmp"; };
+ MASKCOLOR
+};
+
+Image RID_IMG_JAVA_TYPELIB
+{
+ ImageBitmap = Bitmap { File = "javalibrary_16.bmp"; };
+ MASKCOLOR
+};
+
+Image RID_IMG_HELP
+{
+ ImageBitmap = Bitmap { File = "commandimagelist/sc_helperdialog.bmp"; };
+ MASKCOLOR
+};
diff --git a/desktop/source/deployment/gui/dp_gui_dependencydialog.cxx b/desktop/source/deployment/gui/dp_gui_dependencydialog.cxx
new file mode 100644
index 000000000000..7019db610b85
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_dependencydialog.cxx
@@ -0,0 +1,89 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include "sal/config.h"
+
+#include <algorithm>
+#include <vector>
+
+#include "rtl/ustring.hxx"
+#include "tools/gen.hxx"
+#include "tools/resid.hxx"
+#include "tools/resmgr.hxx"
+#include "tools/solar.h"
+#include "tools/string.hxx"
+#include "vcl/dialog.hxx"
+
+#include "dp_gui.hrc"
+#include "dp_gui_dependencydialog.hxx"
+#include "dp_gui_shared.hxx"
+
+class Window;
+
+using dp_gui::DependencyDialog;
+
+DependencyDialog::DependencyDialog(
+ Window * parent, std::vector< rtl::OUString > const & dependencies):
+ ModalDialog(parent, DpGuiResId(RID_DLG_DEPENDENCIES) ),
+ m_text(this, DpGuiResId(RID_DLG_DEPENDENCIES_TEXT)),
+ m_list(this, DpGuiResId(RID_DLG_DEPENDENCIES_LIST)),
+ m_ok(this, DpGuiResId(RID_DLG_DEPENDENCIES_OK)),
+ m_listDelta(
+ GetOutputSizePixel().Width() - m_list.GetSizePixel().Width(),
+ GetOutputSizePixel().Height() - m_list.GetSizePixel().Height())
+{
+ FreeResource();
+ SetMinOutputSizePixel(GetOutputSizePixel());
+ m_list.SetReadOnly();
+ for (std::vector< rtl::OUString >::const_iterator i(dependencies.begin());
+ i != dependencies.end(); ++i)
+ {
+ m_list.InsertEntry(*i);
+ }
+}
+
+DependencyDialog::~DependencyDialog() {}
+
+void DependencyDialog::Resize() {
+ long n = m_ok.GetPosPixel().Y() -
+ (m_list.GetPosPixel().Y() + m_list.GetSizePixel().Height());
+ m_list.SetSizePixel(
+ Size(
+ GetOutputSizePixel().Width() - m_listDelta.Width(),
+ GetOutputSizePixel().Height() - m_listDelta.Height()));
+ m_ok.SetPosPixel(
+ Point(
+ (m_list.GetPosPixel().X() +
+ (m_list.GetSizePixel().Width() - m_ok.GetSizePixel().Width()) / 2),
+ m_list.GetPosPixel().Y() + m_list.GetSizePixel().Height() + n));
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/gui/dp_gui_dependencydialog.hxx b/desktop/source/deployment/gui/dp_gui_dependencydialog.hxx
new file mode 100644
index 000000000000..48ef45fd15c0
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_dependencydialog.hxx
@@ -0,0 +1,69 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_DESKTOP_SOURCE_DEPLOYMENT_GUI_DP_GUI_DEPENDENCYDIALOG_HXX
+#define INCLUDED_DESKTOP_SOURCE_DEPLOYMENT_GUI_DP_GUI_DEPENDENCYDIALOG_HXX
+
+#include "sal/config.h"
+
+#include <vector>
+#include "tools/gen.hxx"
+#include "vcl/button.hxx"
+#include "vcl/dialog.hxx"
+#include "vcl/fixed.hxx"
+#include "vcl/lstbox.hxx"
+
+class Window;
+namespace rtl { class OUString; }
+
+namespace dp_gui {
+
+class DependencyDialog: public ModalDialog {
+public:
+ DependencyDialog(
+ Window * parent, std::vector< rtl::OUString > const & dependencies);
+
+ ~DependencyDialog();
+
+private:
+ DependencyDialog(DependencyDialog &); // not defined
+ void operator =(DependencyDialog &); // not defined
+
+ virtual void Resize();
+
+ FixedText m_text;
+ ListBox m_list;
+ OKButton m_ok;
+ Size m_listDelta;
+};
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/gui/dp_gui_dependencydialog.src b/desktop/source/deployment/gui/dp_gui_dependencydialog.src
new file mode 100644
index 000000000000..e7adbce9992b
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_dependencydialog.src
@@ -0,0 +1,72 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "svtools/controldims.hrc"
+
+#include "dp_gui.hrc"
+
+#define LOCAL_WIDTH (50 * RSC_BS_CHARWIDTH)
+#define LOCAL_TEXT_HEIGHT (2 * RSC_CD_FIXEDTEXT_HEIGHT)
+#define LOCAL_LIST_HEIGHT (6 * RSC_BS_CHARHEIGHT)
+
+ModalDialog RID_DLG_DEPENDENCIES {
+ HelpID = "desktop:ModalDialog:RID_DLG_DEPENDENCIES";
+ Size = MAP_APPFONT(
+ (RSC_SP_DLG_INNERBORDER_LEFT + LOCAL_WIDTH +
+ RSC_SP_DLG_INNERBORDER_RIGHT),
+ (RSC_SP_DLG_INNERBORDER_TOP + LOCAL_TEXT_HEIGHT + RSC_SP_CTRL_DESC_Y +
+ LOCAL_LIST_HEIGHT + RSC_SP_CTRL_Y + RSC_CD_PUSHBUTTON_HEIGHT +
+ RSC_SP_DLG_INNERBORDER_BOTTOM));
+ Text[en-US] = "System dependencies check";
+ Sizeable = TRUE;
+ Moveable = TRUE;
+ Closeable = TRUE;
+ FixedText RID_DLG_DEPENDENCIES_TEXT {
+ Pos = MAP_APPFONT(
+ RSC_SP_DLG_INNERBORDER_LEFT, RSC_SP_DLG_INNERBORDER_TOP);
+ Size = MAP_APPFONT(LOCAL_WIDTH, LOCAL_TEXT_HEIGHT);
+ Text[en-US] = "The extension cannot be installed as the following\nsystem dependencies are not fulfilled:";
+ NoLabel = TRUE;
+ };
+ ListBox RID_DLG_DEPENDENCIES_LIST {
+ HelpID = "desktop:ListBox:RID_DLG_DEPENDENCIES:RID_DLG_DEPENDENCIES_LIST";
+ Pos = MAP_APPFONT(
+ RSC_SP_DLG_INNERBORDER_LEFT,
+ (RSC_SP_DLG_INNERBORDER_TOP + LOCAL_TEXT_HEIGHT +
+ RSC_SP_CTRL_DESC_Y));
+ Size = MAP_APPFONT(LOCAL_WIDTH, LOCAL_LIST_HEIGHT);
+ };
+ OKButton RID_DLG_DEPENDENCIES_OK {
+ Pos = MAP_APPFONT(
+ (RSC_SP_DLG_INNERBORDER_LEFT +
+ (LOCAL_WIDTH - RSC_CD_PUSHBUTTON_WIDTH) / 2),
+ (RSC_SP_DLG_INNERBORDER_TOP + LOCAL_TEXT_HEIGHT +
+ RSC_SP_CTRL_DESC_Y + LOCAL_LIST_HEIGHT + RSC_SP_CTRL_Y));
+ Size = MAP_APPFONT(RSC_CD_PUSHBUTTON_WIDTH, RSC_CD_PUSHBUTTON_HEIGHT);
+ DefButton = TRUE;
+ };
+};
diff --git a/desktop/source/deployment/gui/dp_gui_dialog.src b/desktop/source/deployment/gui/dp_gui_dialog.src
new file mode 100644
index 000000000000..d8c3f77c4635
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_dialog.src
@@ -0,0 +1,387 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#include "svtools/controldims.hrc"
+#include "dp_gui.hrc"
+
+String RID_STR_ADD_PACKAGES
+{
+ Text [ en-US ] = "Add Extension(s)";
+};
+
+String RID_CTX_ITEM_REMOVE
+{
+ Text [ en-US ] = "~Remove";
+};
+
+String RID_CTX_ITEM_ENABLE
+{
+ Text [ en-US ] = "~Enable";
+};
+
+String RID_CTX_ITEM_DISABLE
+{
+ Text [ en-US ] = "~Disable";
+};
+
+String RID_CTX_ITEM_CHECK_UPDATE
+{
+ Text [ en-US ] = "~Update...";
+};
+
+String RID_CTX_ITEM_OPTIONS
+{
+ Text [ en-US ] = "~Options...";
+};
+
+
+String RID_STR_ADDING_PACKAGES
+{
+ Text [ en-US ] = "Adding %EXTENSION_NAME";
+};
+
+String RID_STR_REMOVING_PACKAGES
+{
+ Text [ en-US ] = "Removing %EXTENSION_NAME";
+};
+
+String RID_STR_ENABLING_PACKAGES
+{
+ Text [ en-US ] = "Enabling %EXTENSION_NAME";
+};
+
+String RID_STR_DISABLING_PACKAGES
+{
+ Text [ en-US ] = "Disabling %EXTENSION_NAME";
+};
+
+String RID_STR_ACCEPT_LICENSE
+{
+ Text [ en-US ] = "Accept license for %EXTENSION_NAME";
+};
+
+String RID_STR_INSTALL_FOR_ALL
+{
+ Text [ en-US ] = "~For all users";
+};
+
+String RID_STR_INSTALL_FOR_ME
+{
+ Text [ en-US ] = "~Only for me";
+};
+
+String RID_STR_ERROR_UNKNOWN_STATUS
+{
+ Text [ en-US ] = "Error: The status of this extension is unknown";
+};
+
+String RID_STR_CLOSE_BTN
+{
+ Text [ en-US ] = "Close";
+};
+
+String RID_STR_EXIT_BTN
+{
+ Text [ en-US ] = "Quit";
+};
+
+String RID_STR_NO_ADMIN_PRIVILEGE
+{
+ Text [ en-US ] = "%PRODUCTNAME has been updated to a new version. "
+ "Some shared %PRODUCTNAME extensions are not compatible with this version and need to be updated before %PRODUCTNAME can be started.\n\n"
+ "Updating of shared extension requires administrator privileges. Contact your system administrator to update the following shared extensions:";
+};
+
+String RID_STR_ERROR_MISSING_DEPENDENCIES
+{
+ Text [ en-US ] = "The extension cannot be enabled as the following system dependencies are not fulfilled:";
+};
+
+String RID_STR_ERROR_MISSING_LICENSE
+{
+ Text [ en-US ] = "This extension is disabled because you haven't accepted the license yet.\n";
+};
+
+String RID_STR_SHOW_LICENSE_CMD
+{
+ Text [ en-US ] = "Show license";
+};
+
+// Dialog layout
+// ---------------------------------------------------
+// row 1 | multi line edit
+// ---------------------------------------------------
+// row 2 | fixed text
+// ---------------------------------------------------
+// row 3 | img | fixed text | fixed text | button
+// ----------------------------------------------------
+// row 4 | img | fixed text | fixed text
+// ---------------------------------------------------
+// row 5 |fixed line
+// ---------------------------------------------------
+// row 6 | | |button | button
+// ---------------------------------------------------
+// | col 1 | col 2 | col3 | col4 | col5
+
+//To change the overall size of the multi line edit change
+//ROW1_HEIGHT and COL3_WIDTH
+
+#define ROW1_Y RSC_SP_DLG_INNERBORDER_TOP
+#define ROW1_HEIGHT 16*RSC_CD_FIXEDTEXT_HEIGHT
+#define ROW2_Y ROW1_Y+ROW1_HEIGHT+RSC_SP_CTRL_GROUP_Y
+#define ROW2_HEIGHT 3*RSC_CD_FIXEDTEXT_HEIGHT
+#define ROW3_Y ROW2_Y+ROW2_HEIGHT+RSC_SP_CTRL_GROUP_Y
+#define ROW3_HEIGHT 3*RSC_CD_FIXEDTEXT_HEIGHT
+#define ROW4_Y ROW3_Y+ROW3_HEIGHT+RSC_SP_CTRL_GROUP_Y
+#define ROW4_HEIGHT 3*RSC_CD_FIXEDTEXT_HEIGHT
+#define ROW5_Y ROW4_Y+ROW4_HEIGHT+RSC_SP_CTRL_GROUP_Y
+#define ROW5_HEIGHT RSC_CD_FIXEDTEXT_HEIGHT
+#define ROW6_Y ROW5_Y+ROW5_HEIGHT+RSC_SP_CTRL_GROUP_Y
+#define ROW6_HEIGHT RSC_CD_PUSHBUTTON_HEIGHT
+
+#define LIC_DLG_HEIGHT ROW6_Y+ROW6_HEIGHT+RSC_SP_DLG_INNERBORDER_BOTTOM
+
+#define COL1_X RSC_SP_DLG_INNERBORDER_LEFT
+#define IMG_ARROW_WIDTH 16
+#define COL1_WIDTH IMG_ARROW_WIDTH
+#define COL2_X COL1_X+COL1_WIDTH
+#define COL2_WIDTH 10
+#define COL3_X COL2_X+COL2_WIDTH+RSC_SP_CTRL_GROUP_X
+#define COL3_WIDTH 150
+#define COL4_X COL3_X+COL3_WIDTH
+#define COL4_WIDTH RSC_CD_PUSHBUTTON_WIDTH+RSC_SP_CTRL_GROUP_X
+#define COL5_X COL4_X+COL4_WIDTH
+
+#define LIC_DLG_WIDTH COL5_X+RSC_CD_PUSHBUTTON_WIDTH+RSC_SP_DLG_INNERBORDER_RIGHT
+#define BODYWIDTH LIC_DLG_WIDTH-RSC_SP_DLG_INNERBORDER_LEFT-RSC_SP_DLG_INNERBORDER_RIGHT
+
+ModalDialog RID_DLG_LICENSE
+{
+ HelpID = "desktop:ModalDialog:RID_DLG_LICENSE";
+ Text [ en-US ] = "Extension Software License Agreement";
+
+ Size = MAP_APPFONT(LIC_DLG_WIDTH, LIC_DLG_HEIGHT);
+ OutputSize = TRUE;
+ SVLook = TRUE;
+ Moveable = TRUE;
+ Closeable = TRUE;
+ Sizeable = FALSE;
+
+ MultiLineEdit ML_LICENSE
+ {
+ HelpID = "desktop:MultiLineEdit:RID_DLG_LICENSE:ML_LICENSE";
+ Pos = MAP_APPFONT(COL1_X, ROW1_Y);
+ Size = MAP_APPFONT(BODYWIDTH, ROW1_HEIGHT);
+ Border = TRUE;
+ VScroll = TRUE;
+ ReadOnly = TRUE;
+ };
+
+ FixedText FT_LICENSE_HEADER
+ {
+ Pos = MAP_APPFONT(COL1_X, ROW2_Y);
+ Size = MAP_APPFONT(COL1_WIDTH+COL2_WIDTH+COL3_WIDTH+COL4_WIDTH, ROW2_HEIGHT);
+ WordBreak = TRUE;
+ NoLabel = TRUE;
+ Text [ en-US ] = "Please follow these steps to proceed with the installation of the extension:";
+ };
+
+ FixedText FT_LICENSE_BODY_1
+ {
+ Pos = MAP_APPFONT(COL2_X, ROW3_Y);
+ Size = MAP_APPFONT( COL2_WIDTH, ROW3_HEIGHT );
+ NoLabel = TRUE;
+ Text [ en-US ] = "1.";
+ };
+
+ //spans col3 + col4
+ FixedText FT_LICENSE_BODY_1_TXT
+ {
+ Pos = MAP_APPFONT(COL3_X, ROW3_Y);
+ Size = MAP_APPFONT(COL3_WIDTH+COL4_WIDTH, ROW3_HEIGHT);
+ WordBreak = TRUE;
+ NoLabel = TRUE;
+ Text [ en-US ] = "Read the complete License Agreement. Use the scroll bar or the \'Scroll Down\' button in this dialog to view the entire license text.";
+ };
+
+ FixedText FT_LICENSE_BODY_2
+ {
+ Pos = MAP_APPFONT(COL2_X, ROW4_Y);
+ Size = MAP_APPFONT(COL2_WIDTH, ROW4_HEIGHT);
+ NoLabel = TRUE;
+ Text [ en-US ] = "2.";
+ };
+
+ FixedText FT_LICENSE_BODY_2_TXT
+ {
+ Pos = MAP_APPFONT(COL3_X, ROW4_Y);
+ Size = MAP_APPFONT(COL3_WIDTH+COL4_WIDTH, ROW4_HEIGHT);
+ WordBreak = TRUE;
+ NoLabel = TRUE;
+ Text [ en-US ] = "Accept the License Agreement for the extension by pressing the \'Accept\' button.";
+
+ };
+
+ PushButton PB_LICENSE_DOWN
+ {
+ HelpID = "desktop:PushButton:RID_DLG_LICENSE:PB_LICENSE_DOWN";
+ TabStop = TRUE ;
+ Pos = MAP_APPFONT(COL5_X , ROW3_Y) ;
+ Size = MAP_APPFONT(RSC_CD_PUSHBUTTON_WIDTH, RSC_CD_PUSHBUTTON_HEIGHT) ;
+ Text [ en-US ] = "~Scroll Down";
+
+ };
+
+ FixedLine FL_LICENSE
+ {
+ Pos = MAP_APPFONT ( 0, ROW5_Y) ;
+ Size = MAP_APPFONT ( LIC_DLG_WIDTH, ROW5_HEIGHT ) ;
+ };
+
+ FixedImage FI_LICENSE_ARROW1
+ {
+ Pos = MAP_APPFONT (COL1_X, ROW3_Y) ;
+ Size = (16, 16);
+ Fixed = Image
+ {
+ ImageBitmap = Bitmap { File = "sc06300.png"; };
+ MASKCOLOR
+ };
+ };
+
+ FixedImage FI_LICENSE_ARROW2
+ {
+ Pos = MAP_APPFONT (COL1_X, ROW4_Y) ;
+ Size = (16,16);
+ Fixed = Image
+ {
+ ImageBitmap = Bitmap { File = "sc06300.png"; };
+ MASKCOLOR
+ };
+ };
+
+ OKButton BTN_LICENSE_ACCEPT
+ {
+ Pos = MAP_APPFONT(COL4_X, ROW6_Y);
+ Size = MAP_APPFONT(RSC_CD_PUSHBUTTON_WIDTH, RSC_CD_PUSHBUTTON_HEIGHT );
+
+ TabStop = TRUE;
+ DefButton = TRUE;
+ Text [ en-US ] = "Accept";
+ };
+
+ CancelButton BTN_LICENSE_DECLINE
+ {
+ Pos = MAP_APPFONT(COL5_X, ROW6_Y);
+ Size = MAP_APPFONT( RSC_CD_PUSHBUTTON_WIDTH, RSC_CD_PUSHBUTTON_HEIGHT );
+ Text [ en-US ] = "Decline" ;
+ TabStop = TRUE;
+ };
+
+};
+
+ModalDialog RID_DLG_SHOW_LICENSE
+{
+ Text [ en-US ] = "Extension Software License Agreement";
+ Size = MAP_APPFONT( 300, 200 );
+ OutputSize = TRUE;
+ SVLook = TRUE;
+ Moveable = TRUE;
+ Closeable = TRUE;
+ Sizeable = TRUE;
+
+ MultiLineEdit ML_LICENSE
+ {
+ Pos = MAP_APPFONT( 5, 5 );
+ Size = MAP_APPFONT( 300 - 10, 200 - 15 - RSC_CD_PUSHBUTTON_HEIGHT );
+ Border = TRUE;
+ VScroll = TRUE;
+ ReadOnly = TRUE;
+ };
+
+ OKButton RID_EM_BTN_CLOSE
+ {
+ TabStop = TRUE;
+ DefButton = TRUE;
+ Text [ en-US ] = "Close";
+ Pos = MAP_APPFONT( (300-RSC_CD_PUSHBUTTON_WIDTH)/2, 200 - 5 - RSC_CD_PUSHBUTTON_HEIGHT );
+ Size = MAP_APPFONT( RSC_CD_PUSHBUTTON_WIDTH, RSC_CD_PUSHBUTTON_HEIGHT );
+ };
+};
+
+
+
+WarningBox RID_WARNINGBOX_INSTALL_EXTENSION {
+ Buttons = WB_OK_CANCEL;
+ DefButton = WB_DEF_OK;
+ Message[en-US] = "You are about to install the extension \'%NAME\'.\n"
+ "Click \'OK\' to proceed with the installation.\n"
+ "Click \'Cancel\' to stop the installation.";
+};
+
+WarningBox RID_WARNINGBOX_REMOVE_EXTENSION {
+ Buttons = WB_OK_CANCEL;
+ DefButton = WB_DEF_CANCEL;
+ Message[en-US] = "You are about to remove the extension \'%NAME\'.\n"
+ "Click \'OK\' to remove the extension.\n"
+ "Click \'Cancel\' to stop removing the extension.";
+};
+
+WARNINGBOX RID_WARNINGBOX_REMOVE_SHARED_EXTENSION
+{
+ Buttons = WB_OK_CANCEL;
+ DefButton = WB_DEF_CANCEL;
+ Message[en-US] = "Make sure that no further users are working with the same "
+ "%PRODUCTNAME, when changing shared extensions in a multi user environment.\n"
+ "Click \'OK\' to remove the extension.\n"
+ "Click \'Cancel\' to stop removing the extension.";
+};
+
+WARNINGBOX RID_WARNINGBOX_ENABLE_SHARED_EXTENSION
+{
+ Buttons = WB_OK_CANCEL;
+ DefButton = WB_DEF_CANCEL;
+ Message[en-US] = "Make sure that no further users are working with the same "
+ "%PRODUCTNAME, when changing shared extensions in a multi user environment.\n"
+ "Click \'OK\' to enable the extension.\n"
+ "Click \'Cancel\' to stop enabling the extension.";
+};
+
+WARNINGBOX RID_WARNINGBOX_DISABLE_SHARED_EXTENSION
+{
+ Buttons = WB_OK_CANCEL;
+ DefButton = WB_DEF_CANCEL;
+ Message[en-US] = "Make sure that no further users are working with the same "
+ "%PRODUCTNAME, when changing shared extensions in a multi user environment.\n"
+ "Click \'OK\' to disable the extension.\n"
+ "Click \'Cancel\' to stop disabling the extension.";
+};
+
+
+String RID_STR_UNSUPPORTED_PLATFORM
+{
+ Text [ en-US ] = "The extension \'%Name\' does not work on this computer.";
+};
diff --git a/desktop/source/deployment/gui/dp_gui_dialog2.cxx b/desktop/source/deployment/gui/dp_gui_dialog2.cxx
new file mode 100644
index 000000000000..e564fade8e5e
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_dialog2.cxx
@@ -0,0 +1,1827 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include "dp_gui.hrc"
+#include "svtools/controldims.hrc"
+#include "svtools/svtools.hrc"
+
+#include "dp_gui.h"
+#include "dp_gui_dialog2.hxx"
+#include "dp_gui_extlistbox.hxx"
+#include "dp_gui_shared.hxx"
+#include "dp_gui_theextmgr.hxx"
+#include "dp_gui_extensioncmdqueue.hxx"
+#include "dp_misc.h"
+#include "dp_ucb.h"
+#include "dp_update.hxx"
+#include "dp_identifier.hxx"
+#include "dp_descriptioninfoset.hxx"
+
+#include "vcl/ctrl.hxx"
+#include "vcl/menu.hxx"
+#include "vcl/msgbox.hxx"
+#include "vcl/scrbar.hxx"
+#include "vcl/svapp.hxx"
+
+#include "osl/mutex.hxx"
+
+#include "svtools/extensionlistbox.hxx"
+
+#include "sfx2/sfxdlg.hxx"
+
+#include "comphelper/anytostring.hxx"
+#include "cppuhelper/exc_hlp.hxx"
+#include "cppuhelper/bootstrap.hxx"
+
+#include "comphelper/processfactory.hxx"
+#include "ucbhelper/content.hxx"
+#include "unotools/collatorwrapper.hxx"
+
+#include "com/sun/star/beans/StringPair.hpp"
+
+#include "com/sun/star/i18n/CollatorOptions.hpp"
+
+#include "com/sun/star/system/SystemShellExecuteFlags.hpp"
+#include "com/sun/star/system/XSystemShellExecute.hpp"
+
+#include "com/sun/star/ui/dialogs/ExecutableDialogResults.hpp"
+#include "com/sun/star/ui/dialogs/TemplateDescription.hpp"
+#include "com/sun/star/ui/dialogs/XFilePicker.hpp"
+#include "com/sun/star/ui/dialogs/XFilterManager.hpp"
+
+#include "com/sun/star/uno/Any.hxx"
+#include "com/sun/star/uno/XComponentContext.hpp"
+
+#include <map>
+#include <vector>
+#include <boost/shared_ptr.hpp>
+
+#define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::system;
+
+using ::rtl::OUString;
+
+
+namespace dp_gui {
+
+#define TOP_OFFSET 5
+#define LINE_SIZE 4
+#define PROGRESS_WIDTH 60
+#define PROGRESS_HEIGHT 14
+
+//------------------------------------------------------------------------------
+struct StrAllFiles : public rtl::StaticWithInit< const OUString, StrAllFiles >
+{
+ const OUString operator () () {
+ const SolarMutexGuard guard;
+ ::std::auto_ptr< ResMgr > const resmgr( ResMgr::CreateResMgr( "fps_office" ) );
+ OSL_ASSERT( resmgr.get() != 0 );
+ String ret( ResId( STR_FILTERNAME_ALL, *resmgr.get() ) );
+ return ret;
+ }
+};
+
+//------------------------------------------------------------------------------
+// ExtBoxWithBtns_Impl
+//------------------------------------------------------------------------------
+
+enum MENU_COMMAND
+{
+ CMD_NONE = 0,
+ CMD_REMOVE = 1,
+ CMD_ENABLE,
+ CMD_DISABLE,
+ CMD_UPDATE,
+ CMD_SHOW_LICENSE
+};
+
+class ExtBoxWithBtns_Impl : public ExtensionBox_Impl
+{
+ Size m_aOutputSize;
+ bool m_bInterfaceLocked;
+
+ PushButton *m_pOptionsBtn;
+ PushButton *m_pEnableBtn;
+ PushButton *m_pRemoveBtn;
+
+ ExtMgrDialog *m_pParent;
+
+ void SetButtonPos( const Rectangle& rRect );
+ void SetButtonStatus( const TEntry_Impl pEntry );
+ bool HandleTabKey( bool bReverse );
+ MENU_COMMAND ShowPopupMenu( const Point &rPos, const long nPos );
+
+ //-----------------
+ DECL_DLLPRIVATE_LINK( ScrollHdl, ScrollBar * );
+
+ DECL_DLLPRIVATE_LINK( HandleOptionsBtn, void * );
+ DECL_DLLPRIVATE_LINK( HandleEnableBtn, void * );
+ DECL_DLLPRIVATE_LINK( HandleRemoveBtn, void * );
+ DECL_DLLPRIVATE_LINK( HandleHyperlink, svt::FixedHyperlink * );
+
+public:
+ ExtBoxWithBtns_Impl( ExtMgrDialog* pParent, TheExtensionManager *pManager );
+ ~ExtBoxWithBtns_Impl();
+
+ virtual void MouseButtonDown( const MouseEvent& rMEvt );
+ virtual long Notify( NotifyEvent& rNEvt );
+
+ const Size GetMinOutputSizePixel() const;
+
+ virtual void RecalcAll();
+ virtual void selectEntry( const long nPos );
+ //-----------------
+ void enableButtons( bool bEnable );
+};
+
+//------------------------------------------------------------------------------
+ExtBoxWithBtns_Impl::ExtBoxWithBtns_Impl( ExtMgrDialog* pParent, TheExtensionManager *pManager ) :
+ ExtensionBox_Impl( pParent, pManager ),
+ m_bInterfaceLocked( false ),
+ m_pOptionsBtn( NULL ),
+ m_pEnableBtn( NULL ),
+ m_pRemoveBtn( NULL ),
+ m_pParent( pParent )
+{
+ m_pOptionsBtn = new PushButton( this, WB_TABSTOP );
+ m_pEnableBtn = new PushButton( this, WB_TABSTOP );
+ m_pRemoveBtn = new PushButton( this, WB_TABSTOP );
+
+ SetHelpId( HID_EXTENSION_MANAGER_LISTBOX );
+ m_pOptionsBtn->SetHelpId( HID_EXTENSION_MANAGER_LISTBOX_OPTIONS );
+ m_pEnableBtn->SetHelpId( HID_EXTENSION_MANAGER_LISTBOX_DISABLE );
+ m_pRemoveBtn->SetHelpId( HID_EXTENSION_MANAGER_LISTBOX_REMOVE );
+
+ m_pOptionsBtn->SetClickHdl( LINK( this, ExtBoxWithBtns_Impl, HandleOptionsBtn ) );
+ m_pEnableBtn->SetClickHdl( LINK( this, ExtBoxWithBtns_Impl, HandleEnableBtn ) );
+ m_pRemoveBtn->SetClickHdl( LINK( this, ExtBoxWithBtns_Impl, HandleRemoveBtn ) );
+
+ m_pOptionsBtn->SetText( DialogHelper::getResourceString( RID_CTX_ITEM_OPTIONS ) );
+ m_pEnableBtn->SetText( DialogHelper::getResourceString( RID_CTX_ITEM_DISABLE ) );
+ m_pRemoveBtn->SetText( DialogHelper::getResourceString( RID_CTX_ITEM_REMOVE ) );
+
+ Size aSize = LogicToPixel( Size( RSC_CD_PUSHBUTTON_WIDTH, RSC_CD_PUSHBUTTON_HEIGHT ),
+ MapMode( MAP_APPFONT ) );
+ m_pOptionsBtn->SetSizePixel( aSize );
+ m_pEnableBtn->SetSizePixel( aSize );
+ m_pRemoveBtn->SetSizePixel( aSize );
+
+ SetExtraSize( aSize.Height() + 2 * TOP_OFFSET );
+
+ SetScrollHdl( LINK( this, ExtBoxWithBtns_Impl, ScrollHdl ) );
+}
+
+//------------------------------------------------------------------------------
+ExtBoxWithBtns_Impl::~ExtBoxWithBtns_Impl()
+{
+ delete m_pOptionsBtn;
+ delete m_pEnableBtn;
+ delete m_pRemoveBtn;
+}
+
+//------------------------------------------------------------------------------
+const Size ExtBoxWithBtns_Impl::GetMinOutputSizePixel() const
+{
+ Size aMinSize( ExtensionBox_Impl::GetMinOutputSizePixel() );
+ long nHeight = aMinSize.Height();
+ nHeight += m_pOptionsBtn->GetSizePixel().Height();
+ nHeight += 2 * TOP_OFFSET;
+ long nWidth = m_pOptionsBtn->GetSizePixel().Width();
+ nWidth *= 3;
+ nWidth += 5*TOP_OFFSET + 20;
+
+ return Size( nWidth, nHeight );
+}
+
+// -----------------------------------------------------------------------
+void ExtBoxWithBtns_Impl::RecalcAll()
+{
+ const sal_Int32 nActive = getSelIndex();
+
+ if ( nActive != EXTENSION_LISTBOX_ENTRY_NOTFOUND )
+ {
+ SetButtonStatus( GetEntryData( nActive) );
+ }
+ else
+ {
+ m_pOptionsBtn->Hide();
+ m_pEnableBtn->Hide();
+ m_pRemoveBtn->Hide();
+ }
+
+ ExtensionBox_Impl::RecalcAll();
+
+ if ( nActive != EXTENSION_LISTBOX_ENTRY_NOTFOUND )
+ SetButtonPos( GetEntryRect( nActive ) );
+}
+
+
+//------------------------------------------------------------------------------
+//This function may be called with nPos < 0
+void ExtBoxWithBtns_Impl::selectEntry( const long nPos )
+{
+ if ( HasActive() && ( nPos == getSelIndex() ) )
+ return;
+
+ ExtensionBox_Impl::selectEntry( nPos );
+}
+
+// -----------------------------------------------------------------------
+void ExtBoxWithBtns_Impl::SetButtonPos( const Rectangle& rRect )
+{
+ Size aBtnSize( m_pOptionsBtn->GetSizePixel() );
+ Point aBtnPos( rRect.Left() + ICON_OFFSET,
+ rRect.Bottom() - TOP_OFFSET - aBtnSize.Height() );
+
+ m_pOptionsBtn->SetPosPixel( aBtnPos );
+ aBtnPos.X() = rRect.Right() - TOP_OFFSET - aBtnSize.Width();
+ m_pRemoveBtn->SetPosPixel( aBtnPos );
+ aBtnPos.X() -= ( TOP_OFFSET + aBtnSize.Width() );
+ m_pEnableBtn->SetPosPixel( aBtnPos );
+}
+
+// -----------------------------------------------------------------------
+void ExtBoxWithBtns_Impl::SetButtonStatus( const TEntry_Impl pEntry )
+{
+ bool bShowOptionBtn = true;
+
+ pEntry->m_bHasButtons = false;
+ if ( ( pEntry->m_eState == REGISTERED ) || ( pEntry->m_eState == NOT_AVAILABLE ) )
+ {
+ m_pEnableBtn->SetText( DialogHelper::getResourceString( RID_CTX_ITEM_DISABLE ) );
+ m_pEnableBtn->SetHelpId( HID_EXTENSION_MANAGER_LISTBOX_DISABLE );
+ }
+ else
+ {
+ m_pEnableBtn->SetText( DialogHelper::getResourceString( RID_CTX_ITEM_ENABLE ) );
+ m_pEnableBtn->SetHelpId( HID_EXTENSION_MANAGER_LISTBOX_ENABLE );
+ bShowOptionBtn = false;
+ }
+
+ if ( ( !pEntry->m_bUser || ( pEntry->m_eState == NOT_AVAILABLE ) || pEntry->m_bMissingDeps )
+ && !pEntry->m_bMissingLic )
+ m_pEnableBtn->Hide();
+ else
+ {
+ m_pEnableBtn->Enable( !pEntry->m_bLocked );
+ m_pEnableBtn->Show();
+ pEntry->m_bHasButtons = true;
+ }
+
+ if ( pEntry->m_bHasOptions && bShowOptionBtn )
+ {
+ m_pOptionsBtn->Enable( pEntry->m_bHasOptions );
+ m_pOptionsBtn->Show();
+ pEntry->m_bHasButtons = true;
+ }
+ else
+ m_pOptionsBtn->Hide();
+
+ if ( pEntry->m_bUser || pEntry->m_bShared )
+ {
+ m_pRemoveBtn->Enable( !pEntry->m_bLocked );
+ m_pRemoveBtn->Show();
+ pEntry->m_bHasButtons = true;
+ }
+ else
+ m_pRemoveBtn->Hide();
+}
+
+// -----------------------------------------------------------------------
+bool ExtBoxWithBtns_Impl::HandleTabKey( bool bReverse )
+{
+ sal_Int32 nIndex = getSelIndex();
+
+ if ( nIndex == EXTENSION_LISTBOX_ENTRY_NOTFOUND )
+ return false;
+
+ PushButton *pNext = NULL;
+
+ if ( m_pOptionsBtn->HasFocus() ) {
+ if ( !bReverse && !GetEntryData( nIndex )->m_bLocked )
+ pNext = m_pEnableBtn;
+ }
+ else if ( m_pEnableBtn->HasFocus() ) {
+ if ( !bReverse )
+ pNext = m_pRemoveBtn;
+ else if ( GetEntryData( nIndex )->m_bHasOptions )
+ pNext = m_pOptionsBtn;
+ }
+ else if ( m_pRemoveBtn->HasFocus() ) {
+ if ( bReverse )
+ pNext = m_pEnableBtn;
+ }
+ else {
+ if ( !bReverse ) {
+ if ( GetEntryData( nIndex )->m_bHasOptions )
+ pNext = m_pOptionsBtn;
+ else if ( ! GetEntryData( nIndex )->m_bLocked )
+ pNext = m_pEnableBtn;
+ } else {
+ if ( ! GetEntryData( nIndex )->m_bLocked )
+ pNext = m_pRemoveBtn;
+ else if ( GetEntryData( nIndex )->m_bHasOptions )
+ pNext = m_pOptionsBtn;
+ }
+ }
+
+ if ( pNext )
+ {
+ pNext->GrabFocus();
+ return true;
+ }
+ else
+ return false;
+}
+
+// -----------------------------------------------------------------------
+MENU_COMMAND ExtBoxWithBtns_Impl::ShowPopupMenu( const Point & rPos, const long nPos )
+{
+ if ( nPos >= (long) getItemCount() )
+ return CMD_NONE;
+
+ PopupMenu aPopup;
+
+ aPopup.InsertItem( CMD_UPDATE, DialogHelper::getResourceString( RID_CTX_ITEM_CHECK_UPDATE ) );
+
+ if ( ! GetEntryData( nPos )->m_bLocked )
+ {
+ if ( GetEntryData( nPos )->m_bUser )
+ {
+ if ( GetEntryData( nPos )->m_eState == REGISTERED )
+ aPopup.InsertItem( CMD_DISABLE, DialogHelper::getResourceString( RID_CTX_ITEM_DISABLE ) );
+ else if ( GetEntryData( nPos )->m_eState != NOT_AVAILABLE )
+ aPopup.InsertItem( CMD_ENABLE, DialogHelper::getResourceString( RID_CTX_ITEM_ENABLE ) );
+ }
+ aPopup.InsertItem( CMD_REMOVE, DialogHelper::getResourceString( RID_CTX_ITEM_REMOVE ) );
+ }
+
+ if ( GetEntryData( nPos )->m_sLicenseText.Len() )
+ aPopup.InsertItem( CMD_SHOW_LICENSE, DialogHelper::getResourceString( RID_STR_SHOW_LICENSE_CMD ) );
+
+ return (MENU_COMMAND) aPopup.Execute( this, rPos );
+}
+
+//------------------------------------------------------------------------------
+void ExtBoxWithBtns_Impl::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ if ( m_bInterfaceLocked )
+ return;
+
+ const Point aMousePos( rMEvt.GetPosPixel() );
+ const long nPos = PointToPos( aMousePos );
+
+ if ( rMEvt.IsRight() )
+ {
+ switch( ShowPopupMenu( aMousePos, nPos ) )
+ {
+ case CMD_NONE: break;
+ case CMD_ENABLE: m_pParent->enablePackage( GetEntryData( nPos )->m_xPackage, true );
+ break;
+ case CMD_DISABLE: m_pParent->enablePackage( GetEntryData( nPos )->m_xPackage, false );
+ break;
+ case CMD_UPDATE: m_pParent->updatePackage( GetEntryData( nPos )->m_xPackage );
+ break;
+ case CMD_REMOVE: m_pParent->removePackage( GetEntryData( nPos )->m_xPackage );
+ break;
+ case CMD_SHOW_LICENSE:
+ {
+ ShowLicenseDialog aLicenseDlg( m_pParent, GetEntryData( nPos )->m_xPackage );
+ aLicenseDlg.Execute();
+ break;
+ }
+ }
+ }
+ else if ( rMEvt.IsLeft() )
+ {
+ const SolarMutexGuard aGuard;
+ if ( rMEvt.IsMod1() && HasActive() )
+ selectEntry( EXTENSION_LISTBOX_ENTRY_NOTFOUND ); // Selecting an not existing entry will deselect the current one
+ else
+ selectEntry( nPos );
+ }
+}
+
+//------------------------------------------------------------------------------
+long ExtBoxWithBtns_Impl::Notify( NotifyEvent& rNEvt )
+{
+ bool bHandled = false;
+
+ if ( rNEvt.GetType() == EVENT_KEYINPUT )
+ {
+ const KeyEvent* pKEvt = rNEvt.GetKeyEvent();
+ KeyCode aKeyCode = pKEvt->GetKeyCode();
+ sal_uInt16 nKeyCode = aKeyCode.GetCode();
+
+ if ( nKeyCode == KEY_TAB )
+ bHandled = HandleTabKey( aKeyCode.IsShift() );
+ }
+
+ if ( !bHandled )
+ return ExtensionBox_Impl::Notify( rNEvt );
+ else
+ return true;
+}
+
+//------------------------------------------------------------------------------
+void ExtBoxWithBtns_Impl::enableButtons( bool bEnable )
+{
+ m_bInterfaceLocked = ! bEnable;
+
+ if ( bEnable )
+ {
+ sal_Int32 nIndex = getSelIndex();
+ if ( nIndex != EXTENSION_LISTBOX_ENTRY_NOTFOUND )
+ SetButtonStatus( GetEntryData( nIndex ) );
+ }
+ else
+ {
+ m_pOptionsBtn->Enable( false );
+ m_pRemoveBtn->Enable( false );
+ m_pEnableBtn->Enable( false );
+ }
+}
+
+// -----------------------------------------------------------------------
+IMPL_LINK( ExtBoxWithBtns_Impl, ScrollHdl, ScrollBar*, pScrBar )
+{
+ long nDelta = pScrBar->GetDelta();
+
+ Point aNewOptPt( m_pOptionsBtn->GetPosPixel() - Point( 0, nDelta ) );
+ Point aNewRemPt( m_pRemoveBtn->GetPosPixel() - Point( 0, nDelta ) );
+ Point aNewEnPt( m_pEnableBtn->GetPosPixel() - Point( 0, nDelta ) );
+
+ DoScroll( nDelta );
+
+ m_pOptionsBtn->SetPosPixel( aNewOptPt );
+ m_pRemoveBtn->SetPosPixel( aNewRemPt );
+ m_pEnableBtn->SetPosPixel( aNewEnPt );
+
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+IMPL_LINK( ExtBoxWithBtns_Impl, HandleOptionsBtn, void*, EMPTYARG )
+{
+ const sal_Int32 nActive = getSelIndex();
+
+ if ( nActive != EXTENSION_LISTBOX_ENTRY_NOTFOUND )
+ {
+ SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create();
+
+ if ( pFact )
+ {
+ OUString sExtensionId = GetEntryData( nActive )->m_xPackage->getIdentifier().Value;
+ VclAbstractDialog* pDlg = pFact->CreateOptionsDialog( this, sExtensionId, rtl::OUString() );
+
+ pDlg->Execute();
+
+ delete pDlg;
+ }
+ }
+
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+IMPL_LINK( ExtBoxWithBtns_Impl, HandleEnableBtn, void*, EMPTYARG )
+{
+ const sal_Int32 nActive = getSelIndex();
+
+ if ( nActive != EXTENSION_LISTBOX_ENTRY_NOTFOUND )
+ {
+ TEntry_Impl pEntry = GetEntryData( nActive );
+
+ if ( pEntry->m_bMissingLic )
+ m_pParent->acceptLicense( pEntry->m_xPackage );
+ else
+ {
+ const bool bEnable( pEntry->m_eState != REGISTERED );
+ m_pParent->enablePackage( pEntry->m_xPackage, bEnable );
+ }
+ }
+
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+IMPL_LINK( ExtBoxWithBtns_Impl, HandleRemoveBtn, void*, EMPTYARG )
+{
+ const sal_Int32 nActive = getSelIndex();
+
+ if ( nActive != EXTENSION_LISTBOX_ENTRY_NOTFOUND )
+ {
+ TEntry_Impl pEntry = GetEntryData( nActive );
+ m_pParent->removePackage( pEntry->m_xPackage );
+ }
+
+ return 1;
+}
+
+//------------------------------------------------------------------------------
+// DialogHelper
+//------------------------------------------------------------------------------
+DialogHelper::DialogHelper( const uno::Reference< uno::XComponentContext > &xContext,
+ Dialog *pWindow ) :
+ m_pVCLWindow( pWindow ),
+ m_nEventID( 0 ),
+ m_bIsBusy( false )
+{
+ m_xContext = xContext;
+}
+
+//------------------------------------------------------------------------------
+DialogHelper::~DialogHelper()
+{
+ if ( m_nEventID )
+ Application::RemoveUserEvent( m_nEventID );
+}
+
+//------------------------------------------------------------------------------
+ResId DialogHelper::getResId( sal_uInt16 nId )
+{
+ const SolarMutexGuard guard;
+ return ResId( nId, *DeploymentGuiResMgr::get() );
+}
+
+//------------------------------------------------------------------------------
+String DialogHelper::getResourceString( sal_uInt16 id )
+{
+ // init with non-acquired solar mutex:
+ BrandName::get();
+ const SolarMutexGuard guard;
+ String ret( ResId( id, *DeploymentGuiResMgr::get() ) );
+ if (ret.SearchAscii( "%PRODUCTNAME" ) != STRING_NOTFOUND) {
+ ret.SearchAndReplaceAllAscii( "%PRODUCTNAME", BrandName::get() );
+ }
+ return ret;
+}
+
+//------------------------------------------------------------------------------
+bool DialogHelper::IsSharedPkgMgr( const uno::Reference< deployment::XPackage > &xPackage )
+{
+ if ( xPackage->getRepositoryName().equals( OUSTR("shared") ) )
+ return true;
+ else
+ return false;
+}
+
+//------------------------------------------------------------------------------
+bool DialogHelper::continueOnSharedExtension( const uno::Reference< deployment::XPackage > &xPackage,
+ Window *pParent,
+ const sal_uInt16 nResID,
+ bool &bHadWarning )
+{
+ if ( !bHadWarning && IsSharedPkgMgr( xPackage ) )
+ {
+ const SolarMutexGuard guard;
+ WarningBox aInfoBox( pParent, getResId( nResID ) );
+ String aMsgText = aInfoBox.GetMessText();
+ aMsgText.SearchAndReplaceAllAscii( "%PRODUCTNAME", BrandName::get() );
+ aInfoBox.SetMessText( aMsgText );
+
+ bHadWarning = true;
+
+ if ( RET_OK == aInfoBox.Execute() )
+ return true;
+ else
+ return false;
+ }
+ else
+ return true;
+}
+
+//------------------------------------------------------------------------------
+void DialogHelper::openWebBrowser( const OUString & sURL, const OUString &sTitle ) const
+{
+ if ( ! sURL.getLength() ) // Nothing to do, when the URL is empty
+ return;
+
+ try
+ {
+ uno::Reference< XSystemShellExecute > xSystemShellExecute(
+ m_xContext->getServiceManager()->createInstanceWithContext( OUSTR( "com.sun.star.system.SystemShellExecute" ), m_xContext), uno::UNO_QUERY_THROW);
+ //throws css::lang::IllegalArgumentException, css::system::SystemShellExecuteException
+ xSystemShellExecute->execute( sURL, OUString(), SystemShellExecuteFlags::DEFAULTS );
+ }
+ catch ( uno::Exception& )
+ {
+ uno::Any exc( ::cppu::getCaughtException() );
+ OUString msg( ::comphelper::anyToString( exc ) );
+ const SolarMutexGuard guard;
+ ErrorBox aErrorBox( NULL, WB_OK, msg );
+ aErrorBox.SetText( sTitle );
+ aErrorBox.Execute();
+ }
+}
+
+//------------------------------------------------------------------------------
+bool DialogHelper::installExtensionWarn( const OUString &rExtensionName ) const
+{
+ const SolarMutexGuard guard;
+ WarningBox aInfo( m_pVCLWindow, getResId( RID_WARNINGBOX_INSTALL_EXTENSION ) );
+
+ String sText( aInfo.GetMessText() );
+ sText.SearchAndReplaceAllAscii( "%NAME", rExtensionName );
+ aInfo.SetMessText( sText );
+
+ return ( RET_OK == aInfo.Execute() );
+}
+
+//------------------------------------------------------------------------------
+bool DialogHelper::installForAllUsers( bool &bInstallForAll ) const
+{
+ const SolarMutexGuard guard;
+ QueryBox aQuery( m_pVCLWindow, getResId( RID_QUERYBOX_INSTALL_FOR_ALL ) );
+
+ String sMsgText = aQuery.GetMessText();
+ sMsgText.SearchAndReplaceAllAscii( "%PRODUCTNAME", BrandName::get() );
+ aQuery.SetMessText( sMsgText );
+
+ sal_uInt16 nYesBtnID = aQuery.GetButtonId( 0 );
+ sal_uInt16 nNoBtnID = aQuery.GetButtonId( 1 );
+
+ if ( nYesBtnID != BUTTONDIALOG_BUTTON_NOTFOUND )
+ aQuery.SetButtonText( nYesBtnID, getResourceString( RID_STR_INSTALL_FOR_ME ) );
+ if ( nNoBtnID != BUTTONDIALOG_BUTTON_NOTFOUND )
+ aQuery.SetButtonText( nNoBtnID, getResourceString( RID_STR_INSTALL_FOR_ALL ) );
+
+ short nRet = aQuery.Execute();
+
+ if ( nRet == RET_CANCEL )
+ return false;
+
+ bInstallForAll = ( nRet == RET_NO );
+ return true;
+}
+
+//------------------------------------------------------------------------------
+void DialogHelper::PostUserEvent( const Link& rLink, void* pCaller )
+{
+ if ( m_nEventID )
+ Application::RemoveUserEvent( m_nEventID );
+
+ m_nEventID = Application::PostUserEvent( rLink, pCaller );
+}
+
+//------------------------------------------------------------------------------
+// ExtMgrDialog
+//------------------------------------------------------------------------------
+ExtMgrDialog::ExtMgrDialog( Window *pParent, TheExtensionManager *pManager ) :
+ ModelessDialog( pParent, getResId( RID_DLG_EXTENSION_MANAGER ) ),
+ DialogHelper( pManager->getContext(), (Dialog*) this ),
+ m_aAddBtn( this, getResId( RID_EM_BTN_ADD ) ),
+ m_aUpdateBtn( this, getResId( RID_EM_BTN_CHECK_UPDATES ) ),
+ m_aCloseBtn( this, getResId( RID_EM_BTN_CLOSE ) ),
+ m_aHelpBtn( this, getResId( RID_EM_BTN_HELP ) ),
+ m_aDivider( this ),
+ m_aGetExtensions( this, getResId( RID_EM_FT_GET_EXTENSIONS ) ),
+ m_aProgressText( this, getResId( RID_EM_FT_PROGRESS ) ),
+ m_aProgressBar( this, WB_BORDER + WB_3DLOOK ),
+ m_aCancelBtn( this, getResId( RID_EM_BTN_CANCEL ) ),
+ m_sAddPackages( getResourceString( RID_STR_ADD_PACKAGES ) ),
+ m_bHasProgress( false ),
+ m_bProgressChanged( false ),
+ m_bStartProgress( false ),
+ m_bStopProgress( false ),
+ m_bUpdateWarning( false ),
+ m_bEnableWarning( false ),
+ m_bDisableWarning( false ),
+ m_bDeleteWarning( false ),
+ m_nProgress( 0 ),
+ m_pManager( pManager )
+{
+ // free local resources (RID < 256):
+ FreeResource();
+
+ m_pExtensionBox = new ExtBoxWithBtns_Impl( this, pManager );
+ m_pExtensionBox->SetHyperlinkHdl( LINK( this, ExtMgrDialog, HandleHyperlink ) );
+
+ m_aAddBtn.SetClickHdl( LINK( this, ExtMgrDialog, HandleAddBtn ) );
+ m_aUpdateBtn.SetClickHdl( LINK( this, ExtMgrDialog, HandleUpdateBtn ) );
+ m_aGetExtensions.SetClickHdl( LINK( this, ExtMgrDialog, HandleHyperlink ) );
+ m_aCancelBtn.SetClickHdl( LINK( this, ExtMgrDialog, HandleCancelBtn ) );
+
+ // resize update button
+ Size aBtnSize = m_aUpdateBtn.GetSizePixel();
+ String sTitle = m_aUpdateBtn.GetText();
+ long nWidth = m_aUpdateBtn.GetCtrlTextWidth( sTitle );
+ nWidth += 2 * m_aUpdateBtn.GetTextHeight();
+ if ( nWidth > aBtnSize.Width() )
+ m_aUpdateBtn.SetSizePixel( Size( nWidth, aBtnSize.Height() ) );
+
+ // minimum size:
+ SetMinOutputSizePixel(
+ Size( // width:
+ (3 * m_aHelpBtn.GetSizePixel().Width()) +
+ m_aUpdateBtn.GetSizePixel().Width() +
+ (5 * RSC_SP_DLG_INNERBORDER_LEFT ),
+ // height:
+ (1 * m_aHelpBtn.GetSizePixel().Height()) +
+ (1 * m_aGetExtensions.GetSizePixel().Height()) +
+ (1 * m_pExtensionBox->GetMinOutputSizePixel().Height()) +
+ (3 * RSC_SP_DLG_INNERBORDER_LEFT) ) );
+
+ m_aDivider.Show();
+ m_aProgressBar.Hide();
+
+ m_aUpdateBtn.Enable( false );
+
+ m_aTimeoutTimer.SetTimeout( 500 ); // mSec
+ m_aTimeoutTimer.SetTimeoutHdl( LINK( this, ExtMgrDialog, TimeOutHdl ) );
+}
+
+//------------------------------------------------------------------------------
+ExtMgrDialog::~ExtMgrDialog()
+{
+ m_aTimeoutTimer.Stop();
+ delete m_pExtensionBox;
+}
+
+//------------------------------------------------------------------------------
+void ExtMgrDialog::setGetExtensionsURL( const ::rtl::OUString &rURL )
+{
+ m_aGetExtensions.SetURL( rURL );
+}
+
+//------------------------------------------------------------------------------
+long ExtMgrDialog::addPackageToList( const uno::Reference< deployment::XPackage > &xPackage,
+ bool bLicenseMissing )
+{
+ const SolarMutexGuard aGuard;
+ m_aUpdateBtn.Enable( true );
+ return m_pExtensionBox->addEntry( xPackage, bLicenseMissing );
+}
+
+//------------------------------------------------------------------------------
+void ExtMgrDialog::prepareChecking()
+{
+ m_pExtensionBox->prepareChecking();
+}
+
+//------------------------------------------------------------------------------
+void ExtMgrDialog::checkEntries()
+{
+ const SolarMutexGuard guard;
+ m_pExtensionBox->checkEntries();
+}
+
+//------------------------------------------------------------------------------
+bool ExtMgrDialog::removeExtensionWarn( const OUString &rExtensionName ) const
+{
+ const SolarMutexGuard guard;
+ WarningBox aInfo( const_cast< ExtMgrDialog* >(this), getResId( RID_WARNINGBOX_REMOVE_EXTENSION ) );
+
+ String sText( aInfo.GetMessText() );
+ sText.SearchAndReplaceAllAscii( "%NAME", rExtensionName );
+ aInfo.SetMessText( sText );
+
+ return ( RET_OK == aInfo.Execute() );
+}
+
+//------------------------------------------------------------------------------
+bool ExtMgrDialog::enablePackage( const uno::Reference< deployment::XPackage > &xPackage,
+ bool bEnable )
+{
+ if ( !xPackage.is() )
+ return false;
+
+ if ( bEnable )
+ {
+ if ( ! continueOnSharedExtension( xPackage, this, RID_WARNINGBOX_ENABLE_SHARED_EXTENSION, m_bEnableWarning ) )
+ return false;
+ }
+ else
+ {
+ if ( ! continueOnSharedExtension( xPackage, this, RID_WARNINGBOX_DISABLE_SHARED_EXTENSION, m_bDisableWarning ) )
+ return false;
+ }
+
+ m_pManager->getCmdQueue()->enableExtension( xPackage, bEnable );
+
+ return true;
+}
+
+//------------------------------------------------------------------------------
+bool ExtMgrDialog::removePackage( const uno::Reference< deployment::XPackage > &xPackage )
+{
+ if ( !xPackage.is() )
+ return false;
+
+ if ( !IsSharedPkgMgr( xPackage ) || m_bDeleteWarning )
+ {
+ if ( ! removeExtensionWarn( xPackage->getDisplayName() ) )
+ return false;
+ }
+
+ if ( ! continueOnSharedExtension( xPackage, this, RID_WARNINGBOX_REMOVE_SHARED_EXTENSION, m_bDeleteWarning ) )
+ return false;
+
+ m_pManager->getCmdQueue()->removeExtension( xPackage );
+
+ return true;
+}
+
+//------------------------------------------------------------------------------
+bool ExtMgrDialog::updatePackage( const uno::Reference< deployment::XPackage > &xPackage )
+{
+ if ( !xPackage.is() )
+ return false;
+
+ // get the extension with highest version
+ uno::Sequence<uno::Reference<deployment::XPackage> > seqExtensions =
+ m_pManager->getExtensionManager()->getExtensionsWithSameIdentifier(
+ dp_misc::getIdentifier(xPackage), xPackage->getName(), uno::Reference<ucb::XCommandEnvironment>());
+ uno::Reference<deployment::XPackage> extension =
+ dp_misc::getExtensionWithHighestVersion(seqExtensions);
+ OSL_ASSERT(extension.is());
+ std::vector< css::uno::Reference< css::deployment::XPackage > > vEntries;
+ vEntries.push_back(extension);
+
+ m_pManager->getCmdQueue()->checkForUpdates( vEntries );
+
+ return true;
+}
+
+//------------------------------------------------------------------------------
+bool ExtMgrDialog::acceptLicense( const uno::Reference< deployment::XPackage > &xPackage )
+{
+ if ( !xPackage.is() )
+ return false;
+
+ m_pManager->getCmdQueue()->acceptLicense( xPackage );
+
+ return true;
+}
+
+//------------------------------------------------------------------------------
+uno::Sequence< OUString > ExtMgrDialog::raiseAddPicker()
+{
+ const uno::Any mode( static_cast< sal_Int16 >( ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE ) );
+ const uno::Reference< uno::XComponentContext > xContext( m_pManager->getContext() );
+ const uno::Reference< ui::dialogs::XFilePicker > xFilePicker(
+ xContext->getServiceManager()->createInstanceWithArgumentsAndContext(
+ OUSTR("com.sun.star.ui.dialogs.FilePicker"),
+ uno::Sequence< uno::Any >( &mode, 1 ), xContext ), uno::UNO_QUERY_THROW );
+ xFilePicker->setTitle( m_sAddPackages );
+
+ if ( m_sLastFolderURL.Len() )
+ xFilePicker->setDisplayDirectory( m_sLastFolderURL );
+
+ // collect and set filter list:
+ typedef ::std::map< OUString, OUString > t_string2string;
+ t_string2string title2filter;
+ OUString sDefaultFilter( StrAllFiles::get() );
+
+ const uno::Sequence< uno::Reference< deployment::XPackageTypeInfo > > packageTypes(
+ m_pManager->getExtensionManager()->getSupportedPackageTypes() );
+
+ for ( sal_Int32 pos = 0; pos < packageTypes.getLength(); ++pos )
+ {
+ uno::Reference< deployment::XPackageTypeInfo > const & xPackageType = packageTypes[ pos ];
+ const OUString filter( xPackageType->getFileFilter() );
+ if (filter.getLength() > 0)
+ {
+ const OUString title( xPackageType->getShortDescription() );
+ const ::std::pair< t_string2string::iterator, bool > insertion(
+ title2filter.insert( t_string2string::value_type( title, filter ) ) );
+ if ( ! insertion.second )
+ { // already existing, append extensions:
+ ::rtl::OUStringBuffer buf;
+ buf.append( insertion.first->second );
+ buf.append( static_cast<sal_Unicode>(';') );
+ buf.append( filter );
+ insertion.first->second = buf.makeStringAndClear();
+ }
+ if ( xPackageType->getMediaType() == OUSTR( "application/vnd.sun.star.package-bundle" ) )
+ sDefaultFilter = title;
+ }
+ }
+
+ const uno::Reference< ui::dialogs::XFilterManager > xFilterManager( xFilePicker, uno::UNO_QUERY_THROW );
+ // All files at top:
+ xFilterManager->appendFilter( StrAllFiles::get(), OUSTR("*.*") );
+ // then supported ones:
+ t_string2string::const_iterator iPos( title2filter.begin() );
+ const t_string2string::const_iterator iEnd( title2filter.end() );
+ for ( ; iPos != iEnd; ++iPos ) {
+ try {
+ xFilterManager->appendFilter( iPos->first, iPos->second );
+ }
+ catch (lang::IllegalArgumentException & exc) {
+ OSL_FAIL( ::rtl::OUStringToOString(
+ exc.Message, RTL_TEXTENCODING_UTF8 ).getStr() );
+ (void) exc;
+ }
+ }
+ xFilterManager->setCurrentFilter( sDefaultFilter );
+
+ if ( xFilePicker->execute() != ui::dialogs::ExecutableDialogResults::OK )
+ return uno::Sequence<OUString>(); // cancelled
+
+ m_sLastFolderURL = xFilePicker->getDisplayDirectory();
+ uno::Sequence< OUString > files( xFilePicker->getFiles() );
+ OSL_ASSERT( files.getLength() > 0 );
+ return files;
+}
+
+//------------------------------------------------------------------------------
+IMPL_LINK( ExtMgrDialog, HandleCancelBtn, void*, EMPTYARG )
+{
+ if ( m_xAbortChannel.is() )
+ {
+ try
+ {
+ m_xAbortChannel->sendAbort();
+ }
+ catch ( uno::RuntimeException & )
+ {
+ OSL_FAIL( "### unexpected RuntimeException!" );
+ }
+ }
+ return 1;
+}
+
+// ------------------------------------------------------------------------------
+IMPL_LINK( ExtMgrDialog, startProgress, void*, _bLockInterface )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ bool bLockInterface = (bool) _bLockInterface;
+
+ if ( m_bStartProgress && !m_bHasProgress )
+ m_aTimeoutTimer.Start();
+
+ if ( m_bStopProgress )
+ {
+ if ( m_aProgressBar.IsVisible() )
+ m_aProgressBar.SetValue( 100 );
+ m_xAbortChannel.clear();
+
+ OSL_TRACE( " startProgress handler: stop\n" );
+ }
+ else
+ {
+ OSL_TRACE( " startProgress handler: start\n" );
+ }
+
+ m_aCancelBtn.Enable( bLockInterface );
+ m_aAddBtn.Enable( !bLockInterface );
+ m_aUpdateBtn.Enable( !bLockInterface && m_pExtensionBox->getItemCount() );
+ m_pExtensionBox->enableButtons( !bLockInterface );
+
+ clearEventID();
+
+ return 0;
+}
+
+// ------------------------------------------------------------------------------
+void ExtMgrDialog::showProgress( bool _bStart )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ bool bStart = _bStart;
+
+ if ( bStart )
+ {
+ m_nProgress = 0;
+ m_bStartProgress = true;
+ OSL_TRACE( "showProgress start\n" );
+ }
+ else
+ {
+ m_nProgress = 100;
+ m_bStopProgress = true;
+ OSL_TRACE( "showProgress stop!\n" );
+ }
+
+ DialogHelper::PostUserEvent( LINK( this, ExtMgrDialog, startProgress ), (void*) bStart );
+}
+
+// -----------------------------------------------------------------------
+void ExtMgrDialog::updateProgress( const long nProgress )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ m_nProgress = nProgress;
+}
+
+// -----------------------------------------------------------------------
+void ExtMgrDialog::updateProgress( const OUString &rText,
+ const uno::Reference< task::XAbortChannel > &xAbortChannel)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ m_xAbortChannel = xAbortChannel;
+ m_sProgressText = rText;
+ m_bProgressChanged = true;
+}
+
+//------------------------------------------------------------------------------
+void ExtMgrDialog::updatePackageInfo( const uno::Reference< deployment::XPackage > &xPackage )
+{
+ const SolarMutexGuard aGuard;
+ m_pExtensionBox->updateEntry( xPackage );
+}
+
+// -----------------------------------------------------------------------
+IMPL_LINK( ExtMgrDialog, HandleAddBtn, void*, EMPTYARG )
+{
+ setBusy( true );
+
+ uno::Sequence< OUString > aFileList = raiseAddPicker();
+
+ if ( aFileList.getLength() )
+ {
+ m_pManager->installPackage( aFileList[0] );
+ }
+
+ setBusy( false );
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+IMPL_LINK( ExtMgrDialog, HandleUpdateBtn, void*, EMPTYARG )
+{
+ m_pManager->checkUpdates( false, true );
+
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+IMPL_LINK( ExtMgrDialog, HandleHyperlink, svt::FixedHyperlink*, pHyperlink )
+{
+ openWebBrowser( pHyperlink->GetURL(), GetText() );
+
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+IMPL_LINK( ExtMgrDialog, TimeOutHdl, Timer*, EMPTYARG )
+{
+ if ( m_bStopProgress )
+ {
+ m_bHasProgress = false;
+ m_bStopProgress = false;
+ m_aProgressText.Hide();
+ m_aProgressBar.Hide();
+ m_aCancelBtn.Hide();
+ }
+ else
+ {
+ if ( m_bProgressChanged )
+ {
+ m_bProgressChanged = false;
+ m_aProgressText.SetText( m_sProgressText );
+ }
+
+ if ( m_bStartProgress )
+ {
+ m_bStartProgress = false;
+ m_bHasProgress = true;
+ m_aProgressBar.Show();
+ m_aProgressText.Show();
+ m_aCancelBtn.Enable();
+ m_aCancelBtn.Show();
+ }
+
+ if ( m_aProgressBar.IsVisible() )
+ m_aProgressBar.SetValue( (sal_uInt16) m_nProgress );
+
+ m_aTimeoutTimer.Start();
+ }
+
+ return 1;
+}
+
+//------------------------------------------------------------------------------
+// VCL::Window / Dialog
+void ExtMgrDialog::Resize()
+{
+ Size aTotalSize( GetOutputSizePixel() );
+ Size aBtnSize( m_aHelpBtn.GetSizePixel() );
+ Size aUpdBtnSize( m_aUpdateBtn.GetSizePixel() );
+
+ Point aPos( RSC_SP_DLG_INNERBORDER_LEFT,
+ aTotalSize.Height() - RSC_SP_DLG_INNERBORDER_BOTTOM - aBtnSize.Height() );
+
+ m_aHelpBtn.SetPosPixel( aPos );
+
+ aPos.X() = aTotalSize.Width() - RSC_SP_DLG_INNERBORDER_RIGHT - aBtnSize.Width();
+ m_aCloseBtn.SetPosPixel( aPos );
+
+ aPos.X() -= ( RSC_SP_CTRL_X + aUpdBtnSize.Width() );
+ m_aUpdateBtn.SetPosPixel( aPos );
+
+ aPos.X() -= ( RSC_SP_CTRL_GROUP_Y + aBtnSize.Width() );
+ m_aAddBtn.SetPosPixel( aPos );
+
+ Size aDivSize( aTotalSize.Width(), LINE_SIZE );
+ aPos = Point( 0, aPos.Y() - LINE_SIZE - RSC_SP_DLG_INNERBORDER_BOTTOM );
+ m_aDivider.SetPosSizePixel( aPos, aDivSize );
+
+ Size aFTSize( m_aGetExtensions.CalcMinimumSize() );
+ aPos = Point( RSC_SP_DLG_INNERBORDER_LEFT, aPos.Y() - RSC_CD_FIXEDTEXT_HEIGHT - 2*RSC_SP_DLG_INNERBORDER_BOTTOM );
+
+ m_aGetExtensions.SetPosSizePixel( aPos, aFTSize );
+
+ aPos.X() = aTotalSize.Width() - RSC_SP_DLG_INNERBORDER_RIGHT - aBtnSize.Width();
+ m_aCancelBtn.SetPosPixel( Point( aPos.X(), aPos.Y() - ((aBtnSize.Height()-aFTSize.Height())/2) ) );
+
+ // Calc progress height
+ long nProgressHeight = aFTSize.Height();
+
+ if( IsNativeControlSupported( CTRL_PROGRESS, PART_ENTIRE_CONTROL ) )
+ {
+ ImplControlValue aValue;
+ Rectangle aControlRegion( Point( 0, 0 ), m_aProgressBar.GetSizePixel() );
+ Rectangle aNativeControlRegion, aNativeContentRegion;
+ if( GetNativeControlRegion( CTRL_PROGRESS, PART_ENTIRE_CONTROL, aControlRegion,
+ CTRL_STATE_ENABLED, aValue, rtl::OUString(),
+ aNativeControlRegion, aNativeContentRegion ) != sal_False )
+ {
+ nProgressHeight = aNativeControlRegion.GetHeight();
+ }
+ }
+
+ if ( nProgressHeight < PROGRESS_HEIGHT )
+ nProgressHeight = PROGRESS_HEIGHT;
+
+ aPos.X() -= ( RSC_SP_CTRL_GROUP_Y + PROGRESS_WIDTH );
+ m_aProgressBar.SetPosSizePixel( Point( aPos.X(), aPos.Y() - ((nProgressHeight-aFTSize.Height())/2) ),
+ Size( PROGRESS_WIDTH, nProgressHeight ) );
+
+ Rectangle aRect1( m_aGetExtensions.GetPosPixel(), m_aGetExtensions.GetSizePixel() );
+ Rectangle aRect2( m_aProgressBar.GetPosPixel(), m_aProgressBar.GetSizePixel() );
+
+ aFTSize.Width() = ( aRect2.Left() - aRect1.Right() ) - 2*RSC_SP_DLG_INNERBORDER_LEFT;
+ aPos.X() = aRect1.Right() + RSC_SP_DLG_INNERBORDER_LEFT;
+ m_aProgressText.SetPosSizePixel( aPos, aFTSize );
+
+ Size aSize( aTotalSize.Width() - RSC_SP_DLG_INNERBORDER_LEFT - RSC_SP_DLG_INNERBORDER_RIGHT,
+ aTotalSize.Height() - 2*aBtnSize.Height() - LINE_SIZE -
+ RSC_SP_DLG_INNERBORDER_TOP - 3*RSC_SP_DLG_INNERBORDER_BOTTOM );
+
+ m_pExtensionBox->SetSizePixel( aSize );
+}
+//------------------------------------------------------------------------------
+// VCL::Window / Dialog
+
+long ExtMgrDialog::Notify( NotifyEvent& rNEvt )
+{
+ bool bHandled = false;
+
+ if ( rNEvt.GetType() == EVENT_KEYINPUT )
+ {
+ const KeyEvent* pKEvt = rNEvt.GetKeyEvent();
+ KeyCode aKeyCode = pKEvt->GetKeyCode();
+ sal_uInt16 nKeyCode = aKeyCode.GetCode();
+
+ if ( nKeyCode == KEY_TAB )
+ {
+ if ( aKeyCode.IsShift() ) {
+ if ( m_aAddBtn.HasFocus() ) {
+ m_pExtensionBox->GrabFocus();
+ bHandled = true;
+ }
+ } else {
+ if ( m_aGetExtensions.HasFocus() ) {
+ m_pExtensionBox->GrabFocus();
+ bHandled = true;
+ }
+ }
+ }
+ if ( aKeyCode.GetGroup() == KEYGROUP_CURSOR )
+ bHandled = m_pExtensionBox->Notify( rNEvt );
+ }
+// VCLEVENT_WINDOW_CLOSE
+ if ( !bHandled )
+ return ModelessDialog::Notify( rNEvt );
+ else
+ return true;
+}
+
+//------------------------------------------------------------------------------
+sal_Bool ExtMgrDialog::Close()
+{
+ bool bRet = m_pManager->queryTermination();
+ if ( bRet )
+ {
+ bRet = ModelessDialog::Close();
+ m_pManager->terminateDialog();
+ }
+ return bRet;
+}
+
+//------------------------------------------------------------------------------
+// UpdateRequiredDialog
+//------------------------------------------------------------------------------
+UpdateRequiredDialog::UpdateRequiredDialog( Window *pParent, TheExtensionManager *pManager ) :
+ ModalDialog( pParent, getResId( RID_DLG_UPDATE_REQUIRED ) ),
+ DialogHelper( pManager->getContext(), (Dialog*) this ),
+ m_aUpdateNeeded( this, getResId( RID_EM_FT_MSG ) ),
+ m_aUpdateBtn( this, getResId( RID_EM_BTN_CHECK_UPDATES ) ),
+ m_aCloseBtn( this, getResId( RID_EM_BTN_CLOSE ) ),
+ m_aHelpBtn( this, getResId( RID_EM_BTN_HELP ) ),
+ m_aCancelBtn( this, getResId( RID_EM_BTN_CANCEL ) ),
+ m_aDivider( this ),
+ m_aProgressText( this, getResId( RID_EM_FT_PROGRESS ) ),
+ m_aProgressBar( this, WB_BORDER + WB_3DLOOK ),
+ m_sAddPackages( getResourceString( RID_STR_ADD_PACKAGES ) ),
+ m_sCloseText( getResourceString( RID_STR_CLOSE_BTN ) ),
+ m_bHasProgress( false ),
+ m_bProgressChanged( false ),
+ m_bStartProgress( false ),
+ m_bStopProgress( false ),
+ m_bUpdateWarning( false ),
+ m_bDisableWarning( false ),
+ m_bHasLockedEntries( false ),
+ m_nProgress( 0 ),
+ m_pManager( pManager )
+{
+ // free local resources (RID < 256):
+ FreeResource();
+
+ m_pExtensionBox = new ExtensionBox_Impl( this, pManager );
+ m_pExtensionBox->SetHyperlinkHdl( LINK( this, UpdateRequiredDialog, HandleHyperlink ) );
+
+ m_aUpdateBtn.SetClickHdl( LINK( this, UpdateRequiredDialog, HandleUpdateBtn ) );
+ m_aCloseBtn.SetClickHdl( LINK( this, UpdateRequiredDialog, HandleCloseBtn ) );
+ m_aCancelBtn.SetClickHdl( LINK( this, UpdateRequiredDialog, HandleCancelBtn ) );
+
+ String aText = m_aUpdateNeeded.GetText();
+ aText.SearchAndReplaceAllAscii( "%PRODUCTNAME", BrandName::get() );
+ m_aUpdateNeeded.SetText( aText );
+
+ // resize update button
+ Size aBtnSize = m_aUpdateBtn.GetSizePixel();
+ String sTitle = m_aUpdateBtn.GetText();
+ long nWidth = m_aUpdateBtn.GetCtrlTextWidth( sTitle );
+ nWidth += 2 * m_aUpdateBtn.GetTextHeight();
+ if ( nWidth > aBtnSize.Width() )
+ m_aUpdateBtn.SetSizePixel( Size( nWidth, aBtnSize.Height() ) );
+
+ // resize update button
+ aBtnSize = m_aCloseBtn.GetSizePixel();
+ sTitle = m_aCloseBtn.GetText();
+ nWidth = m_aCloseBtn.GetCtrlTextWidth( sTitle );
+ nWidth += 2 * m_aCloseBtn.GetTextHeight();
+ if ( nWidth > aBtnSize.Width() )
+ m_aCloseBtn.SetSizePixel( Size( nWidth, aBtnSize.Height() ) );
+
+ // minimum size:
+ SetMinOutputSizePixel(
+ Size( // width:
+ (5 * m_aHelpBtn.GetSizePixel().Width()) +
+ (5 * RSC_SP_DLG_INNERBORDER_LEFT ),
+ // height:
+ (1 * m_aHelpBtn.GetSizePixel().Height()) +
+ (1 * m_aUpdateNeeded.GetSizePixel().Height()) +
+ (1 * m_pExtensionBox->GetMinOutputSizePixel().Height()) +
+ (3 * RSC_SP_DLG_INNERBORDER_LEFT) ) );
+
+ m_aDivider.Show();
+ m_aProgressBar.Hide();
+ m_aUpdateBtn.Enable( false );
+ m_aCloseBtn.GrabFocus();
+
+ m_aTimeoutTimer.SetTimeout( 50 ); // mSec
+ m_aTimeoutTimer.SetTimeoutHdl( LINK( this, UpdateRequiredDialog, TimeOutHdl ) );
+}
+
+//------------------------------------------------------------------------------
+UpdateRequiredDialog::~UpdateRequiredDialog()
+{
+ m_aTimeoutTimer.Stop();
+
+ delete m_pExtensionBox;
+}
+
+//------------------------------------------------------------------------------
+long UpdateRequiredDialog::addPackageToList( const uno::Reference< deployment::XPackage > &xPackage,
+ bool bLicenseMissing )
+{
+ // We will only add entries to the list with unsatisfied dependencies
+ if ( !bLicenseMissing && !checkDependencies( xPackage ) )
+ {
+ m_bHasLockedEntries |= m_pManager->isReadOnly( xPackage );
+ const SolarMutexGuard aGuard;
+ m_aUpdateBtn.Enable( true );
+ return m_pExtensionBox->addEntry( xPackage );
+ }
+ return 0;
+}
+
+//------------------------------------------------------------------------------
+void UpdateRequiredDialog::prepareChecking()
+{
+ m_pExtensionBox->prepareChecking();
+}
+
+//------------------------------------------------------------------------------
+void UpdateRequiredDialog::checkEntries()
+{
+ const SolarMutexGuard guard;
+ m_pExtensionBox->checkEntries();
+
+ if ( ! hasActiveEntries() )
+ {
+ m_aCloseBtn.SetText( m_sCloseText );
+ m_aCloseBtn.GrabFocus();
+ }
+}
+
+//------------------------------------------------------------------------------
+bool UpdateRequiredDialog::enablePackage( const uno::Reference< deployment::XPackage > &xPackage,
+ bool bEnable )
+{
+ m_pManager->getCmdQueue()->enableExtension( xPackage, bEnable );
+
+ return true;
+}
+
+//------------------------------------------------------------------------------
+IMPL_LINK( UpdateRequiredDialog, HandleCancelBtn, void*, EMPTYARG )
+{
+ if ( m_xAbortChannel.is() )
+ {
+ try
+ {
+ m_xAbortChannel->sendAbort();
+ }
+ catch ( uno::RuntimeException & )
+ {
+ OSL_FAIL( "### unexpected RuntimeException!" );
+ }
+ }
+ return 1;
+}
+
+// ------------------------------------------------------------------------------
+IMPL_LINK( UpdateRequiredDialog, startProgress, void*, _bLockInterface )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ bool bLockInterface = (bool) _bLockInterface;
+
+ if ( m_bStartProgress && !m_bHasProgress )
+ m_aTimeoutTimer.Start();
+
+ if ( m_bStopProgress )
+ {
+ if ( m_aProgressBar.IsVisible() )
+ m_aProgressBar.SetValue( 100 );
+ m_xAbortChannel.clear();
+ OSL_TRACE( " startProgress handler: stop\n" );
+ }
+ else
+ {
+ OSL_TRACE( " startProgress handler: start\n" );
+ }
+
+ m_aCancelBtn.Enable( bLockInterface );
+ m_aUpdateBtn.Enable( false );
+ clearEventID();
+
+ return 0;
+}
+
+// ------------------------------------------------------------------------------
+void UpdateRequiredDialog::showProgress( bool _bStart )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ bool bStart = _bStart;
+
+ if ( bStart )
+ {
+ m_nProgress = 0;
+ m_bStartProgress = true;
+ OSL_TRACE( "showProgress start\n" );
+ }
+ else
+ {
+ m_nProgress = 100;
+ m_bStopProgress = true;
+ OSL_TRACE( "showProgress stop!\n" );
+ }
+
+ DialogHelper::PostUserEvent( LINK( this, UpdateRequiredDialog, startProgress ), (void*) bStart );
+}
+
+// -----------------------------------------------------------------------
+void UpdateRequiredDialog::updateProgress( const long nProgress )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ m_nProgress = nProgress;
+}
+
+// -----------------------------------------------------------------------
+void UpdateRequiredDialog::updateProgress( const OUString &rText,
+ const uno::Reference< task::XAbortChannel > &xAbortChannel)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ m_xAbortChannel = xAbortChannel;
+ m_sProgressText = rText;
+ m_bProgressChanged = true;
+}
+
+//------------------------------------------------------------------------------
+void UpdateRequiredDialog::updatePackageInfo( const uno::Reference< deployment::XPackage > &xPackage )
+{
+ // We will remove all updated packages with satisfied dependencies, but
+ // we will show all disabled entries so the user sees the result
+ // of the 'disable all' button
+ const SolarMutexGuard aGuard;
+ if ( isEnabled( xPackage ) && checkDependencies( xPackage ) )
+ m_pExtensionBox->removeEntry( xPackage );
+ else
+ m_pExtensionBox->updateEntry( xPackage );
+
+ if ( ! hasActiveEntries() )
+ {
+ m_aCloseBtn.SetText( m_sCloseText );
+ m_aCloseBtn.GrabFocus();
+ }
+}
+
+// -----------------------------------------------------------------------
+IMPL_LINK( UpdateRequiredDialog, HandleUpdateBtn, void*, EMPTYARG )
+{
+ ::osl::ClearableMutexGuard aGuard( m_aMutex );
+
+ std::vector< uno::Reference< deployment::XPackage > > vUpdateEntries;
+ sal_Int32 nCount = m_pExtensionBox->GetEntryCount();
+
+ for ( sal_Int32 i = 0; i < nCount; ++i )
+ {
+ TEntry_Impl pEntry = m_pExtensionBox->GetEntryData( i );
+ vUpdateEntries.push_back( pEntry->m_xPackage );
+ }
+
+ aGuard.clear();
+
+ m_pManager->getCmdQueue()->checkForUpdates( vUpdateEntries );
+
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+IMPL_LINK( UpdateRequiredDialog, HandleCloseBtn, void*, EMPTYARG )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ if ( !isBusy() )
+ {
+ if ( m_bHasLockedEntries )
+ EndDialog( -1 );
+ else if ( hasActiveEntries() )
+ disableAllEntries();
+ else
+ EndDialog( 0 );
+ }
+
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+IMPL_LINK( UpdateRequiredDialog, HandleHyperlink, svt::FixedHyperlink*, pHyperlink )
+{
+ openWebBrowser( pHyperlink->GetURL(), GetText() );
+
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+IMPL_LINK( UpdateRequiredDialog, TimeOutHdl, Timer*, EMPTYARG )
+{
+ if ( m_bStopProgress )
+ {
+ m_bHasProgress = false;
+ m_bStopProgress = false;
+ m_aProgressText.Hide();
+ m_aProgressBar.Hide();
+ m_aCancelBtn.Hide();
+ }
+ else
+ {
+ if ( m_bProgressChanged )
+ {
+ m_bProgressChanged = false;
+ m_aProgressText.SetText( m_sProgressText );
+ }
+
+ if ( m_bStartProgress )
+ {
+ m_bStartProgress = false;
+ m_bHasProgress = true;
+ m_aProgressBar.Show();
+ m_aProgressText.Show();
+ m_aCancelBtn.Enable();
+ m_aCancelBtn.Show();
+ }
+
+ if ( m_aProgressBar.IsVisible() )
+ m_aProgressBar.SetValue( (sal_uInt16) m_nProgress );
+
+ m_aTimeoutTimer.Start();
+ }
+
+ return 1;
+}
+
+//------------------------------------------------------------------------------
+// VCL::Window / Dialog
+void UpdateRequiredDialog::Resize()
+{
+ Size aTotalSize( GetOutputSizePixel() );
+ Size aBtnSize( m_aHelpBtn.GetSizePixel() );
+
+ Point aPos( RSC_SP_DLG_INNERBORDER_LEFT,
+ aTotalSize.Height() - RSC_SP_DLG_INNERBORDER_BOTTOM - aBtnSize.Height() );
+
+ m_aHelpBtn.SetPosPixel( aPos );
+
+ aPos.X() = aTotalSize.Width() - RSC_SP_DLG_INNERBORDER_RIGHT - m_aCloseBtn.GetSizePixel().Width();
+ m_aCloseBtn.SetPosPixel( aPos );
+
+ aPos.X() -= ( RSC_SP_CTRL_X + m_aUpdateBtn.GetSizePixel().Width() );
+ m_aUpdateBtn.SetPosPixel( aPos );
+
+ Size aDivSize( aTotalSize.Width(), LINE_SIZE );
+ aPos = Point( 0, aPos.Y() - LINE_SIZE - RSC_SP_DLG_INNERBORDER_BOTTOM );
+ m_aDivider.SetPosSizePixel( aPos, aDivSize );
+
+ // Calc fixed text size
+ aPos = Point( RSC_SP_DLG_INNERBORDER_LEFT, RSC_SP_DLG_INNERBORDER_TOP );
+ Size aFTSize = m_aUpdateNeeded.CalcMinimumSize( aTotalSize.Width() - RSC_SP_DLG_INNERBORDER_RIGHT - RSC_SP_DLG_INNERBORDER_LEFT );
+ m_aUpdateNeeded.SetPosSizePixel( aPos, aFTSize );
+
+ // Calc list box size
+ Size aSize( aTotalSize.Width() - RSC_SP_DLG_INNERBORDER_LEFT - RSC_SP_DLG_INNERBORDER_RIGHT,
+ aTotalSize.Height() - 2*aBtnSize.Height() - LINE_SIZE -
+ 2*RSC_SP_DLG_INNERBORDER_TOP - 3*RSC_SP_DLG_INNERBORDER_BOTTOM - aFTSize.Height() );
+ aPos.Y() += aFTSize.Height()+RSC_SP_DLG_INNERBORDER_TOP;
+
+ m_pExtensionBox->SetPosSizePixel( aPos, aSize );
+
+ aPos.X() = aTotalSize.Width() - RSC_SP_DLG_INNERBORDER_RIGHT - aBtnSize.Width();
+ aPos.Y() += aSize.Height()+RSC_SP_DLG_INNERBORDER_TOP;
+ m_aCancelBtn.SetPosPixel( aPos );
+
+ // Calc progress height
+ aFTSize = m_aProgressText.GetSizePixel();
+ long nProgressHeight = aFTSize.Height();
+
+ if( IsNativeControlSupported( CTRL_PROGRESS, PART_ENTIRE_CONTROL ) )
+ {
+ ImplControlValue aValue;
+ Rectangle aControlRegion( Point( 0, 0 ), m_aProgressBar.GetSizePixel() );
+ Rectangle aNativeControlRegion, aNativeContentRegion;
+ if( GetNativeControlRegion( CTRL_PROGRESS, PART_ENTIRE_CONTROL, aControlRegion,
+ CTRL_STATE_ENABLED, aValue, rtl::OUString(),
+ aNativeControlRegion, aNativeContentRegion ) != sal_False )
+ {
+ nProgressHeight = aNativeControlRegion.GetHeight();
+ }
+ }
+
+ if ( nProgressHeight < PROGRESS_HEIGHT )
+ nProgressHeight = PROGRESS_HEIGHT;
+
+ aPos.X() -= ( RSC_SP_CTRL_GROUP_Y + PROGRESS_WIDTH );
+ m_aProgressBar.SetPosSizePixel( Point( aPos.X(), aPos.Y() + ((aBtnSize.Height()-nProgressHeight)/2) ),
+ Size( PROGRESS_WIDTH, nProgressHeight ) );
+
+ aFTSize.Width() = aPos.X() - 2*RSC_SP_DLG_INNERBORDER_LEFT;
+ aPos.X() = RSC_SP_DLG_INNERBORDER_LEFT;
+ aPos.Y() += ( aBtnSize.Height() - aFTSize.Height() - 1 ) / 2;
+ m_aProgressText.SetPosSizePixel( aPos, aFTSize );
+}
+
+//------------------------------------------------------------------------------
+// VCL::Dialog
+short UpdateRequiredDialog::Execute()
+{
+ if ( m_bHasLockedEntries )
+ {
+ // Set other text, disable update btn, remove not shared entries from list;
+ m_aUpdateNeeded.SetText( DialogHelper::getResourceString( RID_STR_NO_ADMIN_PRIVILEGE ) );
+ m_aCloseBtn.SetText( DialogHelper::getResourceString( RID_STR_EXIT_BTN ) );
+ m_aUpdateBtn.Enable( false );
+ m_pExtensionBox->RemoveUnlocked();
+ Resize();
+ }
+
+ return Dialog::Execute();
+}
+
+//------------------------------------------------------------------------------
+// VCL::Dialog
+sal_Bool UpdateRequiredDialog::Close()
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ if ( !isBusy() )
+ {
+ if ( m_bHasLockedEntries )
+ EndDialog( -1 );
+ else if ( hasActiveEntries() )
+ disableAllEntries();
+ else
+ EndDialog( 0 );
+ }
+
+ return false;
+}
+
+//------------------------------------------------------------------------------
+// Check dependencies of all packages
+//------------------------------------------------------------------------------
+bool UpdateRequiredDialog::isEnabled( const uno::Reference< deployment::XPackage > &xPackage ) const
+{
+ bool bRegistered = false;
+ try {
+ beans::Optional< beans::Ambiguous< sal_Bool > > option( xPackage->isRegistered( uno::Reference< task::XAbortChannel >(),
+ uno::Reference< ucb::XCommandEnvironment >() ) );
+ if ( option.IsPresent )
+ {
+ ::beans::Ambiguous< sal_Bool > const & reg = option.Value;
+ if ( reg.IsAmbiguous )
+ bRegistered = false;
+ else
+ bRegistered = reg.Value ? true : false;
+ }
+ else
+ bRegistered = false;
+ }
+ catch ( uno::RuntimeException & ) { throw; }
+ catch ( uno::Exception & exc) {
+ (void) exc;
+ OSL_FAIL( ::rtl::OUStringToOString( exc.Message, RTL_TEXTENCODING_UTF8 ).getStr() );
+ bRegistered = false;
+ }
+
+ return bRegistered;
+}
+
+//------------------------------------------------------------------------------
+bool UpdateRequiredDialog::checkDependencies( const uno::Reference< deployment::XPackage > &xPackage ) const
+{
+ if ( isEnabled( xPackage ) )
+ {
+ bool bDependenciesValid = false;
+ try {
+ bDependenciesValid = xPackage->checkDependencies( uno::Reference< ucb::XCommandEnvironment >() );
+ }
+ catch ( deployment::DeploymentException & ) {}
+ if ( ! bDependenciesValid )
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+//------------------------------------------------------------------------------
+bool UpdateRequiredDialog::hasActiveEntries()
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ bool bRet = false;
+ long nCount = m_pExtensionBox->GetEntryCount();
+ for ( long nIndex = 0; nIndex < nCount; nIndex++ )
+ {
+ TEntry_Impl pEntry = m_pExtensionBox->GetEntryData( nIndex );
+
+ if ( !checkDependencies( pEntry->m_xPackage ) )
+ {
+ bRet = true;
+ break;
+ }
+ }
+
+ return bRet;
+}
+
+//------------------------------------------------------------------------------
+void UpdateRequiredDialog::disableAllEntries()
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ setBusy( true );
+
+ long nCount = m_pExtensionBox->GetEntryCount();
+ for ( long nIndex = 0; nIndex < nCount; nIndex++ )
+ {
+ TEntry_Impl pEntry = m_pExtensionBox->GetEntryData( nIndex );
+ enablePackage( pEntry->m_xPackage, false );
+ }
+
+ setBusy( false );
+
+ if ( ! hasActiveEntries() )
+ m_aCloseBtn.SetText( m_sCloseText );
+}
+
+//------------------------------------------------------------------------------
+// ShowLicenseDialog
+//------------------------------------------------------------------------------
+ShowLicenseDialog::ShowLicenseDialog( Window * pParent,
+ const uno::Reference< deployment::XPackage > &xPackage ) :
+ ModalDialog( pParent, DialogHelper::getResId( RID_DLG_SHOW_LICENSE ) ),
+ m_aLicenseText( this, DialogHelper::getResId( ML_LICENSE ) ),
+ m_aCloseBtn( this, DialogHelper::getResId( RID_EM_BTN_CLOSE ) )
+{
+ FreeResource();
+
+ OUString aText = xPackage->getLicenseText();
+ m_aLicenseText.SetText( aText );
+}
+
+//------------------------------------------------------------------------------
+ShowLicenseDialog::~ShowLicenseDialog()
+{}
+
+//------------------------------------------------------------------------------
+void ShowLicenseDialog::Resize()
+{
+ Size aTotalSize( GetOutputSizePixel() );
+ Size aTextSize( aTotalSize.Width() - RSC_SP_DLG_INNERBORDER_LEFT - RSC_SP_DLG_INNERBORDER_RIGHT,
+ aTotalSize.Height() - RSC_SP_DLG_INNERBORDER_TOP - 2*RSC_SP_DLG_INNERBORDER_BOTTOM
+ - m_aCloseBtn.GetSizePixel().Height() );
+
+ m_aLicenseText.SetPosSizePixel( Point( RSC_SP_DLG_INNERBORDER_LEFT, RSC_SP_DLG_INNERBORDER_TOP ),
+ aTextSize );
+
+ Point aBtnPos( (aTotalSize.Width() - m_aCloseBtn.GetSizePixel().Width())/2,
+ aTotalSize.Height() - RSC_SP_DLG_INNERBORDER_BOTTOM
+ - m_aCloseBtn.GetSizePixel().Height() );
+ m_aCloseBtn.SetPosPixel( aBtnPos );
+}
+
+//=================================================================================
+// UpdateRequiredDialogService
+//=================================================================================
+UpdateRequiredDialogService::UpdateRequiredDialogService( uno::Sequence< uno::Any > const&,
+ uno::Reference< uno::XComponentContext > const& xComponentContext )
+ : m_xComponentContext( xComponentContext )
+{
+}
+
+//------------------------------------------------------------------------------
+// XExecutableDialog
+//------------------------------------------------------------------------------
+void UpdateRequiredDialogService::setTitle( OUString const & ) throw ( uno::RuntimeException )
+{
+}
+
+//------------------------------------------------------------------------------
+sal_Int16 UpdateRequiredDialogService::execute() throw ( uno::RuntimeException )
+{
+ ::rtl::Reference< ::dp_gui::TheExtensionManager > xManager( TheExtensionManager::get(
+ m_xComponentContext,
+ uno::Reference< awt::XWindow >(),
+ OUString() ) );
+ xManager->createDialog( true );
+ sal_Int16 nRet = xManager->execute();
+
+ return nRet;
+}
+
+//------------------------------------------------------------------------------
+SelectedPackage::~SelectedPackage() {}
+
+} //namespace dp_gui
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/gui/dp_gui_dialog2.hxx b/desktop/source/deployment/gui/dp_gui_dialog2.hxx
new file mode 100644
index 000000000000..8288d27b5e6f
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_dialog2.hxx
@@ -0,0 +1,283 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_DP_GUI_DIALOG2_HXX
+#define INCLUDED_DP_GUI_DIALOG2_HXX
+
+#include "vcl/dialog.hxx"
+#include "vcl/button.hxx"
+#include "vcl/fixed.hxx"
+#include "vcl/timer.hxx"
+
+#include "svtools/fixedhyper.hxx"
+#include "svtools/prgsbar.hxx"
+#include "svtools/svmedit.hxx"
+
+#include "osl/conditn.hxx"
+#include "osl/mutex.hxx"
+
+#include "rtl/ref.hxx"
+#include "rtl/ustring.hxx"
+
+#include "cppuhelper/implbase1.hxx"
+
+#include "com/sun/star/awt/XWindow.hpp"
+#include "com/sun/star/deployment/XPackage.hpp"
+#include "com/sun/star/uno/XComponentContext.hpp"
+#include "com/sun/star/ui/dialogs/XExecutableDialog.hpp"
+#include "com/sun/star/util/XModifyListener.hpp"
+
+namespace dp_gui {
+
+//==============================================================================
+class ExtBoxWithBtns_Impl;
+class ExtensionBox_Impl;
+class TheExtensionManager;
+
+//==============================================================================
+class DialogHelper
+{
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > m_xContext;
+ Dialog* m_pVCLWindow;
+ sal_uLong m_nEventID;
+ bool m_bIsBusy;
+
+public:
+ DialogHelper( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > &,
+ Dialog *pWindow );
+ virtual ~DialogHelper();
+
+ void openWebBrowser( const ::rtl::OUString & sURL, const ::rtl::OUString & sTitle ) const;
+ Dialog* getWindow() const { return m_pVCLWindow; };
+ void PostUserEvent( const Link& rLink, void* pCaller );
+ void clearEventID() { m_nEventID = 0; }
+
+ virtual void showProgress( bool bStart ) = 0;
+ virtual void updateProgress( const ::rtl::OUString &rText,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::task::XAbortChannel > &xAbortChannel) = 0;
+ virtual void updateProgress( const long nProgress ) = 0;
+
+ virtual void updatePackageInfo( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &xPackage ) = 0;
+ virtual long addPackageToList( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &xPackage,
+ bool bLicenseMissing = false ) = 0;
+
+ virtual void prepareChecking() = 0;
+ virtual void checkEntries() = 0;
+
+ static ResId getResId( sal_uInt16 nId );
+ static String getResourceString( sal_uInt16 id );
+ static bool IsSharedPkgMgr( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &);
+ static bool continueOnSharedExtension( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &,
+ Window *pParent,
+ const sal_uInt16 nResID,
+ bool &bHadWarning );
+
+ void setBusy( const bool bBusy ) { m_bIsBusy = bBusy; }
+ bool isBusy() const { return m_bIsBusy; }
+ bool installExtensionWarn( const ::rtl::OUString &rExtensionURL ) const;
+ bool installForAllUsers( bool &bInstallForAll ) const;
+};
+
+//==============================================================================
+class ExtMgrDialog : public ModelessDialog,
+ public DialogHelper
+{
+ ExtBoxWithBtns_Impl *m_pExtensionBox;
+ PushButton m_aAddBtn;
+ PushButton m_aUpdateBtn;
+ OKButton m_aCloseBtn;
+ HelpButton m_aHelpBtn;
+ FixedLine m_aDivider;
+ svt::FixedHyperlink m_aGetExtensions;
+ FixedText m_aProgressText;
+ ProgressBar m_aProgressBar;
+ CancelButton m_aCancelBtn;
+ const String m_sAddPackages;
+ String m_sProgressText;
+ String m_sLastFolderURL;
+ ::osl::Mutex m_aMutex;
+ bool m_bHasProgress;
+ bool m_bProgressChanged;
+ bool m_bStartProgress;
+ bool m_bStopProgress;
+ bool m_bUpdateWarning;
+ bool m_bEnableWarning;
+ bool m_bDisableWarning;
+ bool m_bDeleteWarning;
+ long m_nProgress;
+ Timer m_aTimeoutTimer;
+ TheExtensionManager *m_pManager;
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::task::XAbortChannel > m_xAbortChannel;
+
+ bool removeExtensionWarn( const ::rtl::OUString &rExtensionTitle ) const;
+
+ DECL_DLLPRIVATE_LINK( HandleAddBtn, void * );
+ DECL_DLLPRIVATE_LINK( HandleUpdateBtn, void * );
+ DECL_DLLPRIVATE_LINK( HandleCancelBtn, void * );
+ DECL_DLLPRIVATE_LINK( HandleHyperlink, svt::FixedHyperlink * );
+ DECL_DLLPRIVATE_LINK( TimeOutHdl, Timer* );
+ DECL_DLLPRIVATE_LINK( startProgress, void * );
+
+public:
+ ExtMgrDialog( Window * pParent, TheExtensionManager *pManager );
+ virtual ~ExtMgrDialog();
+
+ virtual void Resize();
+ virtual long Notify( NotifyEvent& rNEvt );
+ virtual sal_Bool Close();
+
+ virtual void showProgress( bool bStart );
+ virtual void updateProgress( const ::rtl::OUString &rText,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::task::XAbortChannel > &xAbortChannel);
+ virtual void updateProgress( const long nProgress );
+
+ virtual void updatePackageInfo( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &xPackage );
+
+ void setGetExtensionsURL( const ::rtl::OUString &rURL );
+ virtual long addPackageToList( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &,
+ bool bLicenseMissing = false );
+ bool enablePackage(const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &xPackage,
+ bool bEnable );
+ bool removePackage(const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &xPackage );
+ bool updatePackage(const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &xPackage );
+ bool acceptLicense(const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &xPackage );
+
+ virtual void prepareChecking();
+ virtual void checkEntries();
+
+ ::com::sun::star::uno::Sequence< ::rtl::OUString > raiseAddPicker();
+};
+
+//==============================================================================
+class UpdateRequiredDialog : public ModalDialog,
+ public DialogHelper
+{
+ ExtensionBox_Impl *m_pExtensionBox;
+ FixedText m_aUpdateNeeded;
+ PushButton m_aUpdateBtn;
+ PushButton m_aCloseBtn;
+ HelpButton m_aHelpBtn;
+ CancelButton m_aCancelBtn;
+ FixedLine m_aDivider;
+ FixedText m_aProgressText;
+ ProgressBar m_aProgressBar;
+ const String m_sAddPackages;
+ const String m_sCloseText;
+ String m_sProgressText;
+ ::osl::Mutex m_aMutex;
+ bool m_bHasProgress;
+ bool m_bProgressChanged;
+ bool m_bStartProgress;
+ bool m_bStopProgress;
+ bool m_bUpdateWarning;
+ bool m_bDisableWarning;
+ bool m_bHasLockedEntries;
+ long m_nProgress;
+ Timer m_aTimeoutTimer;
+ TheExtensionManager *m_pManager;
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::task::XAbortChannel > m_xAbortChannel;
+
+ DECL_DLLPRIVATE_LINK( HandleUpdateBtn, void * );
+ DECL_DLLPRIVATE_LINK( HandleCloseBtn, void * );
+ DECL_DLLPRIVATE_LINK( HandleCancelBtn, void * );
+ DECL_DLLPRIVATE_LINK( TimeOutHdl, Timer* );
+ DECL_DLLPRIVATE_LINK( startProgress, void * );
+ DECL_DLLPRIVATE_LINK( HandleHyperlink, svt::FixedHyperlink * );
+
+ bool isEnabled( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &xPackage ) const;
+ bool checkDependencies( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &xPackage ) const;
+ bool hasActiveEntries();
+ void disableAllEntries();
+
+public:
+ UpdateRequiredDialog( Window * pParent, TheExtensionManager *pManager );
+ virtual ~UpdateRequiredDialog();
+
+ virtual short Execute();
+ virtual void Resize();
+ virtual sal_Bool Close();
+
+ virtual void showProgress( bool bStart );
+ virtual void updateProgress( const ::rtl::OUString &rText,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::task::XAbortChannel > &xAbortChannel);
+ virtual void updateProgress( const long nProgress );
+
+ virtual void updatePackageInfo( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &xPackage );
+
+ void selectEntry( long nPos );
+ virtual long addPackageToList( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &,
+ bool bLicenseMissing = false );
+ bool enablePackage( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &xPackage, bool bEnable );
+ bool updatePackage( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &xPackage );
+
+ virtual void prepareChecking();
+ virtual void checkEntries();
+
+ ::com::sun::star::uno::Sequence< ::rtl::OUString > raiseAddPicker();
+
+ bool installForAllUsers( bool &bInstallForAll ) const;
+ bool installExtensionWarn( const ::rtl::OUString &rExtensionURL ) const;
+};
+
+//==============================================================================
+class ShowLicenseDialog : public ModalDialog
+{
+ MultiLineEdit m_aLicenseText;
+ OKButton m_aCloseBtn;
+
+public:
+ ShowLicenseDialog( Window * pParent,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &xPackage );
+ virtual ~ShowLicenseDialog();
+
+ virtual void Resize();
+};
+
+//==============================================================================
+class UpdateRequiredDialogService : public ::cppu::WeakImplHelper1< ::com::sun::star::ui::dialogs::XExecutableDialog >
+{
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > const m_xComponentContext;
+ ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow > m_xParent;
+ ::rtl::OUString m_sInitialTitle;
+
+public:
+ UpdateRequiredDialogService( ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any > const & args,
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext> const & xComponentContext );
+
+ // XExecutableDialog
+ virtual void SAL_CALL setTitle( rtl::OUString const & title ) throw ( ::com::sun::star::uno::RuntimeException );
+ virtual sal_Int16 SAL_CALL execute() throw ( ::com::sun::star::uno::RuntimeException );
+};
+
+} // namespace dp_gui
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/gui/dp_gui_dialog2.src b/desktop/source/deployment/gui/dp_gui_dialog2.src
new file mode 100644
index 000000000000..2d11f1175e88
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_dialog2.src
@@ -0,0 +1,236 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "svtools/controldims.hrc"
+#include "dp_gui.hrc"
+
+ModelessDialog RID_DLG_EXTENSION_MANAGER
+{
+ HelpId = HID_PACKAGE_MANAGER;
+ Text [ en-US ] = "Extension Manager";
+
+ Size = MAP_APPFONT( 300, 200 );
+ OutputSize = TRUE;
+ SVLook = TRUE;
+ Moveable = TRUE;
+ Closeable = TRUE;
+ Sizeable = TRUE;
+ Hide = TRUE;
+
+ PushButton RID_EM_BTN_ADD
+ {
+ HelpID = "desktop:PushButton:RID_DLG_EXTENSION_MANAGER:RID_EM_BTN_ADD";
+ TabStop = TRUE;
+ Text [ en-US ] = "~Add...";
+ Size = MAP_APPFONT(RSC_CD_PUSHBUTTON_WIDTH, RSC_CD_PUSHBUTTON_HEIGHT );
+ };
+
+ PushButton RID_EM_BTN_CHECK_UPDATES
+ {
+ HelpID = "desktop:PushButton:RID_DLG_EXTENSION_MANAGER:RID_EM_BTN_CHECK_UPDATES";
+ TabStop = TRUE;
+ Text [ en-US ] = "Check for ~Updates...";
+ Size = MAP_APPFONT(RSC_CD_PUSHBUTTON_WIDTH, RSC_CD_PUSHBUTTON_HEIGHT );
+ };
+
+ FixedText RID_EM_FT_GET_EXTENSIONS
+ {
+ NoLabel = TRUE;
+ TabStop = TRUE;
+ Text [ en-US ] = "Get more extensions online...";
+ Size = MAP_APPFONT(RSC_CD_PUSHBUTTON_WIDTH, RSC_CD_FIXEDTEXT_HEIGHT );
+ };
+
+ FixedText RID_EM_FT_PROGRESS
+ {
+ Hide = TRUE;
+ Right = TRUE;
+ Text [ en-US ] = "Adding %EXTENSION_NAME";
+ Size = MAP_APPFONT(RSC_CD_PUSHBUTTON_WIDTH, RSC_CD_FIXEDTEXT_HEIGHT );
+ };
+
+ CancelButton RID_EM_BTN_CANCEL
+ {
+ TabStop = TRUE;
+ Hide = TRUE;
+ Size = MAP_APPFONT(RSC_CD_PUSHBUTTON_WIDTH, RSC_CD_PUSHBUTTON_HEIGHT );
+ };
+
+ OKButton RID_EM_BTN_CLOSE
+ {
+ TabStop = TRUE;
+ DefButton = TRUE;
+ Text [ en-US ] = "Close";
+ Size = MAP_APPFONT(RSC_CD_PUSHBUTTON_WIDTH, RSC_CD_PUSHBUTTON_HEIGHT );
+ };
+
+ HelpButton RID_EM_BTN_HELP
+ {
+ TabStop = TRUE;
+ Size = MAP_APPFONT(RSC_CD_PUSHBUTTON_WIDTH, RSC_CD_PUSHBUTTON_HEIGHT );
+ };
+};
+
+ModalDialog RID_DLG_UPDATE_REQUIRED
+{
+ HelpId = HID_PACKAGE_MANAGER_UPD_REQ;
+ Text [ en-US ] = "Extension Update Required";
+
+ Size = MAP_APPFONT( 300, 200 );
+ OutputSize = TRUE;
+ SVLook = TRUE;
+ Moveable = TRUE;
+ Closeable = TRUE;
+ Sizeable = TRUE;
+ Hide = TRUE;
+
+ FixedText RID_EM_FT_MSG
+ {
+ Text [ en-US ] = "%PRODUCTNAME has been updated to a new version. Some installed %PRODUCTNAME extensions are not compatible with this version and need to be updated before they can be used.";
+ WordBreak = TRUE;
+ NoLabel = TRUE;
+ Size = MAP_APPFONT( 280, 3*RSC_BS_CHARHEIGHT );
+ Pos = MAP_APPFONT( 5, 5 );
+ };
+
+ FixedText RID_EM_FT_PROGRESS
+ {
+ Hide = TRUE;
+ Right = TRUE;
+ Text [ en-US ] = "Adding %EXTENSION_NAME";
+ Size = MAP_APPFONT(RSC_CD_PUSHBUTTON_WIDTH, RSC_CD_FIXEDTEXT_HEIGHT );
+ };
+
+ HelpButton RID_EM_BTN_HELP
+ {
+ TabStop = TRUE;
+ Size = MAP_APPFONT(RSC_CD_PUSHBUTTON_WIDTH, RSC_CD_PUSHBUTTON_HEIGHT );
+ };
+
+ PushButton RID_EM_BTN_CHECK_UPDATES
+ {
+ HelpID = "desktop:PushButton:RID_DLG_UPDATE_REQUIRED:RID_EM_BTN_CHECK_UPDATES";
+ TabStop = TRUE;
+ Text [ en-US ] = "Check for ~Updates...";
+ Size = MAP_APPFONT(RSC_CD_PUSHBUTTON_WIDTH, RSC_CD_PUSHBUTTON_HEIGHT );
+ };
+
+ PushButton RID_EM_BTN_CLOSE
+ {
+ HelpID = "desktop:PushButton:RID_DLG_UPDATE_REQUIRED:RID_EM_BTN_CLOSE";
+ TabStop = TRUE;
+ DefButton = TRUE;
+ Text [ en-US ] = "Disable all";
+ Size = MAP_APPFONT(RSC_CD_PUSHBUTTON_WIDTH, RSC_CD_PUSHBUTTON_HEIGHT );
+ };
+
+ CancelButton RID_EM_BTN_CANCEL
+ {
+ TabStop = TRUE;
+ Hide = TRUE;
+ Size = MAP_APPFONT(RSC_CD_PUSHBUTTON_WIDTH, RSC_CD_PUSHBUTTON_HEIGHT );
+ };
+
+};
+
+Image RID_IMG_WARNING
+{
+ ImageBitmap = Bitmap { File = "caution_16.png"; };
+};
+
+Image RID_IMG_LOCKED
+{
+ ImageBitmap = Bitmap { File = "lock_16.png"; };
+};
+
+Image RID_IMG_SHARED
+{
+ ImageBitmap = Bitmap { File = "shared_16.png"; };
+};
+
+Image RID_IMG_EXTENSION
+{
+ ImageBitmap = Bitmap { File = "extension_32.png"; };
+};
+
+QueryBox RID_QUERYBOX_INSTALL_FOR_ALL
+{
+ Buttons = WB_YES_NO_CANCEL;
+ DefButton = WB_DEF_YES;
+ Message[en-US] = "Make sure that no further users are working with the same %PRODUCTNAME, when installing an extension for all users in a multi user environment.\n\nFor whom do you want to install the extension?\n";
+};
+
+
+// Dialog layout
+// ---------------------------------------------------
+// row 1 | multi line edit
+// ---------------------------------------------------
+// row 2 | fixed text
+// ---------------------------------------------------
+// row 3 | img | fixed text | fixed text | button
+// ----------------------------------------------------
+// row 4 | img | fixed text | fixed text
+// ---------------------------------------------------
+// row 5 |fixed line
+// ---------------------------------------------------
+// row 6 | | |button | button
+// ---------------------------------------------------
+// | col 1 | col 2 | col3 | col4 | col5
+
+//To change the overall size of the multi line edit change
+//ROW1_HEIGHT and COL3_WIDTH
+
+#define ROW1_Y RSC_SP_DLG_INNERBORDER_TOP
+#define ROW1_HEIGHT 16*RSC_CD_FIXEDTEXT_HEIGHT
+#define ROW2_Y ROW1_Y+ROW1_HEIGHT+RSC_SP_CTRL_GROUP_Y
+#define ROW2_HEIGHT 2*RSC_CD_FIXEDTEXT_HEIGHT
+#define ROW3_Y ROW2_Y+ROW2_HEIGHT+RSC_SP_CTRL_GROUP_Y
+#define ROW3_HEIGHT 3*RSC_CD_FIXEDTEXT_HEIGHT
+#define ROW4_Y ROW3_Y+ROW3_HEIGHT+RSC_SP_CTRL_GROUP_Y
+#define ROW4_HEIGHT 3*RSC_CD_FIXEDTEXT_HEIGHT
+#define ROW5_Y ROW4_Y+ROW4_HEIGHT+RSC_SP_CTRL_GROUP_Y
+#define ROW5_HEIGHT RSC_CD_FIXEDTEXT_HEIGHT
+#define ROW6_Y ROW5_Y+ROW5_HEIGHT+RSC_SP_CTRL_GROUP_Y
+#define ROW6_HEIGHT RSC_CD_PUSHBUTTON_HEIGHT
+
+#define LIC_DLG_HEIGHT ROW6_Y+ROW6_HEIGHT+RSC_SP_DLG_INNERBORDER_BOTTOM
+
+#define COL1_X RSC_SP_DLG_INNERBORDER_LEFT
+#define IMG_ARROW_WIDTH 16
+#define COL1_WIDTH IMG_ARROW_WIDTH
+#define COL2_X COL1_X+COL1_WIDTH
+#define COL2_WIDTH 10
+#define COL3_X COL2_X+COL2_WIDTH+RSC_SP_CTRL_GROUP_X
+#define COL3_WIDTH 150
+#define COL4_X COL3_X+COL3_WIDTH
+#define COL4_WIDTH RSC_CD_PUSHBUTTON_WIDTH+RSC_SP_CTRL_GROUP_X
+#define COL5_X COL4_X+COL4_WIDTH
+
+#define LIC_DLG_WIDTH COL5_X+RSC_CD_PUSHBUTTON_WIDTH+RSC_SP_DLG_INNERBORDER_RIGHT
+#define BODYWIDTH LIC_DLG_WIDTH-RSC_SP_DLG_INNERBORDER_LEFT-RSC_SP_DLG_INNERBORDER_RIGHT
+
+
diff --git a/desktop/source/deployment/gui/dp_gui_extensioncmdqueue.cxx b/desktop/source/deployment/gui/dp_gui_extensioncmdqueue.cxx
new file mode 100644
index 000000000000..96a279f481a2
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_extensioncmdqueue.cxx
@@ -0,0 +1,1178 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#define _WIN32_WINNT 0x0500
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+
+
+
+#include "sal/config.h"
+
+#include <cstddef>
+
+#include "com/sun/star/beans/PropertyValue.hpp"
+#include "com/sun/star/beans/NamedValue.hpp"
+
+#include "com/sun/star/deployment/DependencyException.hpp"
+#include "com/sun/star/deployment/LicenseException.hpp"
+#include "com/sun/star/deployment/VersionException.hpp"
+#include "com/sun/star/deployment/InstallException.hpp"
+#include "com/sun/star/deployment/PlatformException.hpp"
+
+#include "com/sun/star/deployment/ui/LicenseDialog.hpp"
+#include "com/sun/star/deployment/DeploymentException.hpp"
+#include "com/sun/star/deployment/UpdateInformationProvider.hpp"
+#include "com/sun/star/deployment/XPackage.hpp"
+
+#include "com/sun/star/task/XAbortChannel.hpp"
+#include "com/sun/star/task/XInteractionAbort.hpp"
+#include "com/sun/star/task/XInteractionApprove.hpp"
+
+#include "com/sun/star/ucb/CommandAbortedException.hpp"
+#include "com/sun/star/ucb/CommandFailedException.hpp"
+#include "com/sun/star/ucb/XCommandEnvironment.hpp"
+
+#include "com/sun/star/ui/dialogs/ExecutableDialogResults.hpp"
+
+#include "com/sun/star/uno/Reference.hxx"
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include "com/sun/star/uno/Sequence.hxx"
+#include "com/sun/star/uno/XInterface.hpp"
+#include "com/sun/star/uno/TypeClass.hpp"
+#include "osl/diagnose.h"
+#include "osl/mutex.hxx"
+#include "rtl/ref.hxx"
+#include "rtl/ustring.h"
+#include "rtl/ustring.hxx"
+#include "sal/types.h"
+#include "ucbhelper/content.hxx"
+#include "cppuhelper/exc_hlp.hxx"
+#include "cppuhelper/implbase3.hxx"
+#include "comphelper/anytostring.hxx"
+#include "vcl/msgbox.hxx"
+#include "toolkit/helper/vclunohelper.hxx"
+#include "comphelper/processfactory.hxx"
+
+#include "dp_gui.h"
+#include "dp_gui_thread.hxx"
+#include "dp_gui_extensioncmdqueue.hxx"
+#include "dp_gui_dependencydialog.hxx"
+#include "dp_gui_dialog2.hxx"
+#include "dp_gui_shared.hxx"
+#include "dp_gui_theextmgr.hxx"
+#include "dp_gui_updatedialog.hxx"
+#include "dp_gui_updateinstalldialog.hxx"
+#include "dp_dependencies.hxx"
+#include "dp_identifier.hxx"
+#include "dp_version.hxx"
+
+#include <queue>
+#include <boost/shared_ptr.hpp>
+
+#if (defined(_MSC_VER) && (_MSC_VER < 1400))
+#define _WIN32_WINNT 0x0400
+#endif
+
+#ifdef WNT
+#define GradientStyle_RECT BLA_GradientStyle_RECT
+#include <windows.h>
+#include <objbase.h>
+#undef GradientStyle_RECT
+#endif
+
+
+using namespace ::com::sun::star;
+using ::rtl::OUString;
+
+namespace {
+
+OUString getVersion( OUString const & sVersion )
+{
+ return ( sVersion.getLength() == 0 ) ? OUString( RTL_CONSTASCII_USTRINGPARAM( "0" ) ) : sVersion;
+}
+
+OUString getVersion( const uno::Reference< deployment::XPackage > &rPackage )
+{
+ return getVersion( rPackage->getVersion());
+}
+}
+
+
+namespace dp_gui {
+
+//==============================================================================
+
+class ProgressCmdEnv
+ : public ::cppu::WeakImplHelper3< ucb::XCommandEnvironment,
+ task::XInteractionHandler,
+ ucb::XProgressHandler >
+{
+ uno::Reference< task::XInteractionHandler> m_xHandler;
+ uno::Reference< uno::XComponentContext > m_xContext;
+ uno::Reference< task::XAbortChannel> m_xAbortChannel;
+
+ DialogHelper *m_pDialogHelper;
+ OUString m_sTitle;
+ bool m_bAborted;
+ bool m_bWarnUser;
+ sal_Int32 m_nCurrentProgress;
+
+ void updateProgress();
+
+ void update_( uno::Any const & Status ) throw ( uno::RuntimeException );
+
+public:
+ virtual ~ProgressCmdEnv();
+
+ /** When param bAskWhenInstalling = true, then the user is asked if he
+ agrees to install this extension. In case this extension is already installed
+ then the user is also notified and asked if he wants to replace that existing
+ extension. In first case an interaction request with an InstallException
+ will be handled and in the second case a VersionException will be handled.
+ */
+
+ ProgressCmdEnv( const uno::Reference< uno::XComponentContext > rContext,
+ DialogHelper *pDialogHelper,
+ const OUString &rTitle )
+ : m_xContext( rContext ),
+ m_pDialogHelper( pDialogHelper ),
+ m_sTitle( rTitle ),
+ m_bAborted( false ),
+ m_bWarnUser( false )
+ {}
+
+ Dialog * activeDialog() { return m_pDialogHelper ? m_pDialogHelper->getWindow() : NULL; }
+
+ void setTitle( const OUString& rNewTitle ) { m_sTitle = rNewTitle; }
+ void startProgress();
+ void stopProgress();
+ void progressSection( const OUString &rText,
+ const uno::Reference< task::XAbortChannel > &xAbortChannel = 0 );
+ inline bool isAborted() const { return m_bAborted; }
+ inline void setWarnUser( bool bNewVal ) { m_bWarnUser = bNewVal; }
+
+ // XCommandEnvironment
+ virtual uno::Reference< task::XInteractionHandler > SAL_CALL getInteractionHandler()
+ throw ( uno::RuntimeException );
+ virtual uno::Reference< ucb::XProgressHandler > SAL_CALL getProgressHandler()
+ throw ( uno::RuntimeException );
+
+ // XInteractionHandler
+ virtual void SAL_CALL handle( uno::Reference< task::XInteractionRequest > const & xRequest )
+ throw ( uno::RuntimeException );
+
+ // XProgressHandler
+ virtual void SAL_CALL push( uno::Any const & Status )
+ throw ( uno::RuntimeException );
+ virtual void SAL_CALL update( uno::Any const & Status )
+ throw ( uno::RuntimeException );
+ virtual void SAL_CALL pop() throw ( uno::RuntimeException );
+};
+
+//------------------------------------------------------------------------------
+struct ExtensionCmd
+{
+ enum E_CMD_TYPE { ADD, ENABLE, DISABLE, REMOVE, CHECK_FOR_UPDATES, ACCEPT_LICENSE };
+
+ E_CMD_TYPE m_eCmdType;
+ bool m_bWarnUser;
+ OUString m_sExtensionURL;
+ OUString m_sRepository;
+ uno::Reference< deployment::XPackage > m_xPackage;
+ std::vector< uno::Reference< deployment::XPackage > > m_vExtensionList;
+
+ ExtensionCmd( const E_CMD_TYPE eCommand,
+ const OUString &rExtensionURL,
+ const OUString &rRepository,
+ const bool bWarnUser )
+ : m_eCmdType( eCommand ),
+ m_bWarnUser( bWarnUser ),
+ m_sExtensionURL( rExtensionURL ),
+ m_sRepository( rRepository ) {};
+ ExtensionCmd( const E_CMD_TYPE eCommand,
+ const uno::Reference< deployment::XPackage > &rPackage )
+ : m_eCmdType( eCommand ),
+ m_bWarnUser( false ),
+ m_xPackage( rPackage ) {};
+ ExtensionCmd( const E_CMD_TYPE eCommand,
+ const std::vector<uno::Reference<deployment::XPackage > > &vExtensionList )
+ : m_eCmdType( eCommand ),
+ m_bWarnUser( false ),
+ m_vExtensionList( vExtensionList ) {};
+};
+
+typedef ::boost::shared_ptr< ExtensionCmd > TExtensionCmd;
+
+//------------------------------------------------------------------------------
+class ExtensionCmdQueue::Thread: public dp_gui::Thread
+{
+public:
+ Thread( DialogHelper *pDialogHelper,
+ TheExtensionManager *pManager,
+ const uno::Reference< uno::XComponentContext > & rContext );
+
+ void addExtension( const OUString &rExtensionURL,
+ const OUString &rRepository,
+ const bool bWarnUser );
+ void removeExtension( const uno::Reference< deployment::XPackage > &rPackage );
+ void enableExtension( const uno::Reference< deployment::XPackage > &rPackage,
+ const bool bEnable );
+ void checkForUpdates( const std::vector<uno::Reference<deployment::XPackage > > &vExtensionList );
+ void acceptLicense( const uno::Reference< deployment::XPackage > &rPackage );
+ void stop();
+ bool isBusy();
+
+ static OUString searchAndReplaceAll( const OUString &rSource,
+ const OUString &rWhat,
+ const OUString &rWith );
+private:
+ Thread( Thread & ); // not defined
+ void operator =( Thread & ); // not defined
+
+ virtual ~Thread();
+
+ virtual void execute();
+ virtual void SAL_CALL onTerminated();
+
+ void _insert(const TExtensionCmd& rExtCmd);
+
+ void _addExtension( ::rtl::Reference< ProgressCmdEnv > &rCmdEnv,
+ const OUString &rPackageURL,
+ const OUString &rRepository,
+ const bool bWarnUser );
+ void _removeExtension( ::rtl::Reference< ProgressCmdEnv > &rCmdEnv,
+ const uno::Reference< deployment::XPackage > &xPackage );
+ void _enableExtension( ::rtl::Reference< ProgressCmdEnv > &rCmdEnv,
+ const uno::Reference< deployment::XPackage > &xPackage );
+ void _disableExtension( ::rtl::Reference< ProgressCmdEnv > &rCmdEnv,
+ const uno::Reference< deployment::XPackage > &xPackage );
+ void _checkForUpdates( const std::vector<uno::Reference<deployment::XPackage > > &vExtensionList );
+ void _acceptLicense( ::rtl::Reference< ProgressCmdEnv > &rCmdEnv,
+ const uno::Reference< deployment::XPackage > &xPackage );
+
+ enum Input { NONE, START, STOP };
+
+ uno::Reference< uno::XComponentContext > m_xContext;
+ std::queue< TExtensionCmd > m_queue;
+
+ DialogHelper *m_pDialogHelper;
+ TheExtensionManager *m_pManager;
+
+ const OUString m_sEnablingPackages;
+ const OUString m_sDisablingPackages;
+ const OUString m_sAddingPackages;
+ const OUString m_sRemovingPackages;
+ const OUString m_sDefaultCmd;
+ const OUString m_sAcceptLicense;
+ osl::Condition m_wakeup;
+ osl::Mutex m_mutex;
+ Input m_eInput;
+ bool m_bTerminated;
+ bool m_bStopped;
+ bool m_bWorking;
+};
+
+//------------------------------------------------------------------------------
+void ProgressCmdEnv::startProgress()
+{
+ m_nCurrentProgress = 0;
+
+ if ( m_pDialogHelper )
+ m_pDialogHelper->showProgress( true );
+}
+
+//------------------------------------------------------------------------------
+void ProgressCmdEnv::stopProgress()
+{
+ if ( m_pDialogHelper )
+ m_pDialogHelper->showProgress( false );
+}
+
+//------------------------------------------------------------------------------
+void ProgressCmdEnv::progressSection( const OUString &rText,
+ const uno::Reference< task::XAbortChannel > &xAbortChannel )
+{
+ m_xAbortChannel = xAbortChannel;
+ if (! m_bAborted)
+ {
+ m_nCurrentProgress = 0;
+ if ( m_pDialogHelper )
+ {
+ m_pDialogHelper->updateProgress( rText, xAbortChannel );
+ m_pDialogHelper->updateProgress( 5 );
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+void ProgressCmdEnv::updateProgress()
+{
+ if ( ! m_bAborted )
+ {
+ long nProgress = ((m_nCurrentProgress*5) % 100) + 5;
+ if ( m_pDialogHelper )
+ m_pDialogHelper->updateProgress( nProgress );
+ }
+}
+
+//------------------------------------------------------------------------------
+ProgressCmdEnv::~ProgressCmdEnv()
+{
+ // TODO: stop all threads and wait
+}
+
+
+//------------------------------------------------------------------------------
+// XCommandEnvironment
+//------------------------------------------------------------------------------
+uno::Reference< task::XInteractionHandler > ProgressCmdEnv::getInteractionHandler()
+ throw ( uno::RuntimeException )
+{
+ return this;
+}
+
+//------------------------------------------------------------------------------
+uno::Reference< ucb::XProgressHandler > ProgressCmdEnv::getProgressHandler()
+ throw ( uno::RuntimeException )
+{
+ return this;
+}
+
+//------------------------------------------------------------------------------
+// XInteractionHandler
+//------------------------------------------------------------------------------
+void ProgressCmdEnv::handle( uno::Reference< task::XInteractionRequest > const & xRequest )
+ throw ( uno::RuntimeException )
+{
+ uno::Any request( xRequest->getRequest() );
+ OSL_ASSERT( request.getValueTypeClass() == uno::TypeClass_EXCEPTION );
+ dp_misc::TRACE( OUSTR("[dp_gui_cmdenv.cxx] incoming request:\n")
+ + ::comphelper::anyToString(request) + OUSTR("\n"));
+
+ lang::WrappedTargetException wtExc;
+ deployment::DependencyException depExc;
+ deployment::LicenseException licExc;
+ deployment::VersionException verExc;
+ deployment::InstallException instExc;
+ deployment::PlatformException platExc;
+
+ // selections:
+ bool approve = false;
+ bool abort = false;
+
+ if (request >>= wtExc) {
+ // handable deployment error signalled, e.g.
+ // bundle item registration failed, notify cause only:
+ uno::Any cause;
+ deployment::DeploymentException dpExc;
+ if (wtExc.TargetException >>= dpExc)
+ cause = dpExc.Cause;
+ else {
+ ucb::CommandFailedException cfExc;
+ if (wtExc.TargetException >>= cfExc)
+ cause = cfExc.Reason;
+ else
+ cause = wtExc.TargetException;
+ }
+ update_( cause );
+
+ // ignore intermediate errors of legacy packages, i.e.
+ // former pkgchk behaviour:
+ const uno::Reference< deployment::XPackage > xPackage( wtExc.Context, uno::UNO_QUERY );
+ OSL_ASSERT( xPackage.is() );
+ if ( xPackage.is() )
+ {
+ const uno::Reference< deployment::XPackageTypeInfo > xPackageType( xPackage->getPackageType() );
+ OSL_ASSERT( xPackageType.is() );
+ if (xPackageType.is())
+ {
+ approve = ( xPackage->isBundle() &&
+ xPackageType->getMediaType().matchAsciiL(
+ RTL_CONSTASCII_STRINGPARAM(
+ "application/"
+ "vnd.sun.star.legacy-package-bundle") ));
+ }
+ }
+ abort = !approve;
+ }
+ else if (request >>= depExc)
+ {
+ std::vector< rtl::OUString > deps;
+ for (sal_Int32 i = 0; i < depExc.UnsatisfiedDependencies.getLength();
+ ++i)
+ {
+ deps.push_back(
+ dp_misc::Dependencies::getErrorText( depExc.UnsatisfiedDependencies[i]) );
+ }
+ {
+ SolarMutexGuard guard;
+ short n = DependencyDialog( m_pDialogHelper? m_pDialogHelper->getWindow() : NULL, deps ).Execute();
+ // Distinguish between closing the dialog and programatically
+ // canceling the dialog (headless VCL):
+ approve = n == RET_OK
+ || (n == RET_CANCEL && !Application::IsDialogCancelEnabled());
+ }
+ }
+ else if (request >>= licExc)
+ {
+ uno::Reference< ui::dialogs::XExecutableDialog > xDialog(
+ deployment::ui::LicenseDialog::create(
+ m_xContext, VCLUnoHelper::GetInterface( m_pDialogHelper? m_pDialogHelper->getWindow() : NULL ),
+ licExc.ExtensionName, licExc.Text ) );
+ sal_Int16 res = xDialog->execute();
+ if ( res == ui::dialogs::ExecutableDialogResults::CANCEL )
+ abort = true;
+ else if ( res == ui::dialogs::ExecutableDialogResults::OK )
+ approve = true;
+ else
+ {
+ OSL_ASSERT(0);
+ }
+ }
+ else if (request >>= verExc)
+ {
+ sal_uInt32 id;
+ switch (dp_misc::compareVersions(
+ verExc.NewVersion, verExc.Deployed->getVersion() ))
+ {
+ case dp_misc::LESS:
+ id = RID_WARNINGBOX_VERSION_LESS;
+ break;
+ case dp_misc::EQUAL:
+ id = RID_WARNINGBOX_VERSION_EQUAL;
+ break;
+ default: // dp_misc::GREATER
+ id = RID_WARNINGBOX_VERSION_GREATER;
+ break;
+ }
+ OSL_ASSERT( verExc.Deployed.is() );
+ bool bEqualNames = verExc.NewDisplayName.equals(
+ verExc.Deployed->getDisplayName());
+ {
+ SolarMutexGuard guard;
+ WarningBox box( m_pDialogHelper? m_pDialogHelper->getWindow() : NULL, ResId(id, *DeploymentGuiResMgr::get()));
+ String s;
+ if (bEqualNames)
+ {
+ s = box.GetMessText();
+ }
+ else if (id == RID_WARNINGBOX_VERSION_EQUAL)
+ {
+ //hypothetical: requires two instances of an extension with the same
+ //version to have different display names. Probably the developer forgot
+ //to change the version.
+ s = String(ResId(RID_STR_WARNINGBOX_VERSION_EQUAL_DIFFERENT_NAMES, *DeploymentGuiResMgr::get()));
+ }
+ else if (id == RID_WARNINGBOX_VERSION_LESS)
+ {
+ s = String(ResId(RID_STR_WARNINGBOX_VERSION_LESS_DIFFERENT_NAMES, *DeploymentGuiResMgr::get()));
+ }
+ else if (id == RID_WARNINGBOX_VERSION_GREATER)
+ {
+ s = String(ResId(RID_STR_WARNINGBOX_VERSION_GREATER_DIFFERENT_NAMES, *DeploymentGuiResMgr::get()));
+ }
+ s.SearchAndReplaceAllAscii( "$NAME", verExc.NewDisplayName);
+ s.SearchAndReplaceAllAscii( "$OLDNAME", verExc.Deployed->getDisplayName());
+ s.SearchAndReplaceAllAscii( "$NEW", getVersion(verExc.NewVersion) );
+ s.SearchAndReplaceAllAscii( "$DEPLOYED", getVersion(verExc.Deployed) );
+ box.SetMessText(s);
+ approve = box.Execute() == RET_OK;
+ abort = !approve;
+ }
+ }
+ else if (request >>= instExc)
+ {
+ if ( ! m_bWarnUser )
+ {
+ approve = true;
+ }
+ else
+ {
+ if ( m_pDialogHelper )
+ {
+ SolarMutexGuard guard;
+
+ approve = m_pDialogHelper->installExtensionWarn( instExc.displayName );
+ }
+ else
+ approve = false;
+ abort = !approve;
+ }
+ }
+ else if (request >>= platExc)
+ {
+ SolarMutexGuard guard;
+ String sMsg( ResId( RID_STR_UNSUPPORTED_PLATFORM, *DeploymentGuiResMgr::get() ) );
+ sMsg.SearchAndReplaceAllAscii( "%Name", platExc.package->getDisplayName() );
+ ErrorBox box( m_pDialogHelper? m_pDialogHelper->getWindow() : NULL, WB_OK, sMsg );
+ box.Execute();
+ approve = true;
+ }
+
+ if (approve == false && abort == false)
+ {
+ // forward to UUI handler:
+ if (! m_xHandler.is()) {
+ // late init:
+ uno::Sequence< uno::Any > handlerArgs( 1 );
+ handlerArgs[ 0 ] <<= beans::PropertyValue(
+ OUSTR("Context"), -1, uno::Any( m_sTitle ),
+ beans::PropertyState_DIRECT_VALUE );
+ m_xHandler.set( m_xContext->getServiceManager()
+ ->createInstanceWithArgumentsAndContext(
+ OUSTR("com.sun.star.uui.InteractionHandler"),
+ handlerArgs, m_xContext ), uno::UNO_QUERY_THROW );
+ }
+ m_xHandler->handle( xRequest );
+ }
+ else
+ {
+ // select:
+ uno::Sequence< uno::Reference< task::XInteractionContinuation > > conts(
+ xRequest->getContinuations() );
+ uno::Reference< task::XInteractionContinuation > const * pConts = conts.getConstArray();
+ sal_Int32 len = conts.getLength();
+ for ( sal_Int32 pos = 0; pos < len; ++pos )
+ {
+ if (approve) {
+ uno::Reference< task::XInteractionApprove > xInteractionApprove( pConts[ pos ], uno::UNO_QUERY );
+ if (xInteractionApprove.is()) {
+ xInteractionApprove->select();
+ // don't query again for ongoing continuations:
+ approve = false;
+ }
+ }
+ else if (abort) {
+ uno::Reference< task::XInteractionAbort > xInteractionAbort( pConts[ pos ], uno::UNO_QUERY );
+ if (xInteractionAbort.is()) {
+ xInteractionAbort->select();
+ // don't query again for ongoing continuations:
+ abort = false;
+ }
+ }
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+// XProgressHandler
+//------------------------------------------------------------------------------
+void ProgressCmdEnv::push( uno::Any const & rStatus )
+ throw( uno::RuntimeException )
+{
+ update_( rStatus );
+}
+
+//------------------------------------------------------------------------------
+void ProgressCmdEnv::update_( uno::Any const & rStatus )
+ throw( uno::RuntimeException )
+{
+ OUString text;
+ if ( rStatus.hasValue() && !( rStatus >>= text) )
+ {
+ if ( rStatus.getValueTypeClass() == uno::TypeClass_EXCEPTION )
+ text = static_cast< uno::Exception const *>( rStatus.getValue() )->Message;
+ if ( text.getLength() == 0 )
+ text = ::comphelper::anyToString( rStatus ); // fallback
+
+ const SolarMutexGuard aGuard;
+ const ::std::auto_ptr< ErrorBox > aBox( new ErrorBox( m_pDialogHelper? m_pDialogHelper->getWindow() : NULL, WB_OK, text ) );
+ aBox->Execute();
+ }
+ ++m_nCurrentProgress;
+ updateProgress();
+}
+
+//------------------------------------------------------------------------------
+void ProgressCmdEnv::update( uno::Any const & rStatus )
+ throw( uno::RuntimeException )
+{
+ update_( rStatus );
+}
+
+//------------------------------------------------------------------------------
+void ProgressCmdEnv::pop()
+ throw( uno::RuntimeException )
+{
+ update_( uno::Any() ); // no message
+}
+
+//------------------------------------------------------------------------------
+ExtensionCmdQueue::Thread::Thread( DialogHelper *pDialogHelper,
+ TheExtensionManager *pManager,
+ const uno::Reference< uno::XComponentContext > & rContext ) :
+ m_xContext( rContext ),
+ m_pDialogHelper( pDialogHelper ),
+ m_pManager( pManager ),
+ m_sEnablingPackages( DialogHelper::getResourceString( RID_STR_ENABLING_PACKAGES ) ),
+ m_sDisablingPackages( DialogHelper::getResourceString( RID_STR_DISABLING_PACKAGES ) ),
+ m_sAddingPackages( DialogHelper::getResourceString( RID_STR_ADDING_PACKAGES ) ),
+ m_sRemovingPackages( DialogHelper::getResourceString( RID_STR_REMOVING_PACKAGES ) ),
+ m_sDefaultCmd( DialogHelper::getResourceString( RID_STR_ADD_PACKAGES ) ),
+ m_sAcceptLicense( DialogHelper::getResourceString( RID_STR_ACCEPT_LICENSE ) ),
+ m_eInput( NONE ),
+ m_bTerminated( false ),
+ m_bStopped( false ),
+ m_bWorking( false )
+{
+ OSL_ASSERT( pDialogHelper );
+}
+
+//------------------------------------------------------------------------------
+void ExtensionCmdQueue::Thread::addExtension( const ::rtl::OUString &rExtensionURL,
+ const ::rtl::OUString &rRepository,
+ const bool bWarnUser )
+{
+ if ( rExtensionURL.getLength() )
+ {
+ TExtensionCmd pEntry( new ExtensionCmd( ExtensionCmd::ADD, rExtensionURL, rRepository, bWarnUser ) );
+ _insert( pEntry );
+ }
+}
+
+//------------------------------------------------------------------------------
+void ExtensionCmdQueue::Thread::removeExtension( const uno::Reference< deployment::XPackage > &rPackage )
+{
+ if ( rPackage.is() )
+ {
+ TExtensionCmd pEntry( new ExtensionCmd( ExtensionCmd::REMOVE, rPackage ) );
+ _insert( pEntry );
+ }
+}
+
+//------------------------------------------------------------------------------
+void ExtensionCmdQueue::Thread::acceptLicense( const uno::Reference< deployment::XPackage > &rPackage )
+{
+ if ( rPackage.is() )
+ {
+ TExtensionCmd pEntry( new ExtensionCmd( ExtensionCmd::ACCEPT_LICENSE, rPackage ) );
+ _insert( pEntry );
+ }
+}
+
+//------------------------------------------------------------------------------
+void ExtensionCmdQueue::Thread::enableExtension( const uno::Reference< deployment::XPackage > &rPackage,
+ const bool bEnable )
+{
+ if ( rPackage.is() )
+ {
+ TExtensionCmd pEntry( new ExtensionCmd( bEnable ? ExtensionCmd::ENABLE :
+ ExtensionCmd::DISABLE,
+ rPackage ) );
+ _insert( pEntry );
+ }
+}
+
+//------------------------------------------------------------------------------
+void ExtensionCmdQueue::Thread::checkForUpdates(
+ const std::vector<uno::Reference<deployment::XPackage > > &vExtensionList )
+{
+ TExtensionCmd pEntry( new ExtensionCmd( ExtensionCmd::CHECK_FOR_UPDATES, vExtensionList ) );
+ _insert( pEntry );
+}
+
+//------------------------------------------------------------------------------
+//Stopping this thread will not abort the installation of extensions.
+void ExtensionCmdQueue::Thread::stop()
+{
+ osl::MutexGuard aGuard( m_mutex );
+ m_bStopped = true;
+ m_eInput = STOP;
+ m_wakeup.set();
+}
+
+//------------------------------------------------------------------------------
+bool ExtensionCmdQueue::Thread::isBusy()
+{
+ osl::MutexGuard aGuard( m_mutex );
+ return m_bWorking;
+}
+
+//------------------------------------------------------------------------------
+ExtensionCmdQueue::Thread::~Thread() {}
+
+//------------------------------------------------------------------------------
+void ExtensionCmdQueue::Thread::execute()
+{
+#ifdef WNT
+ //Needed for use of the service "com.sun.star.system.SystemShellExecute" in
+ //DialogHelper::openWebBrowser
+ CoUninitialize();
+ HRESULT r = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
+#endif
+ for (;;)
+ {
+ if ( m_wakeup.wait() != osl::Condition::result_ok )
+ {
+ dp_misc::TRACE( "dp_gui::ExtensionCmdQueue::Thread::run: ignored "
+ "osl::Condition::wait failure\n" );
+ }
+ m_wakeup.reset();
+
+ int nSize;
+ Input eInput;
+ {
+ osl::MutexGuard aGuard( m_mutex );
+ eInput = m_eInput;
+ m_eInput = NONE;
+ nSize = m_queue.size();
+ m_bWorking = false;
+ }
+
+ // If this thread has been woken up by anything else except start, stop
+ // then input is NONE and we wait again.
+ // We only install the extension which are currently in the queue.
+ // The progressbar will be set to show the progress of the current number
+ // of extensions. If we allowed to add extensions now then the progressbar may
+ // have reached the end while we still install newly added extensions.
+ if ( ( eInput == NONE ) || ( nSize == 0 ) )
+ continue;
+ if ( eInput == STOP )
+ break;
+
+ ::rtl::Reference< ProgressCmdEnv > currentCmdEnv( new ProgressCmdEnv( m_xContext, m_pDialogHelper, m_sDefaultCmd ) );
+
+ // Do not lock the following part with addExtension. addExtension may be called in the main thread.
+ // If the message box "Do you want to install the extension (or similar)" is shown and then
+ // addExtension is called, which then blocks the main thread, then we deadlock.
+ bool bStartProgress = true;
+
+ while ( !currentCmdEnv->isAborted() && --nSize >= 0 )
+ {
+ {
+ osl::MutexGuard aGuard( m_mutex );
+ m_bWorking = true;
+ }
+
+ try
+ {
+ TExtensionCmd pEntry;
+ {
+ ::osl::MutexGuard queueGuard( m_mutex );
+ pEntry = m_queue.front();
+ m_queue.pop();
+ }
+
+ if ( bStartProgress && ( pEntry->m_eCmdType != ExtensionCmd::CHECK_FOR_UPDATES ) )
+ {
+ currentCmdEnv->startProgress();
+ bStartProgress = false;
+ }
+
+ switch ( pEntry->m_eCmdType ) {
+ case ExtensionCmd::ADD :
+ _addExtension( currentCmdEnv, pEntry->m_sExtensionURL, pEntry->m_sRepository, pEntry->m_bWarnUser );
+ break;
+ case ExtensionCmd::REMOVE :
+ _removeExtension( currentCmdEnv, pEntry->m_xPackage );
+ break;
+ case ExtensionCmd::ENABLE :
+ _enableExtension( currentCmdEnv, pEntry->m_xPackage );
+ break;
+ case ExtensionCmd::DISABLE :
+ _disableExtension( currentCmdEnv, pEntry->m_xPackage );
+ break;
+ case ExtensionCmd::CHECK_FOR_UPDATES :
+ _checkForUpdates( pEntry->m_vExtensionList );
+ break;
+ case ExtensionCmd::ACCEPT_LICENSE :
+ _acceptLicense( currentCmdEnv, pEntry->m_xPackage );
+ break;
+ }
+ }
+ catch ( ucb::CommandAbortedException & )
+ {
+ //This exception is thrown when the user clicks cancel on the progressbar.
+ //Then we cancel the installation of all extensions and remove them from
+ //the queue.
+ {
+ ::osl::MutexGuard queueGuard2(m_mutex);
+ while ( --nSize >= 0 )
+ m_queue.pop();
+ }
+ break;
+ }
+ catch ( ucb::CommandFailedException & )
+ {
+ //This exception is thrown when a user clicked cancel in the messagebox which was
+ //startet by the interaction handler. For example the user will be asked if he/she
+ //really wants to install the extension.
+ //These interaction are run for exectly one extension at a time. Therefore we continue
+ //with installing the remaining extensions.
+ continue;
+ }
+ catch ( uno::Exception & )
+ {
+ //Todo display the user an error
+ //see also DialogImpl::SyncPushButton::Click()
+ uno::Any exc( ::cppu::getCaughtException() );
+ OUString msg;
+ deployment::DeploymentException dpExc;
+ if ((exc >>= dpExc) &&
+ dpExc.Cause.getValueTypeClass() == uno::TypeClass_EXCEPTION)
+ {
+ // notify error cause only:
+ msg = reinterpret_cast< uno::Exception const * >( dpExc.Cause.getValue() )->Message;
+ }
+ if (msg.getLength() == 0) // fallback for debugging purposes
+ msg = ::comphelper::anyToString(exc);
+
+ const SolarMutexGuard guard;
+ ::std::auto_ptr<ErrorBox> box(
+ new ErrorBox( currentCmdEnv->activeDialog(), WB_OK, msg ) );
+ if ( m_pDialogHelper )
+ box->SetText( m_pDialogHelper->getWindow()->GetText() );
+ box->Execute();
+ //Continue with installation of the remaining extensions
+ }
+ {
+ osl::MutexGuard aGuard( m_mutex );
+ m_bWorking = false;
+ }
+ }
+
+ {
+ // when leaving the while loop with break, we should set working to false, too
+ osl::MutexGuard aGuard( m_mutex );
+ m_bWorking = false;
+ }
+
+ if ( !bStartProgress )
+ currentCmdEnv->stopProgress();
+ }
+ //end for
+#ifdef WNT
+ CoUninitialize();
+#endif
+}
+
+//------------------------------------------------------------------------------
+void ExtensionCmdQueue::Thread::_addExtension( ::rtl::Reference< ProgressCmdEnv > &rCmdEnv,
+ const OUString &rPackageURL,
+ const OUString &rRepository,
+ const bool bWarnUser )
+{
+ //check if we have a string in anyTitle. For example "unopkg gui \" caused anyTitle to be void
+ //and anyTitle.get<OUString> throws as RuntimeException.
+ uno::Any anyTitle;
+ try
+ {
+ anyTitle = ::ucbhelper::Content( rPackageURL, rCmdEnv.get() ).getPropertyValue( OUSTR("Title") );
+ }
+ catch ( uno::Exception & )
+ {
+ return;
+ }
+
+ OUString sName;
+ if ( ! (anyTitle >>= sName) )
+ {
+ OSL_FAIL("Could not get file name for extension.");
+ return;
+ }
+
+ rCmdEnv->setWarnUser( bWarnUser );
+ uno::Reference< deployment::XExtensionManager > xExtMgr = m_pManager->getExtensionManager();
+ uno::Reference< task::XAbortChannel > xAbortChannel( xExtMgr->createAbortChannel() );
+ OUString sTitle = searchAndReplaceAll( m_sAddingPackages, OUSTR("%EXTENSION_NAME"), sName );
+ rCmdEnv->progressSection( sTitle, xAbortChannel );
+
+ try
+ {
+ xExtMgr->addExtension(rPackageURL, uno::Sequence<beans::NamedValue>(),
+ rRepository, xAbortChannel, rCmdEnv.get() );
+ }
+ catch ( ucb::CommandFailedException & )
+ {
+ // When the extension is already installed we'll get a dialog asking if we want to overwrite. If we then press
+ // cancel this exception is thrown.
+ }
+ catch ( ucb::CommandAbortedException & )
+ {
+ // User clicked the cancel button
+ // TODO: handle cancel
+ }
+ rCmdEnv->setWarnUser( false );
+}
+
+//------------------------------------------------------------------------------
+void ExtensionCmdQueue::Thread::_removeExtension( ::rtl::Reference< ProgressCmdEnv > &rCmdEnv,
+ const uno::Reference< deployment::XPackage > &xPackage )
+{
+ uno::Reference< deployment::XExtensionManager > xExtMgr = m_pManager->getExtensionManager();
+ uno::Reference< task::XAbortChannel > xAbortChannel( xExtMgr->createAbortChannel() );
+ OUString sTitle = searchAndReplaceAll( m_sRemovingPackages, OUSTR("%EXTENSION_NAME"), xPackage->getDisplayName() );
+ rCmdEnv->progressSection( sTitle, xAbortChannel );
+
+ OUString id( dp_misc::getIdentifier( xPackage ) );
+ try
+ {
+ xExtMgr->removeExtension( id, xPackage->getName(), xPackage->getRepositoryName(), xAbortChannel, rCmdEnv.get() );
+ }
+ catch ( deployment::DeploymentException & )
+ {}
+ catch ( ucb::CommandFailedException & )
+ {}
+ catch ( ucb::CommandAbortedException & )
+ {}
+
+ // Check, if there are still updates to be notified via menu bar icon
+ uno::Sequence< uno::Sequence< rtl::OUString > > aItemList;
+ UpdateDialog::createNotifyJob( false, aItemList );
+}
+
+//------------------------------------------------------------------------------
+void ExtensionCmdQueue::Thread::_checkForUpdates(
+ const std::vector<uno::Reference<deployment::XPackage > > &vExtensionList )
+{
+ UpdateDialog* pUpdateDialog;
+ std::vector< UpdateData > vData;
+
+ const SolarMutexGuard guard;
+
+ pUpdateDialog = new UpdateDialog( m_xContext, m_pDialogHelper? m_pDialogHelper->getWindow() : NULL, vExtensionList, &vData );
+
+ pUpdateDialog->notifyMenubar( true, false ); // prepare the checking, if there updates to be notified via menu bar icon
+
+ if ( ( pUpdateDialog->Execute() == RET_OK ) && !vData.empty() )
+ {
+ // If there is at least one directly downloadable extension then we
+ // open the install dialog.
+ ::std::vector< UpdateData > dataDownload;
+ int countWebsiteDownload = 0;
+ typedef std::vector< dp_gui::UpdateData >::const_iterator cit;
+
+ for ( cit i = vData.begin(); i < vData.end(); ++i )
+ {
+ if ( i->sWebsiteURL.getLength() > 0 )
+ countWebsiteDownload ++;
+ else
+ dataDownload.push_back( *i );
+ }
+
+ short nDialogResult = RET_OK;
+ if ( !dataDownload.empty() )
+ {
+ nDialogResult = UpdateInstallDialog( m_pDialogHelper? m_pDialogHelper->getWindow() : NULL, dataDownload, m_xContext ).Execute();
+ pUpdateDialog->notifyMenubar( false, true ); // Check, if there are still pending updates to be notified via menu bar icon
+ }
+ else
+ pUpdateDialog->notifyMenubar( false, false ); // Check, if there are pending updates to be notified via menu bar icon
+
+ //Now start the webbrowser and navigate to the websites where we get the updates
+ if ( RET_OK == nDialogResult )
+ {
+ for ( cit i = vData.begin(); i < vData.end(); ++i )
+ {
+ if ( m_pDialogHelper && ( i->sWebsiteURL.getLength() > 0 ) )
+ m_pDialogHelper->openWebBrowser( i->sWebsiteURL, m_pDialogHelper->getWindow()->GetText() );
+ }
+ }
+ }
+ else
+ pUpdateDialog->notifyMenubar( false, false ); // check if there updates to be notified via menu bar icon
+
+ delete pUpdateDialog;
+}
+
+//------------------------------------------------------------------------------
+void ExtensionCmdQueue::Thread::_enableExtension( ::rtl::Reference< ProgressCmdEnv > &rCmdEnv,
+ const uno::Reference< deployment::XPackage > &xPackage )
+{
+ if ( !xPackage.is() )
+ return;
+
+ uno::Reference< deployment::XExtensionManager > xExtMgr = m_pManager->getExtensionManager();
+ uno::Reference< task::XAbortChannel > xAbortChannel( xExtMgr->createAbortChannel() );
+ OUString sTitle = searchAndReplaceAll( m_sEnablingPackages, OUSTR("%EXTENSION_NAME"), xPackage->getDisplayName() );
+ rCmdEnv->progressSection( sTitle, xAbortChannel );
+
+ try
+ {
+ xExtMgr->enableExtension( xPackage, xAbortChannel, rCmdEnv.get() );
+ if ( m_pDialogHelper )
+ m_pDialogHelper->updatePackageInfo( xPackage );
+ }
+ catch ( ::ucb::CommandAbortedException & )
+ {}
+}
+
+//------------------------------------------------------------------------------
+void ExtensionCmdQueue::Thread::_disableExtension( ::rtl::Reference< ProgressCmdEnv > &rCmdEnv,
+ const uno::Reference< deployment::XPackage > &xPackage )
+{
+ if ( !xPackage.is() )
+ return;
+
+ uno::Reference< deployment::XExtensionManager > xExtMgr = m_pManager->getExtensionManager();
+ uno::Reference< task::XAbortChannel > xAbortChannel( xExtMgr->createAbortChannel() );
+ OUString sTitle = searchAndReplaceAll( m_sDisablingPackages, OUSTR("%EXTENSION_NAME"), xPackage->getDisplayName() );
+ rCmdEnv->progressSection( sTitle, xAbortChannel );
+
+ try
+ {
+ xExtMgr->disableExtension( xPackage, xAbortChannel, rCmdEnv.get() );
+ if ( m_pDialogHelper )
+ m_pDialogHelper->updatePackageInfo( xPackage );
+ }
+ catch ( ::ucb::CommandAbortedException & )
+ {}
+}
+
+//------------------------------------------------------------------------------
+void ExtensionCmdQueue::Thread::_acceptLicense( ::rtl::Reference< ProgressCmdEnv > &rCmdEnv,
+ const uno::Reference< deployment::XPackage > &xPackage )
+{
+ if ( !xPackage.is() )
+ return;
+
+ uno::Reference< deployment::XExtensionManager > xExtMgr = m_pManager->getExtensionManager();
+ uno::Reference< task::XAbortChannel > xAbortChannel( xExtMgr->createAbortChannel() );
+ OUString sTitle = searchAndReplaceAll( m_sAcceptLicense, OUSTR("%EXTENSION_NAME"), xPackage->getDisplayName() );
+ rCmdEnv->progressSection( sTitle, xAbortChannel );
+
+ try
+ {
+ xExtMgr->checkPrerequisitesAndEnable( xPackage, xAbortChannel, rCmdEnv.get() );
+ if ( m_pDialogHelper )
+ m_pDialogHelper->updatePackageInfo( xPackage );
+ }
+ catch ( ::ucb::CommandAbortedException & )
+ {}
+}
+
+//------------------------------------------------------------------------------
+void ExtensionCmdQueue::Thread::onTerminated()
+{
+ ::osl::MutexGuard g(m_mutex);
+ m_bTerminated = true;
+}
+
+void ExtensionCmdQueue::Thread::_insert(const TExtensionCmd& rExtCmd)
+{
+ ::osl::MutexGuard aGuard( m_mutex );
+
+ // If someone called stop then we do not process the command -> game over!
+ if ( m_bStopped )
+ return;
+
+ m_queue.push( rExtCmd );
+ m_eInput = START;
+ m_wakeup.set();
+}
+
+//------------------------------------------------------------------------------
+OUString ExtensionCmdQueue::Thread::searchAndReplaceAll( const OUString &rSource,
+ const OUString &rWhat,
+ const OUString &rWith )
+{
+ OUString aRet( rSource );
+ sal_Int32 nLen = rWhat.getLength();
+
+ if ( !nLen )
+ return aRet;
+
+ sal_Int32 nIndex = rSource.indexOf( rWhat );
+ while ( nIndex != -1 )
+ {
+ aRet = aRet.replaceAt( nIndex, nLen, rWith );
+ nIndex = aRet.indexOf( rWhat, nIndex + rWith.getLength() );
+ }
+ return aRet;
+}
+
+
+//------------------------------------------------------------------------------
+ExtensionCmdQueue::ExtensionCmdQueue( DialogHelper * pDialogHelper,
+ TheExtensionManager *pManager,
+ const uno::Reference< uno::XComponentContext > &rContext )
+ : m_thread( new Thread( pDialogHelper, pManager, rContext ) )
+{
+ m_thread->launch();
+}
+
+ExtensionCmdQueue::~ExtensionCmdQueue() {
+ stop();
+}
+
+void ExtensionCmdQueue::addExtension( const ::rtl::OUString & extensionURL,
+ const ::rtl::OUString & repository,
+ const bool bWarnUser )
+{
+ m_thread->addExtension( extensionURL, repository, bWarnUser );
+}
+
+void ExtensionCmdQueue::removeExtension( const uno::Reference< deployment::XPackage > &rPackage )
+{
+ m_thread->removeExtension( rPackage );
+}
+
+void ExtensionCmdQueue::enableExtension( const uno::Reference< deployment::XPackage > &rPackage,
+ const bool bEnable )
+{
+ m_thread->enableExtension( rPackage, bEnable );
+}
+
+void ExtensionCmdQueue::checkForUpdates( const std::vector<uno::Reference<deployment::XPackage > > &vExtensionList )
+{
+ m_thread->checkForUpdates( vExtensionList );
+}
+
+void ExtensionCmdQueue::acceptLicense( const uno::Reference< deployment::XPackage > &rPackage )
+{
+ m_thread->acceptLicense( rPackage );
+}
+
+void ExtensionCmdQueue::syncRepositories( const uno::Reference< uno::XComponentContext > &xContext )
+{
+ dp_misc::syncRepositories( new ProgressCmdEnv( xContext, NULL, OUSTR("Extension Manager") ) );
+}
+
+void ExtensionCmdQueue::stop()
+{
+ m_thread->stop();
+}
+
+bool ExtensionCmdQueue::isBusy()
+{
+ return m_thread->isBusy();
+}
+
+void handleInteractionRequest( const uno::Reference< uno::XComponentContext > & xContext,
+ const uno::Reference< task::XInteractionRequest > & xRequest )
+{
+ ::rtl::Reference< ProgressCmdEnv > xCmdEnv( new ProgressCmdEnv( xContext, NULL, OUSTR("Extension Manager") ) );
+ xCmdEnv->handle( xRequest );
+}
+
+} //namespace dp_gui
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/gui/dp_gui_extensioncmdqueue.hxx b/desktop/source/deployment/gui/dp_gui_extensioncmdqueue.hxx
new file mode 100644
index 000000000000..f8fd1f1b2e05
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_extensioncmdqueue.hxx
@@ -0,0 +1,114 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_DP_GUI_EXTENSIONCMDQUEUE_HXX
+#define INCLUDED_DP_GUI_EXTENSIONCMDQUEUE_HXX
+
+#include "sal/config.h"
+
+#include "com/sun/star/uno/Reference.hxx"
+#include "rtl/ref.hxx"
+
+#include <vector>
+
+#include "dp_gui_updatedata.hxx"
+
+/// @HTML
+
+namespace com { namespace sun { namespace star {
+ namespace task { class XInteractionRequest; }
+ namespace uno { class XComponentContext; }
+} } }
+
+namespace dp_gui {
+
+class DialogHelper;
+class TheExtensionManager;
+
+/**
+ Manages installing of extensions in the GUI mode. Requests for installing
+ Extensions can be asynchronous. For example, the Extension Manager is running
+ in an office process and someone uses the system integration to install an Extension.
+ That is, the user double clicks an extension symbol in a file browser, which then
+ causes an invocation of "unopkg gui ext". When at that time the Extension Manager
+ already performs a task, triggered by the user (for example, add, update, disable,
+ enable) then adding of the extension will be postponed until the user has finished
+ the task.
+
+ This class also ensures that the extensions are not installed in the main thread.
+ Doing so would cause a deadlock because of the progress bar which needs to be constantly
+ updated.
+*/
+class ExtensionCmdQueue {
+
+public:
+ /**
+ Create an instance.
+ */
+ ExtensionCmdQueue( DialogHelper * pDialogHelper,
+ TheExtensionManager *pManager,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > & rContext);
+
+ ~ExtensionCmdQueue();
+
+ /**
+ */
+ void addExtension( const ::rtl::OUString &rExtensionURL,
+ const ::rtl::OUString &rRepository,
+ const bool bWarnUser );
+ void removeExtension( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &rPackage );
+ void enableExtension( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &rPackage,
+ const bool bEnable );
+ void checkForUpdates(const std::vector< ::com::sun::star::uno::Reference<
+ ::com::sun::star::deployment::XPackage > > &vList );
+ void acceptLicense( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &rPackage );
+ static void syncRepositories( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > & xContext );
+ /**
+ This call does not block. It signals the internal thread
+ that it should install the remaining extensions and then terminate.
+ */
+ void stop();
+
+ bool isBusy();
+private:
+ ExtensionCmdQueue(ExtensionCmdQueue &); // not defined
+ void operator =(ExtensionCmdQueue &); // not defined
+
+ class Thread;
+
+ rtl::Reference< Thread > m_thread;
+};
+
+void handleInteractionRequest( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > & xContext,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionRequest > & xRequest );
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/gui/dp_gui_extlistbox.cxx b/desktop/source/deployment/gui/dp_gui_extlistbox.cxx
new file mode 100644
index 000000000000..7b00c4ede248
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_extlistbox.cxx
@@ -0,0 +1,1214 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include "svtools/controldims.hrc"
+
+#include "dp_gui.h"
+#include "dp_gui_extlistbox.hxx"
+#include "dp_gui_theextmgr.hxx"
+#include "dp_gui_dialog2.hxx"
+#include "dp_dependencies.hxx"
+
+#include "comphelper/processfactory.hxx"
+#include "com/sun/star/i18n/CollatorOptions.hpp"
+#include "com/sun/star/deployment/DependencyException.hpp"
+#include "com/sun/star/deployment/DeploymentException.hpp"
+
+
+#define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
+
+#define USER_PACKAGE_MANAGER OUSTR("user")
+#define SHARED_PACKAGE_MANAGER OUSTR("shared")
+#define BUNDLED_PACKAGE_MANAGER OUSTR("bundled")
+
+using namespace ::com::sun::star;
+
+namespace dp_gui {
+
+//------------------------------------------------------------------------------
+// struct Entry_Impl
+//------------------------------------------------------------------------------
+Entry_Impl::Entry_Impl( const uno::Reference< deployment::XPackage > &xPackage,
+ const PackageState eState, const bool bReadOnly ) :
+ m_bActive( false ),
+ m_bLocked( bReadOnly ),
+ m_bHasOptions( false ),
+ m_bUser( false ),
+ m_bShared( false ),
+ m_bNew( false ),
+ m_bChecked( false ),
+ m_bMissingDeps( false ),
+ m_bHasButtons( false ),
+ m_bMissingLic( false ),
+ m_eState( eState ),
+ m_pPublisher( NULL ),
+ m_xPackage( xPackage )
+{
+ try
+ {
+ m_sTitle = xPackage->getDisplayName();
+ m_sVersion = xPackage->getVersion();
+ m_sDescription = xPackage->getDescription();
+ m_sLicenseText = xPackage->getLicenseText();
+
+ beans::StringPair aInfo( m_xPackage->getPublisherInfo() );
+ m_sPublisher = aInfo.First;
+ m_sPublisherURL = aInfo.Second;
+
+ // get the icons for the package if there are any
+ uno::Reference< graphic::XGraphic > xGraphic = xPackage->getIcon( false );
+ if ( xGraphic.is() )
+ m_aIcon = Image( xGraphic );
+
+ xGraphic = xPackage->getIcon( true );
+ if ( xGraphic.is() )
+ m_aIconHC = Image( xGraphic );
+ else
+ m_aIconHC = m_aIcon;
+
+ if ( eState == AMBIGUOUS )
+ m_sErrorText = DialogHelper::getResourceString( RID_STR_ERROR_UNKNOWN_STATUS );
+ else if ( eState == NOT_REGISTERED )
+ checkDependencies();
+ }
+ catch (deployment::ExtensionRemovedException &) {}
+ catch (uno::RuntimeException &) {}
+}
+
+//------------------------------------------------------------------------------
+Entry_Impl::~Entry_Impl()
+{}
+
+//------------------------------------------------------------------------------
+StringCompare Entry_Impl::CompareTo( const CollatorWrapper *pCollator, const TEntry_Impl pEntry ) const
+{
+ StringCompare eCompare = (StringCompare) pCollator->compareString( m_sTitle, pEntry->m_sTitle );
+ if ( eCompare == COMPARE_EQUAL )
+ {
+ eCompare = m_sVersion.CompareTo( pEntry->m_sVersion );
+ if ( eCompare == COMPARE_EQUAL )
+ {
+ sal_Int32 nCompare = m_xPackage->getRepositoryName().compareTo( pEntry->m_xPackage->getRepositoryName() );
+ if ( nCompare < 0 )
+ eCompare = COMPARE_LESS;
+ else if ( nCompare > 0 )
+ eCompare = COMPARE_GREATER;
+ }
+ }
+ return eCompare;
+}
+
+//------------------------------------------------------------------------------
+void Entry_Impl::checkDependencies()
+{
+ try {
+ m_xPackage->checkDependencies( uno::Reference< ucb::XCommandEnvironment >() );
+ }
+ catch ( deployment::DeploymentException &e )
+ {
+ deployment::DependencyException depExc;
+ if ( e.Cause >>= depExc )
+ {
+ rtl::OUString aMissingDep( DialogHelper::getResourceString( RID_STR_ERROR_MISSING_DEPENDENCIES ) );
+ for ( sal_Int32 i = 0; i < depExc.UnsatisfiedDependencies.getLength(); ++i )
+ {
+ aMissingDep += OUSTR("\n");
+ aMissingDep += dp_misc::Dependencies::getErrorText( depExc.UnsatisfiedDependencies[i]);
+ }
+ aMissingDep += OUSTR("\n");
+ m_sErrorText = aMissingDep;
+ m_bMissingDeps = true;
+ }
+ }
+}
+//------------------------------------------------------------------------------
+// ExtensionRemovedListener
+//------------------------------------------------------------------------------
+void ExtensionRemovedListener::disposing( lang::EventObject const & rEvt )
+ throw ( uno::RuntimeException )
+{
+ uno::Reference< deployment::XPackage > xPackage( rEvt.Source, uno::UNO_QUERY );
+
+ if ( xPackage.is() )
+ {
+ m_pParent->removeEntry( xPackage );
+ }
+}
+
+//------------------------------------------------------------------------------
+ExtensionRemovedListener::~ExtensionRemovedListener()
+{
+}
+
+//------------------------------------------------------------------------------
+// ExtensionBox_Impl
+//------------------------------------------------------------------------------
+ExtensionBox_Impl::ExtensionBox_Impl( Dialog* pParent, TheExtensionManager *pManager ) :
+ IExtensionListBox( pParent, WB_BORDER | WB_TABSTOP | WB_CHILDDLGCTRL ),
+ m_bHasScrollBar( false ),
+ m_bHasActive( false ),
+ m_bNeedsRecalc( true ),
+ m_bHasNew( false ),
+ m_bInCheckMode( false ),
+ m_bAdjustActive( false ),
+ m_bInDelete( false ),
+ m_nActive( 0 ),
+ m_nTopIndex( 0 ),
+ m_nActiveHeight( 0 ),
+ m_nExtraHeight( 2 ),
+ m_aSharedImage( DialogHelper::getResId( RID_IMG_SHARED ) ),
+ m_aLockedImage( DialogHelper::getResId( RID_IMG_LOCKED ) ),
+ m_aWarningImage( DialogHelper::getResId( RID_IMG_WARNING ) ),
+ m_aDefaultImage( DialogHelper::getResId( RID_IMG_EXTENSION ) ),
+ m_pScrollBar( NULL ),
+ m_pManager( pManager )
+{
+ SetHelpId( HID_EXTENSION_MANAGER_LISTBOX );
+
+ m_pScrollBar = new ScrollBar( this, WB_VERT );
+ m_pScrollBar->SetScrollHdl( LINK( this, ExtensionBox_Impl, ScrollHdl ) );
+ m_pScrollBar->EnableDrag();
+
+ SetPaintTransparent( true );
+ SetPosPixel( Point( RSC_SP_DLG_INNERBORDER_LEFT, RSC_SP_DLG_INNERBORDER_TOP ) );
+ long nIconHeight = 2*TOP_OFFSET + SMALL_ICON_SIZE;
+ long nTitleHeight = 2*TOP_OFFSET + GetTextHeight();
+ if ( nIconHeight < nTitleHeight )
+ m_nStdHeight = nTitleHeight;
+ else
+ m_nStdHeight = nIconHeight;
+ m_nStdHeight += GetTextHeight() + TOP_OFFSET;
+
+ nIconHeight = ICON_HEIGHT + 2*TOP_OFFSET + 1;
+ if ( m_nStdHeight < nIconHeight )
+ m_nStdHeight = nIconHeight;
+
+ m_nActiveHeight = m_nStdHeight;
+
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ if( IsControlBackground() )
+ SetBackground( GetControlBackground() );
+ else
+ SetBackground( rStyleSettings.GetFieldColor() );
+
+ m_xRemoveListener = new ExtensionRemovedListener( this );
+
+ m_pLocale = new lang::Locale( Application::GetSettings().GetLocale() );
+ m_pCollator = new CollatorWrapper( ::comphelper::getProcessServiceFactory() );
+ m_pCollator->loadDefaultCollator( *m_pLocale, i18n::CollatorOptions::CollatorOptions_IGNORE_CASE );
+
+ Show();
+}
+
+//------------------------------------------------------------------------------
+ExtensionBox_Impl::~ExtensionBox_Impl()
+{
+ if ( ! m_bInDelete )
+ DeleteRemoved();
+
+ m_bInDelete = true;
+
+ typedef std::vector< TEntry_Impl >::iterator ITER;
+
+ for ( ITER iIndex = m_vEntries.begin(); iIndex < m_vEntries.end(); ++iIndex )
+ {
+ if ( (*iIndex)->m_pPublisher )
+ {
+ delete (*iIndex)->m_pPublisher;
+ (*iIndex)->m_pPublisher = NULL;
+ }
+ (*iIndex)->m_xPackage->removeEventListener( uno::Reference< lang::XEventListener > ( m_xRemoveListener, uno::UNO_QUERY ) );
+ }
+
+ m_vEntries.clear();
+
+ delete m_pScrollBar;
+
+ m_xRemoveListener.clear();
+
+ delete m_pLocale;
+ delete m_pCollator;
+}
+
+//------------------------------------------------------------------------------
+sal_Int32 ExtensionBox_Impl::getItemCount() const
+{
+ return static_cast< sal_Int32 >( m_vEntries.size() );
+}
+
+//------------------------------------------------------------------------------
+sal_Int32 ExtensionBox_Impl::getSelIndex() const
+{
+ if ( m_bHasActive )
+ {
+ OSL_ASSERT( m_nActive >= -1);
+ return static_cast< sal_Int32 >( m_nActive );
+ }
+ else
+ return static_cast< sal_Int32 >( EXTENSION_LISTBOX_ENTRY_NOTFOUND );
+}
+
+//------------------------------------------------------------------------------
+void ExtensionBox_Impl::checkIndex( sal_Int32 nIndex ) const
+{
+ if ( nIndex < 0 )
+ throw lang::IllegalArgumentException( OUSTR("The list index starts with 0"),0, 0 );
+ if ( static_cast< sal_uInt32 >( nIndex ) >= m_vEntries.size())
+ throw lang::IllegalArgumentException( OUSTR("There is no element at the provided position."
+ "The position exceeds the number of available list entries"),0, 0 );
+}
+
+//------------------------------------------------------------------------------
+rtl::OUString ExtensionBox_Impl::getItemName( sal_Int32 nIndex ) const
+{
+ const ::osl::MutexGuard aGuard( m_entriesMutex );
+ checkIndex( nIndex );
+ return m_vEntries[ nIndex ]->m_sTitle;
+}
+
+//------------------------------------------------------------------------------
+rtl::OUString ExtensionBox_Impl::getItemVersion( sal_Int32 nIndex ) const
+{
+ const ::osl::MutexGuard aGuard( m_entriesMutex );
+ checkIndex( nIndex );
+ return m_vEntries[ nIndex ]->m_sVersion;
+}
+
+//------------------------------------------------------------------------------
+rtl::OUString ExtensionBox_Impl::getItemDescription( sal_Int32 nIndex ) const
+{
+ const ::osl::MutexGuard aGuard( m_entriesMutex );
+ checkIndex( nIndex );
+ return m_vEntries[ nIndex ]->m_sDescription;
+}
+
+//------------------------------------------------------------------------------
+rtl::OUString ExtensionBox_Impl::getItemPublisher( sal_Int32 nIndex ) const
+{
+ const ::osl::MutexGuard aGuard( m_entriesMutex );
+ checkIndex( nIndex );
+ return m_vEntries[ nIndex ]->m_sPublisher;
+}
+
+//------------------------------------------------------------------------------
+rtl::OUString ExtensionBox_Impl::getItemPublisherLink( sal_Int32 nIndex ) const
+{
+ const ::osl::MutexGuard aGuard( m_entriesMutex );
+ checkIndex( nIndex );
+ return m_vEntries[ nIndex ]->m_sPublisherURL;
+}
+
+//------------------------------------------------------------------------------
+void ExtensionBox_Impl::select( sal_Int32 nIndex )
+{
+ const ::osl::MutexGuard aGuard( m_entriesMutex );
+ checkIndex( nIndex );
+ selectEntry( nIndex );
+}
+
+//------------------------------------------------------------------------------
+void ExtensionBox_Impl::select( const rtl::OUString & sName )
+{
+ const ::osl::MutexGuard aGuard( m_entriesMutex );
+ typedef ::std::vector< TEntry_Impl >::const_iterator It;
+
+ for ( It iIter = m_vEntries.begin(); iIter < m_vEntries.end(); iIter++ )
+ {
+ if ( sName.equals( (*iIter)->m_sTitle ) )
+ {
+ long nPos = iIter - m_vEntries.begin();
+ selectEntry( nPos );
+ break;
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+// Title + description
+void ExtensionBox_Impl::CalcActiveHeight( const long nPos )
+{
+ const ::osl::MutexGuard aGuard( m_entriesMutex );
+
+ // get title height
+ long aTextHeight;
+ long nIconHeight = 2*TOP_OFFSET + SMALL_ICON_SIZE;
+ long nTitleHeight = 2*TOP_OFFSET + GetTextHeight();
+ if ( nIconHeight < nTitleHeight )
+ aTextHeight = nTitleHeight;
+ else
+ aTextHeight = nIconHeight;
+
+ // calc description height
+ Size aSize = GetOutputSizePixel();
+ if ( m_bHasScrollBar )
+ aSize.Width() -= m_pScrollBar->GetSizePixel().Width();
+
+ aSize.Width() -= ICON_OFFSET;
+ aSize.Height() = 10000;
+
+ rtl::OUString aText( m_vEntries[ nPos ]->m_sErrorText );
+ if ( aText.getLength() )
+ aText += OUSTR("\n");
+ aText += m_vEntries[ nPos ]->m_sDescription;
+
+ Rectangle aRect = GetTextRect( Rectangle( Point(), aSize ), aText,
+ TEXT_DRAW_MULTILINE | TEXT_DRAW_WORDBREAK );
+ aTextHeight += aRect.GetHeight();
+
+ if ( aTextHeight < m_nStdHeight )
+ aTextHeight = m_nStdHeight;
+
+ if ( m_vEntries[ nPos ]->m_bHasButtons )
+ m_nActiveHeight = aTextHeight + m_nExtraHeight;
+ else
+ m_nActiveHeight = aTextHeight + 2;
+}
+
+//------------------------------------------------------------------------------
+const Size ExtensionBox_Impl::GetMinOutputSizePixel() const
+{
+ return Size( 200, 80 );
+}
+
+//------------------------------------------------------------------------------
+Rectangle ExtensionBox_Impl::GetEntryRect( const long nPos ) const
+{
+ const ::osl::MutexGuard aGuard( m_entriesMutex );
+
+ Size aSize( GetOutputSizePixel() );
+
+ if ( m_bHasScrollBar )
+ aSize.Width() -= m_pScrollBar->GetSizePixel().Width();
+
+ if ( m_vEntries[ nPos ]->m_bActive )
+ aSize.Height() = m_nActiveHeight;
+ else
+ aSize.Height() = m_nStdHeight;
+
+ Point aPos( 0, -m_nTopIndex + nPos * m_nStdHeight );
+ if ( m_bHasActive && ( nPos < m_nActive ) )
+ aPos.Y() += m_nActiveHeight - m_nStdHeight;
+
+ return Rectangle( aPos, aSize );
+}
+
+//------------------------------------------------------------------------------
+void ExtensionBox_Impl::DeleteRemoved()
+{
+ const ::osl::MutexGuard aGuard( m_entriesMutex );
+
+ m_bInDelete = true;
+
+ if ( ! m_vRemovedEntries.empty() )
+ {
+ typedef std::vector< TEntry_Impl >::iterator ITER;
+
+ for ( ITER iIndex = m_vRemovedEntries.begin(); iIndex < m_vRemovedEntries.end(); ++iIndex )
+ {
+ if ( (*iIndex)->m_pPublisher )
+ {
+ delete (*iIndex)->m_pPublisher;
+ (*iIndex)->m_pPublisher = NULL;
+ }
+ }
+
+ m_vRemovedEntries.clear();
+ }
+
+ m_bInDelete = false;
+}
+
+//------------------------------------------------------------------------------
+//This function may be called with nPos < 0
+void ExtensionBox_Impl::selectEntry( const long nPos )
+{
+ //ToDo whe should not use the guard at such a big scope here.
+ //Currently it is used to gard m_vEntries and m_nActive. m_nActive will be
+ //modified in this function.
+ //It would be probably best to always use a copy of m_vEntries
+ //and some other state variables from ExtensionBox_Impl for
+ //the whole painting operation. See issue i86993
+ ::osl::ClearableMutexGuard guard(m_entriesMutex);
+
+ if ( m_bInCheckMode )
+ return;
+
+ if ( m_bHasActive )
+ {
+ if ( nPos == m_nActive )
+ return;
+
+ m_bHasActive = false;
+ m_vEntries[ m_nActive ]->m_bActive = false;
+ }
+
+ if ( ( nPos >= 0 ) && ( nPos < (long) m_vEntries.size() ) )
+ {
+ m_bHasActive = true;
+ m_nActive = nPos;
+ m_vEntries[ nPos ]->m_bActive = true;
+
+ if ( IsReallyVisible() )
+ {
+ m_bAdjustActive = true;
+ }
+ }
+
+ if ( IsReallyVisible() )
+ {
+ m_bNeedsRecalc = true;
+ Invalidate();
+ }
+
+ guard.clear();
+}
+
+// -----------------------------------------------------------------------
+void ExtensionBox_Impl::DrawRow( const Rectangle& rRect, const TEntry_Impl pEntry )
+{
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+
+ if ( pEntry->m_bActive )
+ SetTextColor( rStyleSettings.GetHighlightTextColor() );
+ else if ( ( pEntry->m_eState != REGISTERED ) && ( pEntry->m_eState != NOT_AVAILABLE ) )
+ SetTextColor( rStyleSettings.GetDisableColor() );
+ else if ( IsControlForeground() )
+ SetTextColor( GetControlForeground() );
+ else
+ SetTextColor( rStyleSettings.GetFieldTextColor() );
+
+ if ( pEntry->m_bActive )
+ {
+ SetLineColor();
+ SetFillColor( rStyleSettings.GetHighlightColor() );
+ DrawRect( rRect );
+ }
+ else
+ {
+ if( IsControlBackground() )
+ SetBackground( GetControlBackground() );
+ else
+ SetBackground( rStyleSettings.GetFieldColor() );
+
+ SetTextFillColor();
+ Erase( rRect );
+ }
+
+ // Draw extension icon
+ Point aPos( rRect.TopLeft() );
+ aPos += Point( TOP_OFFSET, TOP_OFFSET );
+ Image aImage;
+ if ( ! pEntry->m_aIcon )
+ aImage = m_aDefaultImage;
+ else
+ aImage = pEntry->m_aIcon;
+ Size aImageSize = aImage.GetSizePixel();
+ if ( ( aImageSize.Width() <= ICON_WIDTH ) && ( aImageSize.Height() <= ICON_HEIGHT ) )
+ DrawImage( Point( aPos.X()+((ICON_WIDTH-aImageSize.Width())/2), aPos.Y()+((ICON_HEIGHT-aImageSize.Height())/2) ), aImage );
+ else
+ DrawImage( aPos, Size( ICON_WIDTH, ICON_HEIGHT ), aImage );
+
+ // Setup fonts
+ Font aStdFont( GetFont() );
+ Font aBoldFont( aStdFont );
+ aBoldFont.SetWeight( WEIGHT_BOLD );
+ SetFont( aBoldFont );
+ long aTextHeight = GetTextHeight();
+
+ // Init publisher link here
+ if ( !pEntry->m_pPublisher && pEntry->m_sPublisher.Len() )
+ {
+ pEntry->m_pPublisher = new svt::FixedHyperlink( this );
+ pEntry->m_pPublisher->SetBackground();
+ pEntry->m_pPublisher->SetPaintTransparent( true );
+ pEntry->m_pPublisher->SetURL( pEntry->m_sPublisherURL );
+ pEntry->m_pPublisher->SetDescription( pEntry->m_sPublisher );
+ Size aSize = FixedText::CalcMinimumTextSize( pEntry->m_pPublisher );
+ pEntry->m_pPublisher->SetSizePixel( aSize );
+
+ if ( m_aClickHdl.IsSet() )
+ pEntry->m_pPublisher->SetClickHdl( m_aClickHdl );
+ }
+
+ // Get max title width
+ long nMaxTitleWidth = rRect.GetWidth() - ICON_OFFSET;
+ nMaxTitleWidth -= ( 2 * SMALL_ICON_SIZE ) + ( 4 * SPACE_BETWEEN );
+ if ( pEntry->m_pPublisher )
+ {
+ nMaxTitleWidth -= pEntry->m_pPublisher->GetSizePixel().Width() + (2*SPACE_BETWEEN);
+ }
+
+ long aVersionWidth = GetTextWidth( pEntry->m_sVersion );
+ long aTitleWidth = GetTextWidth( pEntry->m_sTitle ) + (aTextHeight / 3);
+
+ aPos = rRect.TopLeft() + Point( ICON_OFFSET, TOP_OFFSET );
+
+ if ( aTitleWidth > nMaxTitleWidth - aVersionWidth )
+ {
+ aTitleWidth = nMaxTitleWidth - aVersionWidth - (aTextHeight / 3);
+ String aShortTitle = GetEllipsisString( pEntry->m_sTitle, aTitleWidth );
+ DrawText( aPos, aShortTitle );
+ aTitleWidth += (aTextHeight / 3);
+ }
+ else
+ DrawText( aPos, pEntry->m_sTitle );
+
+ SetFont( aStdFont );
+ DrawText( Point( aPos.X() + aTitleWidth, aPos.Y() ), pEntry->m_sVersion );
+
+ long nIconHeight = TOP_OFFSET + SMALL_ICON_SIZE;
+ long nTitleHeight = TOP_OFFSET + GetTextHeight();
+ if ( nIconHeight < nTitleHeight )
+ aTextHeight = nTitleHeight;
+ else
+ aTextHeight = nIconHeight;
+
+ // draw description
+ String sDescription;
+ if ( pEntry->m_sErrorText.Len() )
+ {
+ if ( pEntry->m_bActive )
+ sDescription = pEntry->m_sErrorText + OUSTR("\n") + pEntry->m_sDescription;
+ else
+ sDescription = pEntry->m_sErrorText;
+ }
+ else
+ sDescription = pEntry->m_sDescription;
+
+ aPos.Y() += aTextHeight;
+ if ( pEntry->m_bActive )
+ {
+ long nExtraHeight = 0;
+
+ if ( pEntry->m_bHasButtons )
+ nExtraHeight = m_nExtraHeight;
+
+ DrawText( Rectangle( aPos.X(), aPos.Y(), rRect.Right(), rRect.Bottom() - nExtraHeight ),
+ sDescription, TEXT_DRAW_MULTILINE | TEXT_DRAW_WORDBREAK );
+ }
+ else
+ {
+ const long nWidth = GetTextWidth( sDescription );
+ if ( nWidth > rRect.GetWidth() - aPos.X() )
+ sDescription = GetEllipsisString( sDescription, rRect.GetWidth() - aPos.X() );
+ DrawText( aPos, sDescription );
+ }
+
+ // Draw publisher link
+ if ( pEntry->m_pPublisher )
+ {
+ pEntry->m_pPublisher->Show();
+ aPos = rRect.TopLeft() + Point( ICON_OFFSET + nMaxTitleWidth + (2*SPACE_BETWEEN), TOP_OFFSET );
+ pEntry->m_pPublisher->SetPosPixel( aPos );
+ }
+
+ // Draw status icons
+ if ( !pEntry->m_bUser )
+ {
+ aPos = rRect.TopRight() + Point( -(RIGHT_ICON_OFFSET + SMALL_ICON_SIZE), TOP_OFFSET );
+ if ( pEntry->m_bLocked )
+ DrawImage( aPos, Size( SMALL_ICON_SIZE, SMALL_ICON_SIZE ), m_aLockedImage );
+ else
+ DrawImage( aPos, Size( SMALL_ICON_SIZE, SMALL_ICON_SIZE ), m_aSharedImage );
+ }
+ if ( ( pEntry->m_eState == AMBIGUOUS ) || pEntry->m_bMissingDeps || pEntry->m_bMissingLic )
+ {
+ aPos = rRect.TopRight() + Point( -(RIGHT_ICON_OFFSET + SPACE_BETWEEN + 2*SMALL_ICON_SIZE), TOP_OFFSET );
+ DrawImage( aPos, Size( SMALL_ICON_SIZE, SMALL_ICON_SIZE ), m_aWarningImage );
+ }
+
+ SetLineColor( Color( COL_LIGHTGRAY ) );
+ DrawLine( rRect.BottomLeft(), rRect.BottomRight() );
+}
+
+// -----------------------------------------------------------------------
+void ExtensionBox_Impl::RecalcAll()
+{
+ if ( m_bHasActive )
+ CalcActiveHeight( m_nActive );
+
+ SetupScrollBar();
+
+ if ( m_bHasActive )
+ {
+ Rectangle aEntryRect = GetEntryRect( m_nActive );
+
+ if ( m_bAdjustActive )
+ {
+ m_bAdjustActive = false;
+
+ // If the top of the selected entry isn't visible, make it visible
+ if ( aEntryRect.Top() < 0 )
+ {
+ m_nTopIndex += aEntryRect.Top();
+ aEntryRect.Move( 0, -aEntryRect.Top() );
+ }
+
+ // If the bottom of the selected entry isn't visible, make it visible even if now the top
+ // isn't visible any longer ( the buttons are more important )
+ Size aOutputSize = GetOutputSizePixel();
+ if ( aEntryRect.Bottom() > aOutputSize.Height() )
+ {
+ m_nTopIndex += ( aEntryRect.Bottom() - aOutputSize.Height() );
+ aEntryRect.Move( 0, -( aEntryRect.Bottom() - aOutputSize.Height() ) );
+ }
+
+ // If there is unused space below the last entry but all entries don't fit into the box,
+ // move the content down to use the whole space
+ const long nTotalHeight = GetTotalHeight();
+ if ( m_bHasScrollBar && ( aOutputSize.Height() + m_nTopIndex > nTotalHeight ) )
+ {
+ long nOffset = m_nTopIndex;
+ m_nTopIndex = nTotalHeight - aOutputSize.Height();
+ nOffset -= m_nTopIndex;
+ aEntryRect.Move( 0, nOffset );
+ }
+
+ if ( m_bHasScrollBar )
+ m_pScrollBar->SetThumbPos( m_nTopIndex );
+ }
+ }
+
+ m_bNeedsRecalc = false;
+}
+
+// -----------------------------------------------------------------------
+bool ExtensionBox_Impl::HandleTabKey( bool )
+{
+ return false;
+}
+
+// -----------------------------------------------------------------------
+bool ExtensionBox_Impl::HandleCursorKey( sal_uInt16 nKeyCode )
+{
+ if ( m_vEntries.empty() )
+ return true;
+
+ long nSelect = 0;
+
+ if ( m_bHasActive )
+ {
+ long nPageSize = GetOutputSizePixel().Height() / m_nStdHeight;
+ if ( nPageSize < 2 )
+ nPageSize = 2;
+
+ if ( ( nKeyCode == KEY_DOWN ) || ( nKeyCode == KEY_RIGHT ) )
+ nSelect = m_nActive + 1;
+ else if ( ( nKeyCode == KEY_UP ) || ( nKeyCode == KEY_LEFT ) )
+ nSelect = m_nActive - 1;
+ else if ( nKeyCode == KEY_HOME )
+ nSelect = 0;
+ else if ( nKeyCode == KEY_END )
+ nSelect = m_vEntries.size() - 1;
+ else if ( nKeyCode == KEY_PAGEUP )
+ nSelect = m_nActive - nPageSize + 1;
+ else if ( nKeyCode == KEY_PAGEDOWN )
+ nSelect = m_nActive + nPageSize - 1;
+ }
+ else // when there is no selected entry, we will select the first or the last.
+ {
+ if ( ( nKeyCode == KEY_DOWN ) || ( nKeyCode == KEY_PAGEDOWN ) || ( nKeyCode == KEY_HOME ) )
+ nSelect = 0;
+ else if ( ( nKeyCode == KEY_UP ) || ( nKeyCode == KEY_PAGEUP ) || ( nKeyCode == KEY_END ) )
+ nSelect = m_vEntries.size() - 1;
+ }
+
+ if ( nSelect < 0 )
+ nSelect = 0;
+ if ( nSelect >= (long) m_vEntries.size() )
+ nSelect = m_vEntries.size() - 1;
+
+ selectEntry( nSelect );
+
+ return true;
+}
+
+// -----------------------------------------------------------------------
+void ExtensionBox_Impl::Paint( const Rectangle &/*rPaintRect*/ )
+{
+ if ( !m_bInDelete )
+ DeleteRemoved();
+
+ if ( m_bNeedsRecalc )
+ RecalcAll();
+
+ Point aStart( 0, -m_nTopIndex );
+ Size aSize( GetOutputSizePixel() );
+
+ if ( m_bHasScrollBar )
+ aSize.Width() -= m_pScrollBar->GetSizePixel().Width();
+
+ const ::osl::MutexGuard aGuard( m_entriesMutex );
+
+ typedef std::vector< TEntry_Impl >::iterator ITER;
+ for ( ITER iIndex = m_vEntries.begin(); iIndex < m_vEntries.end(); ++iIndex )
+ {
+ aSize.Height() = (*iIndex)->m_bActive ? m_nActiveHeight : m_nStdHeight;
+ Rectangle aEntryRect( aStart, aSize );
+ DrawRow( aEntryRect, *iIndex );
+ aStart.Y() += aSize.Height();
+ }
+}
+
+// -----------------------------------------------------------------------
+long ExtensionBox_Impl::GetTotalHeight() const
+{
+ long nHeight = m_vEntries.size() * m_nStdHeight;
+
+ if ( m_bHasActive )
+ {
+ nHeight += m_nActiveHeight - m_nStdHeight;
+ }
+
+ return nHeight;
+}
+
+// -----------------------------------------------------------------------
+void ExtensionBox_Impl::SetupScrollBar()
+{
+ const Size aSize = GetOutputSizePixel();
+ const long nScrBarSize = GetSettings().GetStyleSettings().GetScrollBarSize();
+ const long nTotalHeight = GetTotalHeight();
+ const bool bNeedsScrollBar = ( nTotalHeight > aSize.Height() );
+
+ if ( bNeedsScrollBar )
+ {
+ if ( m_nTopIndex + aSize.Height() > nTotalHeight )
+ m_nTopIndex = nTotalHeight - aSize.Height();
+
+ m_pScrollBar->SetPosSizePixel( Point( aSize.Width() - nScrBarSize, 0 ),
+ Size( nScrBarSize, aSize.Height() ) );
+ m_pScrollBar->SetRangeMax( nTotalHeight );
+ m_pScrollBar->SetVisibleSize( aSize.Height() );
+ m_pScrollBar->SetPageSize( ( aSize.Height() * 4 ) / 5 );
+ m_pScrollBar->SetLineSize( m_nStdHeight );
+ m_pScrollBar->SetThumbPos( m_nTopIndex );
+
+ if ( !m_bHasScrollBar )
+ m_pScrollBar->Show();
+ }
+ else if ( m_bHasScrollBar )
+ {
+ m_pScrollBar->Hide();
+ m_nTopIndex = 0;
+ }
+
+ m_bHasScrollBar = bNeedsScrollBar;
+}
+
+// -----------------------------------------------------------------------
+void ExtensionBox_Impl::Resize()
+{
+ RecalcAll();
+}
+
+//------------------------------------------------------------------------------
+long ExtensionBox_Impl::PointToPos( const Point& rPos )
+{
+ long nPos = ( rPos.Y() + m_nTopIndex ) / m_nStdHeight;
+
+ if ( m_bHasActive && ( nPos > m_nActive ) )
+ {
+ if ( rPos.Y() + m_nTopIndex <= m_nActive*m_nStdHeight + m_nActiveHeight )
+ nPos = m_nActive;
+ else
+ nPos = ( rPos.Y() + m_nTopIndex - (m_nActiveHeight - m_nStdHeight) ) / m_nStdHeight;
+ }
+
+ return nPos;
+}
+
+//------------------------------------------------------------------------------
+void ExtensionBox_Impl::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ long nPos = PointToPos( rMEvt.GetPosPixel() );
+
+ if ( rMEvt.IsLeft() )
+ {
+ if ( rMEvt.IsMod1() && m_bHasActive )
+ selectEntry( m_vEntries.size() ); // Selecting an not existing entry will deselect the current one
+ else
+ selectEntry( nPos );
+ }
+}
+
+//------------------------------------------------------------------------------
+long ExtensionBox_Impl::Notify( NotifyEvent& rNEvt )
+{
+ if ( !m_bInDelete )
+ DeleteRemoved();
+
+ bool bHandled = false;
+
+ if ( rNEvt.GetType() == EVENT_KEYINPUT )
+ {
+ const KeyEvent* pKEvt = rNEvt.GetKeyEvent();
+ KeyCode aKeyCode = pKEvt->GetKeyCode();
+ sal_uInt16 nKeyCode = aKeyCode.GetCode();
+
+ if ( nKeyCode == KEY_TAB )
+ bHandled = HandleTabKey( aKeyCode.IsShift() );
+ else if ( aKeyCode.GetGroup() == KEYGROUP_CURSOR )
+ bHandled = HandleCursorKey( nKeyCode );
+ }
+
+ if ( rNEvt.GetType() == EVENT_COMMAND )
+ {
+ if ( m_bHasScrollBar &&
+ ( rNEvt.GetCommandEvent()->GetCommand() == COMMAND_WHEEL ) )
+ {
+ const CommandWheelData* pData = rNEvt.GetCommandEvent()->GetWheelData();
+ if ( pData->GetMode() == COMMAND_WHEEL_SCROLL )
+ {
+ long nThumbPos = m_pScrollBar->GetThumbPos();
+ if ( pData->GetDelta() < 0 )
+ m_pScrollBar->DoScroll( nThumbPos + m_nStdHeight );
+ else
+ m_pScrollBar->DoScroll( nThumbPos - m_nStdHeight );
+ bHandled = true;
+ }
+ }
+ }
+
+ if ( !bHandled )
+ return Control::Notify( rNEvt );
+ else
+ return true;
+}
+
+//------------------------------------------------------------------------------
+bool ExtensionBox_Impl::FindEntryPos( const TEntry_Impl pEntry, const long nStart,
+ const long nEnd, long &nPos )
+{
+ nPos = nStart;
+ if ( nStart > nEnd )
+ return false;
+
+ StringCompare eCompare;
+
+ if ( nStart == nEnd )
+ {
+ eCompare = pEntry->CompareTo( m_pCollator, m_vEntries[ nStart ] );
+ if ( eCompare == COMPARE_LESS )
+ return false;
+ else if ( eCompare == COMPARE_EQUAL )
+ {
+ //Workaround. See i86963.
+ if (pEntry->m_xPackage != m_vEntries[nStart]->m_xPackage)
+ return false;
+
+ if ( m_bInCheckMode )
+ m_vEntries[ nStart ]->m_bChecked = true;
+ return true;
+ }
+ else
+ {
+ nPos = nStart + 1;
+ return false;
+ }
+ }
+
+ const long nMid = nStart + ( ( nEnd - nStart ) / 2 );
+ eCompare = pEntry->CompareTo( m_pCollator, m_vEntries[ nMid ] );
+
+ if ( eCompare == COMPARE_LESS )
+ return FindEntryPos( pEntry, nStart, nMid-1, nPos );
+ else if ( eCompare == COMPARE_GREATER )
+ return FindEntryPos( pEntry, nMid+1, nEnd, nPos );
+ else
+ {
+ //Workaround.See i86963.
+ if (pEntry->m_xPackage != m_vEntries[nMid]->m_xPackage)
+ return false;
+
+ if ( m_bInCheckMode )
+ m_vEntries[ nMid ]->m_bChecked = true;
+ nPos = nMid;
+ return true;
+ }
+}
+
+//------------------------------------------------------------------------------
+long ExtensionBox_Impl::addEntry( const uno::Reference< deployment::XPackage > &xPackage,
+ bool bLicenseMissing )
+{
+ long nPos = 0;
+ PackageState eState = m_pManager->getPackageState( xPackage );
+ bool bLocked = m_pManager->isReadOnly( xPackage );
+
+ TEntry_Impl pEntry( new Entry_Impl( xPackage, eState, bLocked ) );
+
+ // Don't add empty entries
+ if ( ! pEntry->m_sTitle.Len() )
+ return 0;
+
+ xPackage->addEventListener( uno::Reference< lang::XEventListener > ( m_xRemoveListener, uno::UNO_QUERY ) );
+
+ ::osl::ClearableMutexGuard guard(m_entriesMutex);
+ if ( m_vEntries.empty() )
+ {
+ m_vEntries.push_back( pEntry );
+ }
+ else
+ {
+ if ( !FindEntryPos( pEntry, 0, m_vEntries.size()-1, nPos ) )
+ {
+ m_vEntries.insert( m_vEntries.begin()+nPos, pEntry );
+ }
+ else if ( !m_bInCheckMode )
+ {
+ OSL_FAIL( "ExtensionBox_Impl::addEntry(): Will not add duplicate entries" );
+ }
+ }
+
+ pEntry->m_bHasOptions = m_pManager->supportsOptions( xPackage );
+ pEntry->m_bUser = xPackage->getRepositoryName().equals( USER_PACKAGE_MANAGER );
+ pEntry->m_bShared = xPackage->getRepositoryName().equals( SHARED_PACKAGE_MANAGER );
+ pEntry->m_bNew = m_bInCheckMode;
+ pEntry->m_bMissingLic = bLicenseMissing;
+
+ if ( bLicenseMissing )
+ pEntry->m_sErrorText = DialogHelper::getResourceString( RID_STR_ERROR_MISSING_LICENSE );
+
+ //access to m_nActive must be guarded
+ if ( !m_bInCheckMode && m_bHasActive && ( m_nActive >= nPos ) )
+ m_nActive += 1;
+
+ guard.clear();
+
+ if ( IsReallyVisible() )
+ Invalidate();
+
+ m_bNeedsRecalc = true;
+
+ return nPos;
+}
+
+//------------------------------------------------------------------------------
+void ExtensionBox_Impl::updateEntry( const uno::Reference< deployment::XPackage > &xPackage )
+{
+ typedef std::vector< TEntry_Impl >::iterator ITER;
+ for ( ITER iIndex = m_vEntries.begin(); iIndex < m_vEntries.end(); ++iIndex )
+ {
+ if ( (*iIndex)->m_xPackage == xPackage )
+ {
+ PackageState eState = m_pManager->getPackageState( xPackage );
+ (*iIndex)->m_bHasOptions = m_pManager->supportsOptions( xPackage );
+ (*iIndex)->m_eState = eState;
+ (*iIndex)->m_sTitle = xPackage->getDisplayName();
+ (*iIndex)->m_sVersion = xPackage->getVersion();
+ (*iIndex)->m_sDescription = xPackage->getDescription();
+
+ if ( eState == REGISTERED )
+ (*iIndex)->m_bMissingLic = false;
+
+ if ( eState == AMBIGUOUS )
+ (*iIndex)->m_sErrorText = DialogHelper::getResourceString( RID_STR_ERROR_UNKNOWN_STATUS );
+ else if ( ! (*iIndex)->m_bMissingLic )
+ (*iIndex)->m_sErrorText = String();
+
+ if ( IsReallyVisible() )
+ Invalidate();
+ break;
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+void ExtensionBox_Impl::removeEntry( const uno::Reference< deployment::XPackage > &xPackage )
+{
+ if ( ! m_bInDelete )
+ {
+ ::osl::ClearableMutexGuard aGuard( m_entriesMutex );
+
+ typedef std::vector< TEntry_Impl >::iterator ITER;
+
+ for ( ITER iIndex = m_vEntries.begin(); iIndex < m_vEntries.end(); ++iIndex )
+ {
+ if ( (*iIndex)->m_xPackage == xPackage )
+ {
+ long nPos = iIndex - m_vEntries.begin();
+
+ // Entries mustn't removed here, because they contain a hyperlink control
+ // which can only be deleted when the thread has the solar mutex. Therefor
+ // the entry will be moved into the m_vRemovedEntries list which will be
+ // cleared on the next paint event
+ m_vRemovedEntries.push_back( *iIndex );
+ m_vEntries.erase( iIndex );
+
+ m_bNeedsRecalc = true;
+
+ if ( IsReallyVisible() )
+ Invalidate();
+
+ if ( m_bHasActive )
+ {
+ if ( nPos < m_nActive )
+ m_nActive -= 1;
+ else if ( ( nPos == m_nActive ) &&
+ ( nPos == (long) m_vEntries.size() ) )
+ m_nActive -= 1;
+
+ m_bHasActive = false;
+ //clear before calling out of this method
+ aGuard.clear();
+ selectEntry( m_nActive );
+ }
+ break;
+ }
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+void ExtensionBox_Impl::RemoveUnlocked()
+{
+ bool bAllRemoved = false;
+
+ while ( ! bAllRemoved )
+ {
+ bAllRemoved = true;
+
+ ::osl::ClearableMutexGuard aGuard( m_entriesMutex );
+
+ typedef std::vector< TEntry_Impl >::iterator ITER;
+
+ for ( ITER iIndex = m_vEntries.begin(); iIndex < m_vEntries.end(); ++iIndex )
+ {
+ if ( !(*iIndex)->m_bLocked )
+ {
+ bAllRemoved = false;
+ uno::Reference< deployment::XPackage> xPackage = (*iIndex)->m_xPackage;
+ aGuard.clear();
+ removeEntry( xPackage );
+ break;
+ }
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+void ExtensionBox_Impl::prepareChecking()
+{
+ m_bInCheckMode = true;
+ typedef std::vector< TEntry_Impl >::iterator ITER;
+ for ( ITER iIndex = m_vEntries.begin(); iIndex < m_vEntries.end(); ++iIndex )
+ {
+ (*iIndex)->m_bChecked = false;
+ (*iIndex)->m_bNew = false;
+ }
+}
+
+//------------------------------------------------------------------------------
+void ExtensionBox_Impl::checkEntries()
+{
+ long nNewPos = -1;
+ long nPos = 0;
+ bool bNeedsUpdate = false;
+
+ ::osl::ClearableMutexGuard guard(m_entriesMutex);
+ typedef std::vector< TEntry_Impl >::iterator ITER;
+ ITER iIndex = m_vEntries.begin();
+ while ( iIndex < m_vEntries.end() )
+ {
+ if ( (*iIndex)->m_bChecked == false )
+ {
+ (*iIndex)->m_bChecked = true;
+ bNeedsUpdate = true;
+ nPos = iIndex-m_vEntries.begin();
+ if ( (*iIndex)->m_bNew )
+ { // add entry to list and correct active pos
+ if ( nNewPos == - 1)
+ nNewPos = nPos;
+ if ( nPos <= m_nActive )
+ m_nActive += 1;
+ ++iIndex;
+ }
+ else
+ { // remove entry from list
+ if ( nPos < m_nActive )
+ m_nActive -= 1;
+ else if ( ( nPos == m_nActive ) && ( nPos == (long) m_vEntries.size() - 1 ) )
+ m_nActive -= 1;
+ m_vRemovedEntries.push_back( *iIndex );
+ m_vEntries.erase( iIndex );
+ iIndex = m_vEntries.begin() + nPos;
+ }
+ }
+ else
+ ++iIndex;
+ }
+ guard.clear();
+
+ m_bInCheckMode = false;
+
+ if ( nNewPos != - 1)
+ selectEntry( nNewPos );
+
+ if ( bNeedsUpdate )
+ {
+ m_bNeedsRecalc = true;
+ if ( IsReallyVisible() )
+ Invalidate();
+ }
+}
+
+//------------------------------------------------------------------------------
+void ExtensionBox_Impl::SetScrollHdl( const Link& rLink )
+{
+ if ( m_pScrollBar )
+ m_pScrollBar->SetScrollHdl( rLink );
+}
+
+// -----------------------------------------------------------------------
+void ExtensionBox_Impl::DoScroll( long nDelta )
+{
+ m_nTopIndex += nDelta;
+ Point aNewSBPt( m_pScrollBar->GetPosPixel() );
+
+ Rectangle aScrRect( Point(), GetOutputSizePixel() );
+ aScrRect.Right() -= m_pScrollBar->GetSizePixel().Width();
+ Scroll( 0, -nDelta, aScrRect );
+
+ m_pScrollBar->SetPosPixel( aNewSBPt );
+}
+
+// -----------------------------------------------------------------------
+IMPL_LINK( ExtensionBox_Impl, ScrollHdl, ScrollBar*, pScrBar )
+{
+ DoScroll( pScrBar->GetDelta() );
+
+ return 1;
+}
+
+} //namespace dp_gui
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/gui/dp_gui_extlistbox.hxx b/desktop/source/deployment/gui/dp_gui_extlistbox.hxx
new file mode 100644
index 000000000000..9dbbb7d33789
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_extlistbox.hxx
@@ -0,0 +1,269 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "rtl/ustring.hxx"
+#include "vcl/scrbar.hxx"
+#include "vcl/fixed.hxx"
+#include "vcl/dialog.hxx"
+
+#include "svtools/extensionlistbox.hxx"
+#include "svtools/fixedhyper.hxx"
+#include "cppuhelper/implbase1.hxx"
+#include "unotools/collatorwrapper.hxx"
+
+#include "com/sun/star/lang/Locale.hpp"
+#include "com/sun/star/lang/XEventListener.hpp"
+#include "com/sun/star/deployment/XPackage.hpp"
+
+#include <boost/shared_ptr.hpp>
+
+namespace dp_gui {
+
+#define SMALL_ICON_SIZE 16
+#define TOP_OFFSET 5
+#define ICON_HEIGHT 42
+#define ICON_WIDTH 47
+#define ICON_OFFSET 72
+#define RIGHT_ICON_OFFSET 5
+#define SPACE_BETWEEN 3
+
+class TheExtensionManager;
+
+typedef ::boost::shared_ptr< svt::FixedHyperlink > TFixedHyperlink;
+
+//------------------------------------------------------------------------------
+// struct Entry_Impl
+//------------------------------------------------------------------------------
+struct Entry_Impl;
+
+typedef ::boost::shared_ptr< Entry_Impl > TEntry_Impl;
+
+struct Entry_Impl
+{
+ bool m_bActive :1;
+ bool m_bLocked :1;
+ bool m_bHasOptions :1;
+ bool m_bUser :1;
+ bool m_bShared :1;
+ bool m_bNew :1;
+ bool m_bChecked :1;
+ bool m_bMissingDeps :1;
+ bool m_bHasButtons :1;
+ bool m_bMissingLic :1;
+ PackageState m_eState;
+ String m_sTitle;
+ String m_sVersion;
+ String m_sDescription;
+ String m_sPublisher;
+ String m_sPublisherURL;
+ String m_sErrorText;
+ String m_sLicenseText;
+ Image m_aIcon;
+ Image m_aIconHC;
+ svt::FixedHyperlink *m_pPublisher;
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage> m_xPackage;
+
+ Entry_Impl( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &xPackage,
+ const PackageState eState, const bool bReadOnly );
+ ~Entry_Impl();
+
+ StringCompare CompareTo( const CollatorWrapper *pCollator, const TEntry_Impl pEntry ) const;
+ void checkDependencies();
+};
+
+//------------------------------------------------------------------------------
+// class ExtensionBox_Impl
+//------------------------------------------------------------------------------
+
+class ExtensionBox_Impl;
+
+//------------------------------------------------------------------------------
+class ExtensionRemovedListener : public ::cppu::WeakImplHelper1< ::com::sun::star::lang::XEventListener >
+{
+ ExtensionBox_Impl *m_pParent;
+
+public:
+
+ ExtensionRemovedListener( ExtensionBox_Impl *pParent ) { m_pParent = pParent; }
+ ~ExtensionRemovedListener();
+
+ //===================================================================================
+ // XEventListener
+ virtual void SAL_CALL disposing( ::com::sun::star::lang::EventObject const & evt )
+ throw (::com::sun::star::uno::RuntimeException);
+};
+
+//------------------------------------------------------------------------------
+class ExtensionBox_Impl : public ::svt::IExtensionListBox
+{
+ bool m_bHasScrollBar;
+ bool m_bHasActive;
+ bool m_bNeedsRecalc;
+ bool m_bHasNew;
+ bool m_bInCheckMode;
+ bool m_bAdjustActive;
+ bool m_bInDelete;
+ //Must be guarded together with m_vEntries to ensure a valid index at all times.
+ //Use m_entriesMutex as guard.
+ long m_nActive;
+ long m_nTopIndex;
+ long m_nStdHeight;
+ long m_nActiveHeight;
+ long m_nExtraHeight;
+ Size m_aOutputSize;
+ Image m_aSharedImage;
+ Image m_aLockedImage;
+ Image m_aWarningImage;
+ Image m_aDefaultImage;
+ Link m_aClickHdl;
+
+ ScrollBar *m_pScrollBar;
+
+ com::sun::star::uno::Reference< ExtensionRemovedListener > m_xRemoveListener;
+
+ TheExtensionManager *m_pManager;
+ //This mutex is used for synchronizing access to m_vEntries.
+ //Currently it is used to synchronize adding, removing entries and
+ //functions like getItemName, getItemDescription, etc. to prevent
+ //that m_vEntries is accessed at an invalid index.
+ //ToDo: There are many more places where m_vEntries is read and which may
+ //fail. For example the Paint method is probable called from the main thread
+ //while new entries are added / removed in a separate thread.
+ mutable ::osl::Mutex m_entriesMutex;
+ std::vector< TEntry_Impl > m_vEntries;
+ std::vector< TEntry_Impl > m_vRemovedEntries;
+
+ ::com::sun::star::lang::Locale *m_pLocale;
+ CollatorWrapper *m_pCollator;
+
+ void CalcActiveHeight( const long nPos );
+ long GetTotalHeight() const;
+ void SetupScrollBar();
+ void DrawRow( const Rectangle& rRect, const TEntry_Impl pEntry );
+ bool HandleTabKey( bool bReverse );
+ bool HandleCursorKey( sal_uInt16 nKeyCode );
+ bool FindEntryPos( const TEntry_Impl pEntry, long nStart, long nEnd, long &nFound );
+ void DeleteRemoved();
+
+ //-----------------
+ DECL_DLLPRIVATE_LINK( ScrollHdl, ScrollBar * );
+
+ //Index starts with 1.
+ //Throws an com::sun::star::lang::IllegalArgumentException, when the index is invalid.
+ void checkIndex(sal_Int32 pos) const;
+
+
+public:
+ ExtensionBox_Impl( Dialog* pParent, TheExtensionManager *pManager );
+ ~ExtensionBox_Impl();
+
+ virtual void MouseButtonDown( const MouseEvent& rMEvt );
+ virtual void Paint( const Rectangle &rPaintRect );
+ virtual void Resize();
+ virtual long Notify( NotifyEvent& rNEvt );
+
+ const Size GetMinOutputSizePixel() const;
+ void SetExtraSize( long nSize ) { m_nExtraHeight = nSize; }
+ TEntry_Impl GetEntryData( long nPos ) { return m_vEntries[ nPos ]; }
+ long GetEntryCount() { return (long) m_vEntries.size(); }
+ Rectangle GetEntryRect( const long nPos ) const;
+ bool HasActive() { return m_bHasActive; }
+ long PointToPos( const Point& rPos );
+ void SetScrollHdl( const Link& rLink );
+ void DoScroll( long nDelta );
+ void SetHyperlinkHdl( const Link& rLink ){ m_aClickHdl = rLink; }
+ virtual void RecalcAll();
+ void RemoveUnlocked();
+
+ //-----------------
+ virtual void selectEntry( const long nPos );
+ long addEntry( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &xPackage,
+ bool bLicenseMissing = false );
+ void updateEntry( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &xPackage );
+ void removeEntry( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &xPackage );
+
+ void prepareChecking();
+ void checkEntries();
+
+ TheExtensionManager* getExtensionManager() const { return m_pManager; }
+
+ //===================================================================================
+ //These functions are used for automatic testing
+
+ /** @return The count of the entries in the list box. */
+ virtual sal_Int32 getItemCount() const;
+
+ /** @return The index of the first selected entry in the list box.
+ When nothing is selected, which is the case when getItemCount returns '0',
+ then this function returns EXTENSION_LISTBOX_ENTRY_NOTFOUND */
+ virtual sal_Int32 getSelIndex() const;
+
+ /** @return The item name of the entry with the given index
+ The index starts with 0.
+ Throws an com::sun::star::lang::IllegalArgumentException, when the position is invalid. */
+ virtual ::rtl::OUString getItemName( sal_Int32 index ) const;
+
+ /** @return The version string of the entry with the given index
+ The index starts with 0.
+ Throws an com::sun::star::lang::IllegalArgumentException, when the position is invalid. */
+ virtual ::rtl::OUString getItemVersion( sal_Int32 index ) const;
+
+ /** @return The description string of the entry with the given index
+ The index starts with 0.
+ Throws an com::sun::star::lang::IllegalArgumentException, when the position is invalid. */
+ virtual ::rtl::OUString getItemDescription( sal_Int32 index ) const;
+
+ /** @return The publisher string of the entry with the given index
+ The index starts with 0.
+ Throws an com::sun::star::lang::IllegalArgumentException, when the position is invalid. */
+ virtual ::rtl::OUString getItemPublisher( sal_Int32 index ) const;
+
+ /** @return The link behind the publisher text of the entry with the given index
+ The index starts with 0.
+ Throws an com::sun::star::lang::IllegalArgumentException, when the position is invalid. */
+ virtual ::rtl::OUString getItemPublisherLink( sal_Int32 index ) const;
+
+ /** The entry at the given position will be selected
+ Index starts with 0.
+ Throws an com::sun::star::lang::IllegalArgumentException, when the position is invalid. */
+ virtual void select( sal_Int32 pos );
+
+ /** The first found entry with the given name will be selected
+ When there was no entry found with the name, the selection doesn't change.
+ Please note that there might be more than one entry with the same
+ name, because:
+ 1. the name is not unique
+ 2. one extension can be installed as user and shared extension.
+ */
+ virtual void select( const ::rtl::OUString & sName );
+};
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/gui/dp_gui_service.cxx b/desktop/source/deployment/gui/dp_gui_service.cxx
new file mode 100644
index 000000000000..915470108fb6
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_service.cxx
@@ -0,0 +1,371 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include "dp_gui_shared.hxx"
+#include "dp_gui.h"
+#include "dp_gui_theextmgr.hxx"
+#include "cppuhelper/implbase2.hxx"
+#include "cppuhelper/implementationentry.hxx"
+#include "unotools/configmgr.hxx"
+#include "comphelper/servicedecl.hxx"
+#include "comphelper/unwrapargs.hxx"
+#include <i18npool/mslangid.hxx>
+#include "vcl/svapp.hxx"
+#include "vcl/msgbox.hxx"
+#include "com/sun/star/lang/XServiceInfo.hpp"
+#include "com/sun/star/task/XJobExecutor.hpp"
+#include "com/sun/star/ui/dialogs/XAsynchronousExecutableDialog.hpp"
+
+#include "boost/bind.hpp"
+#include "license_dialog.hxx"
+#include "dp_gui_dialog2.hxx"
+#include "dp_gui_extensioncmdqueue.hxx"
+
+using namespace ::dp_misc;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+
+using ::rtl::OUString;
+
+namespace css = ::com::sun::star;
+namespace dp_gui {
+
+//==============================================================================
+class MyApp : public Application, private boost::noncopyable
+{
+public:
+ MyApp();
+ virtual ~MyApp();
+
+ // Application
+ virtual int Main();
+};
+
+//______________________________________________________________________________
+MyApp::~MyApp()
+{
+}
+
+//______________________________________________________________________________
+MyApp::MyApp()
+{
+}
+
+//______________________________________________________________________________
+int MyApp::Main()
+{
+ return EXIT_SUCCESS;
+}
+
+
+namespace
+{
+ struct ProductName
+ : public rtl::Static< String, ProductName > {};
+ struct Version
+ : public rtl::Static< String, Version > {};
+ struct AboutBoxVersion
+ : public rtl::Static< String, AboutBoxVersion > {};
+ struct OOOVendor
+ : public rtl::Static< String, OOOVendor > {};
+ struct Extension
+ : public rtl::Static< String, Extension > {};
+}
+
+void ReplaceProductNameHookProc( String& rStr )
+{
+ static int nAll = 0, nPro = 0;
+
+ nAll++;
+ if ( rStr.SearchAscii( "%PRODUCT" ) != STRING_NOTFOUND )
+ {
+ String &rProductName = ProductName::get();
+ String &rVersion = Version::get();
+ String &rAboutBoxVersion = AboutBoxVersion::get();
+ String &rExtension = Extension::get();
+ String &rOOOVendor = OOOVendor::get();
+
+ if ( !rProductName.Len() )
+ {
+ rtl::OUString aTmp;
+ Any aRet = ::utl::ConfigManager::GetDirectConfigProperty( ::utl::ConfigManager::PRODUCTNAME );
+ aRet >>= aTmp;
+ rProductName = aTmp;
+
+ aRet = ::utl::ConfigManager::GetDirectConfigProperty( ::utl::ConfigManager::PRODUCTVERSION );
+ aRet >>= aTmp;
+ rVersion = aTmp;
+
+ aRet = ::utl::ConfigManager::GetDirectConfigProperty( ::utl::ConfigManager::ABOUTBOXPRODUCTVERSION );
+ aRet >>= aTmp;
+ rAboutBoxVersion = aTmp;
+
+ aRet = ::utl::ConfigManager::GetDirectConfigProperty( ::utl::ConfigManager::OOOVENDOR );
+ aRet >>= aTmp;
+ rOOOVendor = aTmp;
+
+ if ( !rExtension.Len() )
+ {
+ aRet = ::utl::ConfigManager::GetDirectConfigProperty( ::utl::ConfigManager::PRODUCTEXTENSION );
+ aRet >>= aTmp;
+ rExtension = aTmp;
+ }
+ }
+
+ nPro++;
+ rStr.SearchAndReplaceAllAscii( "%PRODUCTNAME", rProductName );
+ rStr.SearchAndReplaceAllAscii( "%PRODUCTVERSION", rVersion );
+ rStr.SearchAndReplaceAllAscii( "%ABOUTBOXPRODUCTVERSION", rAboutBoxVersion );
+ rStr.SearchAndReplaceAllAscii( "%OOOVENDOR", rOOOVendor );
+ rStr.SearchAndReplaceAllAscii( "%PRODUCTEXTENSION", rExtension );
+ }
+}
+
+//==============================================================================
+class ServiceImpl
+ : public ::cppu::WeakImplHelper2<ui::dialogs::XAsynchronousExecutableDialog,
+ task::XJobExecutor>
+{
+ Reference<XComponentContext> const m_xComponentContext;
+ boost::optional< Reference<awt::XWindow> > /* const */ m_parent;
+ boost::optional<OUString> /* const */ m_view;
+ /* if true then this service is running in an unopkg process and not in an office process */
+ boost::optional<sal_Bool> /* const */ m_unopkg;
+ boost::optional<OUString> m_extensionURL;
+ OUString m_initialTitle;
+ bool m_bShowUpdateOnly;
+
+public:
+ ServiceImpl( Sequence<Any> const & args,
+ Reference<XComponentContext> const & xComponentContext );
+
+ // XAsynchronousExecutableDialog
+ virtual void SAL_CALL setDialogTitle( OUString const & aTitle )
+ throw (RuntimeException);
+ virtual void SAL_CALL startExecuteModal(
+ Reference< ui::dialogs::XDialogClosedListener > const & xListener )
+ throw (RuntimeException);
+
+ // XJobExecutor
+ virtual void SAL_CALL trigger( OUString const & event )
+ throw (RuntimeException);
+};
+
+//______________________________________________________________________________
+ServiceImpl::ServiceImpl( Sequence<Any> const& args,
+ Reference<XComponentContext> const& xComponentContext)
+ : m_xComponentContext(xComponentContext),
+ m_bShowUpdateOnly( false )
+{
+ try {
+ comphelper::unwrapArgs( args, m_parent, m_view, m_unopkg );
+ return;
+ } catch (css::lang::IllegalArgumentException & ) {
+ }
+ try {
+ comphelper::unwrapArgs( args, m_extensionURL);
+ } catch (css::lang::IllegalArgumentException & ) {
+ }
+
+ ResHookProc pProc = ResMgr::GetReadStringHook();
+ if ( !pProc )
+ ResMgr::SetReadStringHook( ReplaceProductNameHookProc );
+}
+
+// XAsynchronousExecutableDialog
+//______________________________________________________________________________
+void ServiceImpl::setDialogTitle( OUString const & title )
+ throw (RuntimeException)
+{
+ if ( dp_gui::TheExtensionManager::s_ExtMgr.is() )
+ {
+ const SolarMutexGuard guard;
+ ::rtl::Reference< ::dp_gui::TheExtensionManager > dialog(
+ ::dp_gui::TheExtensionManager::get( m_xComponentContext,
+ m_parent ? *m_parent : Reference<awt::XWindow>(),
+ m_extensionURL ? *m_extensionURL : OUString() ) );
+ dialog->SetText( title );
+ }
+ else
+ m_initialTitle = title;
+}
+
+//______________________________________________________________________________
+void ServiceImpl::startExecuteModal(
+ Reference< ui::dialogs::XDialogClosedListener > const & xListener )
+ throw (RuntimeException)
+{
+ bool bCloseDialog = true; // only used if m_bShowUpdateOnly is true
+ ::std::auto_ptr<Application> app;
+ //ToDo: synchronize access to s_dialog !!!
+ if (! dp_gui::TheExtensionManager::s_ExtMgr.is())
+ {
+ const bool bAppUp = (GetpApp() != 0);
+ bool bOfficePipePresent;
+ try {
+ bOfficePipePresent = dp_misc::office_is_running();
+ }
+ catch (Exception & exc) {
+ if (bAppUp) {
+ const SolarMutexGuard guard;
+ std::auto_ptr<ErrorBox> box(
+ new ErrorBox( Application::GetActiveTopWindow(),
+ WB_OK, exc.Message ) );
+ box->Execute();
+ }
+ throw;
+ }
+
+ if (! bOfficePipePresent) {
+ OSL_ASSERT( ! bAppUp );
+ app.reset( new MyApp );
+ if (! InitVCL( Reference<lang::XMultiServiceFactory>(
+ m_xComponentContext->getServiceManager(),
+ UNO_QUERY_THROW ) ))
+ throw RuntimeException( OUSTR("Cannot initialize VCL!"),
+ static_cast<OWeakObject *>(this) );
+ AllSettings as = app->GetSettings();
+ OUString slang;
+ if (! (::utl::ConfigManager::GetDirectConfigProperty(
+ ::utl::ConfigManager::LOCALE ) >>= slang))
+ throw RuntimeException( OUSTR("Cannot determine language!"),
+ static_cast<OWeakObject *>(this) );
+ as.SetUILanguage( MsLangId::convertIsoStringToLanguage( slang ) );
+ app->SetSettings( as );
+ String sTitle = ::utl::ConfigManager::GetDirectConfigProperty(
+ ::utl::ConfigManager::PRODUCTNAME).get<OUString>()
+ + String(static_cast<sal_Unicode>(' '))
+ + ::utl::ConfigManager::GetDirectConfigProperty(
+ ::utl::ConfigManager::PRODUCTVERSION).get<OUString>();
+ app->SetDisplayName(sTitle);
+ ExtensionCmdQueue::syncRepositories( m_xComponentContext );
+ }
+ }
+ else
+ {
+ // When m_bShowUpdateOnly is set, we are inside the office and the user clicked
+ // the update notification icon in the menu bar. We must not close the extensions
+ // dialog after displaying the update dialog when it has been visible before
+ if ( m_bShowUpdateOnly )
+ bCloseDialog = ! dp_gui::TheExtensionManager::s_ExtMgr->isVisible();
+ }
+
+ {
+ const SolarMutexGuard guard;
+ ::rtl::Reference< ::dp_gui::TheExtensionManager > myExtMgr(
+ ::dp_gui::TheExtensionManager::get(
+ m_xComponentContext,
+ m_parent ? *m_parent : Reference<awt::XWindow>(),
+ m_extensionURL ? *m_extensionURL : OUString() ) );
+ myExtMgr->createDialog( false );
+ if (m_initialTitle.getLength() > 0) {
+ myExtMgr->SetText( m_initialTitle );
+ m_initialTitle = OUString();
+ }
+ if ( m_bShowUpdateOnly )
+ {
+ myExtMgr->checkUpdates( true, !bCloseDialog );
+ if ( bCloseDialog )
+ myExtMgr->Close();
+ else
+ myExtMgr->ToTop( TOTOP_RESTOREWHENMIN );
+ }
+ else
+ {
+ myExtMgr->Show();
+ myExtMgr->ToTop( TOTOP_RESTOREWHENMIN );
+ }
+ }
+
+ if (app.get() != 0) {
+ Application::Execute();
+ DeInitVCL();
+ }
+
+ if (xListener.is())
+ xListener->dialogClosed(
+ ui::dialogs::DialogClosedEvent(
+ static_cast< ::cppu::OWeakObject * >(this),
+ sal_Int16(0)) );
+}
+
+// XJobExecutor
+//______________________________________________________________________________
+void ServiceImpl::trigger( OUString const &rEvent ) throw (RuntimeException)
+{
+ if ( rEvent == OUSTR("SHOW_UPDATE_DIALOG") )
+ m_bShowUpdateOnly = true;
+ else
+ m_bShowUpdateOnly = false;
+
+ startExecuteModal( Reference< ui::dialogs::XDialogClosedListener >() );
+}
+
+namespace sdecl = comphelper::service_decl;
+sdecl::class_<ServiceImpl, sdecl::with_args<true> > serviceSI;
+sdecl::ServiceDecl const serviceDecl(
+ serviceSI,
+ "com.sun.star.comp.deployment.ui.PackageManagerDialog",
+ "com.sun.star.deployment.ui.PackageManagerDialog" );
+
+sdecl::class_<LicenseDialog, sdecl::with_args<true> > licenseSI;
+sdecl::ServiceDecl const licenseDecl(
+ licenseSI,
+ "com.sun.star.comp.deployment.ui.LicenseDialog",
+ "com.sun.star.deployment.ui.LicenseDialog" );
+
+sdecl::class_<UpdateRequiredDialogService, sdecl::with_args<true> > updateSI;
+sdecl::ServiceDecl const updateDecl(
+ updateSI,
+ "com.sun.star.comp.deployment.ui.UpdateRequiredDialog",
+ "com.sun.star.deployment.ui.UpdateRequiredDialog" );
+} // namespace dp_gui
+
+extern "C" {
+
+void SAL_CALL component_getImplementationEnvironment(
+ const sal_Char ** ppEnvTypeName, uno_Environment ** )
+{
+ *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
+}
+
+void * SAL_CALL component_getFactory(
+ sal_Char const * pImplName,
+ lang::XMultiServiceFactory * pServiceManager,
+ registry::XRegistryKey * pRegistryKey )
+{
+ return component_getFactoryHelper(
+ pImplName, pServiceManager, pRegistryKey, dp_gui::serviceDecl, dp_gui::licenseDecl, dp_gui::updateDecl );
+}
+
+} // extern "C"
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/gui/dp_gui_shared.hxx b/desktop/source/deployment/gui/dp_gui_shared.hxx
new file mode 100644
index 000000000000..e056e81fa395
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_shared.hxx
@@ -0,0 +1,65 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#if !defined INCLUDED_DP_GUI_SHARED_HXX
+#define INCLUDED_DP_GUI_SHARED_HXX
+
+#include "unotools/configmgr.hxx"
+#include "rtl/instance.hxx"
+#include "tools/resmgr.hxx"
+
+
+namespace css = ::com::sun::star;
+
+namespace dp_gui {
+
+struct DeploymentGuiResMgr :
+ public ::rtl::StaticWithInit< ResMgr *, DeploymentGuiResMgr > {
+ ResMgr * operator () () {
+ return ResMgr::CreateResMgr( "deploymentgui" );
+ }
+};
+
+struct BrandName : public ::rtl::StaticWithInit<const ::rtl::OUString, BrandName> {
+ const ::rtl::OUString operator () () {
+ return ::utl::ConfigManager::GetDirectConfigProperty(
+ ::utl::ConfigManager::PRODUCTNAME ).get< ::rtl::OUString >();
+ }
+};
+
+class DpGuiResId : public ResId
+{
+public:
+ DpGuiResId( sal_uInt16 nId ):ResId( nId, *DeploymentGuiResMgr::get() ) {}
+};
+
+} // namespace dp_gui
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/gui/dp_gui_theextmgr.cxx b/desktop/source/deployment/gui/dp_gui_theextmgr.cxx
new file mode 100644
index 000000000000..c86d3e2ba90b
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_theextmgr.cxx
@@ -0,0 +1,533 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include "vcl/svapp.hxx"
+#include "vcl/msgbox.hxx"
+
+#include "osl/mutex.hxx"
+
+#include "toolkit/helper/vclunohelper.hxx"
+
+#include "com/sun/star/beans/XPropertySet.hpp"
+
+#include "dp_gui_dialog2.hxx"
+#include "dp_gui_extensioncmdqueue.hxx"
+#include "dp_gui_theextmgr.hxx"
+#include "dp_gui_theextmgr.hxx"
+#include "dp_identifier.hxx"
+#include "dp_update.hxx"
+
+#define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
+
+#define USER_PACKAGE_MANAGER OUSTR("user")
+#define SHARED_PACKAGE_MANAGER OUSTR("shared")
+#define BUNDLED_PACKAGE_MANAGER OUSTR("bundled")
+
+using namespace ::com::sun::star;
+using ::rtl::OUString;
+
+namespace dp_gui {
+
+//------------------------------------------------------------------------------
+
+::rtl::Reference< TheExtensionManager > TheExtensionManager::s_ExtMgr;
+
+//------------------------------------------------------------------------------
+// TheExtensionManager
+//------------------------------------------------------------------------------
+
+TheExtensionManager::TheExtensionManager( Window *pParent,
+ const uno::Reference< uno::XComponentContext > &xContext ) :
+ m_xContext( xContext ),
+ m_pParent( pParent ),
+ m_pExtMgrDialog( NULL ),
+ m_pUpdReqDialog( NULL ),
+ m_pExecuteCmdQueue( NULL )
+{
+ m_xExtensionManager = deployment::ExtensionManager::get( xContext );
+ m_xExtensionManager->addModifyListener( this );
+
+ uno::Reference< lang::XMultiServiceFactory > xConfig(
+ xContext->getServiceManager()->createInstanceWithContext(
+ OUSTR("com.sun.star.configuration.ConfigurationProvider"), xContext ), uno::UNO_QUERY_THROW);
+ uno::Any args[1];
+ beans::PropertyValue aValue( OUSTR("nodepath"), 0, uno::Any( OUSTR("/org.openoffice.Office.OptionsDialog/Nodes") ),
+ beans::PropertyState_DIRECT_VALUE );
+ args[0] <<= aValue;
+ m_xNameAccessNodes = uno::Reference< container::XNameAccess >(
+ xConfig->createInstanceWithArguments( OUSTR("com.sun.star.configuration.ConfigurationAccess"),
+ uno::Sequence< uno::Any >( args, 1 )), uno::UNO_QUERY_THROW);
+
+ // get the 'get more extensions here' url
+ uno::Reference< container::XNameAccess > xNameAccessRepositories;
+ beans::PropertyValue aValue2( OUSTR("nodepath"), 0, uno::Any( OUSTR("/org.openoffice.Office.ExtensionManager/ExtensionRepositories") ),
+ beans::PropertyState_DIRECT_VALUE );
+ args[0] <<= aValue2;
+ xNameAccessRepositories = uno::Reference< container::XNameAccess > (
+ xConfig->createInstanceWithArguments( OUSTR("com.sun.star.configuration.ConfigurationAccess"),
+ uno::Sequence< uno::Any >( args, 1 )), uno::UNO_QUERY_THROW);
+ try
+ { //throws css::container::NoSuchElementException, css::lang::WrappedTargetException
+ uno::Any value = xNameAccessRepositories->getByName( OUSTR( "WebsiteLink" ) );
+ m_sGetExtensionsURL = value.get< OUString > ();
+ }
+ catch ( uno::Exception& )
+ {}
+
+ if ( dp_misc::office_is_running() )
+ {
+ // the registration should be done after the construction has been ended
+ // otherwise an exception prevents object creation, but it is registered as a listener
+ m_xDesktop.set( xContext->getServiceManager()->createInstanceWithContext(
+ OUSTR("com.sun.star.frame.Desktop"), xContext ), uno::UNO_QUERY );
+ if ( m_xDesktop.is() )
+ m_xDesktop->addTerminateListener( this );
+ }
+}
+
+//------------------------------------------------------------------------------
+TheExtensionManager::~TheExtensionManager()
+{
+ if ( m_pUpdReqDialog )
+ delete m_pUpdReqDialog;
+ if ( m_pExtMgrDialog )
+ delete m_pExtMgrDialog;
+ if ( m_pExecuteCmdQueue )
+ delete m_pExecuteCmdQueue;
+}
+
+//------------------------------------------------------------------------------
+void TheExtensionManager::createDialog( const bool bCreateUpdDlg )
+{
+ const SolarMutexGuard guard;
+
+ if ( bCreateUpdDlg )
+ {
+ if ( !m_pUpdReqDialog )
+ {
+ m_pUpdReqDialog = new UpdateRequiredDialog( NULL, this );
+ delete m_pExecuteCmdQueue;
+ m_pExecuteCmdQueue = new ExtensionCmdQueue( (DialogHelper*) m_pUpdReqDialog, this, m_xContext );
+ createPackageList();
+ }
+ }
+ else if ( !m_pExtMgrDialog )
+ {
+ m_pExtMgrDialog = new ExtMgrDialog( m_pParent, this );
+ delete m_pExecuteCmdQueue;
+ m_pExecuteCmdQueue = new ExtensionCmdQueue( (DialogHelper*) m_pExtMgrDialog, this, m_xContext );
+ m_pExtMgrDialog->setGetExtensionsURL( m_sGetExtensionsURL );
+ createPackageList();
+ }
+}
+
+//------------------------------------------------------------------------------
+void TheExtensionManager::Show()
+{
+ const SolarMutexGuard guard;
+
+ getDialog()->Show();
+}
+
+//------------------------------------------------------------------------------
+void TheExtensionManager::SetText( const ::rtl::OUString &rTitle )
+{
+ const SolarMutexGuard guard;
+
+ getDialog()->SetText( rTitle );
+}
+
+//------------------------------------------------------------------------------
+void TheExtensionManager::ToTop( sal_uInt16 nFlags )
+{
+ const SolarMutexGuard guard;
+
+ getDialog()->ToTop( nFlags );
+}
+
+//------------------------------------------------------------------------------
+bool TheExtensionManager::Close()
+{
+ if ( m_pExtMgrDialog )
+ return m_pExtMgrDialog->Close();
+ else if ( m_pUpdReqDialog )
+ return m_pUpdReqDialog->Close();
+ else
+ return true;
+}
+
+//------------------------------------------------------------------------------
+sal_Int16 TheExtensionManager::execute()
+{
+ sal_Int16 nRet = 0;
+
+ if ( m_pUpdReqDialog )
+ {
+ nRet = m_pUpdReqDialog->Execute();
+ delete m_pUpdReqDialog;
+ m_pUpdReqDialog = NULL;
+ }
+
+ return nRet;
+}
+
+//------------------------------------------------------------------------------
+bool TheExtensionManager::isVisible()
+{
+ return getDialog()->IsVisible();
+}
+
+//------------------------------------------------------------------------------
+bool TheExtensionManager::checkUpdates( bool /* bShowUpdateOnly */, bool /*bParentVisible*/ )
+{
+ std::vector< uno::Reference< deployment::XPackage > > vEntries;
+ uno::Sequence< uno::Sequence< uno::Reference< deployment::XPackage > > > xAllPackages;
+
+ try {
+ xAllPackages = m_xExtensionManager->getAllExtensions( uno::Reference< task::XAbortChannel >(),
+ uno::Reference< ucb::XCommandEnvironment >() );
+ } catch ( deployment::DeploymentException & ) {
+ return false;
+ } catch ( ucb::CommandFailedException & ) {
+ return false;
+ } catch ( ucb::CommandAbortedException & ) {
+ return false;
+ } catch ( lang::IllegalArgumentException & e ) {
+ throw uno::RuntimeException( e.Message, e.Context );
+ }
+
+ for ( sal_Int32 i = 0; i < xAllPackages.getLength(); ++i )
+ {
+ uno::Reference< deployment::XPackage > xPackage = dp_misc::getExtensionWithHighestVersion(xAllPackages[i]);
+ OSL_ASSERT(xPackage.is());
+ if ( xPackage.is() )
+ {
+ vEntries.push_back( xPackage );
+ }
+ }
+
+ m_pExecuteCmdQueue->checkForUpdates( vEntries );
+ return true;
+}
+
+//------------------------------------------------------------------------------
+bool TheExtensionManager::installPackage( const OUString &rPackageURL, bool bWarnUser )
+{
+ if ( rPackageURL.getLength() == 0 )
+ return false;
+
+ createDialog( false );
+
+ bool bInstall = true;
+ bool bInstallForAll = false;
+
+ // DV! missing function is read only repository from extension manager
+ if ( !bWarnUser && ! m_xExtensionManager->isReadOnlyRepository( SHARED_PACKAGE_MANAGER ) )
+ bInstall = getDialogHelper()->installForAllUsers( bInstallForAll );
+
+ if ( !bInstall )
+ return false;
+
+ if ( bInstallForAll )
+ m_pExecuteCmdQueue->addExtension( rPackageURL, SHARED_PACKAGE_MANAGER, false );
+ else
+ m_pExecuteCmdQueue->addExtension( rPackageURL, USER_PACKAGE_MANAGER, bWarnUser );
+
+ return true;
+}
+
+//------------------------------------------------------------------------------
+bool TheExtensionManager::queryTermination()
+{
+ if ( dp_misc::office_is_running() )
+ return true;
+ // the standalone application unopkg must not close ( and quit ) the dialog
+ // when there are still actions in the queue
+ return true;
+}
+
+//------------------------------------------------------------------------------
+void TheExtensionManager::terminateDialog()
+{
+ if ( ! dp_misc::office_is_running() )
+ {
+ const SolarMutexGuard guard;
+ delete m_pExtMgrDialog;
+ m_pExtMgrDialog = NULL;
+ delete m_pUpdReqDialog;
+ m_pUpdReqDialog = NULL;
+ Application::Quit();
+ }
+}
+
+//------------------------------------------------------------------------------
+void TheExtensionManager::createPackageList()
+{
+ uno::Sequence< uno::Sequence< uno::Reference< deployment::XPackage > > > xAllPackages;
+
+ try {
+ xAllPackages = m_xExtensionManager->getAllExtensions( uno::Reference< task::XAbortChannel >(),
+ uno::Reference< ucb::XCommandEnvironment >() );
+ } catch ( deployment::DeploymentException & ) {
+ return;
+ } catch ( ucb::CommandFailedException & ) {
+ return;
+ } catch ( ucb::CommandAbortedException & ) {
+ return;
+ } catch ( lang::IllegalArgumentException & e ) {
+ throw uno::RuntimeException( e.Message, e.Context );
+ }
+
+ for ( sal_Int32 i = 0; i < xAllPackages.getLength(); ++i )
+ {
+ uno::Sequence< uno::Reference< deployment::XPackage > > xPackageList = xAllPackages[i];
+
+ for ( sal_Int32 j = 0; j < xPackageList.getLength(); ++j )
+ {
+ uno::Reference< deployment::XPackage > xPackage = xPackageList[j];
+ if ( xPackage.is() )
+ {
+ PackageState eState = getPackageState( xPackage );
+ getDialogHelper()->addPackageToList( xPackage );
+ // When the package is enabled, we can stop here, otherwise we have to look for
+ // another version of this package
+ if ( ( eState == REGISTERED ) || ( eState == NOT_AVAILABLE ) )
+ break;
+ }
+ }
+ }
+
+ uno::Sequence< uno::Reference< deployment::XPackage > > xNoLicPackages;
+ xNoLicPackages = m_xExtensionManager->getExtensionsWithUnacceptedLicenses( SHARED_PACKAGE_MANAGER,
+ uno::Reference< ucb::XCommandEnvironment >() );
+ for ( sal_Int32 i = 0; i < xNoLicPackages.getLength(); ++i )
+ {
+ uno::Reference< deployment::XPackage > xPackage = xNoLicPackages[i];
+ if ( xPackage.is() )
+ {
+ getDialogHelper()->addPackageToList( xPackage, true );
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+PackageState TheExtensionManager::getPackageState( const uno::Reference< deployment::XPackage > &xPackage ) const
+{
+ try {
+ beans::Optional< beans::Ambiguous< sal_Bool > > option(
+ xPackage->isRegistered( uno::Reference< task::XAbortChannel >(),
+ uno::Reference< ucb::XCommandEnvironment >() ) );
+ if ( option.IsPresent )
+ {
+ ::beans::Ambiguous< sal_Bool > const & reg = option.Value;
+ if ( reg.IsAmbiguous )
+ return AMBIGUOUS;
+ else
+ return reg.Value ? REGISTERED : NOT_REGISTERED;
+ }
+ else
+ return NOT_AVAILABLE;
+ }
+ catch ( uno::RuntimeException & ) {
+ throw;
+ }
+ catch ( uno::Exception & exc) {
+ (void) exc;
+ OSL_FAIL( ::rtl::OUStringToOString( exc.Message, RTL_TEXTENCODING_UTF8 ).getStr() );
+ return NOT_AVAILABLE;
+ }
+}
+
+//------------------------------------------------------------------------------
+bool TheExtensionManager::isReadOnly( const uno::Reference< deployment::XPackage > &xPackage ) const
+{
+ if ( m_xExtensionManager.is() && xPackage.is() )
+ {
+ return m_xExtensionManager->isReadOnlyRepository( xPackage->getRepositoryName() );
+ }
+ else
+ return true;
+}
+
+//------------------------------------------------------------------------------
+// The function investigates if the extension supports options.
+bool TheExtensionManager::supportsOptions( const uno::Reference< deployment::XPackage > &xPackage ) const
+{
+ bool bOptions = false;
+
+ if ( ! xPackage->isBundle() )
+ return false;
+
+ beans::Optional< OUString > aId = xPackage->getIdentifier();
+
+ //a bundle must always have an id
+ OSL_ASSERT( aId.IsPresent );
+
+ //iterate over all available nodes
+ uno::Sequence< OUString > seqNames = m_xNameAccessNodes->getElementNames();
+
+ for ( int i = 0; i < seqNames.getLength(); i++ )
+ {
+ uno::Any anyNode = m_xNameAccessNodes->getByName( seqNames[i] );
+ //If we have a node then then it must contain the set of leaves. This is part of OptionsDialog.xcs
+ uno::Reference< XInterface> xIntNode = anyNode.get< uno::Reference< XInterface > >();
+ uno::Reference< container::XNameAccess > xNode( xIntNode, uno::UNO_QUERY_THROW );
+
+ uno::Any anyLeaves = xNode->getByName( OUSTR("Leaves") );
+ uno::Reference< XInterface > xIntLeaves = anyLeaves.get< uno::Reference< XInterface > >();
+ uno::Reference< container::XNameAccess > xLeaves( xIntLeaves, uno::UNO_QUERY_THROW );
+
+ //iterate over all available leaves
+ uno::Sequence< OUString > seqLeafNames = xLeaves->getElementNames();
+ for ( int j = 0; j < seqLeafNames.getLength(); j++ )
+ {
+ uno::Any anyLeaf = xLeaves->getByName( seqLeafNames[j] );
+ uno::Reference< XInterface > xIntLeaf = anyLeaf.get< uno::Reference< XInterface > >();
+ uno::Reference< beans::XPropertySet > xLeaf( xIntLeaf, uno::UNO_QUERY_THROW );
+ //investigate the Id property if it matches the extension identifier which
+ //has been passed in.
+ uno::Any anyValue = xLeaf->getPropertyValue( OUSTR("Id") );
+
+ OUString sId = anyValue.get< OUString >();
+ if ( sId == aId.Value )
+ {
+ bOptions = true;
+ break;
+ }
+ }
+ if ( bOptions )
+ break;
+ }
+ return bOptions;
+}
+
+//------------------------------------------------------------------------------
+// XEventListener
+void TheExtensionManager::disposing( lang::EventObject const & rEvt )
+ throw ( uno::RuntimeException )
+{
+ bool shutDown = (rEvt.Source == m_xDesktop);
+
+ if ( shutDown && m_xDesktop.is() )
+ {
+ m_xDesktop->removeTerminateListener( this );
+ m_xDesktop.clear();
+ }
+
+ if ( shutDown )
+ {
+ if ( dp_misc::office_is_running() )
+ {
+ const SolarMutexGuard guard;
+ delete m_pExtMgrDialog;
+ m_pExtMgrDialog = NULL;
+ delete m_pUpdReqDialog;
+ m_pUpdReqDialog = NULL;
+ }
+ s_ExtMgr.clear();
+ }
+}
+
+//------------------------------------------------------------------------------
+// XTerminateListener
+void TheExtensionManager::queryTermination( ::lang::EventObject const & )
+ throw ( frame::TerminationVetoException, uno::RuntimeException )
+{
+ DialogHelper *pDialogHelper = getDialogHelper();
+
+ if ( m_pExecuteCmdQueue->isBusy() || ( pDialogHelper && pDialogHelper->isBusy() ) )
+ {
+ ToTop( TOTOP_RESTOREWHENMIN );
+ throw frame::TerminationVetoException(
+ OUSTR("The office cannot be closed while the Extension Manager is running"),
+ uno::Reference<XInterface>(static_cast<frame::XTerminateListener*>(this), uno::UNO_QUERY));
+ }
+ else
+ {
+ if ( m_pExtMgrDialog )
+ m_pExtMgrDialog->Close();
+ if ( m_pUpdReqDialog )
+ m_pUpdReqDialog->Close();
+ }
+}
+
+//------------------------------------------------------------------------------
+void TheExtensionManager::notifyTermination( ::lang::EventObject const & rEvt )
+ throw ( uno::RuntimeException )
+{
+ disposing( rEvt );
+}
+
+//------------------------------------------------------------------------------
+// XModifyListener
+void TheExtensionManager::modified( ::lang::EventObject const & /*rEvt*/ )
+ throw ( uno::RuntimeException )
+{
+ getDialogHelper()->prepareChecking();
+ createPackageList();
+ getDialogHelper()->checkEntries();
+}
+
+//------------------------------------------------------------------------------
+::rtl::Reference< TheExtensionManager > TheExtensionManager::get( const uno::Reference< uno::XComponentContext > &xContext,
+ const uno::Reference< awt::XWindow > &xParent,
+ const OUString & extensionURL )
+{
+ if ( s_ExtMgr.is() )
+ {
+ OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
+ if ( extensionURL.getLength() )
+ s_ExtMgr->installPackage( extensionURL, true );
+ return s_ExtMgr;
+ }
+
+ Window * pParent = DIALOG_NO_PARENT;
+ if ( xParent.is() )
+ pParent = VCLUnoHelper::GetWindow(xParent);
+
+ ::rtl::Reference<TheExtensionManager> that( new TheExtensionManager( pParent, xContext ) );
+
+ const SolarMutexGuard guard;
+ if ( ! s_ExtMgr.is() )
+ {
+ OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
+ s_ExtMgr = that;
+ }
+
+ if ( extensionURL.getLength() )
+ s_ExtMgr->installPackage( extensionURL, true );
+
+ return s_ExtMgr;
+}
+
+} //namespace dp_gui
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/gui/dp_gui_theextmgr.hxx b/desktop/source/deployment/gui/dp_gui_theextmgr.hxx
new file mode 100644
index 000000000000..39bad610bb9a
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_theextmgr.hxx
@@ -0,0 +1,133 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_DP_GUI_THEEXTMGR_HXX
+#define INCLUDED_DP_GUI_THEEXTMGR_HXX
+
+#include "comphelper/sequence.hxx"
+
+#include "cppuhelper/implbase2.hxx"
+
+#include "com/sun/star/container/XNameAccess.hpp"
+#include "com/sun/star/deployment/XExtensionManager.hpp"
+#include "com/sun/star/deployment/ExtensionManager.hpp"
+#include "com/sun/star/frame/XDesktop.hpp"
+#include "com/sun/star/frame/XTerminateListener.hpp"
+#include "com/sun/star/uno/XComponentContext.hpp"
+#include "com/sun/star/util/XModifyListener.hpp"
+
+#include "dp_gui.h"
+#include "dp_gui_dialog2.hxx"
+#include "dp_gui_updatedata.hxx"
+
+//==============================================================================
+namespace dp_gui {
+
+//------------------------------------------------------------------------------
+class ExtensionCmdQueue;
+
+//------------------------------------------------------------------------------
+class TheExtensionManager :
+ public ::cppu::WeakImplHelper2< ::com::sun::star::frame::XTerminateListener,
+ ::com::sun::star::util::XModifyListener >
+{
+private:
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > m_xContext;
+ ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDesktop > m_xDesktop;
+ ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XExtensionManager > m_xExtensionManager;
+ ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > m_xNameAccessNodes;
+
+ Window *m_pParent;
+ ExtMgrDialog *m_pExtMgrDialog;
+ UpdateRequiredDialog *m_pUpdReqDialog;
+ ExtensionCmdQueue *m_pExecuteCmdQueue;
+
+ ::rtl::OUString m_sGetExtensionsURL;
+
+ void createPackageList();
+
+public:
+ static ::rtl::Reference<TheExtensionManager> s_ExtMgr;
+
+ TheExtensionManager( Window * pParent,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > &xContext );
+ ~TheExtensionManager();
+
+ void createDialog( const bool bCreateUpdDlg );
+ sal_Int16 execute();
+
+ Dialog* getDialog() { return m_pExtMgrDialog ? (Dialog*) m_pExtMgrDialog : (Dialog*) m_pUpdReqDialog; }
+ DialogHelper* getDialogHelper() { return m_pExtMgrDialog ? (DialogHelper*) m_pExtMgrDialog : (DialogHelper*) m_pUpdReqDialog; }
+ ExtensionCmdQueue* getCmdQueue() const { return m_pExecuteCmdQueue; }
+
+ void SetText( const ::rtl::OUString &rTitle );
+ void Show();
+ void ToTop( sal_uInt16 nFlags );
+ bool Close();
+ bool isVisible();
+
+ //-----------------
+ bool checkUpdates( bool showUpdateOnly, bool parentVisible );
+ bool installPackage( const ::rtl::OUString &rPackageURL, bool bWarnUser = false );
+
+ bool queryTermination();
+ void terminateDialog();
+
+ // Tools
+ bool supportsOptions( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &xPackage ) const;
+ PackageState getPackageState( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &xPackage ) const;
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > getContext() const { return m_xContext; }
+ ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XExtensionManager > getExtensionManager() const { return m_xExtensionManager; }
+ bool isReadOnly( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &xPackage ) const;
+
+ //-----------------
+ static ::rtl::Reference<TheExtensionManager> get(
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext> const & xContext,
+ ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow> const & xParent = 0,
+ ::rtl::OUString const & view = ::rtl::OUString() );
+
+ // XEventListener
+ virtual void SAL_CALL disposing( ::com::sun::star::lang::EventObject const & evt )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ // XTerminateListener
+ virtual void SAL_CALL queryTermination( ::com::sun::star::lang::EventObject const & evt )
+ throw (::com::sun::star::frame::TerminationVetoException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL notifyTermination( ::com::sun::star::lang::EventObject const & evt )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ // XModifyListener
+ virtual void SAL_CALL modified( ::com::sun::star::lang::EventObject const & evt )
+ throw (::com::sun::star::uno::RuntimeException);
+};
+
+} // namespace dp_gui
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/gui/dp_gui_thread.cxx b/desktop/source/deployment/gui/dp_gui_thread.cxx
new file mode 100644
index 000000000000..1ad857ad7b86
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_thread.cxx
@@ -0,0 +1,85 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include "sal/config.h"
+
+#include <cstddef>
+#include <new>
+
+#include "osl/thread.hxx"
+#include "salhelper/simplereferenceobject.hxx"
+
+#include "dp_gui_thread.hxx"
+
+using dp_gui::Thread;
+
+Thread::Thread() {}
+
+void Thread::launch() {
+ // Assumption is that osl::Thread::create returns normally iff it causes
+ // osl::Thread::run to start executing:
+ acquire();
+ try {
+ create();
+ } catch (...) {
+ release();
+ throw;
+ }
+}
+
+void * Thread::operator new(std::size_t size)
+ throw (std::bad_alloc)
+{
+ return SimpleReferenceObject::operator new(size);
+}
+
+void Thread::operator delete(void * p) throw () {
+ SimpleReferenceObject::operator delete(p);
+}
+
+Thread::~Thread() {}
+
+void Thread::run() {
+ try {
+ execute();
+ } catch (...) {
+ // Work around the problem that onTerminated is not called if run throws
+ // an exception:
+ onTerminated();
+ throw;
+ }
+}
+
+void Thread::onTerminated() {
+ release();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/gui/dp_gui_thread.hxx b/desktop/source/deployment/gui/dp_gui_thread.hxx
new file mode 100644
index 000000000000..624624b0cb3f
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_thread.hxx
@@ -0,0 +1,87 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_DESKTOP_SOURCE_DEPLOYMENT_GUI_DP_GUI_THREAD_HXX
+#define INCLUDED_DESKTOP_SOURCE_DEPLOYMENT_GUI_DP_GUI_THREAD_HXX
+
+#include "sal/config.h"
+
+#include <cstddef>
+#include <new>
+#include "osl/thread.hxx"
+#include "sal/types.h"
+#include "salhelper/simplereferenceobject.hxx"
+
+/// @HTML
+
+namespace dp_gui {
+
+/**
+ A safe encapsulation of <code>osl::Thread</code>.
+*/
+class Thread: public salhelper::SimpleReferenceObject, private osl::Thread {
+public:
+ Thread();
+
+ /**
+ Launch the thread.
+
+ <p>This function must be called at most once.</p>
+ */
+ void launch();
+
+ using osl::Thread::join;
+
+ static void * operator new(std::size_t size) throw (std::bad_alloc);
+
+ static void operator delete(void * p) throw ();
+
+protected:
+ virtual ~Thread();
+
+ /**
+ The main function executed by the thread.
+
+ <p>Any exceptions terminate the thread and are effectively ignored.</p>
+ */
+ virtual void execute() = 0;
+
+private:
+ Thread(Thread &); // not defined
+ void operator =(Thread &); // not defined
+
+ virtual void SAL_CALL run();
+
+ virtual void SAL_CALL onTerminated();
+};
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/gui/dp_gui_updatedata.hxx b/desktop/source/deployment/gui/dp_gui_updatedata.hxx
new file mode 100644
index 000000000000..9fb4b9f79816
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_updatedata.hxx
@@ -0,0 +1,94 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#if ! defined INCLUDED_DP_GUI_UPDATEDATA_HXX
+#define INCLUDED_DP_GUI_UPDATEDATA_HXX
+
+#include "sal/config.h"
+#include "tools/solar.h"
+#include "rtl/ustring.hxx"
+#include "com/sun/star/uno/Reference.hxx"
+
+#include <boost/shared_ptr.hpp>
+
+
+namespace com { namespace sun { namespace star { namespace deployment {
+ class XPackage;
+}}}}
+namespace com { namespace sun { namespace star { namespace xml { namespace dom {
+ class XNode;
+}}}}}
+
+
+namespace dp_gui {
+
+struct UpdateData
+{
+ UpdateData( ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > const & aExt):
+ bIsShared(false), aInstalledPackage(aExt){};
+
+ //When entries added to the listbox then there can be one for the user update and one
+ //for the shared update. However, both list entries will contain the same UpdateData.
+ //isShared is used to indicate which one is used for the shared entry.
+ bool bIsShared;
+
+ //The currently installed extension which is going to be updated. If the extension exist in
+ //multiple repositories then it is the one with the highest version.
+ ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > aInstalledPackage;
+
+ //The version of the update
+ ::rtl::OUString updateVersion;
+
+ //For online update
+ // ======================
+ // The content of the update information.
+ //Only if aUpdateInfo is set then there is an online update available with a better version
+ //than any of the currently installed extensions with the same identifier.
+ ::com::sun::star::uno::Reference< ::com::sun::star::xml::dom::XNode > aUpdateInfo;
+ //The URL of the locally downloaded extension. It will only be set if there were no errors
+ //during the download
+ ::rtl::OUString sLocalURL;
+ //The URL of the website wher the download can be obtained.
+ ::rtl::OUString sWebsiteURL;
+
+ //For local update
+ //=====================
+ //The locale extension which is used as update for the user or shared repository.
+ //If set then the data for the online update (aUpdateInfo, sLocalURL, sWebsiteURL)
+ //are to be ignored.
+ ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage >
+ aUpdateSource;
+
+ // ID to find this entry in the update listbox
+ sal_uInt16 m_nID;
+ bool m_bIgnored;
+};
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/gui/dp_gui_updatedialog.cxx b/desktop/source/deployment/gui/dp_gui_updatedialog.cxx
new file mode 100644
index 000000000000..d678c8626465
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_updatedialog.cxx
@@ -0,0 +1,1436 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include "sal/config.h"
+
+#include <cstddef>
+#include <limits>
+#include <map>
+#include <memory>
+#include <utility>
+#include <vector>
+
+
+#include "boost/optional.hpp"
+#include "com/sun/star/awt/Rectangle.hpp"
+#include "com/sun/star/awt/WindowAttribute.hpp"
+#include "com/sun/star/awt/WindowClass.hpp"
+#include "com/sun/star/awt/WindowDescriptor.hpp"
+#include "com/sun/star/awt/XToolkit.hpp"
+#include "com/sun/star/awt/XWindow.hpp"
+#include "com/sun/star/awt/XWindowPeer.hpp"
+#include "com/sun/star/beans/NamedValue.hpp"
+#include "com/sun/star/beans/Optional.hpp"
+#include "com/sun/star/beans/PropertyValue.hpp"
+#include "com/sun/star/beans/XPropertySet.hpp"
+#include "com/sun/star/container/XNameAccess.hpp"
+#include "com/sun/star/container/XNameContainer.hpp"
+#include "com/sun/star/deployment/DeploymentException.hpp"
+#include "com/sun/star/deployment/UpdateInformationProvider.hpp"
+#include "com/sun/star/deployment/XPackage.hpp"
+#include "com/sun/star/deployment/XExtensionManager.hpp"
+#include "com/sun/star/deployment/ExtensionManager.hpp"
+#include "com/sun/star/deployment/XUpdateInformationProvider.hpp"
+#include "com/sun/star/frame/XDesktop.hpp"
+#include "com/sun/star/frame/XDispatch.hpp"
+#include "com/sun/star/frame/XDispatchProvider.hpp"
+#include "com/sun/star/lang/IllegalArgumentException.hpp"
+#include "com/sun/star/lang/XMultiComponentFactory.hpp"
+#include "com/sun/star/lang/XSingleServiceFactory.hpp"
+#include "com/sun/star/system/SystemShellExecuteFlags.hpp"
+#include "com/sun/star/system/XSystemShellExecute.hpp"
+#include "com/sun/star/task/XAbortChannel.hpp"
+#include "com/sun/star/task/XJob.hpp"
+#include "com/sun/star/ucb/CommandAbortedException.hpp"
+#include "com/sun/star/ucb/CommandFailedException.hpp"
+#include "com/sun/star/ucb/XCommandEnvironment.hpp"
+#include "com/sun/star/uno/Any.hxx"
+#include "com/sun/star/uno/Exception.hpp"
+#include "com/sun/star/uno/Reference.hxx"
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include "com/sun/star/uno/Sequence.hxx"
+#include "com/sun/star/uno/XInterface.hpp"
+#include "com/sun/star/util/URL.hpp"
+#include "com/sun/star/util/XChangesBatch.hpp"
+#include "com/sun/star/util/XURLTransformer.hpp"
+#include "com/sun/star/xml/dom/XElement.hpp"
+#include "com/sun/star/xml/dom/XNode.hpp"
+#include "osl/diagnose.h"
+#include "rtl/bootstrap.hxx"
+#include "rtl/ref.hxx"
+#include "rtl/string.h"
+#include "rtl/ustrbuf.hxx"
+#include "rtl/ustring.h"
+#include "rtl/ustring.hxx"
+#include "sal/types.h"
+#include "svtools/svlbitm.hxx"
+#include "svtools/svlbox.hxx"
+#include <svtools/controldims.hrc>
+#include "svx/checklbx.hxx"
+#include "tools/gen.hxx"
+#include "tools/link.hxx"
+#include "tools/resid.hxx"
+#include "tools/resmgr.hxx"
+#include "tools/solar.h"
+#include "tools/string.hxx"
+#include "vcl/button.hxx"
+#include "vcl/dialog.hxx"
+#include "vcl/fixed.hxx"
+#include "vcl/image.hxx"
+#include "vcl/msgbox.hxx"
+#include "vcl/svapp.hxx"
+#include "osl/mutex.hxx"
+
+#include "comphelper/processfactory.hxx"
+
+#include "dp_dependencies.hxx"
+#include "dp_descriptioninfoset.hxx"
+#include "dp_identifier.hxx"
+#include "dp_version.hxx"
+#include "dp_misc.h"
+#include "dp_update.hxx"
+
+#include "dp_gui.h"
+#include "dp_gui.hrc"
+#include "dp_gui_thread.hxx"
+#include "dp_gui_updatedata.hxx"
+#include "dp_gui_updatedialog.hxx"
+#include "dp_gui_shared.hxx"
+
+class KeyEvent;
+class MouseEvent;
+class Window;
+namespace com { namespace sun { namespace star { namespace uno {
+ class XComponentContext;
+} } } }
+
+using namespace ::com::sun::star;
+using dp_gui::UpdateDialog;
+
+namespace {
+
+static sal_Unicode const LF = 0x000A;
+static sal_Unicode const CR = 0x000D;
+static const sal_uInt16 CMD_ENABLE_UPDATE = 1;
+static const sal_uInt16 CMD_IGNORE_UPDATE = 2;
+static const sal_uInt16 CMD_IGNORE_ALL_UPDATES = 3;
+
+#define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
+
+#define IGNORED_UPDATES OUSTR("/org.openoffice.Office.ExtensionManager/ExtensionUpdateData/IgnoredUpdates")
+#define PROPERTY_VERSION OUSTR("Version")
+
+enum Kind { ENABLED_UPDATE, DISABLED_UPDATE, SPECIFIC_ERROR };
+
+rtl::OUString confineToParagraph(rtl::OUString const & text) {
+ // Confine arbitrary text to a single paragraph in a dp_gui::AutoScrollEdit.
+ // This assumes that U+000A and U+000D are the only paragraph separators in
+ // a dp_gui::AutoScrollEdit, and that replacing them with a single space
+ // each is acceptable:
+ return text.replace(LF, ' ').replace(CR, ' ');
+}
+}
+
+struct UpdateDialog::DisabledUpdate {
+ rtl::OUString name;
+ uno::Sequence< rtl::OUString > unsatisfiedDependencies;
+ // We also want to show release notes and publisher for disabled updates
+ ::com::sun::star::uno::Reference< ::com::sun::star::xml::dom::XNode > aUpdateInfo;
+ sal_uInt16 m_nID;
+};
+
+struct UpdateDialog::SpecificError {
+ rtl::OUString name;
+ rtl::OUString message;
+ sal_uInt16 m_nID;
+};
+
+//------------------------------------------------------------------------------
+struct UpdateDialog::IgnoredUpdate {
+ rtl::OUString sExtensionID;
+ rtl::OUString sVersion;
+ bool bRemoved;
+
+ IgnoredUpdate( const rtl::OUString &rExtensionID, const rtl::OUString &rVersion );
+};
+
+//------------------------------------------------------------------------------
+UpdateDialog::IgnoredUpdate::IgnoredUpdate( const rtl::OUString &rExtensionID, const rtl::OUString &rVersion ):
+ sExtensionID( rExtensionID ),
+ sVersion( rVersion ),
+ bRemoved( false )
+{}
+
+//------------------------------------------------------------------------------
+struct UpdateDialog::Index
+{
+ Kind m_eKind;
+ bool m_bIgnored;
+ sal_uInt16 m_nID;
+ sal_uInt16 m_nIndex;
+ rtl::OUString m_aName;
+
+ Index( Kind theKind, sal_uInt16 nID, sal_uInt16 nIndex, const rtl::OUString &rName );
+};
+
+//------------------------------------------------------------------------------
+UpdateDialog::Index::Index( Kind theKind, sal_uInt16 nID, sal_uInt16 nIndex, const rtl::OUString &rName ):
+ m_eKind( theKind ),
+ m_bIgnored( false ),
+ m_nID( nID ),
+ m_nIndex( nIndex ),
+ m_aName( rName )
+{}
+
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+class UpdateDialog::Thread: public dp_gui::Thread {
+public:
+ Thread(
+ uno::Reference< uno::XComponentContext > const & context,
+ UpdateDialog & dialog,
+ const std::vector< uno::Reference< deployment::XPackage > > & vExtensionList);
+
+ void stop();
+
+private:
+ Thread(UpdateDialog::Thread &); // not defined
+ void operator =(UpdateDialog::Thread &); // not defined
+
+ virtual ~Thread();
+
+ virtual void execute();
+
+ void handleSpecificError(
+ uno::Reference< deployment::XPackage > const & package,
+ uno::Any const & exception) const;
+
+ uno::Sequence< uno::Reference< xml::dom::XElement > >
+ getUpdateInformation(
+ uno::Reference< deployment::XPackage > const & package,
+ uno::Sequence< rtl::OUString > const & urls,
+ rtl::OUString const & identifier) const;
+
+ ::rtl::OUString getUpdateDisplayString(
+ dp_gui::UpdateData const & data, ::rtl::OUString const & version = ::rtl::OUString()) const;
+
+ void prepareUpdateData(
+ ::com::sun::star::uno::Reference< ::com::sun::star::xml::dom::XNode > const & updateInfo,
+ UpdateDialog::DisabledUpdate & out_du,
+ dp_gui::UpdateData & out_data) const;
+
+ bool update(
+ UpdateDialog::DisabledUpdate & du,
+ dp_gui::UpdateData & data) const;
+
+ uno::Reference< uno::XComponentContext > m_context;
+ UpdateDialog & m_dialog;
+ std::vector< uno::Reference< deployment::XPackage > > m_vExtensionList;
+ uno::Reference< deployment::XUpdateInformationProvider > m_updateInformation;
+ uno::Reference< task::XInteractionHandler > m_xInteractionHdl;
+
+ // guarded by Application::GetSolarMutex():
+ uno::Reference< task::XAbortChannel > m_abort;
+ bool m_stop;
+};
+
+UpdateDialog::Thread::Thread(
+ uno::Reference< uno::XComponentContext > const & context,
+ UpdateDialog & dialog,
+ const std::vector< uno::Reference< deployment::XPackage > > &vExtensionList):
+ m_context(context),
+ m_dialog(dialog),
+ m_vExtensionList(vExtensionList),
+ m_updateInformation(
+ deployment::UpdateInformationProvider::create(context)),
+ m_stop(false)
+{
+ if( m_context.is() )
+ {
+ uno::Reference< lang::XMultiComponentFactory > xServiceManager( m_context->getServiceManager() );
+
+ if( xServiceManager.is() )
+ {
+ m_xInteractionHdl = uno::Reference< task::XInteractionHandler > (
+ xServiceManager->createInstanceWithContext( OUSTR( "com.sun.star.task.InteractionHandler" ), m_context),
+ uno::UNO_QUERY );
+ if ( m_xInteractionHdl.is() )
+ m_updateInformation->setInteractionHandler( m_xInteractionHdl );
+ }
+ }
+}
+
+void UpdateDialog::Thread::stop() {
+ uno::Reference< task::XAbortChannel > abort;
+ {
+ SolarMutexGuard g;
+ abort = m_abort;
+ m_stop = true;
+ }
+ if (abort.is()) {
+ abort->sendAbort();
+ }
+ m_updateInformation->cancel();
+}
+
+UpdateDialog::Thread::~Thread()
+{
+ if ( m_xInteractionHdl.is() )
+ m_updateInformation->setInteractionHandler( uno::Reference< task::XInteractionHandler > () );
+}
+
+void UpdateDialog::Thread::execute()
+{
+ {
+ SolarMutexGuard g;
+ if ( m_stop ) {
+ return;
+ }
+ }
+ uno::Reference<deployment::XExtensionManager> extMgr =
+ deployment::ExtensionManager::get(m_context);
+
+ std::vector<std::pair<uno::Reference<deployment::XPackage>, uno::Any > > errors;
+
+ dp_misc::UpdateInfoMap updateInfoMap = dp_misc::getOnlineUpdateInfos(
+ m_context, extMgr, m_updateInformation, &m_vExtensionList, errors);
+
+ typedef std::vector<std::pair<uno::Reference<deployment::XPackage>,
+ uno::Any> >::const_iterator ITERROR;
+ for (ITERROR ite = errors.begin(); ite != errors.end(); ++ite )
+ handleSpecificError(ite->first, ite->second);
+
+ for (dp_misc::UpdateInfoMap::iterator i(updateInfoMap.begin()); i != updateInfoMap.end(); ++i)
+ {
+ dp_misc::UpdateInfo const & info = i->second;
+ UpdateData updateData(info.extension);
+ DisabledUpdate disableUpdate;
+ //determine if online updates meet the requirements
+ prepareUpdateData(info.info, disableUpdate, updateData);
+
+ //determine if the update is installed in the user or shared repository
+ rtl::OUString sOnlineVersion;
+ if (info.info.is())
+ sOnlineVersion = info.version;
+ rtl::OUString sVersionUser;
+ rtl::OUString sVersionShared;
+ rtl::OUString sVersionBundled;
+ uno::Sequence< uno::Reference< deployment::XPackage> > extensions;
+ try {
+ extensions = extMgr->getExtensionsWithSameIdentifier(
+ dp_misc::getIdentifier(info.extension), info.extension->getName(),
+ uno::Reference<ucb::XCommandEnvironment>());
+ } catch (lang::IllegalArgumentException& ) {
+ OSL_ASSERT(0);
+ continue;
+ } catch (css::ucb::CommandFailedException& ) {
+ OSL_ASSERT(0);
+ continue;
+ }
+ OSL_ASSERT(extensions.getLength() == 3);
+ if (extensions[0].is() )
+ sVersionUser = extensions[0]->getVersion();
+ if (extensions[1].is() )
+ sVersionShared = extensions[1]->getVersion();
+ if (extensions[2].is() )
+ sVersionBundled = extensions[2]->getVersion();
+
+ bool bSharedReadOnly = extMgr->isReadOnlyRepository(OUSTR("shared"));
+
+ dp_misc::UPDATE_SOURCE sourceUser = dp_misc::isUpdateUserExtension(
+ bSharedReadOnly, sVersionUser, sVersionShared, sVersionBundled, sOnlineVersion);
+ dp_misc::UPDATE_SOURCE sourceShared = dp_misc::isUpdateSharedExtension(
+ bSharedReadOnly, sVersionShared, sVersionBundled, sOnlineVersion);
+
+ uno::Reference<deployment::XPackage> updateSource;
+ if (sourceUser != dp_misc::UPDATE_SOURCE_NONE)
+ {
+ if (sourceUser == dp_misc::UPDATE_SOURCE_SHARED)
+ {
+ updateData.aUpdateSource = extensions[1];
+ updateData.updateVersion = extensions[1]->getVersion();
+ }
+ else if (sourceUser == dp_misc::UPDATE_SOURCE_BUNDLED)
+ {
+ updateData.aUpdateSource = extensions[2];
+ updateData.updateVersion = extensions[2]->getVersion();
+ }
+ if (!update(disableUpdate, updateData))
+ return;
+ }
+
+ if (sourceShared != dp_misc::UPDATE_SOURCE_NONE)
+ {
+ if (sourceShared == dp_misc::UPDATE_SOURCE_BUNDLED)
+ {
+ updateData.aUpdateSource = extensions[2];
+ updateData.updateVersion = extensions[2]->getVersion();
+ }
+ updateData.bIsShared = true;
+ if (!update(disableUpdate, updateData))
+ return;
+ }
+ }
+
+
+ SolarMutexGuard g;
+ if (!m_stop) {
+ m_dialog.checkingDone();
+ }
+}
+
+//Parameter package can be null
+void UpdateDialog::Thread::handleSpecificError(
+ uno::Reference< deployment::XPackage > const & package,
+ uno::Any const & exception) const
+{
+ UpdateDialog::SpecificError data;
+ if (package.is())
+ data.name = package->getDisplayName();
+ uno::Exception e;
+ if (exception >>= e) {
+ data.message = e.Message;
+ }
+ SolarMutexGuard g;
+ if (!m_stop) {
+ m_dialog.addSpecificError(data);
+ }
+}
+
+::rtl::OUString UpdateDialog::Thread::getUpdateDisplayString(
+ dp_gui::UpdateData const & data, ::rtl::OUString const & version) const
+{
+ OSL_ASSERT(data.aInstalledPackage.is());
+ rtl::OUStringBuffer b(data.aInstalledPackage->getDisplayName());
+ b.append(static_cast< sal_Unicode >(' '));
+ {
+ SolarMutexGuard g;
+ if(!m_stop)
+ b.append(m_dialog.m_version);
+ }
+ b.append(static_cast< sal_Unicode >(' '));
+ if (version.getLength())
+ b.append(version);
+ else
+ b.append(data.updateVersion);
+
+ if (data.sWebsiteURL.getLength())
+ {
+ b.append(static_cast< sal_Unicode >(' '));
+ {
+ SolarMutexGuard g;
+ if(!m_stop)
+ b.append(m_dialog.m_browserbased);
+ }
+ }
+ return b.makeStringAndClear();
+}
+
+/** out_data will only be filled if all dependencies are ok.
+ */
+void UpdateDialog::Thread::prepareUpdateData(
+ uno::Reference< xml::dom::XNode > const & updateInfo,
+ UpdateDialog::DisabledUpdate & out_du,
+ dp_gui::UpdateData & out_data) const
+{
+ if (!updateInfo.is())
+ return;
+ dp_misc::DescriptionInfoset infoset(m_context, updateInfo);
+ OSL_ASSERT(infoset.getVersion().getLength() != 0);
+ uno::Sequence< uno::Reference< xml::dom::XElement > > ds(
+ dp_misc::Dependencies::check(infoset));
+
+ out_du.aUpdateInfo = updateInfo;
+ out_du.unsatisfiedDependencies.realloc(ds.getLength());
+ for (sal_Int32 i = 0; i < ds.getLength(); ++i) {
+ out_du.unsatisfiedDependencies[i] = dp_misc::Dependencies::getErrorText(ds[i]);
+ }
+
+ const ::boost::optional< ::rtl::OUString> updateWebsiteURL(infoset.getLocalizedUpdateWebsiteURL());
+
+ out_du.name = getUpdateDisplayString(out_data, infoset.getVersion());
+
+ if (out_du.unsatisfiedDependencies.getLength() == 0)
+ {
+ out_data.aUpdateInfo = updateInfo;
+ out_data.updateVersion = infoset.getVersion();
+ if (updateWebsiteURL)
+ out_data.sWebsiteURL = *updateWebsiteURL;
+ }
+}
+
+bool UpdateDialog::Thread::update(
+ UpdateDialog::DisabledUpdate & du,
+ dp_gui::UpdateData & data) const
+{
+ bool ret = false;
+ if (du.unsatisfiedDependencies.getLength() == 0)
+ {
+ SolarMutexGuard g;
+ if (!m_stop) {
+ m_dialog.addEnabledUpdate(getUpdateDisplayString(data), data);
+ }
+ ret = !m_stop;
+ } else {
+ SolarMutexGuard g;
+ if (!m_stop) {
+ m_dialog.addDisabledUpdate(du);
+ }
+ ret = !m_stop;
+ }
+ return ret;
+}
+
+// UpdateDialog ----------------------------------------------------------
+UpdateDialog::UpdateDialog(
+ uno::Reference< uno::XComponentContext > const & context,
+ Window * parent,
+ const std::vector<uno::Reference< deployment::XPackage > > &vExtensionList,
+ std::vector< dp_gui::UpdateData > * updateData):
+ ModalDialog(parent,DpGuiResId(RID_DLG_UPDATE)),
+ m_context(context),
+ m_checking(this, DpGuiResId(RID_DLG_UPDATE_CHECKING)),
+ m_throbber(this, DpGuiResId(RID_DLG_UPDATE_THROBBER)),
+ m_update(this, DpGuiResId(RID_DLG_UPDATE_UPDATE)),
+ m_updates(
+ *this, DpGuiResId(RID_DLG_UPDATE_UPDATES),
+ Image(DpGuiResId(RID_DLG_UPDATE_NORMALALERT))),
+ m_all(this, DpGuiResId(RID_DLG_UPDATE_ALL)),
+ m_description(this, DpGuiResId(RID_DLG_UPDATE_DESCRIPTION)),
+ m_PublisherLabel(this, DpGuiResId(RID_DLG_UPDATE_PUBLISHER_LABEL)),
+ m_PublisherLink(this, DpGuiResId(RID_DLG_UPDATE_PUBLISHER_LINK)),
+ m_ReleaseNotesLabel(this, DpGuiResId(RID_DLG_UPDATE_RELEASENOTES_LABEL)),
+ m_ReleaseNotesLink(this, DpGuiResId(RID_DLG_UPDATE_RELEASENOTES_LINK)),
+ m_descriptions(this, DpGuiResId(RID_DLG_UPDATE_DESCRIPTIONS)),
+ m_line(this, DpGuiResId(RID_DLG_UPDATE_LINE)),
+ m_help(this, DpGuiResId(RID_DLG_UPDATE_HELP)),
+ m_ok(this, DpGuiResId(RID_DLG_UPDATE_OK)),
+ m_close(this, DpGuiResId(RID_DLG_UPDATE_CLOSE)),
+ m_error(String(DpGuiResId(RID_DLG_UPDATE_ERROR))),
+ m_none(String(DpGuiResId(RID_DLG_UPDATE_NONE))),
+ m_noInstallable(String(DpGuiResId(RID_DLG_UPDATE_NOINSTALLABLE))),
+ m_failure(String(DpGuiResId(RID_DLG_UPDATE_FAILURE))),
+ m_unknownError(String(DpGuiResId(RID_DLG_UPDATE_UNKNOWNERROR))),
+ m_noDescription(String(DpGuiResId(RID_DLG_UPDATE_NODESCRIPTION))),
+ m_noInstall(String(DpGuiResId(RID_DLG_UPDATE_NOINSTALL))),
+ m_noDependency(String(DpGuiResId(RID_DLG_UPDATE_NODEPENDENCY))),
+ m_noDependencyCurVer(String(DpGuiResId(RID_DLG_UPDATE_NODEPENDENCY_CUR_VER))),
+ m_browserbased(String(DpGuiResId(RID_DLG_UPDATE_BROWSERBASED))),
+ m_version(String(DpGuiResId(RID_DLG_UPDATE_VERSION))),
+ m_ignoredUpdate(String(DpGuiResId(RID_DLG_UPDATE_IGNORED_UPDATE))),
+ m_updateData(*updateData),
+ m_thread(
+ new UpdateDialog::Thread(
+ context, *this, vExtensionList)),
+ m_nFirstLineDelta(0),
+ m_nOneLineMissing(0),
+ m_nLastID(1),
+ m_bModified( false )
+ // TODO: check!
+// ,
+// m_extensionManagerDialog(extensionManagerDialog)
+{
+ OSL_ASSERT(updateData != NULL);
+
+ m_xExtensionManager = deployment::ExtensionManager::get( context );
+
+ uno::Reference< awt::XToolkit > toolkit;
+ try {
+ toolkit = uno::Reference< awt::XToolkit >(
+ (uno::Reference< lang::XMultiComponentFactory >(
+ m_context->getServiceManager(),
+ uno::UNO_QUERY_THROW)->
+ createInstanceWithContext(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM("com.sun.star.awt.Toolkit")),
+ m_context)),
+ uno::UNO_QUERY_THROW);
+ } catch (uno::RuntimeException &) {
+ throw;
+ } catch (uno::Exception & e) {
+ throw uno::RuntimeException(e.Message, e.Context);
+ }
+ m_updates.SetSelectHdl(LINK(this, UpdateDialog, selectionHandler));
+ m_all.SetToggleHdl(LINK(this, UpdateDialog, allHandler));
+ m_ok.SetClickHdl(LINK(this, UpdateDialog, okHandler));
+ m_close.SetClickHdl(LINK(this, UpdateDialog, closeHandler));
+ if ( ! dp_misc::office_is_running())
+ m_help.Disable();
+ FreeResource();
+
+ initDescription();
+ getIgnoredUpdates();
+}
+
+//------------------------------------------------------------------------------
+UpdateDialog::~UpdateDialog()
+{
+ storeIgnoredUpdates();
+
+ for ( std::vector< UpdateDialog::Index* >::iterator i( m_ListboxEntries.begin() ); i != m_ListboxEntries.end(); ++i )
+ {
+ delete (*i);
+ }
+ for ( std::vector< UpdateDialog::IgnoredUpdate* >::iterator i( m_ignoredUpdates.begin() ); i != m_ignoredUpdates.end(); ++i )
+ {
+ delete (*i);
+ }
+}
+
+//------------------------------------------------------------------------------
+sal_Bool UpdateDialog::Close() {
+ m_thread->stop();
+ return ModalDialog::Close();
+}
+
+short UpdateDialog::Execute() {
+ m_throbber.start();
+ m_thread->launch();
+ return ModalDialog::Execute();
+}
+
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+UpdateDialog::CheckListBox::CheckListBox( UpdateDialog & dialog, ResId const & resource,
+ Image const & normalStaticImage ):
+ SvxCheckListBox( &dialog, resource, normalStaticImage ),
+ m_ignoreUpdate( String( DpGuiResId( RID_DLG_UPDATE_IGNORE ) ) ),
+ m_ignoreAllUpdates( String( DpGuiResId( RID_DLG_UPDATE_IGNORE_ALL ) ) ),
+ m_enableUpdate( String( DpGuiResId( RID_DLG_UPDATE_ENABLE ) ) ),
+ m_dialog(dialog)
+{}
+
+//------------------------------------------------------------------------------
+UpdateDialog::CheckListBox::~CheckListBox() {}
+
+//------------------------------------------------------------------------------
+sal_uInt16 UpdateDialog::CheckListBox::getItemCount() const {
+ sal_uLong i = GetEntryCount();
+ OSL_ASSERT(i <= std::numeric_limits< sal_uInt16 >::max());
+ return sal::static_int_cast< sal_uInt16 >(i);
+}
+
+//------------------------------------------------------------------------------
+void UpdateDialog::CheckListBox::MouseButtonDown( MouseEvent const & event )
+{
+ // When clicking on a selected entry in an SvxCheckListBox, the entry's
+ // checkbox is toggled on mouse button down:
+ SvxCheckListBox::MouseButtonDown( event );
+
+ if ( event.IsRight() )
+ {
+ handlePopupMenu( event.GetPosPixel() );
+ }
+
+ m_dialog.enableOk();
+}
+
+//------------------------------------------------------------------------------
+void UpdateDialog::CheckListBox::MouseButtonUp(MouseEvent const & event) {
+ // When clicking on an entry's checkbox in an SvxCheckListBox, the entry's
+ // checkbox is toggled on mouse button up:
+ SvxCheckListBox::MouseButtonUp(event);
+ m_dialog.enableOk();
+}
+
+void UpdateDialog::CheckListBox::KeyInput(KeyEvent const & event) {
+ SvxCheckListBox::KeyInput(event);
+ m_dialog.enableOk();
+}
+
+//------------------------------------------------------------------------------
+void UpdateDialog::CheckListBox::handlePopupMenu( const Point &rPos )
+{
+ SvListEntry *pData = GetEntry( rPos );
+
+ if ( pData )
+ {
+ sal_uInt16 nEntryPos = GetSelectEntryPos();
+ UpdateDialog::Index * p = static_cast< UpdateDialog::Index * >( GetEntryData( nEntryPos ) );
+
+ if ( ( p->m_eKind == ENABLED_UPDATE ) || ( p->m_eKind == DISABLED_UPDATE ) )
+ {
+ PopupMenu aPopup;
+
+ if ( p->m_bIgnored )
+ aPopup.InsertItem( CMD_ENABLE_UPDATE, m_enableUpdate );
+ else
+ {
+ aPopup.InsertItem( CMD_IGNORE_UPDATE, m_ignoreUpdate );
+ aPopup.InsertItem( CMD_IGNORE_ALL_UPDATES, m_ignoreAllUpdates );
+ }
+
+ sal_uInt16 aCmd = aPopup.Execute( this, rPos );
+ if ( ( aCmd == CMD_IGNORE_UPDATE ) || ( aCmd == CMD_IGNORE_ALL_UPDATES ) )
+ {
+ p->m_bIgnored = true;
+ if ( p->m_eKind == ENABLED_UPDATE )
+ {
+ RemoveEntry( nEntryPos );
+ m_dialog.addAdditional( p, SvLBoxButtonKind_disabledCheckbox );
+ }
+ if ( aCmd == CMD_IGNORE_UPDATE )
+ m_dialog.setIgnoredUpdate( p, true, false );
+ else
+ m_dialog.setIgnoredUpdate( p, true, true );
+ // TODO: reselect entry to display new description!
+ }
+ else if ( aCmd == CMD_ENABLE_UPDATE )
+ {
+ p->m_bIgnored = false;
+ if ( p->m_eKind == ENABLED_UPDATE )
+ {
+ RemoveEntry( nEntryPos );
+ m_dialog.insertItem( p, SvLBoxButtonKind_enabledCheckbox );
+ }
+ m_dialog.setIgnoredUpdate( p, false, false );
+ }
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+sal_uInt16 UpdateDialog::insertItem( UpdateDialog::Index *pEntry, SvLBoxButtonKind kind )
+{
+ m_updates.InsertEntry( pEntry->m_aName, LISTBOX_APPEND, static_cast< void * >( pEntry ), kind );
+
+ for ( sal_uInt16 i = m_updates.getItemCount(); i != 0 ; )
+ {
+ i -= 1;
+ UpdateDialog::Index const * p = static_cast< UpdateDialog::Index const * >( m_updates.GetEntryData( i ) );
+ if ( p == pEntry )
+ return i;
+ }
+ OSL_ASSERT(0);
+ return 0;
+}
+
+//------------------------------------------------------------------------------
+void UpdateDialog::addAdditional( UpdateDialog::Index * index, SvLBoxButtonKind kind )
+{
+ m_all.Enable();
+ if (m_all.IsChecked())
+ {
+ insertItem( index, kind );
+ m_update.Enable();
+ m_updates.Enable();
+ m_description.Enable();
+ m_descriptions.Enable();
+ }
+}
+
+//------------------------------------------------------------------------------
+void UpdateDialog::addEnabledUpdate( rtl::OUString const & name,
+ dp_gui::UpdateData & data )
+{
+ sal_uInt16 nIndex = sal::static_int_cast< sal_uInt16 >( m_enabledUpdates.size() );
+ UpdateDialog::Index *pEntry = new UpdateDialog::Index( ENABLED_UPDATE, m_nLastID, nIndex, name );
+
+ data.m_nID = m_nLastID;
+ m_nLastID += 1;
+
+ m_enabledUpdates.push_back( data );
+ m_ListboxEntries.push_back( pEntry );
+
+ if ( ! isIgnoredUpdate( pEntry ) )
+ {
+ sal_uInt16 nPos = insertItem( pEntry, SvLBoxButtonKind_enabledCheckbox );
+ m_updates.CheckEntryPos( nPos );
+ }
+ else
+ addAdditional( pEntry, SvLBoxButtonKind_disabledCheckbox );
+
+ m_update.Enable();
+ m_updates.Enable();
+ m_description.Enable();
+ m_descriptions.Enable();
+}
+
+//------------------------------------------------------------------------------
+void UpdateDialog::addDisabledUpdate( UpdateDialog::DisabledUpdate & data )
+{
+ sal_uInt16 nIndex = sal::static_int_cast< sal_uInt16 >( m_disabledUpdates.size() );
+ UpdateDialog::Index *pEntry = new UpdateDialog::Index( DISABLED_UPDATE, m_nLastID, nIndex, data.name );
+
+ data.m_nID = m_nLastID;
+ m_nLastID += 1;
+
+ m_disabledUpdates.push_back( data );
+ m_ListboxEntries.push_back( pEntry );
+
+ isIgnoredUpdate( pEntry );
+ addAdditional( pEntry, SvLBoxButtonKind_disabledCheckbox );
+}
+
+//------------------------------------------------------------------------------
+void UpdateDialog::addSpecificError( UpdateDialog::SpecificError & data )
+{
+ sal_uInt16 nIndex = sal::static_int_cast< sal_uInt16 >( m_specificErrors.size() );
+ UpdateDialog::Index *pEntry = new UpdateDialog::Index( DISABLED_UPDATE, m_nLastID, nIndex, data.name );
+
+ data.m_nID = m_nLastID;
+ m_nLastID += 1;
+
+ m_specificErrors.push_back( data );
+ m_ListboxEntries.push_back( pEntry );
+
+ addAdditional( pEntry, SvLBoxButtonKind_staticImage);
+}
+
+void UpdateDialog::checkingDone() {
+ m_checking.Hide();
+ m_throbber.stop();
+ m_throbber.Hide();
+ if (m_updates.getItemCount() == 0)
+ {
+ clearDescription();
+ m_description.Enable();
+ m_descriptions.Enable();
+
+ if ( m_disabledUpdates.empty() && m_specificErrors.empty() && m_ignoredUpdates.empty() )
+ showDescription( m_none, false );
+ else
+ showDescription( m_noInstallable, false );
+ }
+
+ enableOk();
+}
+
+void UpdateDialog::enableOk() {
+ if (!m_checking.IsVisible()) {
+ m_ok.Enable(m_updates.GetCheckedEntryCount() != 0);
+ }
+}
+
+// *********************************************************************************
+void UpdateDialog::createNotifyJob( bool bPrepareOnly,
+ uno::Sequence< uno::Sequence< rtl::OUString > > &rItemList )
+{
+ if ( !dp_misc::office_is_running() )
+ return;
+
+ // notify update check job
+ try
+ {
+ uno::Reference< lang::XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory() );
+ uno::Reference< lang::XMultiServiceFactory > xConfigProvider(
+ xFactory->createInstance( OUSTR( "com.sun.star.configuration.ConfigurationProvider" )),
+ uno::UNO_QUERY_THROW);
+
+ beans::PropertyValue aProperty;
+ aProperty.Name = OUSTR( "nodepath" );
+ aProperty.Value = uno::makeAny( OUSTR("org.openoffice.Office.Addons/AddonUI/OfficeHelp/UpdateCheckJob") );
+
+ uno::Sequence< uno::Any > aArgumentList( 1 );
+ aArgumentList[0] = uno::makeAny( aProperty );
+
+ uno::Reference< container::XNameAccess > xNameAccess(
+ xConfigProvider->createInstanceWithArguments(
+ OUSTR("com.sun.star.configuration.ConfigurationAccess"), aArgumentList ),
+ uno::UNO_QUERY_THROW );
+
+ util::URL aURL;
+ xNameAccess->getByName(OUSTR("URL")) >>= aURL.Complete;
+
+ uno::Reference < util::XURLTransformer > xTransformer( xFactory->createInstance( OUSTR( "com.sun.star.util.URLTransformer" ) ),
+ uno::UNO_QUERY_THROW );
+
+ xTransformer->parseStrict(aURL);
+
+ uno::Reference < frame::XDesktop > xDesktop( xFactory->createInstance( OUSTR( "com.sun.star.frame.Desktop" ) ),
+ uno::UNO_QUERY_THROW );
+ uno::Reference< frame::XDispatchProvider > xDispatchProvider( xDesktop->getCurrentFrame(),
+ uno::UNO_QUERY_THROW );
+ uno::Reference< frame::XDispatch > xDispatch = xDispatchProvider->queryDispatch(aURL, rtl::OUString(), 0);
+
+ if( xDispatch.is() )
+ {
+ uno::Sequence< beans::PropertyValue > aPropList(2);
+ aProperty.Name = OUSTR( "updateList" );
+ aProperty.Value = uno::makeAny( rItemList );
+ aPropList[0] = aProperty;
+ aProperty.Name = OUSTR( "prepareOnly" );
+ aProperty.Value = uno::makeAny( bPrepareOnly );
+ aPropList[1] = aProperty;
+
+ xDispatch->dispatch(aURL, aPropList );
+ }
+ }
+ catch( const uno::Exception& e )
+ {
+ dp_misc::TRACE( OUSTR("Caught exception: ")
+ + e.Message + OUSTR("\n thread terminated.\n\n"));
+ }
+}
+
+// *********************************************************************************
+void UpdateDialog::notifyMenubar( bool bPrepareOnly, bool bRecheckOnly )
+{
+ if ( !dp_misc::office_is_running() )
+ return;
+
+ uno::Sequence< uno::Sequence< rtl::OUString > > aItemList;
+
+ if ( ! bRecheckOnly )
+ {
+ sal_Int32 nCount = 0;
+ for ( sal_Int16 i = 0; i < m_updates.getItemCount(); ++i )
+ {
+ uno::Sequence< rtl::OUString > aItem(2);
+
+ UpdateDialog::Index const * p = static_cast< UpdateDialog::Index const * >(m_updates.GetEntryData(i));
+
+ if ( p->m_eKind == ENABLED_UPDATE )
+ {
+ dp_gui::UpdateData aUpdData = m_enabledUpdates[ p->m_nIndex ];
+ aItem[0] = dp_misc::getIdentifier( aUpdData.aInstalledPackage );
+
+ dp_misc::DescriptionInfoset aInfoset( m_context, aUpdData.aUpdateInfo );
+ aItem[1] = aInfoset.getVersion();
+ }
+ else if ( p->m_eKind == DISABLED_UPDATE )
+ continue;
+ else
+ continue;
+
+ aItemList.realloc( nCount + 1 );
+ aItemList[ nCount ] = aItem;
+ nCount += 1;
+ }
+ }
+
+ storeIgnoredUpdates();
+ createNotifyJob( bPrepareOnly, aItemList );
+}
+
+// *********************************************************************************
+
+void UpdateDialog::initDescription()
+{
+ m_PublisherLabel.Hide();
+ m_PublisherLink.Hide();
+ m_ReleaseNotesLabel.Hide();
+ m_ReleaseNotesLink.Hide();
+ m_descriptions.Hide();
+
+ Link aLink = LINK( this, UpdateDialog, hyperlink_clicked );
+ m_PublisherLink.SetClickHdl( aLink );
+ m_ReleaseNotesLink.SetClickHdl( aLink );
+
+ long nTextWidth = m_PublisherLabel.GetCtrlTextWidth( m_PublisherLabel.GetText() );
+ long nTemp = m_ReleaseNotesLabel.GetTextWidth( m_ReleaseNotesLabel.GetText() );
+ if ( nTemp > nTextWidth )
+ nTextWidth = nTemp;
+ nTextWidth = nTextWidth * 110 / 100;
+
+ Size aNewSize = m_PublisherLabel.GetSizePixel();
+ if ( nTextWidth > aNewSize.Width() )
+ {
+ long nDelta = nTextWidth - aNewSize.Width();
+ aNewSize.Width() = nTextWidth;
+ m_PublisherLabel.SetSizePixel( aNewSize );
+ m_ReleaseNotesLabel.SetSizePixel( aNewSize );
+
+ aNewSize = m_PublisherLink.GetSizePixel();
+ aNewSize.Width() = aNewSize.Width() - nDelta;
+ Point aNewPos = m_PublisherLink.GetPosPixel();
+ aNewPos.X() = aNewPos.X() + nDelta;
+ m_PublisherLink.SetPosSizePixel( aNewPos, aNewSize );
+ aNewPos.Y() = m_ReleaseNotesLink.GetPosPixel().Y();
+ m_ReleaseNotesLink.SetPosSizePixel( aNewPos, aNewSize );
+ }
+
+ m_aFirstLinePos = m_descriptions.GetPosPixel();
+ m_aFirstLineSize = m_descriptions.GetSizePixel();
+ Size aMarginSize = LogicToPixel( Size( RSC_SP_CTRL_GROUP_X, RSC_SP_CTRL_GROUP_Y ), MAP_APPFONT );
+ Point aThirdLinePos = m_ReleaseNotesLabel.GetPosPixel();
+ aThirdLinePos.Y() = aThirdLinePos.Y() + m_ReleaseNotesLabel.GetSizePixel().Height() + aMarginSize.Height();
+ m_nFirstLineDelta = aThirdLinePos.Y() - m_aFirstLinePos.Y();
+ m_nOneLineMissing = m_ReleaseNotesLabel.GetPosPixel().Y() - m_PublisherLabel.GetPosPixel().Y();
+}
+
+void UpdateDialog::clearDescription()
+{
+ String sEmpty;
+ m_PublisherLabel.Hide();
+ m_PublisherLink.Hide();
+ m_PublisherLink.SetDescription( sEmpty );
+ m_PublisherLink.SetURL( sEmpty );
+ m_ReleaseNotesLabel.Hide();
+ m_ReleaseNotesLink.Hide();
+ m_ReleaseNotesLink.SetURL( sEmpty );
+ if ( m_PublisherLabel.GetPosPixel().Y() == m_ReleaseNotesLabel.GetPosPixel().Y() )
+ {
+ Point aNewPos = m_ReleaseNotesLabel.GetPosPixel();
+ aNewPos.Y() += m_nOneLineMissing;
+ m_ReleaseNotesLabel.SetPosPixel( aNewPos );
+ aNewPos = m_ReleaseNotesLink.GetPosPixel();
+ aNewPos.Y() += m_nOneLineMissing;
+ m_ReleaseNotesLink.SetPosPixel( aNewPos );
+ }
+ m_descriptions.Hide();
+ m_descriptions.Clear();
+ m_descriptions.SetPosSizePixel( m_aFirstLinePos, m_aFirstLineSize );
+}
+
+bool UpdateDialog::showDescription(uno::Reference< xml::dom::XNode > const & aUpdateInfo)
+{
+ dp_misc::DescriptionInfoset infoset(m_context, aUpdateInfo);
+ return showDescription(infoset.getLocalizedPublisherNameAndURL(),
+ infoset.getLocalizedReleaseNotesURL());
+}
+
+bool UpdateDialog::showDescription(uno::Reference< deployment::XPackage > const & aExtension)
+{
+ OSL_ASSERT(aExtension.is());
+ beans::StringPair pubInfo = aExtension->getPublisherInfo();
+ return showDescription(std::make_pair(pubInfo.First, pubInfo.Second),
+ OUSTR(""));
+}
+
+bool UpdateDialog::showDescription(std::pair< rtl::OUString, rtl::OUString > const & pairPublisher,
+ rtl::OUString const & sReleaseNotes)
+{
+ rtl::OUString sPub = pairPublisher.first;
+ rtl::OUString sURL = pairPublisher.second;
+
+ if ( sPub.getLength() == 0 && sURL.getLength() == 0 && sReleaseNotes.getLength() == 0 )
+ // nothing to show
+ return false;
+
+ bool bPublisher = false;
+ if ( sPub.getLength() > 0 )
+ {
+ m_PublisherLabel.Show();
+ m_PublisherLink.Show();
+ m_PublisherLink.SetDescription( sPub );
+ m_PublisherLink.SetURL( sURL );
+ bPublisher = true;
+ }
+
+ if ( sReleaseNotes.getLength() > 0 )
+ {
+ if ( !bPublisher )
+ {
+ m_ReleaseNotesLabel.SetPosPixel( m_PublisherLabel.GetPosPixel() );
+ m_ReleaseNotesLink.SetPosPixel( m_PublisherLink.GetPosPixel() );
+ }
+ m_ReleaseNotesLabel.Show();
+ m_ReleaseNotesLink.Show();
+ m_ReleaseNotesLink.SetURL( sReleaseNotes );
+ }
+ return true;
+}
+
+bool UpdateDialog::showDescription( const String& rDescription, bool bWithPublisher )
+{
+ if ( rDescription.Len() == 0 )
+ // nothing to show
+ return false;
+
+ if ( bWithPublisher )
+ {
+ bool bOneLineMissing = !m_ReleaseNotesLabel.IsVisible() || !m_PublisherLabel.IsVisible();
+ Point aNewPos = m_aFirstLinePos;
+ aNewPos.Y() += m_nFirstLineDelta;
+ if ( bOneLineMissing )
+ aNewPos.Y() -= m_nOneLineMissing;
+ Size aNewSize = m_aFirstLineSize;
+ aNewSize.Height() -= m_nFirstLineDelta;
+ if ( bOneLineMissing )
+ aNewSize.Height() += m_nOneLineMissing;
+ m_descriptions.SetPosSizePixel( aNewPos, aNewSize );
+ }
+ m_descriptions.Show();
+ m_descriptions.SetDescription( rDescription );
+ return true;
+}
+
+//------------------------------------------------------------------------------
+void UpdateDialog::getIgnoredUpdates()
+{
+ uno::Reference< lang::XMultiServiceFactory > xConfig( m_context->getServiceManager()->createInstanceWithContext(
+ OUSTR("com.sun.star.configuration.ConfigurationProvider"), m_context ), uno::UNO_QUERY_THROW);
+ beans::NamedValue aValue( OUSTR("nodepath"), uno::Any( IGNORED_UPDATES ) );
+ uno::Sequence< uno::Any > args(1);
+ args[0] <<= aValue;
+
+ uno::Reference< container::XNameAccess > xNameAccess( xConfig->createInstanceWithArguments( OUSTR("com.sun.star.configuration.ConfigurationAccess"), args), uno::UNO_QUERY_THROW );
+ uno::Sequence< rtl::OUString > aElementNames = xNameAccess->getElementNames();
+
+ for ( sal_Int32 i = 0; i < aElementNames.getLength(); i++ )
+ {
+ ::rtl::OUString aIdentifier = aElementNames[i];
+ ::rtl::OUString aVersion;
+
+ uno::Any aPropValue( uno::Reference< beans::XPropertySet >( xNameAccess->getByName( aIdentifier ), uno::UNO_QUERY_THROW )->getPropertyValue( PROPERTY_VERSION ) );
+ aPropValue >>= aVersion;
+ IgnoredUpdate *pData = new IgnoredUpdate( aIdentifier, aVersion );
+ m_ignoredUpdates.push_back( pData );
+ }
+}
+
+//------------------------------------------------------------------------------
+void UpdateDialog::storeIgnoredUpdates()
+{
+ if ( m_bModified && ( m_ignoredUpdates.size() != 0 ) )
+ {
+ uno::Reference< lang::XMultiServiceFactory > xConfig( m_context->getServiceManager()->createInstanceWithContext(
+ OUSTR("com.sun.star.configuration.ConfigurationProvider"), m_context ), uno::UNO_QUERY_THROW );
+ beans::NamedValue aValue( OUSTR("nodepath"), uno::Any( IGNORED_UPDATES ) );
+ uno::Sequence< uno::Any > args(1);
+ args[0] <<= aValue;
+
+ uno::Reference< container::XNameContainer > xNameContainer( xConfig->createInstanceWithArguments(
+ OUSTR("com.sun.star.configuration.ConfigurationUpdateAccess"), args ), uno::UNO_QUERY_THROW );
+
+ for ( std::vector< UpdateDialog::IgnoredUpdate* >::iterator i( m_ignoredUpdates.begin() ); i != m_ignoredUpdates.end(); ++i )
+ {
+ if ( xNameContainer->hasByName( (*i)->sExtensionID ) )
+ {
+ if ( (*i)->bRemoved )
+ xNameContainer->removeByName( (*i)->sExtensionID );
+ else
+ uno::Reference< beans::XPropertySet >( xNameContainer->getByName( (*i)->sExtensionID ), uno::UNO_QUERY_THROW )->setPropertyValue( PROPERTY_VERSION, uno::Any( (*i)->sVersion ) );
+ }
+ else if ( ! (*i)->bRemoved )
+ {
+ uno::Reference< beans::XPropertySet > elem( uno::Reference< lang::XSingleServiceFactory >( xNameContainer, uno::UNO_QUERY_THROW )->createInstance(), uno::UNO_QUERY_THROW );
+ elem->setPropertyValue( PROPERTY_VERSION, uno::Any( (*i)->sVersion ) );
+ xNameContainer->insertByName( (*i)->sExtensionID, uno::Any( elem ) );
+ }
+ }
+
+ uno::Reference< util::XChangesBatch > xChangesBatch( xNameContainer, uno::UNO_QUERY );
+ if ( xChangesBatch.is() && xChangesBatch->hasPendingChanges() )
+ xChangesBatch->commitChanges();
+ }
+
+ m_bModified = false;
+}
+
+//------------------------------------------------------------------------------
+bool UpdateDialog::isIgnoredUpdate( UpdateDialog::Index * index )
+{
+ bool bIsIgnored = false;
+
+ if ( m_ignoredUpdates.size() != 0 )
+ {
+ rtl::OUString aExtensionID;
+ rtl::OUString aVersion;
+
+ if ( index->m_eKind == ENABLED_UPDATE )
+ {
+ dp_gui::UpdateData aUpdData = m_enabledUpdates[ index->m_nIndex ];
+ aExtensionID = dp_misc::getIdentifier( aUpdData.aInstalledPackage );
+ aVersion = aUpdData.updateVersion;
+ }
+ else if ( index->m_eKind == DISABLED_UPDATE )
+ {
+ DisabledUpdate &rData = m_disabledUpdates[ index->m_nIndex ];
+ dp_misc::DescriptionInfoset aInfoset( m_context, rData.aUpdateInfo );
+ ::boost::optional< ::rtl::OUString > aID( aInfoset.getIdentifier() );
+ if ( aID )
+ aExtensionID = *aID;
+ aVersion = aInfoset.getVersion();
+ }
+
+ for ( std::vector< UpdateDialog::IgnoredUpdate* >::iterator i( m_ignoredUpdates.begin() ); i != m_ignoredUpdates.end(); ++i )
+ {
+ if ( (*i)->sExtensionID == aExtensionID )
+ {
+ if ( ( (*i)->sVersion.getLength() == 0 ) || ( (*i)->sVersion == aVersion ) )
+ {
+ bIsIgnored = true;
+ index->m_bIgnored = true;
+ }
+ else // when we find another update of an ignored version, we will remove the old one to keep the ignored list small
+ (*i)->bRemoved = true;
+ break;
+ }
+ }
+ }
+
+ return bIsIgnored;
+}
+
+//------------------------------------------------------------------------------
+void UpdateDialog::setIgnoredUpdate( UpdateDialog::Index *pIndex, bool bIgnore, bool bIgnoreAll )
+{
+ rtl::OUString aExtensionID;
+ rtl::OUString aVersion;
+
+ m_bModified = true;
+
+ if ( pIndex->m_eKind == ENABLED_UPDATE )
+ {
+ dp_gui::UpdateData aUpdData = m_enabledUpdates[ pIndex->m_nIndex ];
+ aExtensionID = dp_misc::getIdentifier( aUpdData.aInstalledPackage );
+ if ( !bIgnoreAll )
+ aVersion = aUpdData.updateVersion;
+ }
+ else if ( pIndex->m_eKind == DISABLED_UPDATE )
+ {
+ DisabledUpdate &rData = m_disabledUpdates[ pIndex->m_nIndex ];
+ dp_misc::DescriptionInfoset aInfoset( m_context, rData.aUpdateInfo );
+ ::boost::optional< ::rtl::OUString > aID( aInfoset.getIdentifier() );
+ if ( aID )
+ aExtensionID = *aID;
+ if ( !bIgnoreAll )
+ aVersion = aInfoset.getVersion();
+ }
+
+ if ( aExtensionID.getLength() )
+ {
+ bool bFound = false;
+ for ( std::vector< UpdateDialog::IgnoredUpdate* >::iterator i( m_ignoredUpdates.begin() ); i != m_ignoredUpdates.end(); ++i )
+ {
+ if ( (*i)->sExtensionID == aExtensionID )
+ {
+ (*i)->sVersion = aVersion;
+ (*i)->bRemoved = !bIgnore;
+ bFound = true;
+ break;
+ }
+ }
+ if ( bIgnore && !bFound )
+ {
+ IgnoredUpdate *pData = new IgnoredUpdate( aExtensionID, aVersion );
+ m_ignoredUpdates.push_back( pData );
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+
+IMPL_LINK(UpdateDialog, selectionHandler, void *, EMPTYARG)
+{
+ rtl::OUStringBuffer b;
+ bool bInserted = false;
+ UpdateDialog::Index const * p = static_cast< UpdateDialog::Index const * >(
+ m_updates.GetEntryData(m_updates.GetSelectEntryPos()));
+ clearDescription();
+
+ if ( p != NULL )
+ {
+ sal_uInt16 pos = p->m_nIndex;
+
+ switch (p->m_eKind)
+ {
+ case ENABLED_UPDATE:
+ {
+ if ( m_enabledUpdates[ pos ].aUpdateSource.is() )
+ bInserted = showDescription( m_enabledUpdates[ pos ].aUpdateSource );
+ else
+ bInserted = showDescription( m_enabledUpdates[ pos ].aUpdateInfo );
+
+ if ( p->m_bIgnored )
+ b.append( m_ignoredUpdate );
+
+ break;
+ }
+ case DISABLED_UPDATE:
+ {
+ bInserted = showDescription( m_disabledUpdates[pos].aUpdateInfo );
+
+ if ( p->m_bIgnored )
+ b.append( m_ignoredUpdate );
+
+ UpdateDialog::DisabledUpdate & data = m_disabledUpdates[ pos ];
+ if (data.unsatisfiedDependencies.getLength() != 0)
+ {
+ // create error string for version mismatch
+ ::rtl::OUString sVersion( RTL_CONSTASCII_USTRINGPARAM("%VERSION") );
+ ::rtl::OUString sProductName( RTL_CONSTASCII_USTRINGPARAM("%PRODUCTNAME") );
+ sal_Int32 nPos = m_noDependencyCurVer.indexOf( sVersion );
+ if ( nPos >= 0 )
+ {
+ ::rtl::OUString sCurVersion( RTL_CONSTASCII_USTRINGPARAM( "${$OOO_BASE_DIR/program/" SAL_CONFIGFILE("version") ":Version:OOOPackageVersion}"));
+ ::rtl::Bootstrap::expandMacros(sCurVersion);
+ m_noDependencyCurVer = m_noDependencyCurVer.replaceAt( nPos, sVersion.getLength(), sCurVersion );
+ }
+ nPos = m_noDependencyCurVer.indexOf( sProductName );
+ if ( nPos >= 0 )
+ {
+ m_noDependencyCurVer = m_noDependencyCurVer.replaceAt( nPos, sProductName.getLength(), BrandName::get() );
+ }
+ nPos = m_noDependency.indexOf( sProductName );
+ if ( nPos >= 0 )
+ {
+ m_noDependency = m_noDependency.replaceAt( nPos, sProductName.getLength(), BrandName::get() );
+ }
+
+ b.append(m_noInstall);
+ b.append(LF);
+ b.append(m_noDependency);
+ for (sal_Int32 i = 0;
+ i < data.unsatisfiedDependencies.getLength(); ++i)
+ {
+ b.append(LF);
+ b.appendAscii(RTL_CONSTASCII_STRINGPARAM(" "));
+ // U+2003 EM SPACE would be better than two spaces,
+ // but some fonts do not contain it
+ b.append(
+ confineToParagraph(
+ data.unsatisfiedDependencies[i]));
+ }
+ b.append(LF);
+ b.appendAscii(RTL_CONSTASCII_STRINGPARAM(" "));
+ b.append(m_noDependencyCurVer);
+ }
+ break;
+ }
+ case SPECIFIC_ERROR:
+ {
+ UpdateDialog::SpecificError & data = m_specificErrors[ pos ];
+ b.append(m_failure);
+ b.append(LF);
+ b.append( data.message.getLength() == 0 ? m_unknownError : data.message );
+ break;
+ }
+ default:
+ OSL_ASSERT(false);
+ break;
+ }
+ }
+
+ if ( b.getLength() == 0 )
+ b.append( m_noDescription );
+
+ showDescription( b.makeStringAndClear(), bInserted );
+ return 0;
+}
+
+IMPL_LINK(UpdateDialog, allHandler, void *, EMPTYARG)
+{
+ if (m_all.IsChecked())
+ {
+ m_update.Enable();
+ m_updates.Enable();
+ m_description.Enable();
+ m_descriptions.Enable();
+
+ for (std::vector< UpdateDialog::Index* >::iterator i( m_ListboxEntries.begin() );
+ i != m_ListboxEntries.end(); ++i )
+ {
+ if ( (*i)->m_bIgnored || ( (*i)->m_eKind != ENABLED_UPDATE ) )
+ insertItem( (*i), SvLBoxButtonKind_disabledCheckbox );
+ }
+ }
+ else
+ {
+ for ( sal_uInt16 i = 0; i < m_updates.getItemCount(); )
+ {
+ UpdateDialog::Index const * p = static_cast< UpdateDialog::Index const * >( m_updates.GetEntryData(i) );
+ if ( p->m_bIgnored || ( p->m_eKind != ENABLED_UPDATE ) )
+ {
+ m_updates.RemoveEntry(i);
+ } else {
+ ++i;
+ }
+ }
+
+ if (m_updates.getItemCount() == 0)
+ {
+ clearDescription();
+ m_update.Disable();
+ m_updates.Disable();
+ if (m_checking.IsVisible())
+ m_description.Disable();
+ else
+ showDescription(m_noInstallable,false);
+ }
+ }
+ return 0;
+}
+
+IMPL_LINK(UpdateDialog, okHandler, void *, EMPTYARG)
+{
+ //If users are going to update a shared extension then we need
+ //to warn them
+ typedef ::std::vector<UpdateData>::const_iterator CIT;
+ for (CIT i = m_enabledUpdates.begin(); i < m_enabledUpdates.end(); i++)
+ {
+ OSL_ASSERT(i->aInstalledPackage.is());
+ //If the user has no write access to the shared folder then the update
+ //for a shared extension is disable, that is it cannot be in m_enabledUpdates
+ }
+
+
+ for (sal_uInt16 i = 0; i < m_updates.getItemCount(); ++i) {
+ UpdateDialog::Index const * p =
+ static_cast< UpdateDialog::Index const * >(
+ m_updates.GetEntryData(i));
+ if (p->m_eKind == ENABLED_UPDATE && m_updates.IsChecked(i)) {
+ m_updateData.push_back( m_enabledUpdates[ p->m_nIndex ] );
+ }
+ }
+
+ EndDialog(RET_OK);
+ return 0;
+}
+
+IMPL_LINK(UpdateDialog, closeHandler, void *, EMPTYARG) {
+ m_thread->stop();
+ EndDialog(RET_CANCEL);
+ return 0;
+}
+
+IMPL_LINK( UpdateDialog, hyperlink_clicked, svt::FixedHyperlink*, pHyperlink )
+{
+ ::rtl::OUString sURL;
+ if ( pHyperlink )
+ sURL = ::rtl::OUString( pHyperlink->GetURL() );
+ if ( sURL.getLength() == 0 )
+ return 0;
+
+ try
+ {
+ uno::Reference< com::sun::star::system::XSystemShellExecute > xSystemShellExecute(
+ m_context->getServiceManager()->createInstanceWithContext(
+ OUSTR( "com.sun.star.system.SystemShellExecute" ),
+ m_context), uno::UNO_QUERY_THROW);
+ //throws lang::IllegalArgumentException, system::SystemShellExecuteException
+ xSystemShellExecute->execute(
+ sURL, ::rtl::OUString(), com::sun::star::system::SystemShellExecuteFlags::DEFAULTS);
+ }
+ catch (uno::Exception& )
+ {
+ }
+
+ return 1;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/gui/dp_gui_updatedialog.hxx b/desktop/source/deployment/gui/dp_gui_updatedialog.hxx
new file mode 100644
index 000000000000..ea1cc8d56201
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_updatedialog.hxx
@@ -0,0 +1,232 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_DESKTOP_SOURCE_DEPLOYMENT_GUI_DP_GUI_UPDATEDIALOG_HXX
+#define INCLUDED_DESKTOP_SOURCE_DEPLOYMENT_GUI_DP_GUI_UPDATEDIALOG_HXX
+
+#include "sal/config.h"
+
+#include <memory>
+#include <vector>
+#include "com/sun/star/uno/Reference.hxx"
+#include "com/sun/star/uno/Sequence.hxx"
+#include "rtl/ref.hxx"
+#include "rtl/ustring.hxx"
+#include "svtools/svlbitm.hxx"
+#include "svx/checklbx.hxx"
+#include "tools/link.hxx"
+#include "tools/solar.h"
+#include "vcl/button.hxx"
+#include "vcl/dialog.hxx"
+#include "vcl/fixed.hxx"
+#include <svtools/fixedhyper.hxx>
+#include <vcl/throbber.hxx>
+
+#include "descedit.hxx"
+#include "dp_gui_updatedata.hxx"
+
+/// @HTML
+
+class Image;
+class KeyEvent;
+class MouseEvent;
+class ResId;
+class Window;
+
+namespace com { namespace sun { namespace star {
+ namespace deployment { class XExtensionManager;
+ class XPackage; }
+ namespace uno { class XComponentContext; }
+} } }
+
+namespace dp_gui {
+/**
+ The modal &ldquo;Check for Updates&rdquo; dialog.
+*/
+class UpdateDialog: public ModalDialog {
+public:
+ /**
+ Create an instance.
+
+ <p>Exactly one of <code>selectedPackages</code> and
+ <code>packageManagers</code> must be non-null.</p>
+
+ @param context
+ a non-null component context
+
+ @param parent
+ the parent window, may be null
+
+ @param vExtensionList
+ check for updates for the contained extensions. There must only be one extension with
+ a particular identifier. If one extension is installed in several repositories, then the
+ one with the highest version must be used, because it contains the latest known update
+ information.
+ */
+ UpdateDialog(
+ com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > const & context,
+ Window * parent,
+ const std::vector< com::sun::star::uno::Reference<
+ com::sun::star::deployment::XPackage > > & vExtensionList,
+ std::vector< dp_gui::UpdateData > * updateData);
+
+ ~UpdateDialog();
+
+ virtual sal_Bool Close();
+
+ virtual short Execute();
+
+ void notifyMenubar( bool bPrepareOnly, bool bRecheckOnly );
+ static void createNotifyJob( bool bPrepareOnly,
+ com::sun::star::uno::Sequence< com::sun::star::uno::Sequence< rtl::OUString > > &rItemList );
+
+private:
+ UpdateDialog(UpdateDialog &); // not defined
+ void operator =(UpdateDialog &); // not defined
+
+ struct DisabledUpdate;
+ struct SpecificError;
+ struct IgnoredUpdate;
+ struct Index;
+ friend struct Index;
+ class Thread;
+ friend class Thread;
+
+ class CheckListBox: public SvxCheckListBox {
+ public:
+ CheckListBox(
+ UpdateDialog & dialog, ResId const & resource,
+ Image const & normalStaticImage);
+
+ virtual ~CheckListBox();
+
+ sal_uInt16 getItemCount() const;
+
+ private:
+ CheckListBox(UpdateDialog::CheckListBox &); // not defined
+ void operator =(UpdateDialog::CheckListBox &); // not defined
+
+ virtual void MouseButtonDown(MouseEvent const & event);
+ virtual void MouseButtonUp(MouseEvent const & event);
+ virtual void KeyInput(KeyEvent const & event);
+
+ void handlePopupMenu( const Point &rPos );
+
+ rtl::OUString m_ignoreUpdate;
+ rtl::OUString m_ignoreAllUpdates;
+ rtl::OUString m_enableUpdate;
+ UpdateDialog & m_dialog;
+ };
+
+
+ friend class CheckListBox;
+
+ sal_uInt16 insertItem( UpdateDialog::Index *pIndex, SvLBoxButtonKind kind );
+ void addAdditional( UpdateDialog::Index *pIndex, SvLBoxButtonKind kind );
+ bool isIgnoredUpdate( UpdateDialog::Index *pIndex );
+ void setIgnoredUpdate( UpdateDialog::Index *pIndex, bool bIgnore, bool bIgnoreAll );
+
+ void addEnabledUpdate( rtl::OUString const & name, dp_gui::UpdateData & data );
+ void addDisabledUpdate( UpdateDialog::DisabledUpdate & data );
+ void addSpecificError( UpdateDialog::SpecificError & data );
+
+ void checkingDone();
+
+ void enableOk();
+
+ void getIgnoredUpdates();
+ void storeIgnoredUpdates();
+
+ void initDescription();
+ void clearDescription();
+ bool showDescription(::com::sun::star::uno::Reference<
+ ::com::sun::star::deployment::XPackage > const & aExtension);
+ bool showDescription(std::pair< rtl::OUString, rtl::OUString > const & pairPublisher,
+ rtl::OUString const & sReleaseNotes);
+ bool showDescription( ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::dom::XNode > const & aUpdateInfo);
+ bool showDescription( const String& rDescription, bool bWithPublisher );
+ bool isReadOnly( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &xPackage ) const;
+
+ DECL_LINK(selectionHandler, void *);
+ DECL_LINK(allHandler, void *);
+ DECL_LINK(okHandler, void *);
+ DECL_LINK(closeHandler, void *);
+ DECL_LINK(hyperlink_clicked, svt::FixedHyperlink *);
+
+ com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext >
+ m_context;
+ FixedText m_checking;
+ Throbber m_throbber;
+ FixedText m_update;
+ UpdateDialog::CheckListBox m_updates;
+ CheckBox m_all;
+ FixedLine m_description;
+ FixedText m_PublisherLabel;
+ svt::FixedHyperlink m_PublisherLink;
+ FixedText m_ReleaseNotesLabel;
+ svt::FixedHyperlink m_ReleaseNotesLink;
+ dp_gui::DescriptionEdit m_descriptions;
+ FixedLine m_line;
+ HelpButton m_help;
+ PushButton m_ok;
+ PushButton m_close;
+ rtl::OUString m_error;
+ rtl::OUString m_none;
+ rtl::OUString m_noInstallable;
+ rtl::OUString m_failure;
+ rtl::OUString m_unknownError;
+ rtl::OUString m_noDescription;
+ rtl::OUString m_noInstall;
+ rtl::OUString m_noDependency;
+ rtl::OUString m_noDependencyCurVer;
+ rtl::OUString m_browserbased;
+ rtl::OUString m_version;
+ rtl::OUString m_ignoredUpdate;
+ std::vector< dp_gui::UpdateData > m_enabledUpdates;
+ std::vector< UpdateDialog::DisabledUpdate > m_disabledUpdates;
+ std::vector< UpdateDialog::SpecificError > m_specificErrors;
+ std::vector< UpdateDialog::IgnoredUpdate* > m_ignoredUpdates;
+ std::vector< Index* > m_ListboxEntries;
+ std::vector< dp_gui::UpdateData > & m_updateData;
+ rtl::Reference< UpdateDialog::Thread > m_thread;
+ ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XExtensionManager > m_xExtensionManager;
+
+ Point m_aFirstLinePos;
+ Size m_aFirstLineSize;
+ long m_nFirstLineDelta;
+ long m_nOneLineMissing;
+ sal_uInt16 m_nLastID;
+ bool m_bModified;
+};
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/gui/dp_gui_updatedialog.src b/desktop/source/deployment/gui/dp_gui_updatedialog.src
new file mode 100644
index 000000000000..b6b6bb7c41e3
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_updatedialog.src
@@ -0,0 +1,275 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "svtools/controldims.hrc"
+
+#include "dp_gui.hrc"
+
+#define LOCAL_WIDTH (60 * RSC_BS_CHARWIDTH)
+#define LABEL_WIDTH (1 * RSC_BS_CHARWIDTH)
+#define LOCAL_LIST_HEIGHT1 (6 * RSC_BS_CHARHEIGHT) + 4
+#define LOCAL_LIST_HEIGHT2 (7 * RSC_BS_CHARHEIGHT) + 3
+
+ModalDialog RID_DLG_UPDATE {
+ HelpID = HID_DEPLOYMENT_GUI_UPDATE;
+ Size = MAP_APPFONT(
+ (RSC_SP_DLG_INNERBORDER_LEFT + LOCAL_WIDTH +
+ RSC_SP_DLG_INNERBORDER_RIGHT),
+ (RSC_SP_DLG_INNERBORDER_TOP + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_DESC_Y + LOCAL_LIST_HEIGHT1 + RSC_SP_CTRL_GROUP_Y +
+ RSC_CD_CHECKBOX_HEIGHT + RSC_SP_CTRL_GROUP_Y + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_DESC_Y + LOCAL_LIST_HEIGHT2 + RSC_SP_FLGR_SPACE_Y +
+ RSC_CD_FIXEDLINE_HEIGHT + RSC_SP_FLGR_SPACE_Y +
+ RSC_CD_PUSHBUTTON_HEIGHT + RSC_SP_DLG_INNERBORDER_BOTTOM));
+ Text[en-US] = "Extension Update";
+ Moveable = TRUE;
+ Closeable = TRUE;
+ FixedText RID_DLG_UPDATE_CHECKING {
+ Pos = MAP_APPFONT(
+ RSC_SP_DLG_INNERBORDER_LEFT + LOCAL_WIDTH * 2 / 3,
+ RSC_SP_DLG_INNERBORDER_TOP);
+ Size = MAP_APPFONT(
+ (LOCAL_WIDTH - LOCAL_WIDTH * 2 / 3 - RSC_SP_CTRL_DESC_X -
+ RSC_CD_FIXEDTEXT_HEIGHT),
+ RSC_CD_FIXEDTEXT_HEIGHT);
+ Text[en-US] = "Checking...";
+ Right = TRUE;
+ NoLabel = TRUE;
+ };
+ FixedImage RID_DLG_UPDATE_THROBBER {
+ Pos = MAP_APPFONT(
+ RSC_SP_DLG_INNERBORDER_LEFT + LOCAL_WIDTH - RSC_CD_FIXEDTEXT_HEIGHT,
+ RSC_SP_DLG_INNERBORDER_TOP);
+ Size = MAP_APPFONT(RSC_CD_FIXEDTEXT_HEIGHT, RSC_CD_FIXEDTEXT_HEIGHT + 1);
+ };
+ FixedText RID_DLG_UPDATE_UPDATE {
+ Disable = TRUE;
+ Pos = MAP_APPFONT(
+ RSC_SP_DLG_INNERBORDER_LEFT, RSC_SP_DLG_INNERBORDER_TOP);
+ Size = MAP_APPFONT(
+ LOCAL_WIDTH * 2 / 3 - RSC_SP_CTRL_GROUP_X, RSC_CD_FIXEDTEXT_HEIGHT);
+ Text[en-US] = "~Available extension updates";
+ };
+ Control RID_DLG_UPDATE_UPDATES {
+ HelpId = HID_DEPLOYMENT_GUI_UPDATE_AVAILABLE_UPDATES;
+ Disable = TRUE;
+ Border = TRUE;
+ Pos = MAP_APPFONT(
+ RSC_SP_DLG_INNERBORDER_LEFT,
+ (RSC_SP_DLG_INNERBORDER_TOP + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_DESC_Y));
+ Size = MAP_APPFONT(LOCAL_WIDTH, LOCAL_LIST_HEIGHT1);
+ TabStop = TRUE;
+ };
+ CheckBox RID_DLG_UPDATE_ALL {
+ HelpID = "desktop:CheckBox:RID_DLG_UPDATE:RID_DLG_UPDATE_ALL";
+ Disable = TRUE;
+ Pos = MAP_APPFONT(
+ RSC_SP_DLG_INNERBORDER_LEFT,
+ (RSC_SP_DLG_INNERBORDER_TOP + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_DESC_Y + LOCAL_LIST_HEIGHT1 + RSC_SP_CTRL_GROUP_Y));
+ Size = MAP_APPFONT(LOCAL_WIDTH, RSC_CD_CHECKBOX_HEIGHT);
+ Text[en-US] = "~Show all updates";
+ };
+ FixedLine RID_DLG_UPDATE_DESCRIPTION {
+ Disable = TRUE;
+ Pos = MAP_APPFONT(
+ RSC_SP_DLG_INNERBORDER_LEFT,
+ (RSC_SP_DLG_INNERBORDER_TOP + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_DESC_Y + LOCAL_LIST_HEIGHT1 + RSC_SP_CTRL_GROUP_Y +
+ RSC_CD_CHECKBOX_HEIGHT + RSC_SP_CTRL_GROUP_Y));
+ Size = MAP_APPFONT(LOCAL_WIDTH, RSC_CD_FIXEDTEXT_HEIGHT);
+ Text[en-US] = "Description";
+ };
+ FixedText RID_DLG_UPDATE_PUBLISHER_LABEL
+ {
+ Pos = MAP_APPFONT(
+ RSC_SP_DLG_INNERBORDER_LEFT,
+ (RSC_SP_DLG_INNERBORDER_TOP + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_DESC_Y + LOCAL_LIST_HEIGHT1 + RSC_SP_CTRL_GROUP_Y +
+ RSC_CD_CHECKBOX_HEIGHT + RSC_SP_CTRL_GROUP_Y + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_DESC_Y));
+ Size = MAP_APPFONT(LABEL_WIDTH, RSC_CD_FIXEDTEXT_HEIGHT);
+ Text[en-US] = "Publisher:";
+ };
+ FixedText RID_DLG_UPDATE_PUBLISHER_LINK
+ {
+ HelpId = HID_DEPLOYMENT_GUI_UPDATE_PUBLISHER;
+ Pos = MAP_APPFONT(
+ RSC_SP_DLG_INNERBORDER_LEFT + LABEL_WIDTH + RSC_SP_CTRL_DESC_X,
+ (RSC_SP_DLG_INNERBORDER_TOP + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_DESC_Y + LOCAL_LIST_HEIGHT1 + RSC_SP_CTRL_GROUP_Y +
+ RSC_CD_CHECKBOX_HEIGHT + RSC_SP_CTRL_GROUP_Y + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_DESC_Y));
+ Size = MAP_APPFONT(LOCAL_WIDTH - LABEL_WIDTH - RSC_SP_CTRL_DESC_X, RSC_CD_FIXEDTEXT_HEIGHT);
+ };
+ FixedText RID_DLG_UPDATE_RELEASENOTES_LABEL
+ {
+ Pos = MAP_APPFONT(
+ RSC_SP_DLG_INNERBORDER_LEFT,
+ (RSC_SP_DLG_INNERBORDER_TOP + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_DESC_Y + LOCAL_LIST_HEIGHT1 + RSC_SP_CTRL_GROUP_Y +
+ RSC_CD_CHECKBOX_HEIGHT + RSC_SP_CTRL_GROUP_Y + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_DESC_Y + RSC_CD_FIXEDTEXT_HEIGHT + RSC_SP_CTRL_DESC_Y));
+ Size = MAP_APPFONT(LABEL_WIDTH, RSC_CD_FIXEDTEXT_HEIGHT);
+ Text[en-US] = "What is new:";
+ };
+ FixedText RID_DLG_UPDATE_RELEASENOTES_LINK
+ {
+ HelpId = HID_DEPLOYMENT_GUI_UPDATE_RELEASENOTES;
+ Pos = MAP_APPFONT(
+ RSC_SP_DLG_INNERBORDER_LEFT + LABEL_WIDTH + RSC_SP_CTRL_DESC_X,
+ (RSC_SP_DLG_INNERBORDER_TOP + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_DESC_Y + LOCAL_LIST_HEIGHT1 + RSC_SP_CTRL_GROUP_Y +
+ RSC_CD_CHECKBOX_HEIGHT + RSC_SP_CTRL_GROUP_Y + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_DESC_Y + RSC_CD_FIXEDTEXT_HEIGHT + RSC_SP_CTRL_DESC_Y));
+ Size = MAP_APPFONT(LOCAL_WIDTH - LABEL_WIDTH - RSC_SP_CTRL_DESC_X, RSC_CD_FIXEDTEXT_HEIGHT);
+ Text[en-US] = "Release Notes";
+ };
+ MultiLineEdit RID_DLG_UPDATE_DESCRIPTIONS {
+ HelpID = "desktop:MultiLineEdit:RID_DLG_UPDATE:RID_DLG_UPDATE_DESCRIPTIONS";
+ Disable = TRUE;
+ Border = TRUE;
+ Pos = MAP_APPFONT(
+ RSC_SP_DLG_INNERBORDER_LEFT,
+ (RSC_SP_DLG_INNERBORDER_TOP + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_DESC_Y + LOCAL_LIST_HEIGHT1 + RSC_SP_CTRL_GROUP_Y +
+ RSC_CD_CHECKBOX_HEIGHT + RSC_SP_CTRL_GROUP_Y + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_DESC_Y));
+ Size = MAP_APPFONT(LOCAL_WIDTH, LOCAL_LIST_HEIGHT2);
+ ReadOnly = TRUE;
+ VScroll = TRUE;
+ IgnoreTab = TRUE;
+ };
+ FixedLine RID_DLG_UPDATE_LINE {
+ Pos = MAP_APPFONT(
+ RSC_SP_DLG_INNERBORDER_LEFT,
+ (RSC_SP_DLG_INNERBORDER_TOP + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_DESC_Y + LOCAL_LIST_HEIGHT1 + RSC_SP_CTRL_GROUP_Y +
+ RSC_CD_CHECKBOX_HEIGHT + RSC_SP_CTRL_GROUP_Y + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_DESC_Y + LOCAL_LIST_HEIGHT2 + RSC_SP_FLGR_SPACE_Y));
+ Size = MAP_APPFONT(LOCAL_WIDTH, RSC_CD_FIXEDLINE_HEIGHT);
+ };
+ HelpButton RID_DLG_UPDATE_HELP {
+ Pos = MAP_APPFONT(
+ RSC_SP_DLG_INNERBORDER_LEFT,
+ (RSC_SP_DLG_INNERBORDER_TOP + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_DESC_Y + LOCAL_LIST_HEIGHT1 + RSC_SP_CTRL_GROUP_Y +
+ RSC_CD_CHECKBOX_HEIGHT + RSC_SP_CTRL_GROUP_Y + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_DESC_Y + LOCAL_LIST_HEIGHT2 + RSC_SP_FLGR_SPACE_Y +
+ RSC_CD_FIXEDLINE_HEIGHT + RSC_SP_FLGR_SPACE_Y));
+ Size = MAP_APPFONT(RSC_CD_PUSHBUTTON_WIDTH, RSC_CD_PUSHBUTTON_HEIGHT);
+ };
+ PushButton RID_DLG_UPDATE_OK {
+ HelpID = "desktop:PushButton:RID_DLG_UPDATE:RID_DLG_UPDATE_OK";
+ Disable = TRUE;
+ Pos = MAP_APPFONT(
+ (RSC_SP_DLG_INNERBORDER_LEFT + LOCAL_WIDTH - RSC_CD_PUSHBUTTON_WIDTH -
+ RSC_SP_CTRL_GROUP_X - RSC_CD_PUSHBUTTON_WIDTH),
+ (RSC_SP_DLG_INNERBORDER_TOP + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_DESC_Y + LOCAL_LIST_HEIGHT1 + RSC_SP_CTRL_GROUP_Y +
+ RSC_CD_CHECKBOX_HEIGHT + RSC_SP_CTRL_GROUP_Y + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_DESC_Y + LOCAL_LIST_HEIGHT2 + RSC_SP_FLGR_SPACE_Y +
+ RSC_CD_FIXEDLINE_HEIGHT + RSC_SP_FLGR_SPACE_Y));
+ Size = MAP_APPFONT(RSC_CD_PUSHBUTTON_WIDTH, RSC_CD_PUSHBUTTON_HEIGHT);
+ Text[en-US] = "~Install";
+ DefButton = TRUE;
+ };
+ PushButton RID_DLG_UPDATE_CLOSE {
+ Pos = MAP_APPFONT(
+ RSC_SP_DLG_INNERBORDER_LEFT + LOCAL_WIDTH - RSC_CD_PUSHBUTTON_WIDTH,
+ (RSC_SP_DLG_INNERBORDER_TOP + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_DESC_Y + LOCAL_LIST_HEIGHT1 + RSC_SP_CTRL_GROUP_Y +
+ RSC_CD_CHECKBOX_HEIGHT + RSC_SP_CTRL_GROUP_Y + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_DESC_Y + LOCAL_LIST_HEIGHT2 + RSC_SP_FLGR_SPACE_Y +
+ RSC_CD_FIXEDLINE_HEIGHT + RSC_SP_FLGR_SPACE_Y));
+ Size = MAP_APPFONT(RSC_CD_PUSHBUTTON_WIDTH, RSC_CD_PUSHBUTTON_HEIGHT);
+ Text[en-US] = "Close";
+ };
+
+ Image RID_DLG_UPDATE_NORMALALERT {
+ ImageBitmap = Bitmap {
+ File = "caution_12.png";
+ };
+ };
+ String RID_DLG_UPDATE_ERROR {
+ Text[en-US] = "Error";
+ };
+ String RID_DLG_UPDATE_NONE {
+ Text[en-US] = "No new updates are available.";
+ };
+ String RID_DLG_UPDATE_NOINSTALLABLE {
+ Text[en-US] = "No installable updates are available. To see ignored or disabled updates, mark the check box 'Show all updates'.";
+ };
+ String RID_DLG_UPDATE_FAILURE {
+ Text[en-US] = "An error occurred:";
+ };
+ String RID_DLG_UPDATE_UNKNOWNERROR {
+ Text[en-US] = "Unknown error.";
+ };
+ String RID_DLG_UPDATE_NODESCRIPTION {
+ Text[en-US] = "No more details are available for this update.";
+ };
+ String RID_DLG_UPDATE_NOINSTALL {
+ Text[en-US] = "The extension cannot be updated because:";
+ };
+ String RID_DLG_UPDATE_NODEPENDENCY {
+ Text[en-US] = "Required %PRODUCTNAME version doesn't match:";
+ };
+ String RID_DLG_UPDATE_NODEPENDENCY_CUR_VER {
+ Text[en-US] = "You have %PRODUCTNAME %VERSION";
+ };
+ String RID_DLG_UPDATE_BROWSERBASED {
+ Text[en-US] = "browser based update";
+ };
+ String RID_DLG_UPDATE_VERSION {
+ Text[en-US] = "Version";
+ };
+ String RID_DLG_UPDATE_IGNORE {
+ Text[en-US] = "Ignore this Update";
+ };
+ String RID_DLG_UPDATE_IGNORE_ALL {
+ Text[en-US] = "Ignore all Updates";
+ };
+ String RID_DLG_UPDATE_ENABLE {
+ Text[en-US] = "Enable Updates";
+ };
+ String RID_DLG_UPDATE_IGNORED_UPDATE {
+ Text[en-US] = "This update will be ignored.\n";
+ };
+};
+
+WarningBox RID_WARNINGBOX_UPDATE_SHARED_EXTENSION
+{
+ Buttons = WB_OK_CANCEL;
+ DefButton = WB_DEF_CANCEL;
+ Message[en-US] = "Make sure that no further users are working with the same "
+ "%PRODUCTNAME, when changing shared extensions in a multi user environment.\n"
+ "Click \'OK\' to update the extensions.\n"
+ "Click \'Cancel\' to stop updating the extensions.";
+};
+
diff --git a/desktop/source/deployment/gui/dp_gui_updateinstalldialog.cxx b/desktop/source/deployment/gui/dp_gui_updateinstalldialog.cxx
new file mode 100644
index 000000000000..696c2fe3ef0c
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_updateinstalldialog.cxx
@@ -0,0 +1,757 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include "dp_gui_updatedata.hxx"
+
+#include "sal/config.h"
+#include "osl/file.hxx"
+#include "osl/conditn.hxx"
+#include "cppuhelper/exc_hlp.hxx"
+#include "tools/resid.hxx"
+#include "tools/resmgr.hxx"
+#include "tools/solar.h"
+#include "tools/string.hxx"
+#include "vcl/dialog.hxx"
+#include "vcl/msgbox.hxx"
+#include "vcl/svapp.hxx"
+#include "osl/mutex.hxx"
+#include "vcl/dialog.hxx"
+#include "cppuhelper/implbase3.hxx"
+
+#include "com/sun/star/beans/PropertyValue.hpp"
+#include "com/sun/star/beans/NamedValue.hpp"
+#include "com/sun/star/xml/dom/XElement.hpp"
+#include "com/sun/star/xml/dom/XNode.hpp"
+#include "com/sun/star/xml/dom/XNodeList.hpp"
+#include "com/sun/star/ucb/NameClash.hpp"
+#include "com/sun/star/ucb/InteractiveAugmentedIOException.hpp"
+#include "com/sun/star/ucb/XCommandEnvironment.hpp"
+#include "com/sun/star/ucb/XProgressHandler.hpp"
+#include "com/sun/star/deployment/XExtensionManager.hpp"
+#include "com/sun/star/deployment/ExtensionManager.hpp"
+#include "com/sun/star/deployment/XUpdateInformationProvider.hpp"
+#include "com/sun/star/deployment/DependencyException.hpp"
+#include "com/sun/star/deployment/LicenseException.hpp"
+#include "com/sun/star/deployment/VersionException.hpp"
+#include "com/sun/star/deployment/ui/LicenseDialog.hpp"
+#include "com/sun/star/task/XInteractionHandler.hpp"
+#include "com/sun/star/ui/dialogs/XExecutableDialog.hpp"
+#include "com/sun/star/ui/dialogs/ExecutableDialogResults.hpp"
+#include "com/sun/star/task/XInteractionAbort.hpp"
+#include "com/sun/star/task/XInteractionApprove.hpp"
+
+#include "dp_descriptioninfoset.hxx"
+#include "dp_gui.hrc"
+#include "dp_gui_updateinstalldialog.hxx"
+#include "dp_gui_shared.hxx"
+#include "dp_gui_updatedata.hxx"
+#include "dp_ucb.h"
+#include "dp_misc.h"
+#include "dp_version.hxx"
+#include "dp_gui_thread.hxx"
+#include "dp_gui_extensioncmdqueue.hxx"
+#include "ucbhelper/content.hxx"
+#include "osl/mutex.hxx"
+#include "osl/mutex.hxx"
+#include "rtl/ref.hxx"
+#include "com/sun/star/uno/Sequence.h"
+#include "comphelper/anytostring.hxx"
+#include "toolkit/helper/vclunohelper.hxx"
+
+#include <vector>
+
+class Window;
+
+namespace cssu = ::com::sun::star::uno;
+namespace css = ::com::sun::star;
+
+using ::rtl::OUString;
+
+
+namespace dp_gui {
+
+class UpdateInstallDialog::Thread: public dp_gui::Thread {
+ friend class UpdateCommandEnv;
+public:
+ Thread(cssu::Reference< cssu::XComponentContext > ctx,
+ UpdateInstallDialog & dialog, std::vector< dp_gui::UpdateData > & aVecUpdateData);
+
+ void stop();
+
+
+
+private:
+ Thread(Thread &); // not defined
+ void operator =(Thread &); // not defined
+
+ virtual ~Thread();
+
+ virtual void execute();
+ void downloadExtensions();
+ void download(::rtl::OUString const & aUrls, UpdateData & aUpdatData);
+ void installExtensions();
+ void removeTempDownloads();
+
+ UpdateInstallDialog & m_dialog;
+ cssu::Reference< css::deployment::XUpdateInformationProvider >
+ m_updateInformation;
+
+ // guarded by Application::GetSolarMutex():
+ cssu::Reference< css::task::XAbortChannel > m_abort;
+ cssu::Reference< cssu::XComponentContext > m_xComponentContext;
+ std::vector< dp_gui::UpdateData > & m_aVecUpdateData;
+ ::rtl::Reference<UpdateCommandEnv> m_updateCmdEnv;
+
+ //A folder which is created in the temp directory in which then the updates are downloaded
+ ::rtl::OUString m_sDownloadFolder;
+
+ bool m_stop;
+
+};
+
+class UpdateCommandEnv
+ : public ::cppu::WeakImplHelper3< css::ucb::XCommandEnvironment,
+ css::task::XInteractionHandler,
+ css::ucb::XProgressHandler >
+{
+ friend class UpdateInstallDialog::Thread;
+
+ UpdateInstallDialog & m_updateDialog;
+ ::rtl::Reference<UpdateInstallDialog::Thread> m_installThread;
+ cssu::Reference< cssu::XComponentContext > m_xContext;
+
+public:
+ virtual ~UpdateCommandEnv();
+ UpdateCommandEnv( cssu::Reference< cssu::XComponentContext > const & xCtx,
+ UpdateInstallDialog & updateDialog,
+ ::rtl::Reference<UpdateInstallDialog::Thread>const & thread);
+
+ // XCommandEnvironment
+ virtual cssu::Reference<css::task::XInteractionHandler > SAL_CALL
+ getInteractionHandler() throw (cssu::RuntimeException);
+ virtual cssu::Reference<css::ucb::XProgressHandler >
+ SAL_CALL getProgressHandler() throw (cssu::RuntimeException);
+
+ // XInteractionHandler
+ virtual void SAL_CALL handle(
+ cssu::Reference<css::task::XInteractionRequest > const & xRequest )
+ throw (cssu::RuntimeException);
+
+ // XProgressHandler
+ virtual void SAL_CALL push( cssu::Any const & Status )
+ throw (cssu::RuntimeException);
+ virtual void SAL_CALL update( cssu::Any const & Status )
+ throw (cssu::RuntimeException);
+ virtual void SAL_CALL pop() throw (cssu::RuntimeException);
+};
+
+
+UpdateInstallDialog::Thread::Thread(
+ cssu::Reference< cssu::XComponentContext> xCtx,
+ UpdateInstallDialog & dialog,
+ std::vector< dp_gui::UpdateData > & aVecUpdateData):
+ m_dialog(dialog),
+ m_xComponentContext(xCtx),
+ m_aVecUpdateData(aVecUpdateData),
+ m_updateCmdEnv(new UpdateCommandEnv(xCtx, m_dialog, this)),
+ m_stop(false)
+{}
+
+void UpdateInstallDialog::Thread::stop() {
+ cssu::Reference< css::task::XAbortChannel > abort;
+ {
+ SolarMutexGuard g;
+ abort = m_abort;
+ m_stop = true;
+ }
+ if (abort.is()) {
+ abort->sendAbort();
+ }
+}
+
+UpdateInstallDialog::Thread::~Thread() {}
+
+void UpdateInstallDialog::Thread::execute()
+{
+ try {
+ downloadExtensions();
+ installExtensions();
+ }
+ catch (...)
+ {
+ }
+
+ //clean up the temp directories
+ try {
+ removeTempDownloads();
+ } catch( ... ) {
+ }
+
+ {
+ //make sure m_dialog is still alive
+ SolarMutexGuard g;
+ if (! m_stop)
+ m_dialog.updateDone();
+ }
+ //UpdateCommandEnv keeps a reference to Thread and prevents destruction. Therefore remove it.
+ m_updateCmdEnv->m_installThread.clear();
+}
+
+
+UpdateInstallDialog::UpdateInstallDialog(
+ Window * parent,
+ std::vector<dp_gui::UpdateData> & aVecUpdateData,
+ cssu::Reference< cssu::XComponentContext > const & xCtx):
+ ModalDialog(
+ parent,
+ DpGuiResId(RID_DLG_UPDATEINSTALL)),
+
+ m_thread(new Thread(xCtx, *this, aVecUpdateData)),
+ m_xComponentContext(xCtx),
+ m_bError(false),
+ m_bNoEntry(true),
+ m_bActivated(false),
+ m_sInstalling(String(DpGuiResId(RID_DLG_UPDATE_INSTALL_INSTALLING))),
+ m_sFinished(String(DpGuiResId(RID_DLG_UPDATE_INSTALL_FINISHED))),
+ m_sNoErrors(String(DpGuiResId(RID_DLG_UPDATE_INSTALL_NO_ERRORS))),
+ m_sErrorDownload(String(DpGuiResId(RID_DLG_UPDATE_INSTALL_ERROR_DOWNLOAD))),
+ m_sErrorInstallation(String(DpGuiResId(RID_DLG_UPDATE_INSTALL_ERROR_INSTALLATION))),
+ m_sErrorLicenseDeclined(String(DpGuiResId(RID_DLG_UPDATE_INSTALL_ERROR_LIC_DECLINED))),
+ m_sNoInstall(String(DpGuiResId(RID_DLG_UPDATE_INSTALL_EXTENSION_NOINSTALL))),
+ m_sThisErrorOccurred(String(DpGuiResId(RID_DLG_UPDATE_INSTALL_THIS_ERROR_OCCURRED))),
+ m_ft_action(this, DpGuiResId(RID_DLG_UPDATE_INSTALL_DOWNLOADING)),
+ m_statusbar(this,DpGuiResId(RID_DLG_UPDATE_INSTALL_STATUSBAR)),
+ m_ft_extension_name(this, DpGuiResId(RID_DLG_UPDATE_INSTALL_EXTENSION_NAME)),
+ m_ft_results(this, DpGuiResId(RID_DLG_UPDATE_INSTALL_RESULTS)),
+ m_mle_info(this, DpGuiResId(RID_DLG_UPDATE_INSTALL_INFO)),
+ m_line(this, DpGuiResId(RID_DLG_UPDATE_INSTALL_LINE)),
+ m_help(this, DpGuiResId(RID_DLG_UPDATE_INSTALL_HELP)),
+ m_ok(this, DpGuiResId(RID_DLG_UPDATE_INSTALL_OK)),
+ m_cancel(this, DpGuiResId(RID_DLG_UPDATE_INSTALL_ABORT))
+{
+ FreeResource();
+
+ m_xExtensionManager = css::deployment::ExtensionManager::get( xCtx );
+
+ m_cancel.SetClickHdl(LINK(this, UpdateInstallDialog, cancelHandler));
+ m_mle_info.EnableCursor(sal_False);
+ if ( ! dp_misc::office_is_running())
+ m_help.Disable();
+}
+
+UpdateInstallDialog::~UpdateInstallDialog() {}
+
+sal_Bool UpdateInstallDialog::Close()
+{
+ m_thread->stop();
+ return ModalDialog::Close();
+}
+
+short UpdateInstallDialog::Execute()
+{
+ m_thread->launch();
+ return ModalDialog::Execute();
+}
+
+
+// make sure the solar mutex is locked before calling
+void UpdateInstallDialog::updateDone()
+{
+ if (!m_bError)
+ m_mle_info.InsertText(m_sNoErrors);
+ m_ok.Enable();
+ m_ok.GrabFocus();
+ m_cancel.Disable();
+}
+// make sure the solar mutex is locked before calling
+//sets an error message in the text area
+void UpdateInstallDialog::setError(INSTALL_ERROR err, ::rtl::OUString const & sExtension,
+ OUString const & exceptionMessage)
+{
+ String sError;
+ m_bError = true;
+
+ switch (err)
+ {
+ case ERROR_DOWNLOAD:
+ sError = m_sErrorDownload;
+ break;
+ case ERROR_INSTALLATION:
+ sError = m_sErrorInstallation;
+ break;
+ case ERROR_LICENSE_DECLINED:
+ sError = m_sErrorLicenseDeclined;
+ break;
+
+ default:
+ OSL_ASSERT(0);
+ }
+
+ sError.SearchAndReplace(String(OUSTR("%NAME")), String(sExtension), 0);
+ //We want to have an empty line between the error messages. However,
+ //there shall be no empty line after the last entry.
+ if (m_bNoEntry)
+ m_bNoEntry = false;
+ else
+ m_mle_info.InsertText(OUSTR("\n"));
+ m_mle_info.InsertText(sError);
+ //Insert more information about the error
+ if (exceptionMessage.getLength())
+ m_mle_info.InsertText(m_sThisErrorOccurred + exceptionMessage + OUSTR("\n"));
+
+ m_mle_info.InsertText(m_sNoInstall);
+ m_mle_info.InsertText(OUSTR("\n"));
+}
+
+void UpdateInstallDialog::setError(OUString const & exceptionMessage)
+{
+ m_bError = true;
+ m_mle_info.InsertText(exceptionMessage + OUSTR("\n"));
+}
+
+IMPL_LINK(UpdateInstallDialog, cancelHandler, void *, EMPTYARG)
+{
+ m_thread->stop();
+ EndDialog(RET_CANCEL);
+ return 0;
+}
+
+//------------------------------------------------------------------------------------------------
+
+void UpdateInstallDialog::Thread::downloadExtensions()
+{
+ try
+ {
+ //create the download directory in the temp folder
+ OUString sTempDir;
+ if (::osl::FileBase::getTempDirURL(sTempDir) != ::osl::FileBase::E_None)
+ throw cssu::Exception(OUSTR("Could not get URL for the temp directory. No extensions will be installed."), 0);
+
+ //create a unique name for the directory
+ OUString tempEntry, destFolder;
+ if (::osl::File::createTempFile(&sTempDir, 0, &tempEntry ) != ::osl::File::E_None)
+ throw cssu::Exception(OUSTR("Could not create a temporary file in ") + sTempDir +
+ OUSTR(". No extensions will be installed"), 0 );
+
+ tempEntry = tempEntry.copy( tempEntry.lastIndexOf( '/' ) + 1 );
+
+ destFolder = dp_misc::makeURL( sTempDir, tempEntry );
+ destFolder += OUSTR("_");
+ m_sDownloadFolder = destFolder;
+ try
+ {
+ dp_misc::create_folder(0, destFolder, m_updateCmdEnv.get(), true );
+ } catch (cssu::Exception & e)
+ {
+ throw cssu::Exception(e.Message + OUSTR(" No extensions will be installed."), 0);
+ }
+
+
+ sal_uInt16 count = 0;
+ typedef std::vector<UpdateData>::iterator It;
+ for (It i = m_aVecUpdateData.begin(); i != m_aVecUpdateData.end(); ++i)
+ {
+ UpdateData & curData = *i;
+
+ if (!curData.aUpdateInfo.is() || curData.aUpdateSource.is())
+ continue;
+ //We assume that m_aVecUpdateData contains only information about extensions which
+ //can be downloaded directly.
+ OSL_ASSERT(curData.sWebsiteURL.getLength() == 0);
+
+ //update the name of the extension which is to be downloaded
+ {
+ SolarMutexGuard g;
+ if (m_stop) {
+ return;
+ }
+ m_dialog.m_ft_extension_name.SetText(curData.aInstalledPackage->getDisplayName());
+ sal_uInt16 prog = (sal::static_int_cast<sal_uInt16>(100) * ++count) /
+ sal::static_int_cast<sal_uInt16>(m_aVecUpdateData.size());
+ m_dialog.m_statusbar.SetValue(prog);
+ }
+ dp_misc::DescriptionInfoset info(m_xComponentContext, curData.aUpdateInfo);
+ //remember occurring exceptions in case we need to print out error information
+ ::std::vector< ::std::pair<OUString, cssu::Exception> > vecExceptions;
+ cssu::Sequence<OUString> seqDownloadURLs = info.getUpdateDownloadUrls();
+ OSL_ENSURE(seqDownloadURLs.getLength() > 0, "No download URL provided!");
+ for (sal_Int32 j = 0; j < seqDownloadURLs.getLength(); j++)
+ {
+ try
+ {
+ OSL_ENSURE(seqDownloadURLs[j].getLength() > 0, "Download URL is empty!");
+ download(seqDownloadURLs[j], curData);
+ if (curData.sLocalURL.getLength() > 0)
+ break;
+ }
+ catch ( cssu::Exception & e )
+ {
+ vecExceptions.push_back( ::std::make_pair(seqDownloadURLs[j], e));
+ //There can be several different errors, for example, the URL is wrong, webserver cannot be reached,
+ //name cannot be resolved. The UCB helper API does not specify different special exceptions for these
+ //cases. Therefore ignore and continue.
+ continue;
+ }
+ }
+ //update the progress and display download error
+ {
+ SolarMutexGuard g;
+ if (m_stop) {
+ return;
+ }
+ if (curData.sLocalURL.getLength() == 0)
+ {
+ //Construct a string of all messages contained in the exceptions plus the respective download URLs
+ ::rtl::OUStringBuffer buf(256);
+ typedef ::std::vector< ::std::pair<OUString, cssu::Exception > >::const_iterator CIT;
+ for (CIT j = vecExceptions.begin(); j != vecExceptions.end(); j++)
+ {
+ if (j != vecExceptions.begin())
+ buf.appendAscii("\n");
+ buf.append(OUSTR("Could not download "));
+ buf.append(j->first);
+ buf.appendAscii(". ");
+ buf.append(j->second.Message);
+ }
+ m_dialog.setError(UpdateInstallDialog::ERROR_DOWNLOAD, curData.aInstalledPackage->getDisplayName(),
+ buf.makeStringAndClear());
+ }
+ }
+
+ }
+ }
+ catch (cssu::Exception & e)
+ {
+ SolarMutexGuard g;
+ if (m_stop) {
+ return;
+ }
+ m_dialog.setError(e.Message);
+ }
+}
+void UpdateInstallDialog::Thread::installExtensions()
+{
+ //Update the fix text in the dialog to "Installing extensions..."
+ {
+ SolarMutexGuard g;
+ if (m_stop) {
+ return;
+ }
+ m_dialog.m_ft_action.SetText(m_dialog.m_sInstalling);
+ m_dialog.m_statusbar.SetValue(0);
+ }
+
+ sal_uInt16 count = 0;
+ typedef std::vector<UpdateData>::iterator It;
+ for (It i = m_aVecUpdateData.begin(); i != m_aVecUpdateData.end(); ++i, ++count)
+ {
+ //update the name of the extension which is to be installed
+ {
+ SolarMutexGuard g;
+ if (m_stop) {
+ return;
+ }
+ //we only show progress after an extension has been installed.
+ if (count > 0) {
+ m_dialog.m_statusbar.SetValue(
+ (sal::static_int_cast<sal_uInt16>(100) * count) /
+ sal::static_int_cast<sal_uInt16>(m_aVecUpdateData.size()));
+ }
+ m_dialog.m_ft_extension_name.SetText(i->aInstalledPackage->getDisplayName());
+ }
+ bool bError = false;
+ bool bLicenseDeclined = false;
+ cssu::Reference<css::deployment::XPackage> xExtension;
+ UpdateData & curData = *i;
+ cssu::Exception exc;
+ try
+ {
+ cssu::Reference< css::task::XAbortChannel > xAbortChannel(
+ curData.aInstalledPackage->createAbortChannel() );
+ {
+ SolarMutexGuard g;
+ if (m_stop) {
+ return;
+ }
+ m_abort = xAbortChannel;
+ }
+ if (!curData.aUpdateSource.is() && curData.sLocalURL.getLength())
+ {
+ css::beans::NamedValue prop(OUSTR("EXTENSION_UPDATE"), css::uno::makeAny(OUSTR("1")));
+ if (!curData.bIsShared)
+ xExtension = m_dialog.getExtensionManager()->addExtension(
+ curData.sLocalURL, css::uno::Sequence<css::beans::NamedValue>(&prop, 1),
+ OUSTR("user"), xAbortChannel, m_updateCmdEnv.get());
+ else
+ xExtension = m_dialog.getExtensionManager()->addExtension(
+ curData.sLocalURL, css::uno::Sequence<css::beans::NamedValue>(&prop, 1),
+ OUSTR("shared"), xAbortChannel, m_updateCmdEnv.get());
+ }
+ else if (curData.aUpdateSource.is())
+ {
+ OSL_ASSERT(curData.aUpdateSource.is());
+ //I am not sure if we should obtain the install properties and pass them into
+ //add extension. Currently it contains only "SUPPRESS_LICENSE". So it it could happen
+ //that a license is displayed when updating from the shared repository, although the
+ //shared extension was installed using "SUPPRESS_LICENSE".
+ css::beans::NamedValue prop(OUSTR("EXTENSION_UPDATE"), css::uno::makeAny(OUSTR("1")));
+ if (!curData.bIsShared)
+ xExtension = m_dialog.getExtensionManager()->addExtension(
+ curData.aUpdateSource->getURL(), css::uno::Sequence<css::beans::NamedValue>(&prop, 1),
+ OUSTR("user"), xAbortChannel, m_updateCmdEnv.get());
+ else
+ xExtension = m_dialog.getExtensionManager()->addExtension(
+ curData.aUpdateSource->getURL(), css::uno::Sequence<css::beans::NamedValue>(&prop, 1),
+ OUSTR("shared"), xAbortChannel, m_updateCmdEnv.get());
+ }
+ }
+ catch (css::deployment::DeploymentException & de)
+ {
+ if (de.Cause.has<css::deployment::LicenseException>())
+ {
+ bLicenseDeclined = true;
+ }
+ else
+ {
+ exc = de.Cause.get<cssu::Exception>();
+ bError = true;
+ }
+ }
+ catch (cssu::Exception& e)
+ {
+ exc = e;
+ bError = true;
+ }
+
+ if (bLicenseDeclined)
+ {
+ SolarMutexGuard g;
+ if (m_stop) {
+ return;
+ }
+ m_dialog.setError(UpdateInstallDialog::ERROR_LICENSE_DECLINED,
+ curData.aInstalledPackage->getDisplayName(), OUString());
+ }
+ else if (!xExtension.is() || bError)
+ {
+ SolarMutexGuard g;
+ if (m_stop) {
+ return;
+ }
+ m_dialog.setError(UpdateInstallDialog::ERROR_INSTALLATION,
+ curData.aInstalledPackage->getDisplayName(), exc.Message);
+ }
+ }
+ {
+ SolarMutexGuard g;
+ if (m_stop) {
+ return;
+ }
+ m_dialog.m_statusbar.SetValue(100);
+ m_dialog.m_ft_extension_name.SetText(OUString());
+ m_dialog.m_ft_action.SetText(m_dialog.m_sFinished);
+ }
+}
+
+void UpdateInstallDialog::Thread::removeTempDownloads()
+{
+ if (m_sDownloadFolder.getLength())
+ {
+ dp_misc::erase_path(m_sDownloadFolder,
+ cssu::Reference<css::ucb::XCommandEnvironment>(),false /* no throw: ignore errors */ );
+ //remove also the temp file which we have used to create the unique name
+ OUString tempFile = m_sDownloadFolder.copy(0, m_sDownloadFolder.getLength() - 1);
+ dp_misc::erase_path(tempFile, cssu::Reference<css::ucb::XCommandEnvironment>(),false);
+ m_sDownloadFolder = OUString();
+ }
+}
+
+
+void UpdateInstallDialog::Thread::download(OUString const & sDownloadURL, UpdateData & aUpdateData)
+{
+ {
+ SolarMutexGuard g;
+ if (m_stop) {
+ return;
+ }
+ }
+
+ OSL_ASSERT(m_sDownloadFolder.getLength());
+ OUString destFolder, tempEntry;
+ if (::osl::File::createTempFile(
+ &m_sDownloadFolder,
+ 0, &tempEntry ) != ::osl::File::E_None)
+ {
+ //ToDo feedback in window that download of this component failed
+ throw cssu::Exception(OUSTR("Could not create temporary file in folder ") + destFolder + OUSTR("."), 0);
+ }
+ tempEntry = tempEntry.copy( tempEntry.lastIndexOf( '/' ) + 1 );
+
+ destFolder = dp_misc::makeURL( m_sDownloadFolder, tempEntry );
+ destFolder += OUSTR("_");
+
+ ::ucbhelper::Content destFolderContent;
+ dp_misc::create_folder( &destFolderContent, destFolder, m_updateCmdEnv.get() );
+
+ ::ucbhelper::Content sourceContent;
+ dp_misc::create_ucb_content( &sourceContent, sDownloadURL, m_updateCmdEnv.get() );
+
+ const OUString sTitle(sourceContent.getPropertyValue(
+ dp_misc::StrTitle::get() ).get<OUString>() );
+
+ if (destFolderContent.transferContent(
+ sourceContent, ::ucbhelper::InsertOperation_COPY,
+ sTitle, css::ucb::NameClash::OVERWRITE ))
+ {
+ //the user may have cancelled the dialog because downloading took to long
+ {
+ SolarMutexGuard g;
+ if (m_stop) {
+ return;
+ }
+ //all errors should be handeld by the command environment.
+ aUpdateData.sLocalURL = destFolder + OUString( RTL_CONSTASCII_USTRINGPARAM( "/" ) ) + sTitle;
+ }
+ }
+}
+
+
+// -------------------------------------------------------------------------------------------------------
+
+UpdateCommandEnv::UpdateCommandEnv( cssu::Reference< cssu::XComponentContext > const & xCtx,
+ UpdateInstallDialog & updateDialog,
+ ::rtl::Reference<UpdateInstallDialog::Thread>const & thread)
+ : m_updateDialog( updateDialog ),
+ m_installThread(thread),
+ m_xContext(xCtx)
+{
+}
+
+UpdateCommandEnv::~UpdateCommandEnv()
+{
+}
+
+
+// XCommandEnvironment
+//______________________________________________________________________________
+cssu::Reference<css::task::XInteractionHandler> UpdateCommandEnv::getInteractionHandler()
+throw (cssu::RuntimeException)
+{
+ return this;
+}
+
+//______________________________________________________________________________
+cssu::Reference<css::ucb::XProgressHandler> UpdateCommandEnv::getProgressHandler()
+throw (cssu::RuntimeException)
+{
+ return this;
+}
+
+// XInteractionHandler
+void UpdateCommandEnv::handle(
+ cssu::Reference< css::task::XInteractionRequest> const & xRequest )
+ throw (cssu::RuntimeException)
+{
+ cssu::Any request( xRequest->getRequest() );
+ OSL_ASSERT( request.getValueTypeClass() == cssu::TypeClass_EXCEPTION );
+ dp_misc::TRACE(OUSTR("[dp_gui_cmdenv.cxx] incoming request:\n")
+ + ::comphelper::anyToString(request) + OUSTR("\n\n"));
+
+ css::deployment::VersionException verExc;
+ bool approve = false;
+ bool abort = false;
+
+ if (request >>= verExc)
+ { //We must catch the version exception during the update,
+ //because otherwise the user would be confronted with the dialogs, asking
+ //them if they want to replace an already installed version of the same extension.
+ //During an update we assume that we always want to replace the old version with the
+ //new version.
+ approve = true;
+ }
+
+ if (approve == false && abort == false)
+ {
+ //forward to interaction handler for main dialog.
+ handleInteractionRequest( m_xContext, xRequest );
+ }
+ else
+ {
+ // select:
+ cssu::Sequence< cssu::Reference< css::task::XInteractionContinuation > > conts(
+ xRequest->getContinuations() );
+ cssu::Reference< css::task::XInteractionContinuation > const * pConts =
+ conts.getConstArray();
+ sal_Int32 len = conts.getLength();
+ for ( sal_Int32 pos = 0; pos < len; ++pos )
+ {
+ if (approve) {
+ cssu::Reference< css::task::XInteractionApprove > xInteractionApprove(
+ pConts[ pos ], cssu::UNO_QUERY );
+ if (xInteractionApprove.is()) {
+ xInteractionApprove->select();
+ // don't query again for ongoing continuations:
+ approve = false;
+ }
+ }
+ else if (abort) {
+ cssu::Reference< css::task::XInteractionAbort > xInteractionAbort(
+ pConts[ pos ], cssu::UNO_QUERY );
+ if (xInteractionAbort.is()) {
+ xInteractionAbort->select();
+ // don't query again for ongoing continuations:
+ abort = false;
+ }
+ }
+ }
+ }
+}
+
+// XProgressHandler
+void UpdateCommandEnv::push( cssu::Any const & /*Status*/ )
+throw (cssu::RuntimeException)
+{
+}
+
+
+void UpdateCommandEnv::update( cssu::Any const & /*Status */)
+throw (cssu::RuntimeException)
+{
+}
+
+void UpdateCommandEnv::pop() throw (cssu::RuntimeException)
+{
+}
+
+
+} //end namespace dp_gui
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/gui/dp_gui_updateinstalldialog.hxx b/desktop/source/deployment/gui/dp_gui_updateinstalldialog.hxx
new file mode 100644
index 000000000000..4f89fdf4a4d7
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_updateinstalldialog.hxx
@@ -0,0 +1,145 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_DESKTOP_SOURCE_DEPLOYMENT_GUI_DP_GUI_INSTALLDIALOG_HXX
+#define INCLUDED_DESKTOP_SOURCE_DEPLOYMENT_GUI_DP_GUI_INSTALLDIALOG_HXX
+
+#include "sal/config.h"
+#include "vcl/button.hxx"
+#include "vcl/fixed.hxx"
+#include "vcl/dialog.hxx"
+#include "svtools/prgsbar.hxx"
+#include "rtl/ref.hxx"
+#include <vector>
+
+#include "dp_gui_autoscrolledit.hxx"
+/// @HTML
+
+namespace com { namespace sun { namespace star { namespace deployment {
+ class XExtensionManager;
+}}}}
+namespace com { namespace sun { namespace star { namespace uno {
+ class XComponentContext;
+}}}}
+namespace com { namespace sun { namespace star { namespace xml { namespace dom {
+ class XNode;
+}}}}}
+namespace com { namespace sun { namespace star { namespace xml { namespace xpath {
+ class XXPathAPI;
+}}}}}
+
+class Window;
+namespace osl {
+ class Condition;
+}
+
+namespace dp_gui {
+
+ struct UpdateData;
+ class UpdateCommandEnv;
+
+
+/**
+ The modal &ldquo;Download and Installation&rdquo; dialog.
+*/
+class UpdateInstallDialog: public ModalDialog {
+public:
+ /**
+ Create an instance.
+
+ @param parent
+ the parent window, may be null
+ */
+ UpdateInstallDialog(Window * parent, std::vector<UpdateData> & aVecUpdateData,
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > const & xCtx);
+
+ ~UpdateInstallDialog();
+
+ sal_Bool Close();
+ virtual short Execute();
+
+private:
+ UpdateInstallDialog(UpdateInstallDialog &); // not defined
+ void operator =(UpdateInstallDialog &); // not defined
+
+ class Thread;
+ friend class Thread;
+ friend class UpdateCommandEnv;
+
+ DECL_LINK(cancelHandler, void *);
+
+ //signals in the dialog that we have finished.
+ void updateDone();
+ //Writes a particular error into the info listbox.
+ enum INSTALL_ERROR
+ {
+ ERROR_DOWNLOAD,
+ ERROR_INSTALLATION,
+ ERROR_LICENSE_DECLINED
+ };
+ void setError(INSTALL_ERROR err, ::rtl::OUString const & sExtension, ::rtl::OUString const & exceptionMessage);
+ void setError(::rtl::OUString const & exceptionMessage);
+ ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XExtensionManager > getExtensionManager() const
+ { return m_xExtensionManager; }
+
+ rtl::Reference< Thread > m_thread;
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > m_xComponentContext;
+ ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XExtensionManager > m_xExtensionManager;
+ //Signals that an error occurred during download and installation
+ bool m_bError;
+ bool m_bNoEntry;
+ bool m_bActivated;
+
+ ::rtl::OUString m_sInstalling;
+ ::rtl::OUString m_sFinished;
+ ::rtl::OUString m_sNoErrors;
+ ::rtl::OUString m_sErrorDownload;
+ ::rtl::OUString m_sErrorInstallation;
+ ::rtl::OUString m_sErrorLicenseDeclined;
+ ::rtl::OUString m_sNoInstall;
+ ::rtl::OUString m_sThisErrorOccurred;
+
+ FixedText m_ft_action;
+ ProgressBar m_statusbar;
+ FixedText m_ft_extension_name;
+ FixedText m_ft_results;
+ AutoScrollEdit m_mle_info;
+ FixedLine m_line;
+ HelpButton m_help;
+ OKButton m_ok;
+ CancelButton m_cancel;
+};
+
+
+
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/gui/dp_gui_updateinstalldialog.src b/desktop/source/deployment/gui/dp_gui_updateinstalldialog.src
new file mode 100644
index 000000000000..f7cc93493b5d
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_updateinstalldialog.src
@@ -0,0 +1,204 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "svtools/controldims.hrc"
+
+#include "dp_gui.hrc"
+
+
+#define LOCAL_WIDTH (60 * RSC_BS_CHARWIDTH)
+#define LOCAL_LIST_HEIGHT (7 * RSC_BS_CHARHEIGHT)
+#define LOCAL_BUTTON_WIDTH 80
+
+ModalDialog RID_DLG_UPDATEINSTALL {
+ HelpId = HID_DEPLOYMENT_GUI_UPDATEINSTALL;
+ Size = MAP_APPFONT(
+ (RSC_SP_DLG_INNERBORDER_LEFT + LOCAL_WIDTH +
+ RSC_SP_DLG_INNERBORDER_RIGHT),
+ (RSC_SP_DLG_INNERBORDER_TOP + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_DESC_Y + RSC_CD_CHECKBOX_HEIGHT +
+ RSC_SP_CTRL_DESC_Y + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_Y + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_FLGR_SPACE_Y + LOCAL_LIST_HEIGHT +
+ RSC_SP_FLGR_SPACE_Y + RSC_CD_FIXEDLINE_HEIGHT +
+ RSC_SP_FLGR_SPACE_Y + RSC_CD_PUSHBUTTON_HEIGHT +
+ RSC_SP_DLG_INNERBORDER_BOTTOM));
+ Text[en-US] = "Download and Installation";
+ Moveable = TRUE;
+ Closeable = TRUE;
+ FixedText RID_DLG_UPDATE_INSTALL_DOWNLOADING {
+ Pos = MAP_APPFONT(
+ RSC_SP_DLG_INNERBORDER_LEFT, RSC_SP_DLG_INNERBORDER_TOP);
+ Size = MAP_APPFONT(LOCAL_WIDTH, RSC_CD_FIXEDTEXT_HEIGHT);
+ Text[en-US] = "Downloading extensions...";
+ NoLabel = TRUE;
+ };
+
+ Window RID_DLG_UPDATE_INSTALL_STATUSBAR {
+ Pos = MAP_APPFONT(
+ RSC_SP_DLG_INNERBORDER_LEFT,
+ (RSC_SP_DLG_INNERBORDER_TOP + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_DESC_Y));
+
+ Size = MAP_APPFONT(LOCAL_WIDTH, RSC_CD_CHECKBOX_HEIGHT);
+ Border = TRUE;
+ };
+
+ FixedText RID_DLG_UPDATE_INSTALL_EXTENSION_NAME {
+ Pos = MAP_APPFONT(
+ RSC_SP_DLG_INNERBORDER_LEFT,
+ RSC_SP_DLG_INNERBORDER_TOP + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_DESC_Y + RSC_CD_CHECKBOX_HEIGHT + RSC_SP_CTRL_DESC_Y);
+ Size = MAP_APPFONT(LOCAL_WIDTH, RSC_CD_FIXEDTEXT_HEIGHT);
+ Text[en-US] = "";
+ NoLabel = TRUE;
+ };
+
+ FixedText RID_DLG_UPDATE_INSTALL_RESULTS {
+ Pos = MAP_APPFONT(
+ RSC_SP_DLG_INNERBORDER_LEFT,
+ RSC_SP_DLG_INNERBORDER_TOP + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_DESC_Y + RSC_CD_CHECKBOX_HEIGHT +
+ RSC_SP_CTRL_DESC_Y + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_Y);
+ Size = MAP_APPFONT(LOCAL_WIDTH, RSC_CD_FIXEDTEXT_HEIGHT);
+ Text[en-US] = "Result";
+ };
+
+ MultiLineEdit RID_DLG_UPDATE_INSTALL_INFO {
+ HelpID = "desktop:MultiLineEdit:RID_DLG_UPDATEINSTALL:RID_DLG_UPDATE_INSTALL_INFO";
+ Pos = MAP_APPFONT(
+ RSC_SP_DLG_INNERBORDER_LEFT,
+ RSC_SP_DLG_INNERBORDER_TOP + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_DESC_Y + RSC_CD_CHECKBOX_HEIGHT +
+ RSC_SP_CTRL_DESC_Y + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_Y + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_DESC_Y);
+
+ Size = MAP_APPFONT(LOCAL_WIDTH, LOCAL_LIST_HEIGHT);
+ Border = TRUE;
+ ReadOnly = TRUE;
+ VScroll = TRUE;
+ TabStop = FALSE;
+ };
+
+ FixedLine RID_DLG_UPDATE_INSTALL_LINE {
+ Pos = MAP_APPFONT(
+ RSC_SP_DLG_INNERBORDER_LEFT,
+ RSC_SP_DLG_INNERBORDER_TOP + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_DESC_Y + RSC_CD_CHECKBOX_HEIGHT +
+ RSC_SP_CTRL_DESC_Y + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_Y + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_DESC_Y + LOCAL_LIST_HEIGHT +
+ RSC_SP_FLGR_SPACE_Y);
+
+ Size = MAP_APPFONT(LOCAL_WIDTH, RSC_CD_FIXEDLINE_HEIGHT);
+ };
+
+ OKButton RID_DLG_UPDATE_INSTALL_OK {
+ Disable = TRUE;
+ Pos = MAP_APPFONT(
+ RSC_SP_DLG_INNERBORDER_LEFT + LOCAL_WIDTH - LOCAL_BUTTON_WIDTH -
+ RSC_SP_CTRL_GROUP_X - RSC_CD_PUSHBUTTON_WIDTH,
+ RSC_SP_DLG_INNERBORDER_TOP + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_DESC_Y + RSC_CD_CHECKBOX_HEIGHT +
+ RSC_SP_CTRL_DESC_Y + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_Y + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_DESC_Y + LOCAL_LIST_HEIGHT +
+ RSC_SP_FLGR_SPACE_Y + RSC_CD_FIXEDLINE_HEIGHT +
+ RSC_SP_FLGR_SPACE_Y);
+
+
+ Size = MAP_APPFONT(RSC_CD_PUSHBUTTON_WIDTH, RSC_CD_PUSHBUTTON_HEIGHT);
+ Text[en-US] = "OK";
+ };
+
+ CancelButton RID_DLG_UPDATE_INSTALL_ABORT {
+ Pos = MAP_APPFONT(
+ RSC_SP_DLG_INNERBORDER_LEFT + LOCAL_WIDTH - LOCAL_BUTTON_WIDTH,
+ RSC_SP_DLG_INNERBORDER_TOP + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_DESC_Y + RSC_CD_CHECKBOX_HEIGHT +
+ RSC_SP_CTRL_DESC_Y + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_Y + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_DESC_Y + LOCAL_LIST_HEIGHT +
+ RSC_SP_FLGR_SPACE_Y + RSC_CD_FIXEDLINE_HEIGHT +
+ RSC_SP_FLGR_SPACE_Y);
+
+ Size = MAP_APPFONT(LOCAL_BUTTON_WIDTH, RSC_CD_PUSHBUTTON_HEIGHT);
+ Text[en-US] = "Cancel Update";
+ DefButton = TRUE;
+ };
+
+ HelpButton RID_DLG_UPDATE_INSTALL_HELP {
+ Pos = MAP_APPFONT(
+ RSC_SP_DLG_INNERBORDER_LEFT,
+ RSC_SP_DLG_INNERBORDER_TOP + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_DESC_Y + RSC_CD_CHECKBOX_HEIGHT +
+ RSC_SP_CTRL_DESC_Y + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_Y + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_DESC_Y + LOCAL_LIST_HEIGHT +
+ RSC_SP_FLGR_SPACE_Y + RSC_CD_FIXEDLINE_HEIGHT +
+ RSC_SP_FLGR_SPACE_Y);
+ Size = MAP_APPFONT(RSC_CD_PUSHBUTTON_WIDTH, RSC_CD_PUSHBUTTON_HEIGHT);
+ };
+
+
+ String RID_DLG_UPDATE_INSTALL_INSTALLING {
+ Text[en-US] = "Installing extensions...";
+ };
+
+ String RID_DLG_UPDATE_INSTALL_FINISHED {
+ Text[en-US] = "Installation finished";
+ };
+
+ String RID_DLG_UPDATE_INSTALL_NO_ERRORS {
+ Text[en-US] = "No errors.";
+ };
+
+ String RID_DLG_UPDATE_INSTALL_ERROR_DOWNLOAD {
+ Text[en-US] = "Error while downloading extension %NAME. ";
+ };
+
+ String RID_DLG_UPDATE_INSTALL_THIS_ERROR_OCCURRED {
+ Text[en-US] = "The error message is: ";
+ };
+
+
+ String RID_DLG_UPDATE_INSTALL_ERROR_INSTALLATION {
+ Text[en-US] = "Error while installing extension %NAME. ";
+ };
+
+ String RID_DLG_UPDATE_INSTALL_ERROR_LIC_DECLINED {
+ Text[en-US] = "The license agreement for extension %NAME was refused. ";
+ };
+
+ String RID_DLG_UPDATE_INSTALL_EXTENSION_NOINSTALL{
+ Text[en-US] = "The extension will not be installed.";
+ };
+
+};
+
diff --git a/desktop/source/deployment/gui/dp_gui_versionboxes.src b/desktop/source/deployment/gui/dp_gui_versionboxes.src
new file mode 100644
index 000000000000..878521ad6dd2
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_versionboxes.src
@@ -0,0 +1,76 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "dp_gui.hrc"
+
+WarningBox RID_WARNINGBOX_VERSION_LESS {
+ Buttons = WB_OK_CANCEL;
+ DefButton = WB_DEF_CANCEL;
+ Message[en-US] = "You are about to install version $NEW of the extension \'$NAME\'.\n"
+ "The newer version $DEPLOYED is already installed.\n"
+ "Click \'OK\' to replace the installed extension.\n"
+ "Click \'Cancel\' to stop the installation.";
+};
+
+String RID_STR_WARNINGBOX_VERSION_LESS_DIFFERENT_NAMES {
+ Text [en-US] = "You are about to install version $NEW of the extension \'$NAME\'.\n"
+ "The newer version $DEPLOYED, named \'$OLDNAME\', is already installed.\n"
+ "Click \'OK\' to replace the installed extension.\n"
+ "Click \'Cancel\' to stop the installation.";
+};
+
+WarningBox RID_WARNINGBOX_VERSION_EQUAL {
+ Buttons = WB_OK_CANCEL;
+ DefButton = WB_DEF_CANCEL;
+ Message[en-US] = "You are about to install version $NEW of the extension \'$NAME\'.\n"
+ "That version is already installed.\n"
+ "Click \'OK\' to replace the installed extension.\n"
+ "Click \'Cancel\' to stop the installation.";
+};
+
+String RID_STR_WARNINGBOX_VERSION_EQUAL_DIFFERENT_NAMES {
+ Text [en-US] = "You are about to install version $NEW of the extension \'$NAME\'.\n"
+ "That version, named \'$OLDNAME\', is already installed.\n"
+ "Click \'OK\' to replace the installed extension.\n"
+ "Click \'Cancel\' to stop the installation.";
+};
+
+WarningBox RID_WARNINGBOX_VERSION_GREATER {
+ Buttons = WB_OK_CANCEL;
+ DefButton = WB_DEF_OK;
+ Message[en-US] = "You are about to install version $NEW of the extension \'$NAME\'.\n"
+ "The older version $DEPLOYED is already installed.\n"
+ "Click \'OK\' to replace the installed extension.\n"
+ "Click \'Cancel\' to stop the installation.";
+};
+
+String RID_STR_WARNINGBOX_VERSION_GREATER_DIFFERENT_NAMES {
+ TEXT [en-US] = "You are about to install version $NEW of the extension \'$NAME\'.\n"
+ "The older version $DEPLOYED, named \'$OLDNAME\', is already installed.\n"
+ "Click \'OK\' to replace the installed extension.\n"
+ "Click \'Cancel\' to stop the installation.";
+}; \ No newline at end of file
diff --git a/desktop/source/deployment/gui/license_dialog.cxx b/desktop/source/deployment/gui/license_dialog.cxx
new file mode 100644
index 000000000000..ebe7c2b52ecb
--- /dev/null
+++ b/desktop/source/deployment/gui/license_dialog.cxx
@@ -0,0 +1,325 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include "cppuhelper/implbase2.hxx"
+#include "cppuhelper/implementationentry.hxx"
+#include "unotools/configmgr.hxx"
+#include "comphelper/servicedecl.hxx"
+#include "comphelper/unwrapargs.hxx"
+#include "i18npool/mslangid.hxx"
+#include "vcl/svapp.hxx"
+#include "vcl/msgbox.hxx"
+#include "toolkit/helper/vclunohelper.hxx"
+#include "com/sun/star/lang/XServiceInfo.hpp"
+#include "com/sun/star/task/XJobExecutor.hpp"
+#include "svtools/svmedit.hxx"
+#include "svl/lstner.hxx"
+#include "svtools/xtextedt.hxx"
+#include <vcl/scrbar.hxx>
+#include "vcl/threadex.hxx"
+
+
+
+#include "boost/bind.hpp"
+#include "dp_gui_shared.hxx"
+#include "license_dialog.hxx"
+#include "dp_gui.hrc"
+
+using namespace ::dp_misc;
+namespace cssu = ::com::sun::star::uno;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using ::rtl::OUString;
+
+namespace dp_gui {
+
+class LicenseView : public MultiLineEdit, public SfxListener
+{
+ sal_Bool mbEndReached;
+ Link maEndReachedHdl;
+ Link maScrolledHdl;
+
+public:
+ LicenseView( Window* pParent, const ResId& rResId );
+ ~LicenseView();
+
+ void ScrollDown( ScrollType eScroll );
+
+ sal_Bool IsEndReached() const;
+ sal_Bool EndReached() const { return mbEndReached; }
+ void SetEndReached( sal_Bool bEnd ) { mbEndReached = bEnd; }
+
+ void SetEndReachedHdl( const Link& rHdl ) { maEndReachedHdl = rHdl; }
+ const Link& GetAutocompleteHdl() const { return maEndReachedHdl; }
+
+ void SetScrolledHdl( const Link& rHdl ) { maScrolledHdl = rHdl; }
+ const Link& GetScrolledHdl() const { return maScrolledHdl; }
+
+ virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint );
+
+protected:
+ using MultiLineEdit::Notify;
+};
+
+struct LicenseDialogImpl : public ModalDialog
+{
+ cssu::Reference<cssu::XComponentContext> m_xComponentContext;
+ FixedText m_ftHead;
+ FixedText m_ftBody1;
+ FixedText m_ftBody1Txt;
+ FixedText m_ftBody2;
+ FixedText m_ftBody2Txt;
+ FixedImage m_fiArrow1;
+ FixedImage m_fiArrow2;
+ LicenseView m_mlLicense;
+ PushButton m_pbDown;
+ FixedLine m_flBottom;
+
+ OKButton m_acceptButton;
+ CancelButton m_declineButton;
+
+ DECL_LINK(PageDownHdl, PushButton*);
+ DECL_LINK(ScrolledHdl, LicenseView*);
+ DECL_LINK(EndReachedHdl, LicenseView*);
+
+ bool m_bLicenseRead;
+
+ virtual ~LicenseDialogImpl();
+
+ LicenseDialogImpl(
+ Window * pParent,
+ css::uno::Reference< css::uno::XComponentContext > const & xContext,
+ const ::rtl::OUString & sExtensionName,
+ const ::rtl::OUString & sLicenseText);
+
+ virtual void Activate();
+
+};
+
+LicenseView::LicenseView( Window* pParent, const ResId& rResId )
+ : MultiLineEdit( pParent, rResId )
+{
+ SetLeftMargin( 5 );
+ mbEndReached = IsEndReached();
+ StartListening( *GetTextEngine() );
+}
+
+LicenseView::~LicenseView()
+{
+ maEndReachedHdl = Link();
+ maScrolledHdl = Link();
+ EndListeningAll();
+}
+
+void LicenseView::ScrollDown( ScrollType eScroll )
+{
+ ScrollBar* pScroll = GetVScrollBar();
+ if ( pScroll )
+ pScroll->DoScrollAction( eScroll );
+}
+
+sal_Bool LicenseView::IsEndReached() const
+{
+ sal_Bool bEndReached;
+
+ ExtTextView* pView = GetTextView();
+ ExtTextEngine* pEdit = GetTextEngine();
+ sal_uLong nHeight = pEdit->GetTextHeight();
+ Size aOutSize = pView->GetWindow()->GetOutputSizePixel();
+ Point aBottom( 0, aOutSize.Height() );
+
+ if ( (sal_uLong) pView->GetDocPos( aBottom ).Y() >= nHeight - 1 )
+ bEndReached = sal_True;
+ else
+ bEndReached = sal_False;
+
+ return bEndReached;
+}
+
+void LicenseView::Notify( SfxBroadcaster&, const SfxHint& rHint )
+{
+ if ( rHint.IsA( TYPE(TextHint) ) )
+ {
+ sal_Bool bLastVal = EndReached();
+ sal_uLong nId = ((const TextHint&)rHint).GetId();
+
+ if ( nId == TEXT_HINT_PARAINSERTED )
+ {
+ if ( bLastVal )
+ mbEndReached = IsEndReached();
+ }
+ else if ( nId == TEXT_HINT_VIEWSCROLLED )
+ {
+ if ( ! mbEndReached )
+ mbEndReached = IsEndReached();
+ maScrolledHdl.Call( this );
+ }
+
+ if ( EndReached() && !bLastVal )
+ {
+ maEndReachedHdl.Call( this );
+ }
+ }
+}
+
+//==============================================================================================================
+
+LicenseDialogImpl::LicenseDialogImpl(
+ Window * pParent,
+ cssu::Reference< cssu::XComponentContext > const & xContext,
+ const ::rtl::OUString & sExtensionName,
+ const ::rtl::OUString & sLicenseText):
+ ModalDialog(pParent, DpGuiResId(RID_DLG_LICENSE))
+ ,m_xComponentContext(xContext)
+ ,m_ftHead(this, DpGuiResId(FT_LICENSE_HEADER))
+ ,m_ftBody1(this, DpGuiResId(FT_LICENSE_BODY_1))
+ ,m_ftBody1Txt(this, DpGuiResId(FT_LICENSE_BODY_1_TXT))
+ ,m_ftBody2(this, DpGuiResId(FT_LICENSE_BODY_2))
+ ,m_ftBody2Txt(this, DpGuiResId(FT_LICENSE_BODY_2_TXT))
+ ,m_fiArrow1(this, DpGuiResId(FI_LICENSE_ARROW1))
+ ,m_fiArrow2(this, DpGuiResId(FI_LICENSE_ARROW2))
+ ,m_mlLicense(this, DpGuiResId(ML_LICENSE))
+ ,m_pbDown(this, DpGuiResId(PB_LICENSE_DOWN))
+ ,m_flBottom(this, DpGuiResId(FL_LICENSE))
+ ,m_acceptButton(this, DpGuiResId(BTN_LICENSE_ACCEPT))
+ ,m_declineButton(this, DpGuiResId(BTN_LICENSE_DECLINE))
+ ,m_bLicenseRead(false)
+
+{
+
+ FreeResource();
+
+ m_acceptButton.SetUniqueId(UID_BTN_LICENSE_ACCEPT);
+ m_fiArrow1.Show(true);
+ m_fiArrow2.Show(false);
+ m_mlLicense.SetText(sLicenseText);
+ m_ftHead.SetText(m_ftHead.GetText() + OUString('\n') + sExtensionName);
+
+ m_mlLicense.SetEndReachedHdl( LINK(this, LicenseDialogImpl, EndReachedHdl) );
+ m_mlLicense.SetScrolledHdl( LINK(this, LicenseDialogImpl, ScrolledHdl) );
+ m_pbDown.SetClickHdl( LINK(this, LicenseDialogImpl, PageDownHdl) );
+
+ // We want a automatic repeating page down button
+ WinBits aStyle = m_pbDown.GetStyle();
+ aStyle |= WB_REPEAT;
+ m_pbDown.SetStyle( aStyle );
+}
+
+LicenseDialogImpl::~LicenseDialogImpl()
+{
+}
+
+void LicenseDialogImpl::Activate()
+{
+ if (!m_bLicenseRead)
+ {
+ //Only enable the scroll down button if the license text does not fit into the window
+ if (m_mlLicense.IsEndReached())
+ {
+ m_pbDown.Disable();
+ m_acceptButton.Enable();
+ m_acceptButton.GrabFocus();
+ }
+ else
+ {
+ m_pbDown.Enable();
+ m_pbDown.GrabFocus();
+ m_acceptButton.Disable();
+ }
+ }
+}
+
+IMPL_LINK( LicenseDialogImpl, ScrolledHdl, LicenseView *, EMPTYARG )
+{
+
+ if (m_mlLicense.IsEndReached())
+ m_pbDown.Disable();
+ else
+ m_pbDown.Enable();
+
+ return 0;
+}
+
+IMPL_LINK( LicenseDialogImpl, PageDownHdl, PushButton *, EMPTYARG )
+{
+ m_mlLicense.ScrollDown( SCROLL_PAGEDOWN );
+ return 0;
+}
+
+IMPL_LINK( LicenseDialogImpl, EndReachedHdl, LicenseView *, EMPTYARG )
+{
+ m_acceptButton.Enable();
+ m_acceptButton.GrabFocus();
+ m_fiArrow1.Show(false);
+ m_fiArrow2.Show(true);
+ m_bLicenseRead = true;
+ return 0;
+}
+
+//=================================================================================
+
+
+
+
+LicenseDialog::LicenseDialog( Sequence<Any> const& args,
+ Reference<XComponentContext> const& xComponentContext)
+ : m_xComponentContext(xComponentContext)
+{
+ comphelper::unwrapArgs( args, m_parent, m_sExtensionName, m_sLicenseText );
+}
+
+// XExecutableDialog
+//______________________________________________________________________________
+void LicenseDialog::setTitle( OUString const & ) throw (RuntimeException)
+{
+
+}
+
+//______________________________________________________________________________
+sal_Int16 LicenseDialog::execute() throw (RuntimeException)
+{
+ return vcl::solarthread::syncExecute(
+ boost::bind( &LicenseDialog::solar_execute, this));
+}
+
+sal_Int16 LicenseDialog::solar_execute()
+{
+ std::auto_ptr<LicenseDialogImpl> dlg(
+ new LicenseDialogImpl(
+ VCLUnoHelper::GetWindow(m_parent),
+ m_xComponentContext, m_sExtensionName, m_sLicenseText));
+
+ return dlg->Execute();
+}
+
+} // namespace dp_gui
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/gui/license_dialog.hxx b/desktop/source/deployment/gui/license_dialog.hxx
new file mode 100644
index 000000000000..2bddfd4f4102
--- /dev/null
+++ b/desktop/source/deployment/gui/license_dialog.hxx
@@ -0,0 +1,69 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef INCLUDED_DESKTOP_SOURCE_DEPLOYMENT_GUI_LICENSE_DIALOG_HXX
+#define INCLUDED_DESKTOP_SOURCE_DEPLOYMENT_GUI_LICENSE_DIALOG_HXX
+
+#include "dp_gui.h"
+#include "cppuhelper/implbase1.hxx"
+#include "com/sun/star/lang/XServiceInfo.hpp"
+#include "com/sun/star/task/XJobExecutor.hpp"
+#include "com/sun/star/ui/dialogs/XExecutableDialog.hpp"
+
+#include "boost/bind.hpp"
+
+using namespace ::dp_misc;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using ::rtl::OUString;
+
+namespace dp_gui {
+
+class LicenseDialog
+ : public ::cppu::WeakImplHelper1<ui::dialogs::XExecutableDialog>
+{
+ Reference<XComponentContext> const m_xComponentContext;
+ Reference<awt::XWindow> /* const */ m_parent;
+ OUString m_sExtensionName;
+ OUString /* const */ m_sLicenseText;
+ OUString m_initialTitle;
+
+ sal_Int16 solar_execute();
+
+public:
+ LicenseDialog( Sequence<Any> const & args,
+ Reference<XComponentContext> const & xComponentContext );
+
+ // XExecutableDialog
+ virtual void SAL_CALL setTitle( OUString const & title )
+ throw (RuntimeException);
+ virtual sal_Int16 SAL_CALL execute() throw (RuntimeException);
+};
+}
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/gui/makefile.mk b/desktop/source/deployment/gui/makefile.mk
new file mode 100755
index 000000000000..73ca83792592
--- /dev/null
+++ b/desktop/source/deployment/gui/makefile.mk
@@ -0,0 +1,113 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ = ..$/..$/..
+
+PRJNAME = desktop
+TARGET = deploymentgui
+ENABLE_EXCEPTIONS = TRUE
+NO_BSYMBOLIC = TRUE
+USE_PCH :=
+ENABLE_PCH :=
+PRJINC:=..$/..
+
+.IF "$(GUI)"=="OS2"
+TARGET = deplgui
+.ENDIF
+
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/source$/deployment$/inc$/dp_misc.mk
+DLLPRE =
+
+SLOFILES = \
+ $(SLO)$/dp_gui_service.obj \
+ $(SLO)$/dp_gui_extlistbox.obj \
+ $(SLO)$/dp_gui_dialog2.obj \
+ $(SLO)$/dp_gui_theextmgr.obj \
+ $(SLO)$/license_dialog.obj \
+ $(SLO)$/dp_gui_dependencydialog.obj \
+ $(SLO)$/dp_gui_thread.obj \
+ $(SLO)$/dp_gui_updatedialog.obj \
+ $(SLO)$/dp_gui_updateinstalldialog.obj \
+ $(SLO)$/dp_gui_autoscrolledit.obj \
+ $(SLO)$/dp_gui_extensioncmdqueue.obj \
+ $(SLO)$/descedit.obj
+
+SHL1TARGET = $(TARGET)$(DLLPOSTFIX).uno
+SHL1VERSIONMAP = $(SOLARENV)/src/component.map
+
+SHL1STDLIBS = \
+ $(SALLIB) \
+ $(SALHELPERLIB) \
+ $(CPPULIB) \
+ $(CPPUHELPERLIB) \
+ $(UCBHELPERLIB) \
+ $(COMPHELPERLIB) \
+ $(UNOTOOLSLIB) \
+ $(TOOLSLIB) \
+ $(I18NISOLANGLIB) \
+ $(TKLIB) \
+ $(VCLLIB) \
+ $(SVTOOLLIB) \
+ $(SVLLIB) \
+ $(SVXLIB) \
+ $(SVXCORELIB) \
+ $(SFXLIB) \
+ $(DEPLOYMENTMISCLIB) \
+ $(OLE32LIB)
+
+SHL1DEPN =
+SHL1IMPLIB = i$(TARGET)
+SHL1LIBS = $(SLB)$/$(TARGET).lib
+SHL1DEF = $(MISC)$/$(SHL1TARGET).def
+
+DEF1NAME = $(SHL1TARGET)
+
+SRS1NAME = $(TARGET)
+SRC1FILES = \
+ dp_gui_dialog.src \
+ dp_gui_dialog2.src \
+ dp_gui_backend.src \
+ dp_gui_dependencydialog.src \
+ dp_gui_updatedialog.src \
+ dp_gui_versionboxes.src \
+ dp_gui_updateinstalldialog.src
+
+RESLIB1NAME = $(TARGET)
+RESLIB1SRSFILES = $(SRS)$/$(TARGET).srs
+RESLIB1IMAGES= $(PRJ)$/res
+
+.INCLUDE : target.mk
+
+
+ALLTAR : $(MISC)/deploymentgui.component
+
+$(MISC)/deploymentgui.component .ERRREMOVE : \
+ $(SOLARENV)/bin/createcomponent.xslt deploymentgui.component
+ $(XSLTPROC) --nonet --stringparam uri \
+ '$(COMPONENTPREFIX_BASIS_NATIVE)$(SHL1TARGETN:f)' -o $@ \
+ $(SOLARENV)/bin/createcomponent.xslt deploymentgui.component
diff --git a/desktop/source/deployment/inc/db.hxx b/desktop/source/deployment/inc/db.hxx
new file mode 100644
index 000000000000..22e9e357b549
--- /dev/null
+++ b/desktop/source/deployment/inc/db.hxx
@@ -0,0 +1,147 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef BERKELEYDBPROXY_DB_HXX_
+#define BERKELEYDBPROXY_DB_HXX_
+
+#include <boost/noncopyable.hpp>
+
+#ifdef SYSTEM_DB
+#include <db.h>
+#else
+#include <berkeleydb/db.h>
+#endif
+
+#include <rtl/string.hxx>
+#include "dp_misc_api.hxx"
+
+extern "C" {
+ typedef void *(*db_malloc_fcn_type)(size_t);
+ typedef void *(*db_realloc_fcn_type)(void *, size_t);
+ typedef void (*db_free_fcn_type)(void *);
+}
+
+namespace berkeleydbproxy {
+
+ class DbEnv;
+ class Dbc;
+ class Dbt;
+
+ class DESKTOP_DEPLOYMENTMISC_DLLPUBLIC DbException
+ {
+ rtl::OString what_;
+ public:
+ explicit DbException(rtl::OString const & theWhat)
+ : what_(theWhat)
+ {}
+
+ const char *what() const
+ { return what_.getStr(); }
+ int get_errno() const
+ { return 0; }
+ };
+
+
+ class DESKTOP_DEPLOYMENTMISC_DLLPUBLIC DbEnv : boost::noncopyable
+ {
+ friend class Db;
+
+ private:
+ DB_ENV* m_pDBENV;
+
+ public:
+ static char *strerror(int);
+ };
+
+ class DESKTOP_DEPLOYMENTMISC_DLLPUBLIC Db : boost::noncopyable
+ {
+ private:
+ DB* m_pDBP;
+
+ public:
+ Db(DbEnv* dbbenv,u_int32_t flags);
+ ~Db();
+
+ int close(u_int32_t flags);
+
+ int open(DB_TXN *txnid,
+ const char *file,
+ const char *database,
+ DBTYPE type,
+ u_int32_t flags,
+ int mode);
+
+ int sync(u_int32_t flags);
+ int del(Dbt *key, u_int32_t flags);
+
+ int get(DB_TXN* txnid, Dbt *key, Dbt *data, u_int32_t flags);
+ int put(DB_TXN* txnid, Dbt *key, Dbt *data, u_int32_t flags);
+
+ int cursor(DB_TXN *txnid, Dbc **cursorp, u_int32_t flags);
+ };
+
+ class DESKTOP_DEPLOYMENTMISC_DLLPUBLIC Dbc : boost::noncopyable
+ {
+ friend class Db;
+ friend class Dbt;
+
+ private:
+ DBC* m_pDBC;
+
+ SAL_DLLPRIVATE explicit Dbc(DBC* pDBC);
+ SAL_DLLPRIVATE ~Dbc();
+
+ public:
+ int close();
+
+ int get(Dbt *key, Dbt *data, u_int32_t flags);
+ };
+
+ class DESKTOP_DEPLOYMENTMISC_DLLPUBLIC Dbt: private DBT
+ {
+ friend class Db;
+ friend class Dbc;
+
+ public:
+ Dbt(void *data_arg, u_int32_t size_arg);
+
+ Dbt();
+ Dbt(const Dbt & other);
+ Dbt & operator=(const Dbt & other);
+
+ ~Dbt();
+
+ void *get_data() const;
+ void set_data(void *value);
+
+ u_int32_t get_size() const;
+ void set_size(u_int32_t value);
+ };
+}
+
+#endif
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/inc/dp_dependencies.hxx b/desktop/source/deployment/inc/dp_dependencies.hxx
new file mode 100644
index 000000000000..e39c70c99a91
--- /dev/null
+++ b/desktop/source/deployment/inc/dp_dependencies.hxx
@@ -0,0 +1,94 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_DESKTOP_SOURCE_DEPLOYMENT_INC_DP_DEPENDENCIES_HXX
+#define INCLUDED_DESKTOP_SOURCE_DEPLOYMENT_INC_DP_DEPENDENCIES_HXX
+
+#include "unotools/configmgr.hxx"
+#include "sal/config.h"
+#include "com/sun/star/uno/Reference.hxx"
+#include "com/sun/star/uno/Sequence.hxx"
+#include "dp_misc_api.hxx"
+
+/// @HTML
+
+namespace com { namespace sun { namespace star { namespace xml { namespace dom {
+ class XElement;
+} } } } }
+namespace dp_misc { class DescriptionInfoset; }
+namespace rtl { class OUString; }
+
+namespace dp_misc {
+
+struct BrandName : public ::rtl::StaticWithInit<const ::rtl::OUString, BrandName> {
+ const ::rtl::OUString operator () () {
+ return ::utl::ConfigManager::GetDirectConfigProperty(
+ ::utl::ConfigManager::PRODUCTNAME ).get< ::rtl::OUString >();
+ }
+};
+
+
+/**
+ Dependency handling.
+*/
+namespace Dependencies {
+ /**
+ Check for unsatisfied dependencies.
+
+ @param infoset
+ the infoset containing the dependencies to check
+
+ @return
+ a list of the unsatisfied dependencies from <code>infoset</code> (in no
+ specific order)
+ */
+ DESKTOP_DEPLOYMENTMISC_DLLPUBLIC
+ ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::dom::XElement > >
+ check(::dp_misc::DescriptionInfoset const & infoset);
+
+ /**
+ Obtain the (human-readable) error message of a failed dependency.
+
+ @param dependency
+ a dependency represented as a non-null XML element
+
+ @return
+ the name of the dependency; will never be empty, as a localized
+ &ldquo;unknown&rdquo; is substituted for an empty/missing name
+ */
+ DESKTOP_DEPLOYMENTMISC_DLLPUBLIC ::rtl::OUString getErrorText(
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::dom::XElement > const & dependency);
+}
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/inc/dp_descriptioninfoset.hxx b/desktop/source/deployment/inc/dp_descriptioninfoset.hxx
new file mode 100644
index 000000000000..d16e9127af8a
--- /dev/null
+++ b/desktop/source/deployment/inc/dp_descriptioninfoset.hxx
@@ -0,0 +1,302 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_DESKTOP_SOURCE_DEPLOYMENT_INC_DP_DESCRIPTIONINFOSET_HXX
+#define INCLUDED_DESKTOP_SOURCE_DEPLOYMENT_INC_DP_DESCRIPTIONINFOSET_HXX
+
+#include "sal/config.h"
+
+#include "boost/optional.hpp"
+#include "com/sun/star/uno/Reference.hxx"
+#include "com/sun/star/uno/Sequence.hxx"
+#include "sal/types.h"
+#include "dp_misc_api.hxx"
+
+/// @HTML
+
+namespace com { namespace sun { namespace star {
+ namespace lang { struct Locale; }
+ namespace uno { class XComponentContext; }
+ namespace xml {
+ namespace dom {
+ class XNode;
+ class XNodeList;
+ }
+ namespace xpath { class XXPathAPI; }
+ }
+} } }
+namespace rtl { class OUString; }
+
+namespace dp_misc {
+
+struct DESKTOP_DEPLOYMENTMISC_DLLPUBLIC SimpleLicenseAttributes
+{
+ ::rtl::OUString acceptBy;
+ //Attribute suppress-on-update. Default is false.
+ bool suppressOnUpdate;
+ //Attribute suppress-if-required. Default is false.
+ bool suppressIfRequired;
+};
+
+
+/**
+ Access to the content of an XML <code>description</code> element.
+
+ <p>This works for <code>description</code> elements in both the
+ <code>description.xml</code> file and online update information formats.</p>
+*/
+class DESKTOP_DEPLOYMENTMISC_DLLPUBLIC DescriptionInfoset {
+public:
+ /**
+ Create an instance.
+
+ @param context
+ a non-null component context
+
+ @param element
+ a <code>description</code> element; may be null (equivalent to an element
+ with no content)
+ */
+ DescriptionInfoset(
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::uno::XComponentContext > const & context,
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::dom::XNode > const & element);
+
+ ~DescriptionInfoset();
+
+ /**
+ Return the identifier.
+
+ @return
+ the identifier, or an empty <code>optional</code> if none is specified
+ */
+ ::boost::optional< ::rtl::OUString > getIdentifier() const;
+
+ /**
+ Return the textual version representation.
+
+ @return
+ textual version representation
+ */
+ ::rtl::OUString getVersion() const;
+
+ /**
+ Returns a list of supported platforms.
+
+ If the extension does not specify a platform by leaving out the platform element
+ then we assume that the extension supports all platforms. In this case the returned
+ sequence will have one element, which is &quot;all&quot;.
+ If the platform element is present but does not specify a platform then an empty
+ sequence is returned. Examples for invalid platform elements:
+ <pre>
+ <platform />, <platform value="" />, <platfrom value=",">
+ </pre>
+
+ The value attribute can contain various platform tokens. They must be separated by
+ commas.Each token will be stripped from leading and trailing white space (trim()).
+ */
+ ::com::sun::star::uno::Sequence< ::rtl::OUString > getSupportedPlaforms() const;
+
+ /**
+ Returns the localized publisher name and the corresponding URL.
+
+ In case there is no publisher element then a pair of two empty strings is returned.
+ */
+ ::std::pair< ::rtl::OUString, ::rtl::OUString > getLocalizedPublisherNameAndURL() const;
+
+ /**
+ Returns the URL for the release notes corresponding to the office's locale.
+
+ In case there is no release-notes element then an empty string is returned.
+ */
+ ::rtl::OUString getLocalizedReleaseNotesURL() const;
+
+ /** returns the relative path to the license file.
+
+ In case there is no simple-license element then an empty string is returned.
+ */
+ ::rtl::OUString getLocalizedLicenseURL() const;
+
+ /** returns the attributes of the simple-license element
+
+ As long as there is a simple-license element, the function will return
+ the structure. If it does not exist, then the optional object is uninitialized.
+ */
+ ::boost::optional<SimpleLicenseAttributes> getSimpleLicenseAttributes() const;
+
+ /** returns the localized display name of the extensions.
+
+ In case there is no localized display-name then an empty string is returned.
+ */
+ ::rtl::OUString getLocalizedDisplayName() const;
+
+ /**
+ returns the download website URL from the update information.
+
+ There can be multiple URLs where each is assigned to a particular locale.
+ The function returs the URL which locale matches best the one used in the office.
+
+ The return value is an optional because it may be necessary to find out if there
+ was a value provided or not. This is necessary to flag the extension in the update dialog
+ properly as "browser based update". The return value will only then not be initialized
+ if there is no <code>&lt;update-website&gt;</code>. If the element exists, then it must
+ have at least one child element containing an URL.
+
+ The <code>&lt;update-website&gt;</code> and <code>&lt;update-download&gt;</code>
+ elements are mutually exclusiv.
+
+ @return
+ the download website URL, or an empty <code>optional</code> if none is
+ specified
+ */
+ ::boost::optional< ::rtl::OUString > getLocalizedUpdateWebsiteURL() const;
+
+ /** returns the relative URL to the description.
+
+ The URL is relative to the root directory of the extensions.
+ */
+ ::rtl::OUString getLocalizedDescriptionURL() const;
+ /**
+ Return the dependencies.
+
+ @return
+ dependencies; will never be null
+ */
+ ::com::sun::star::uno::Reference< ::com::sun::star::xml::dom::XNodeList >
+ getDependencies() const;
+
+ /**
+ Return the update information URLs.
+
+ @return
+ update information URLs
+ */
+ ::com::sun::star::uno::Sequence< ::rtl::OUString >
+ getUpdateInformationUrls() const;
+
+ /**
+ Return the download URLs from the update information.
+
+ Because the <code>&lt;update-download&gt;</code> and the <code>&lt;update-website&gt;</code>
+ elements are mutually exclusive one may need to determine exacty if the element
+ was provided.
+
+ @return
+ download URLs
+ */
+ ::com::sun::star::uno::Sequence< ::rtl::OUString >
+ getUpdateDownloadUrls() const;
+
+ /**
+ Returns the URL for the icon image.
+ */
+ ::rtl::OUString getIconURL( sal_Bool bHighContrast ) const;
+
+ bool hasDescription() const;
+
+private:
+ SAL_DLLPRIVATE ::boost::optional< ::rtl::OUString > getOptionalValue(
+ ::rtl::OUString const & expression) const;
+
+ SAL_DLLPRIVATE ::com::sun::star::uno::Sequence< ::rtl::OUString > getUrls(
+ ::rtl::OUString const & expression) const;
+
+ /** Retrieves a child element which as lang attribute which matches the office locale.
+
+ Only top-level children are taken into account. It is also assumed that they are all
+ of the same element type and have a lang attribute. The matching algoritm is according
+ to RFC 3066, with the exception that only one variant is allowed.
+ @param parent
+ the expression used to obtain the parent of the localized children. It can be null.
+ Then a null reference is returned.
+ */
+ SAL_DLLPRIVATE ::com::sun::star::uno::Reference< ::com::sun::star::xml::dom::XNode >
+ getLocalizedChild( ::rtl::OUString const & sParent) const;
+ SAL_DLLPRIVATE ::com::sun::star::uno::Reference< ::com::sun::star::xml::dom::XNode>
+ matchFullLocale(::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::dom::XNode > const & xParent, ::rtl::OUString const & sLocale) const;
+ SAL_DLLPRIVATE ::com::sun::star::uno::Reference< ::com::sun::star::xml::dom::XNode>
+ matchCountryAndLanguage(::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::dom::XNode > const & xParent,
+ ::com::sun::star::lang::Locale const & officeLocale) const;
+ SAL_DLLPRIVATE ::com::sun::star::uno::Reference< ::com::sun::star::xml::dom::XNode>
+ matchLanguage(
+ ::com::sun::star::uno::Reference< ::com::sun::star::xml::dom::XNode > const & xParent,
+ ::com::sun::star::lang::Locale const & officeLocale) const;
+
+ /** If there is no child element with a locale matching the office locale, then we use
+ the first child. In the case of the simple-license we also use the former default locale, which
+ was determined by the default-license-id (/description/registration/simple-license/@default-license-id)
+ and the license-id attributes (/description/registration/simple-license/license-text/@license-id).
+ However, since OOo 2.4 we use also the first child as default for the license
+ unless the two attributes are present.
+ */
+ SAL_DLLPRIVATE ::com::sun::star::uno::Reference< ::com::sun::star::xml::dom::XNode>
+ getChildWithDefaultLocale(
+ ::com::sun::star::uno::Reference< ::com::sun::star::xml::dom::XNode > const & xParent) const;
+ /**
+ @param out_bParentExists
+ indicates if the element node specified in sXPathParent exists.
+ */
+ SAL_DLLPRIVATE ::rtl::OUString getLocalizedHREFAttrFromChild(
+ ::rtl::OUString const & sXPathParent, bool * out_bParentExists) const;
+
+ static SAL_DLLPRIVATE ::rtl::OUString
+ localeToString(::com::sun::star::lang::Locale const & locale);
+
+ /** Gets the node value for a given expression. The expression is used in
+ m_xpath-selectSingleNode. The value of the returned node is return value
+ of this function.
+ */
+ SAL_DLLPRIVATE ::rtl::OUString
+ getNodeValueFromExpression(::rtl::OUString const & expression) const;
+
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::dom::XNode > m_element;
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::xpath::XXPathAPI > m_xpath;
+};
+
+inline bool DescriptionInfoset::hasDescription() const
+{
+ return m_element.is();
+}
+
+/** creates a DescriptionInfoset object.
+
+ The argument sExtensionFolderURL is a file URL to extension folder containing
+ the description.xml.
+ */
+DESKTOP_DEPLOYMENTMISC_DLLPUBLIC
+DescriptionInfoset getDescriptionInfoset(::rtl::OUString const & sExtensionFolderURL);
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/inc/dp_identifier.hxx b/desktop/source/deployment/inc/dp_identifier.hxx
new file mode 100644
index 000000000000..f58b7663a173
--- /dev/null
+++ b/desktop/source/deployment/inc/dp_identifier.hxx
@@ -0,0 +1,95 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_DESKTOP_SOURCE_DEPLOYMENT_INC_DP_IDENTIFIER_HXX
+#define INCLUDED_DESKTOP_SOURCE_DEPLOYMENT_INC_DP_IDENTIFIER_HXX
+
+#include "sal/config.h"
+
+#include "boost/optional.hpp"
+#include "com/sun/star/uno/Reference.hxx"
+
+#include "dp_misc_api.hxx"
+
+namespace com { namespace sun { namespace star { namespace deployment {
+ class XPackage;
+} } } }
+namespace rtl { class OUString; }
+
+namespace dp_misc {
+
+/**
+ Generates an identifier from an optional identifier.
+
+ @param optional
+ an optional identifier
+
+ @param fileName
+ a file name
+
+ @return
+ the given optional identifier if present, otherwise a legacy identifier based
+ on the given file name
+*/
+DESKTOP_DEPLOYMENTMISC_DLLPUBLIC ::rtl::OUString generateIdentifier(
+ ::boost::optional< ::rtl::OUString > const & optional,
+ ::rtl::OUString const & fileName);
+
+/**
+ Gets the identifier of a package.
+
+ @param package
+ a non-null package
+
+ @return
+ the explicit identifier of the given package if present, otherwise the
+ implicit legacy identifier of the given package
+
+ @throws com::sun::star::uno::RuntimeException
+*/
+DESKTOP_DEPLOYMENTMISC_DLLPUBLIC ::rtl::OUString getIdentifier(
+ ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage >
+ const & package);
+
+/**
+ Generates a legacy identifier based on a file name.
+
+ @param fileName
+ a file name
+
+ @return
+ a legacy identifier based on the given file name
+*/
+DESKTOP_DEPLOYMENTMISC_DLLPUBLIC ::rtl::OUString generateLegacyIdentifier(
+ ::rtl::OUString const & fileName);
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/inc/dp_interact.h b/desktop/source/deployment/inc/dp_interact.h
new file mode 100755
index 000000000000..7a59e944f6af
--- /dev/null
+++ b/desktop/source/deployment/inc/dp_interact.h
@@ -0,0 +1,153 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#if ! defined INCLUDED_DP_INTERACT_H
+#define INCLUDED_DP_INTERACT_H
+
+#include "rtl/ref.hxx"
+#include "cppuhelper/implbase1.hxx"
+#include "com/sun/star/uno/XComponentContext.hpp"
+#include "com/sun/star/ucb/XCommandEnvironment.hpp"
+#include "com/sun/star/task/XAbortChannel.hpp"
+#include "dp_misc_api.hxx"
+
+namespace css = ::com::sun::star;
+
+namespace dp_misc
+{
+
+inline void progressUpdate(
+ ::rtl::OUString const & status,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv )
+{
+ if (xCmdEnv.is()) {
+ css::uno::Reference<css::ucb::XProgressHandler> xProgressHandler(
+ xCmdEnv->getProgressHandler() );
+ if (xProgressHandler.is()) {
+ xProgressHandler->update( css::uno::makeAny(status) );
+ }
+ }
+}
+
+//==============================================================================
+class ProgressLevel
+{
+ css::uno::Reference<css::ucb::XProgressHandler> m_xProgressHandler;
+
+public:
+ inline ~ProgressLevel();
+ inline ProgressLevel(
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv,
+ ::rtl::OUString const & status );
+
+ inline void update( ::rtl::OUString const & status ) const;
+ inline void update( css::uno::Any const & status ) const;
+};
+
+//______________________________________________________________________________
+inline ProgressLevel::ProgressLevel(
+ css::uno::Reference< css::ucb::XCommandEnvironment > const & xCmdEnv,
+ ::rtl::OUString const & status )
+{
+ if (xCmdEnv.is())
+ m_xProgressHandler = xCmdEnv->getProgressHandler();
+ if (m_xProgressHandler.is())
+ m_xProgressHandler->push( css::uno::makeAny(status) );
+}
+
+//______________________________________________________________________________
+inline ProgressLevel::~ProgressLevel()
+{
+ if (m_xProgressHandler.is())
+ m_xProgressHandler->pop();
+}
+
+//______________________________________________________________________________
+inline void ProgressLevel::update( ::rtl::OUString const & status ) const
+{
+ if (m_xProgressHandler.is())
+ m_xProgressHandler->update( css::uno::makeAny(status) );
+}
+
+//______________________________________________________________________________
+inline void ProgressLevel::update( css::uno::Any const & status ) const
+{
+ if (m_xProgressHandler.is())
+ m_xProgressHandler->update( status );
+}
+
+//##############################################################################
+
+/** @return true if ia handler is present and any selection has been chosen
+ */
+DESKTOP_DEPLOYMENTMISC_DLLPUBLIC bool interactContinuation(
+ css::uno::Any const & request,
+ css::uno::Type const & continuation,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv,
+ bool * pcont, bool * pabort );
+
+//##############################################################################
+
+//==============================================================================
+class DESKTOP_DEPLOYMENTMISC_DLLPUBLIC AbortChannel :
+ public ::cppu::WeakImplHelper1<css::task::XAbortChannel>
+{
+ bool m_aborted;
+ css::uno::Reference<css::task::XAbortChannel> m_xNext;
+
+public:
+ inline AbortChannel() : m_aborted( false ) {}
+ inline static AbortChannel * get(
+ css::uno::Reference<css::task::XAbortChannel> const & xAbortChannel )
+ { return static_cast<AbortChannel *>(xAbortChannel.get()); }
+
+ inline bool isAborted() const { return m_aborted; }
+
+ // XAbortChannel
+ virtual void SAL_CALL sendAbort() throw (css::uno::RuntimeException);
+
+ class SAL_DLLPRIVATE Chain
+ {
+ const ::rtl::Reference<AbortChannel> m_abortChannel;
+ public:
+ inline Chain(
+ ::rtl::Reference<AbortChannel> const & abortChannel,
+ css::uno::Reference<css::task::XAbortChannel> const & xNext )
+ : m_abortChannel( abortChannel )
+ { if (m_abortChannel.is()) m_abortChannel->m_xNext = xNext; }
+ inline ~Chain()
+ { if (m_abortChannel.is()) m_abortChannel->m_xNext.clear(); }
+ };
+ friend class Chain;
+};
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/inc/dp_misc.h b/desktop/source/deployment/inc/dp_misc.h
new file mode 100755
index 000000000000..9e912531e9f8
--- /dev/null
+++ b/desktop/source/deployment/inc/dp_misc.h
@@ -0,0 +1,182 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#if ! defined INCLUDED_DP_MISC_H
+#define INCLUDED_DP_MISC_H
+
+#include "rtl/ustrbuf.hxx"
+#include "rtl/instance.hxx"
+#include "osl/mutex.hxx"
+#include "osl/process.h"
+#include "com/sun/star/uno/XComponentContext.hpp"
+#include "com/sun/star/lang/XComponent.hpp"
+#include "com/sun/star/lang/DisposedException.hpp"
+#include "com/sun/star/deployment/XPackageRegistry.hpp"
+#include "com/sun/star/ucb/XCommandEnvironment.hpp"
+#include "com/sun/star/awt/XWindow.hpp"
+#include "dp_misc_api.hxx"
+
+#define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
+#define ARLEN(x) (sizeof (x) / sizeof *(x))
+
+namespace dp_misc {
+
+const sal_Char CR = 0x0d;
+const sal_Char LF = 0x0a;
+
+//==============================================================================
+class MutexHolder
+{
+ mutable ::osl::Mutex m_mutex;
+protected:
+ inline ::osl::Mutex & getMutex() const { return m_mutex; }
+};
+
+//==============================================================================
+inline void try_dispose( ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface> const & x )
+{
+ ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent> xComp( x, ::com::sun::star::uno::UNO_QUERY );
+ if (xComp.is())
+ xComp->dispose();
+}
+
+//##############################################################################
+
+//==============================================================================
+DESKTOP_DEPLOYMENTMISC_DLLPUBLIC
+::rtl::OUString expandUnoRcTerm( ::rtl::OUString const & term );
+
+DESKTOP_DEPLOYMENTMISC_DLLPUBLIC
+::rtl::OUString makeRcTerm( ::rtl::OUString const & url );
+
+//==============================================================================
+DESKTOP_DEPLOYMENTMISC_DLLPUBLIC
+::rtl::OUString expandUnoRcUrl( ::rtl::OUString const & url );
+
+//==============================================================================
+
+/** appends a relative path to a url.
+
+ The relative path must already be correctly encoded for use in an URL.
+ If the URL starts with vnd.sun.star.expand then the relative path will
+ be again encoded for use in an "expand" URL.
+ */
+DESKTOP_DEPLOYMENTMISC_DLLPUBLIC ::rtl::OUString makeURL(
+ ::rtl::OUString const & baseURL, ::rtl::OUString const & relPath );
+
+
+/** appends a relative path to a url.
+
+ This is the same as makeURL, but the relative Path must me a segment
+ of an system path.
+ */
+DESKTOP_DEPLOYMENTMISC_DLLPUBLIC ::rtl::OUString makeURLAppendSysPathSegment(
+ ::rtl::OUString const & baseURL, ::rtl::OUString const & relPath );
+
+//==============================================================================
+DESKTOP_DEPLOYMENTMISC_DLLPUBLIC ::rtl::OUString generateRandomPipeId();
+
+class AbortChannel;
+//==============================================================================
+DESKTOP_DEPLOYMENTMISC_DLLPUBLIC
+::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface> resolveUnoURL(
+ ::rtl::OUString const & connectString,
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext> const & xLocalContext,
+ AbortChannel * abortChannel = 0 );
+
+//==============================================================================
+DESKTOP_DEPLOYMENTMISC_DLLPUBLIC bool office_is_running();
+
+//==============================================================================
+DESKTOP_DEPLOYMENTMISC_DLLPUBLIC
+oslProcess raiseProcess( ::rtl::OUString const & appURL,
+ ::com::sun::star::uno::Sequence< ::rtl::OUString > const & args );
+
+//==============================================================================
+
+/** writes the argument string to the console.
+ On Linux/Unix/etc. it converts the UTF16 string to an ANSI string using
+ osl_getThreadTextEncoding() as target encoding. On Windows it uses WriteFile
+ with the standard out stream. unopkg.com reads the data and prints them out using
+ WriteConsoleW.
+*/
+DESKTOP_DEPLOYMENTMISC_DLLPUBLIC
+void writeConsole(::rtl::OUString const & sText);
+
+/** writes the argument string to the console.
+ On Linux/Unix/etc. the string is passed into fprintf without any conversion.
+ On Windows the string is converted to UTF16 assuming the argument is UTF8
+ encoded. The UTF16 string is written to stdout with WriteFile. unopkg.com
+ reads the data and prints them out using WriteConsoleW.
+*/
+DESKTOP_DEPLOYMENTMISC_DLLPUBLIC
+void writeConsole(::rtl::OString const & sText);
+
+/** writes the argument to the console using the error stream.
+ Otherwise the same as writeConsole.
+*/
+DESKTOP_DEPLOYMENTMISC_DLLPUBLIC
+void writeConsoleError(::rtl::OUString const & sText);
+
+
+/** writes the argument to the console using the error stream.
+ Otherwise the same as writeConsole.
+*/
+DESKTOP_DEPLOYMENTMISC_DLLPUBLIC
+void writeConsoleError(::rtl::OString const & sText);
+
+
+/** reads from the console.
+ On Linux/Unix/etc. it uses fgets to read char values and converts them to OUString
+ using osl_getThreadTextEncoding as target encoding. The returned string has a maximum
+ size of 1024 and does NOT include leading and trailing white space(applied OUString::trim())
+*/
+DESKTOP_DEPLOYMENTMISC_DLLPUBLIC
+::rtl::OUString readConsole();
+
+/** print the text to the console in a debug build.
+ The argument is forwarded to writeConsole. The function does not add new line.
+ The code is only executed if OSL_DEBUG_LEVEL > 1
+*/
+DESKTOP_DEPLOYMENTMISC_DLLPUBLIC
+void TRACE(::rtl::OUString const & sText);
+DESKTOP_DEPLOYMENTMISC_DLLPUBLIC
+void TRACE(::rtl::OString const & sText);
+
+/** registers or revokes shared or bundled extensions which have been
+ recently added or removed.
+*/
+DESKTOP_DEPLOYMENTMISC_DLLPUBLIC
+void syncRepositories(::com::sun::star::uno::Reference<
+ ::com::sun::star::ucb::XCommandEnvironment> const & xCmdEnv);
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/inc/dp_misc.mk b/desktop/source/deployment/inc/dp_misc.mk
new file mode 100755
index 000000000000..829a6bb96bbf
--- /dev/null
+++ b/desktop/source/deployment/inc/dp_misc.mk
@@ -0,0 +1,42 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+# To be included after settings.mk
+
+# Although the deployment shared library is a UNO component, it also exports
+# some C++ functionality:
+.IF "$(OS)" == "WNT"
+.IF "$(COM)" == "GCC"
+DEPLOYMENTMISCLIB = -ldeploymentmisc$(DLLPOSTFIX)
+.ELSE
+DEPLOYMENTMISCLIB = ideploymentmisc$(DLLPOSTFIX).lib
+.ENDIF
+.ELIF "$(OS)" == "OS2"
+DEPLOYMENTMISCLIB = ideploymentmisc$(DLLPOSTFIX).lib
+.ELSE
+DEPLOYMENTMISCLIB = -ldeploymentmisc$(DLLPOSTFIX)
+.ENDIF
diff --git a/desktop/source/deployment/inc/dp_misc_api.hxx b/desktop/source/deployment/inc/dp_misc_api.hxx
new file mode 100644
index 000000000000..fbc248a1dfb2
--- /dev/null
+++ b/desktop/source/deployment/inc/dp_misc_api.hxx
@@ -0,0 +1,43 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_DESKTOP_SOURCE_DEPLOYMENT_INC_DP_MISC_API_HXX
+#define INCLUDED_DESKTOP_SOURCE_DEPLOYMENT_INC_DP_MISC_API_HXX
+
+#include "sal/config.h"
+#include "sal/types.h"
+
+#if defined DESKTOP_DEPLOYMENTMISC_DLLIMPLEMENTATION
+#define DESKTOP_DEPLOYMENTMISC_DLLPUBLIC SAL_DLLPUBLIC_EXPORT
+#else
+#define DESKTOP_DEPLOYMENTMISC_DLLPUBLIC SAL_DLLPUBLIC_IMPORT
+#endif
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/inc/dp_persmap.h b/desktop/source/deployment/inc/dp_persmap.h
new file mode 100755
index 000000000000..c078cf902ec5
--- /dev/null
+++ b/desktop/source/deployment/inc/dp_persmap.h
@@ -0,0 +1,68 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#if ! defined INCLUDED_DP_PERSMAP_H
+#define INCLUDED_DP_PERSMAP_H
+
+#include "rtl/ustring.hxx"
+#include "db.hxx"
+#include <boost/unordered_map.hpp>
+
+using namespace berkeleydbproxy;
+
+namespace dp_misc
+{
+
+typedef ::boost::unordered_map<
+ ::rtl::OString, ::rtl::OString, ::rtl::OStringHash > t_string2string_map;
+
+//==============================================================================
+class PersistentMap
+{
+ ::rtl::OUString m_sysPath;
+ mutable Db m_db;
+ void throw_rtexc( int err, char const * msg = 0 ) const;
+
+public:
+ ~PersistentMap();
+ PersistentMap( ::rtl::OUString const & url, bool readOnly );
+ /** in mem db */
+ PersistentMap();
+
+ bool has( ::rtl::OString const & key ) const;
+ bool get( ::rtl::OString * value, ::rtl::OString const & key ) const;
+ t_string2string_map getEntries() const;
+ void put( ::rtl::OString const & key, ::rtl::OString const & value );
+ bool erase( ::rtl::OString const & key, bool flush_immediately = true );
+};
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/inc/dp_platform.hxx b/desktop/source/deployment/inc/dp_platform.hxx
new file mode 100644
index 000000000000..b2b9fad07f49
--- /dev/null
+++ b/desktop/source/deployment/inc/dp_platform.hxx
@@ -0,0 +1,57 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#if ! defined INCLUDED_DP_PLATFORM_HXX
+#define INCLUDED_DP_PLATFORM_HXX
+
+
+#include "dp_misc_api.hxx"
+
+#include "com/sun/star/uno/Sequence.hxx"
+#include "rtl/ustring.hxx"
+
+namespace dp_misc
+{
+
+
+DESKTOP_DEPLOYMENTMISC_DLLPUBLIC ::rtl::OUString const & getPlatformString();
+
+DESKTOP_DEPLOYMENTMISC_DLLPUBLIC
+ bool platform_fits( ::rtl::OUString const & platform_string );
+
+/** determines if the current platform corresponds to one of the platform strings.
+
+*/
+DESKTOP_DEPLOYMENTMISC_DLLPUBLIC
+bool hasValidPlatform( ::com::sun::star::uno::Sequence< ::rtl::OUString > const & platformStrings);
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/inc/dp_resource.h b/desktop/source/deployment/inc/dp_resource.h
new file mode 100755
index 000000000000..d23b187c2275
--- /dev/null
+++ b/desktop/source/deployment/inc/dp_resource.h
@@ -0,0 +1,70 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#if ! defined INCLUDED_DP_RESOURCE_H
+#define INCLUDED_DP_RESOURCE_H
+
+#include "tools/resmgr.hxx"
+#include "tools/string.hxx"
+#include "tools/resid.hxx"
+#include "com/sun/star/lang/Locale.hpp"
+#include "dp_misc.h"
+#include <memory>
+#include "dp_misc_api.hxx"
+
+namespace dp_misc {
+
+//==============================================================================
+ResId getResId( sal_uInt16 id );
+
+//==============================================================================
+DESKTOP_DEPLOYMENTMISC_DLLPUBLIC String getResourceString( sal_uInt16 id );
+
+template <typename Unique, sal_uInt16 id>
+struct StaticResourceString :
+ public ::rtl::StaticWithInit<const ::rtl::OUString, Unique> {
+ const ::rtl::OUString operator () () { return getResourceString(id); }
+};
+
+//==============================================================================
+DESKTOP_DEPLOYMENTMISC_DLLPUBLIC
+::com::sun::star::lang::Locale toLocale( ::rtl::OUString const & slang );
+
+//==============================================================================
+DESKTOP_DEPLOYMENTMISC_DLLPUBLIC
+::com::sun::star::lang::Locale getOfficeLocale();
+
+//==============================================================================
+DESKTOP_DEPLOYMENTMISC_DLLPUBLIC
+::rtl::OUString getOfficeLocaleString();
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/inc/dp_ucb.h b/desktop/source/deployment/inc/dp_ucb.h
new file mode 100755
index 000000000000..22d54de5885a
--- /dev/null
+++ b/desktop/source/deployment/inc/dp_ucb.h
@@ -0,0 +1,94 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#if ! defined INCLUDED_DP_UCB_H
+#define INCLUDED_DP_UCB_H
+
+#include <list>
+#include "rtl/byteseq.hxx"
+#include "rtl/instance.hxx"
+#include "com/sun/star/ucb/XCommandEnvironment.hpp"
+#include "dp_misc_api.hxx"
+
+namespace ucbhelper
+{
+class Content;
+}
+
+namespace css = ::com::sun::star;
+
+namespace dp_misc {
+
+struct DESKTOP_DEPLOYMENTMISC_DLLPUBLIC StrTitle :
+ public rtl::StaticWithInit<const rtl::OUString, StrTitle>
+{
+ const rtl::OUString operator () ();
+};
+
+//==============================================================================
+DESKTOP_DEPLOYMENTMISC_DLLPUBLIC bool create_ucb_content(
+ ::ucbhelper::Content * ucb_content,
+ ::rtl::OUString const & url,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv,
+ bool throw_exc = true );
+
+//==============================================================================
+/** @return true if previously non-existing folder has been created
+ */
+DESKTOP_DEPLOYMENTMISC_DLLPUBLIC bool create_folder(
+ ::ucbhelper::Content * ucb_content,
+ ::rtl::OUString const & url,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv,
+ bool throw_exc = true );
+
+//==============================================================================
+DESKTOP_DEPLOYMENTMISC_DLLPUBLIC bool erase_path(
+ ::rtl::OUString const & url,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv,
+ bool throw_exc = true );
+
+//==============================================================================
+DESKTOP_DEPLOYMENTMISC_DLLPUBLIC
+::rtl::ByteSequence readFile( ::ucbhelper::Content & ucb_content );
+
+//==============================================================================
+DESKTOP_DEPLOYMENTMISC_DLLPUBLIC
+bool readLine( ::rtl::OUString * res, ::rtl::OUString const & startingWith,
+ ::ucbhelper::Content & ucb_content, rtl_TextEncoding textenc );
+
+DESKTOP_DEPLOYMENTMISC_DLLPUBLIC
+bool readProperties( ::std::list< ::std::pair< ::rtl::OUString, ::rtl::OUString> > & out_result,
+ ::ucbhelper::Content & ucb_content);
+
+
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/inc/dp_update.hxx b/desktop/source/deployment/inc/dp_update.hxx
new file mode 100644
index 000000000000..1f22b2bb8d40
--- /dev/null
+++ b/desktop/source/deployment/inc/dp_update.hxx
@@ -0,0 +1,150 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#if ! defined INCLUDED_DP_UPDATE_HXX
+#define INCLUDED_DP_UPDATE_HXX
+
+
+#include "com/sun/star/deployment/XPackage.hpp"
+#include "com/sun/star/deployment/XExtensionManager.hpp"
+#include "com/sun/star/deployment/XUpdateInformationProvider.hpp"
+#include "com/sun/star/uno/XComponentContext.hpp"
+#include "com/sun/star/xml/dom/XNode.hpp"
+
+#include "rtl/ustrbuf.hxx"
+#include "dp_misc_api.hxx"
+
+#include <map>
+#include <vector>
+
+namespace dp_misc {
+
+/** returns the default update URL (for the update information) which
+ is used when an extension does not provide its own URL.
+*/
+DESKTOP_DEPLOYMENTMISC_DLLPUBLIC
+::rtl::OUString getExtensionDefaultUpdateURL();
+
+enum UPDATE_SOURCE
+{
+ UPDATE_SOURCE_NONE,
+ UPDATE_SOURCE_SHARED,
+ UPDATE_SOURCE_BUNDLED,
+ UPDATE_SOURCE_ONLINE
+};
+
+/* determine if an update is available which is installed in the
+ user repository.
+
+ If the return value is UPDATE_SOURCE_NONE, then no update is
+ available, otherwise the return value determine from which the
+ repository the update is used.
+*/
+DESKTOP_DEPLOYMENTMISC_DLLPUBLIC
+UPDATE_SOURCE isUpdateUserExtension(
+ bool bReadOnlyShared,
+ ::rtl::OUString const & userVersion,
+ ::rtl::OUString const & sharedVersion,
+ ::rtl::OUString const & bundledVersion,
+ ::rtl::OUString const & onlineVersion);
+
+/* determine if an update is available which is installed in the
+ shared repository.
+
+ If the return value is UPDATE_SOURCE_NONE, then no update is
+ available, otherwise the return value determine from which the
+ repository the update is used.
+*/
+DESKTOP_DEPLOYMENTMISC_DLLPUBLIC
+UPDATE_SOURCE isUpdateSharedExtension(
+ bool bReadOnlyShared,
+ ::rtl::OUString const & sharedVersion,
+ ::rtl::OUString const & bundledVersion,
+ ::rtl::OUString const & onlineVersion);
+
+/* determines the extension with the highest identifier and returns it
+
+ */
+DESKTOP_DEPLOYMENTMISC_DLLPUBLIC
+::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage>
+getExtensionWithHighestVersion(
+ ::com::sun::star::uno::Sequence<
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::deployment::XPackage> > const & seqExtensionsWithSameId);
+
+
+struct UpdateInfo
+{
+ UpdateInfo( ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage> const & ext);
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::deployment::XPackage> extension;
+//version of the update
+ ::rtl::OUString version;
+ ::com::sun::star::uno::Reference< ::com::sun::star::xml::dom::XNode > info;
+};
+
+typedef std::map< ::rtl::OUString, UpdateInfo > UpdateInfoMap;
+
+/*
+ @param extensionList
+ List of extension for which online update information are to be obtained. If NULL, then
+ for update information are obtained for all installed extension. There may be only one extension
+ with a particular identifier contained in the list. If one extension is installed
+ in several repositories, then the one with the highest version must be used, because it contains
+ the more recent URLs for getting the update information (if at all).
+ @param out_errors
+ the first member of the pair is the extension and the second the exception that was produced
+ when processing the extension.
+
+ @return
+ A map of UpdateInfo instances. If the parameter extensionList was given, then the map contains
+ at only information for those extensions.
+ */
+DESKTOP_DEPLOYMENTMISC_DLLPUBLIC
+UpdateInfoMap getOnlineUpdateInfos(
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext> const &xContext,
+ ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XExtensionManager> const & xExtMgr,
+ ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XUpdateInformationProvider > const & updateInformation,
+ std::vector< ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > > const * extensionList,
+ ::std::vector< ::std::pair< ::com::sun::star::uno::Reference<
+ ::com::sun::star::deployment::XPackage>, ::com::sun::star::uno::Any> > & out_errors);
+
+/* retunrs the highest version from the provided arguments.
+*/
+DESKTOP_DEPLOYMENTMISC_DLLPUBLIC
+::rtl::OUString getHighestVersion(
+ ::rtl::OUString const & userVersion,
+ ::rtl::OUString const & sharedVersion,
+ ::rtl::OUString const & bundledVersion,
+ ::rtl::OUString const & onlineVersion);
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/inc/dp_version.hxx b/desktop/source/deployment/inc/dp_version.hxx
new file mode 100644
index 000000000000..f335b986c5e3
--- /dev/null
+++ b/desktop/source/deployment/inc/dp_version.hxx
@@ -0,0 +1,51 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_DESKTOP_SOURCE_DEPLOYMENT_INC_DP_VERSION_HXX
+#define INCLUDED_DESKTOP_SOURCE_DEPLOYMENT_INC_DP_VERSION_HXX
+
+#include "sal/config.h"
+#include "com/sun/star/uno/Reference.hxx"
+#include "dp_misc_api.hxx"
+
+namespace com { namespace sun { namespace star { namespace deployment {
+ class XPackage;
+} } } }
+namespace rtl { class OUString; }
+
+namespace dp_misc {
+
+enum Order { LESS, EQUAL, GREATER };
+
+DESKTOP_DEPLOYMENTMISC_DLLPUBLIC Order compareVersions(
+ ::rtl::OUString const & version1, ::rtl::OUString const & version2);
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/inc/dp_xml.h b/desktop/source/deployment/inc/dp_xml.h
new file mode 100755
index 000000000000..4e178e1b37bf
--- /dev/null
+++ b/desktop/source/deployment/inc/dp_xml.h
@@ -0,0 +1,60 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#if ! defined INCLUDED_DP_XML_H
+#define INCLUDED_DP_XML_H
+
+#include "rtl/ref.hxx"
+#include "rtl/ustrbuf.hxx"
+#include "cppuhelper/implbase1.hxx"
+#include "com/sun/star/uno/XComponentContext.hpp"
+#include "com/sun/star/xml/input/XRoot.hpp"
+#include "com/sun/star/xml/sax/XDocumentHandler.hpp"
+
+
+namespace ucbhelper
+{
+class Content;
+}
+
+namespace css = ::com::sun::star;
+
+namespace dp_misc
+{
+
+//==============================================================================
+void xml_parse(
+ css::uno::Reference< css::xml::sax::XDocumentHandler > const & xDocHandler,
+ ::ucbhelper::Content & ucb_content,
+ css::uno::Reference< css::uno::XComponentContext > const & xContext );
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/makefile.mk b/desktop/source/deployment/makefile.mk
new file mode 100755
index 000000000000..877379ad7300
--- /dev/null
+++ b/desktop/source/deployment/makefile.mk
@@ -0,0 +1,119 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ = ..$/..
+
+PRJNAME = desktop
+TARGET = deployment
+ENABLE_EXCEPTIONS = TRUE
+NO_BSYMBOLIC = TRUE
+
+.IF "$(GUI)"=="OS2"
+TARGET = deploy
+.ENDIF
+
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/source$/deployment$/inc$/dp_misc.mk
+
+.IF "$(SYSTEM_DB)" == "YES"
+CFLAGS+=-DSYSTEM_DB -I$(DB_INCLUDES)
+.ENDIF
+
+INCPRE += inc
+
+DLLPRE =
+
+SHL1TARGET = $(TARGET)$(DLLPOSTFIX).uno
+SHL1VERSIONMAP = $(SOLARENV)/src/component.map
+
+SHL1LIBS = \
+ $(SLB)$/deployment_manager.lib \
+ $(SLB)$/deployment_registry.lib \
+ $(SLB)$/deployment_registry_executable.lib \
+ $(SLB)$/deployment_registry_component.lib \
+ $(SLB)$/deployment_registry_configuration.lib \
+ $(SLB)$/deployment_registry_package.lib \
+ $(SLB)$/deployment_registry_script.lib \
+ $(SLB)$/deployment_registry_sfwk.lib \
+ $(SLB)$/deployment_registry_help.lib
+
+SHL1OBJS = \
+ $(SLO)$/dp_log.obj \
+ $(SLO)$/dp_persmap.obj \
+ $(SLO)$/dp_services.obj \
+ $(SLO)$/dp_xml.obj
+
+SHL1STDLIBS = \
+ $(SALLIB) \
+ $(CPPULIB) \
+ $(CPPUHELPERLIB) \
+ $(UCBHELPERLIB) \
+ $(COMPHELPERLIB) \
+ $(TOOLSLIB) \
+ $(XMLSCRIPTLIB) \
+ $(SVLLIB) \
+ $(UNOTOOLSLIB) \
+ $(DEPLOYMENTMISCLIB) \
+ $(HELPLINKERLIB)
+
+SHL1DEPN =
+SHL1IMPLIB = i$(TARGET)
+SHL1DEF = $(MISC)$/$(SHL1TARGET).def
+
+DEF1NAME = $(SHL1TARGET)
+
+SLOFILES = $(LIB1OBJFILES)
+
+RESLIB1NAME = $(TARGET)
+
+RESLIB1SRSFILES = \
+ $(SRS)$/deployment_registry_configuration.srs \
+ $(SRS)$/deployment_registry_component.srs \
+ $(SRS)$/deployment_registry_script.srs \
+ $(SRS)$/deployment_registry_sfwk.srs \
+ $(SRS)$/deployment_registry_package.srs \
+ $(SRS)$/deployment_registry_help.srs \
+ $(SRS)$/deployment_registry.srs \
+ $(SRS)$/deployment_manager.srs \
+ $(SRS)$/deployment_unopkg.srs
+
+.IF "$(GUI)"=="OS2"
+RESLIB1SRSFILES += $(SRS)$/deplmisc.srs
+.ELSE
+RESLIB1SRSFILES += $(SRS)$/deployment_misc.srs
+.ENDIF
+
+.INCLUDE : target.mk
+
+
+ALLTAR : $(MISC)/deployment.component
+
+$(MISC)/deployment.component .ERRREMOVE : $(SOLARENV)/bin/createcomponent.xslt \
+ deployment.component
+ $(XSLTPROC) --nonet --stringparam uri \
+ '$(COMPONENTPREFIX_BASIS_NATIVE)$(SHL1TARGETN:f)' -o $@ \
+ $(SOLARENV)/bin/createcomponent.xslt deployment.component
diff --git a/desktop/source/deployment/manager/dp_activepackages.cxx b/desktop/source/deployment/manager/dp_activepackages.cxx
new file mode 100644
index 000000000000..f220aaf40daa
--- /dev/null
+++ b/desktop/source/deployment/manager/dp_activepackages.cxx
@@ -0,0 +1,209 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "precompiled_desktop.hxx"
+
+#include "sal/config.h"
+
+#include <cstddef>
+#include <utility>
+#include <vector>
+
+#include "osl/diagnose.h"
+#include "rtl/strbuf.hxx"
+#include "rtl/string.hxx"
+#include "rtl/textenc.h"
+#include "rtl/uri.h"
+#include "rtl/uri.hxx"
+#include "rtl/ustring.hxx"
+#include <boost/unordered_map.hpp>
+
+#include "dp_identifier.hxx"
+#include "dp_persmap.h"
+
+#include "dp_activepackages.hxx"
+
+// Old format of database entry:
+// key: UTF8(filename)
+// value: UTF8(tempname ";" mediatype)
+// New format of database entry:
+// key: 0xFF UTF8(identifier)
+// value: UTF8(tempname) 0xFF UTF8(filename) 0xFF UTF8(mediatype)
+
+namespace {
+
+static char const separator = static_cast< char >(
+ static_cast< unsigned char >(0xFF));
+
+static char const legacyPrefix[] = "org.openoffice.legacy.";
+
+::rtl::OString oldKey(::rtl::OUString const & fileName) {
+ return ::rtl::OUStringToOString(fileName, RTL_TEXTENCODING_UTF8);
+}
+
+::rtl::OString newKey(::rtl::OUString const & id) {
+ ::rtl::OStringBuffer b;
+ b.append(separator);
+ b.append(::rtl::OUStringToOString(id, RTL_TEXTENCODING_UTF8));
+ return b.makeStringAndClear();
+}
+
+::dp_manager::ActivePackages::Data decodeOldData(
+ ::rtl::OUString const & fileName, ::rtl::OString const & value)
+{
+ ::dp_manager::ActivePackages::Data d;
+ sal_Int32 i = value.indexOf(';');
+ OSL_ASSERT(i >= 0);
+ d.temporaryName = ::rtl::OUString(value.getStr(), i, RTL_TEXTENCODING_UTF8);
+ d.fileName = fileName;
+ d.mediaType = ::rtl::OUString(
+ value.getStr() + i + 1, value.getLength() - i - 1,
+ RTL_TEXTENCODING_UTF8);
+ return d;
+}
+
+::dp_manager::ActivePackages::Data decodeNewData(::rtl::OString const & value) {
+ ::dp_manager::ActivePackages::Data d;
+ sal_Int32 i1 = value.indexOf(separator);
+ OSL_ASSERT(i1 >= 0);
+ d.temporaryName = ::rtl::OUString(
+ value.getStr(), i1, RTL_TEXTENCODING_UTF8);
+ sal_Int32 i2 = value.indexOf(separator, i1 + 1);
+ OSL_ASSERT(i2 >= 0);
+ d.fileName = ::rtl::OUString(
+ value.getStr() + i1 + 1, i2 - i1 - 1, RTL_TEXTENCODING_UTF8);
+ sal_Int32 i3 = value.indexOf(separator, i2 + 1);
+
+ if (i3 < 0)
+ {
+ //Before ActivePackages::Data::version was added
+ d.mediaType = ::rtl::OUString(
+ value.getStr() + i2 + 1, value.getLength() - i2 - 1,
+ RTL_TEXTENCODING_UTF8);
+ }
+ else
+ {
+ sal_Int32 i4 = value.indexOf(separator, i3 + 1);
+ d.mediaType = ::rtl::OUString(
+ value.getStr() + i2 + 1, i3 - i2 -1, RTL_TEXTENCODING_UTF8);
+ d.version = ::rtl::OUString(
+ value.getStr() + i3 + 1, i4 - i3 - 1,
+ RTL_TEXTENCODING_UTF8);
+ d.failedPrerequisites = ::rtl::OUString(
+ value.getStr() + i4 + 1, value.getLength() - i4 - 1,
+ RTL_TEXTENCODING_UTF8);
+ }
+ return d;
+}
+
+}
+
+namespace dp_manager {
+
+ActivePackages::ActivePackages() {}
+
+ActivePackages::ActivePackages(::rtl::OUString const & url, bool readOnly):
+ m_map(url, readOnly) {}
+
+ActivePackages::~ActivePackages() {}
+
+bool ActivePackages::has(
+ ::rtl::OUString const & id, ::rtl::OUString const & fileName) const
+{
+ return get(NULL, id, fileName);
+}
+
+bool ActivePackages::get(
+ Data * data, ::rtl::OUString const & id, ::rtl::OUString const & fileName)
+ const
+{
+ ::rtl::OString v;
+ if (m_map.get(&v, newKey(id))) {
+ if (data != NULL) {
+ *data = decodeNewData(v);
+ }
+ return true;
+ } else if (m_map.get(&v, oldKey(fileName))) {
+ if (data != NULL) {
+ *data = decodeOldData(fileName, v);
+ }
+ return true;
+ } else {
+ return false;
+ }
+}
+
+ActivePackages::Entries ActivePackages::getEntries() const {
+ Entries es;
+ ::dp_misc::t_string2string_map m(m_map.getEntries());
+ for (::dp_misc::t_string2string_map::const_iterator i(m.begin());
+ i != m.end(); ++i)
+ {
+ if (i->first.getLength() > 0 && i->first[0] == separator) {
+ es.push_back(
+ ::std::make_pair(
+ ::rtl::OUString(
+ i->first.getStr() + 1, i->first.getLength() - 1,
+ RTL_TEXTENCODING_UTF8),
+ decodeNewData(i->second)));
+ } else {
+ ::rtl::OUString fn(
+ ::rtl::OStringToOUString(i->first, RTL_TEXTENCODING_UTF8));
+ es.push_back(
+ ::std::make_pair(
+ ::dp_misc::generateLegacyIdentifier(fn),
+ decodeOldData(fn, i->second)));
+ }
+ }
+ return es;
+}
+
+void ActivePackages::put(::rtl::OUString const & id, Data const & data) {
+ ::rtl::OStringBuffer b;
+ b.append(
+ ::rtl::OUStringToOString(data.temporaryName, RTL_TEXTENCODING_UTF8));
+ b.append(separator);
+ b.append(::rtl::OUStringToOString(data.fileName, RTL_TEXTENCODING_UTF8));
+ b.append(separator);
+ b.append(::rtl::OUStringToOString(data.mediaType, RTL_TEXTENCODING_UTF8));
+ b.append(separator);
+ b.append(::rtl::OUStringToOString(data.version, RTL_TEXTENCODING_UTF8));
+ b.append(separator);
+ b.append(::rtl::OUStringToOString(data.failedPrerequisites, RTL_TEXTENCODING_UTF8));
+ m_map.put(newKey(id), b.makeStringAndClear());
+}
+
+void ActivePackages::erase(
+ ::rtl::OUString const & id, ::rtl::OUString const & fileName)
+{
+ m_map.erase(newKey(id), true) || m_map.erase(oldKey(fileName), true);
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/manager/dp_activepackages.hxx b/desktop/source/deployment/manager/dp_activepackages.hxx
new file mode 100644
index 000000000000..2a4d18686346
--- /dev/null
+++ b/desktop/source/deployment/manager/dp_activepackages.hxx
@@ -0,0 +1,102 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_DESKTOP_SOURCE_DEPLOYMENT_MANAGER_DP_ACTIVEPACKAGES_HXX
+#define INCLUDED_DESKTOP_SOURCE_DEPLOYMENT_MANAGER_DP_ACTIVEPACKAGES_HXX
+
+#include "sal/config.h"
+
+#include <utility>
+#include <vector>
+
+#include "dp_persmap.h"
+
+namespace rtl { class OUString; }
+
+namespace dp_manager {
+
+class ActivePackages {
+public:
+ struct Data {
+ Data(): failedPrerequisites(::rtl::OUString::valueOf((sal_Int32)0))
+ {}
+ /* name of the temporary file (shared, user extension) or the name of
+ the folder of the bundled extension.
+ It does not contain the trailing '_' of the folder.
+ UTF-8 encoded
+ */
+ ::rtl::OUString temporaryName;
+ /* The file name (shared, user) or the folder name (bundled)
+ If the key is the file name, then file name is not encoded.
+ If the key is the idendifier then the file name is UTF-8 encoded.
+ */
+ ::rtl::OUString fileName;
+ ::rtl::OUString mediaType;
+ ::rtl::OUString version;
+ /* If this string contains the value according to
+ com::sun::star::deployment::Prerequisites or "0". That is, if
+ the value is > 0 then
+ the call to XPackage::checkPrerequisites failed.
+ In this case the extension must not be registered.
+ */
+ ::rtl::OUString failedPrerequisites;
+ };
+
+ typedef ::std::vector< ::std::pair< ::rtl::OUString, Data > > Entries;
+
+ ActivePackages();
+
+ ActivePackages(::rtl::OUString const & url, bool readOnly);
+
+ ~ActivePackages();
+
+ bool has(::rtl::OUString const & id, ::rtl::OUString const & fileName)
+ const;
+
+ bool get(
+ Data * data, ::rtl::OUString const & id,
+ ::rtl::OUString const & fileName) const;
+
+ Entries getEntries() const;
+
+ void put(::rtl::OUString const & id, Data const & value);
+
+ void erase(::rtl::OUString const & id, ::rtl::OUString const & fileName);
+
+private:
+ ActivePackages(ActivePackages &); // not defined
+ void operator =(ActivePackages &); // not defined
+
+ ::dp_misc::PersistentMap m_map;
+};
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/manager/dp_commandenvironments.cxx b/desktop/source/deployment/manager/dp_commandenvironments.cxx
new file mode 100644
index 000000000000..f8237f35499f
--- /dev/null
+++ b/desktop/source/deployment/manager/dp_commandenvironments.cxx
@@ -0,0 +1,287 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include "com/sun/star/deployment/VersionException.hpp"
+#include "com/sun/star/deployment/LicenseException.hpp"
+#include "com/sun/star/deployment/InstallException.hpp"
+#include "com/sun/star/deployment/DependencyException.hpp"
+#include "com/sun/star/deployment/PlatformException.hpp"
+#include "com/sun/star/task/XInteractionApprove.hpp"
+#include "com/sun/star/task/XInteractionAbort.hpp"
+#include "com/sun/star/task/XInteractionHandler.hpp"
+#include "com/sun/star/ucb/XCommandEnvironment.hpp"
+#include "com/sun/star/uno/XComponentContext.hpp"
+#include "dp_commandenvironments.hxx"
+
+namespace deployment = com::sun::star::deployment;
+namespace lang = com::sun::star::lang;
+namespace task = com::sun::star::task;
+namespace ucb = com::sun::star::ucb;
+namespace uno = com::sun::star::uno;
+namespace css = com::sun::star;
+
+#define OUSTR(s) rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(s))
+
+using ::com::sun::star::uno::Reference;
+using ::rtl::OUString;
+
+namespace dp_manager {
+
+BaseCommandEnv::BaseCommandEnv()
+{
+}
+
+BaseCommandEnv::BaseCommandEnv(
+ Reference< task::XInteractionHandler> const & handler)
+ : m_forwardHandler(handler)
+{
+}
+
+BaseCommandEnv::~BaseCommandEnv()
+{
+}
+// XCommandEnvironment
+//______________________________________________________________________________
+Reference<task::XInteractionHandler> BaseCommandEnv::getInteractionHandler()
+throw (uno::RuntimeException)
+{
+ return this;
+}
+
+//______________________________________________________________________________
+Reference<ucb::XProgressHandler> BaseCommandEnv::getProgressHandler()
+throw (uno::RuntimeException)
+{
+ return this;
+}
+
+void BaseCommandEnv::handle(
+ Reference< task::XInteractionRequest> const & /*xRequest*/ )
+ throw (uno::RuntimeException)
+{
+}
+
+void BaseCommandEnv::handle_(bool approve, bool abort,
+ Reference< task::XInteractionRequest> const & xRequest )
+{
+ if (approve == false && abort == false)
+ {
+ //not handled so far -> forwarding
+ if (m_forwardHandler.is())
+ m_forwardHandler->handle(xRequest);
+ else
+ return; //cannot handle
+ }
+ else
+ {
+ // select:
+ uno::Sequence< Reference< task::XInteractionContinuation > > conts(
+ xRequest->getContinuations() );
+ Reference< task::XInteractionContinuation > const * pConts =
+ conts.getConstArray();
+ sal_Int32 len = conts.getLength();
+ for ( sal_Int32 pos = 0; pos < len; ++pos )
+ {
+ if (approve) {
+ Reference< task::XInteractionApprove > xInteractionApprove(
+ pConts[ pos ], uno::UNO_QUERY );
+ if (xInteractionApprove.is()) {
+ xInteractionApprove->select();
+ // don't query again for ongoing continuations:
+ approve = false;
+ }
+ }
+ else if (abort) {
+ Reference< task::XInteractionAbort > xInteractionAbort(
+ pConts[ pos ], uno::UNO_QUERY );
+ if (xInteractionAbort.is()) {
+ xInteractionAbort->select();
+ // don't query again for ongoing continuations:
+ abort = false;
+ }
+ }
+ }
+ }
+
+}
+
+// XProgressHandler
+void BaseCommandEnv::push( uno::Any const & /*Status*/ )
+throw (uno::RuntimeException)
+{
+}
+
+void BaseCommandEnv::update( uno::Any const & /*Status */)
+throw (uno::RuntimeException)
+{
+}
+
+void BaseCommandEnv::pop() throw (uno::RuntimeException)
+{
+}
+//==============================================================================
+
+TmpRepositoryCommandEnv::TmpRepositoryCommandEnv()
+{
+}
+
+TmpRepositoryCommandEnv::TmpRepositoryCommandEnv(
+ css::uno::Reference< css::task::XInteractionHandler> const & handler):
+ BaseCommandEnv(handler)
+{
+}
+// XInteractionHandler
+void TmpRepositoryCommandEnv::handle(
+ Reference< task::XInteractionRequest> const & xRequest )
+ throw (uno::RuntimeException)
+{
+ uno::Any request( xRequest->getRequest() );
+ OSL_ASSERT( request.getValueTypeClass() == uno::TypeClass_EXCEPTION );
+
+ deployment::VersionException verExc;
+ deployment::LicenseException licExc;
+ deployment::InstallException instExc;
+
+ bool approve = false;
+ bool abort = false;
+
+ if ((request >>= verExc)
+ || (request >>= licExc)
+ || (request >>= instExc))
+ {
+ approve = true;
+ }
+
+ handle_(approve, abort, xRequest);
+}
+//================================================================================
+
+LicenseCommandEnv::LicenseCommandEnv(
+ css::uno::Reference< css::task::XInteractionHandler> const & handler,
+ bool bSuppressLicense,
+ OUString const & repository):
+ BaseCommandEnv(handler), m_repository(repository),
+ m_bSuppressLicense(bSuppressLicense)
+{
+}
+// XInteractionHandler
+void LicenseCommandEnv::handle(
+ Reference< task::XInteractionRequest> const & xRequest )
+ throw (uno::RuntimeException)
+{
+ uno::Any request( xRequest->getRequest() );
+ OSL_ASSERT( request.getValueTypeClass() == uno::TypeClass_EXCEPTION );
+
+ deployment::LicenseException licExc;
+
+ bool approve = false;
+ bool abort = false;
+
+ if (request >>= licExc)
+ {
+ if (m_bSuppressLicense
+ || m_repository.equals(OUSTR("bundled"))
+ || licExc.AcceptBy.equals(OUSTR("admin")))
+ {
+ //always approve in bundled case, because we do not support
+ //showing licenses anyway.
+ //The "admin" already accepted the license when installing the
+ // shared extension
+ approve = true;
+ }
+ }
+
+ handle_(approve, abort, xRequest);
+}
+
+//================================================================================
+
+NoLicenseCommandEnv::NoLicenseCommandEnv(
+ css::uno::Reference< css::task::XInteractionHandler> const & handler):
+ BaseCommandEnv(handler)
+{
+}
+// XInteractionHandler
+void NoLicenseCommandEnv::handle(
+ Reference< task::XInteractionRequest> const & xRequest )
+ throw (uno::RuntimeException)
+{
+ uno::Any request( xRequest->getRequest() );
+ OSL_ASSERT( request.getValueTypeClass() == uno::TypeClass_EXCEPTION );
+
+ deployment::LicenseException licExc;
+
+ bool approve = false;
+ bool abort = false;
+
+ if (request >>= licExc)
+ {
+ approve = true;
+ }
+ handle_(approve, abort, xRequest);
+}
+
+SilentCheckPrerequisitesCommandEnv::SilentCheckPrerequisitesCommandEnv()
+{
+}
+
+void SilentCheckPrerequisitesCommandEnv::handle(
+ Reference< task::XInteractionRequest> const & xRequest )
+ throw (uno::RuntimeException)
+{
+ uno::Any request( xRequest->getRequest() );
+ OSL_ASSERT( request.getValueTypeClass() == uno::TypeClass_EXCEPTION );
+
+ deployment::LicenseException licExc;
+ deployment::PlatformException platformExc;
+ deployment::DependencyException depExc;
+ bool approve = false;
+ bool abort = false;
+
+ if (request >>= licExc)
+ {
+ approve = true;
+ handle_(approve, abort, xRequest);
+ }
+ else if ((request >>= platformExc)
+ || (request >>= depExc))
+ {
+ m_Exception = request;
+ }
+ else
+ {
+ m_UnknownException = request;
+ }
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/manager/dp_commandenvironments.hxx b/desktop/source/deployment/manager/dp_commandenvironments.hxx
new file mode 100644
index 000000000000..59349c469af0
--- /dev/null
+++ b/desktop/source/deployment/manager/dp_commandenvironments.hxx
@@ -0,0 +1,161 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#if ! defined INCLUDED_DP_COMMANDENVIRONMENTS_HXX
+#define INCLUDED_DP_COMMANDENVIRONMENTS_HXX
+
+#include "cppuhelper/compbase3.hxx"
+#include "ucbhelper/content.hxx"
+#include "com/sun/star/uno/Type.hxx"
+
+namespace css = ::com::sun::star;
+
+namespace dp_manager {
+
+/**
+ This command environment is to be used when an extension is temporarily
+ stored in the "tmp" repository. It prevents all kind of user interaction.
+ */
+class BaseCommandEnv
+ : public ::cppu::WeakImplHelper3< css::ucb::XCommandEnvironment,
+ css::task::XInteractionHandler,
+ css::ucb::XProgressHandler >
+{
+protected:
+ css::uno::Reference< css::uno::XComponentContext > m_xContext;
+ css::uno::Reference< css::task::XInteractionHandler> m_forwardHandler;
+
+ void handle_(bool approve, bool abort,
+ css::uno::Reference< css::task::XInteractionRequest> const & xRequest );
+public:
+ virtual ~BaseCommandEnv();
+ BaseCommandEnv();
+ BaseCommandEnv(
+ css::uno::Reference< css::task::XInteractionHandler> const & handler);
+
+ // XCommandEnvironment
+ virtual css::uno::Reference<css::task::XInteractionHandler > SAL_CALL
+ getInteractionHandler() throw (css::uno::RuntimeException);
+ virtual css::uno::Reference<css::ucb::XProgressHandler >
+ SAL_CALL getProgressHandler() throw (css::uno::RuntimeException);
+
+ // XInteractionHandler
+ virtual void SAL_CALL handle(
+ css::uno::Reference<css::task::XInteractionRequest > const & xRequest )
+ throw (css::uno::RuntimeException);
+
+ // XProgressHandler
+ virtual void SAL_CALL push( css::uno::Any const & Status )
+ throw (css::uno::RuntimeException);
+ virtual void SAL_CALL update( css::uno::Any const & Status )
+ throw (css::uno::RuntimeException);
+ virtual void SAL_CALL pop() throw (css::uno::RuntimeException);
+};
+
+class TmpRepositoryCommandEnv : public BaseCommandEnv
+{
+public:
+ TmpRepositoryCommandEnv();
+ TmpRepositoryCommandEnv(css::uno::Reference< css::task::XInteractionHandler> const & handler);
+
+// XInteractionHandler
+ virtual void SAL_CALL handle(
+ css::uno::Reference<css::task::XInteractionRequest > const & xRequest )
+ throw (css::uno::RuntimeException);
+
+};
+
+/** this class is for use in XPackageManager::synchronize.
+
+ It handles particular license cases.
+ */
+class LicenseCommandEnv : public BaseCommandEnv
+{
+private:
+ ::rtl::OUString m_repository;
+ bool m_bSuppressLicense;
+public:
+ LicenseCommandEnv() : m_bSuppressLicense(false) {};
+ LicenseCommandEnv(
+ css::uno::Reference< css::task::XInteractionHandler> const & handler,
+ bool bSuppressLicense,
+ ::rtl::OUString const & repository);
+
+// XInteractionHandler
+ virtual void SAL_CALL handle(
+ css::uno::Reference<css::task::XInteractionRequest > const & xRequest )
+ throw (css::uno::RuntimeException);
+
+};
+
+/** this class is for use in XPackageManager::checkPrerequisites
+
+ It always prohibits a license interaction
+ */
+class NoLicenseCommandEnv : public BaseCommandEnv
+{
+
+public:
+ NoLicenseCommandEnv(){};
+ NoLicenseCommandEnv(css::uno::Reference< css::task::XInteractionHandler> const & handler);
+
+// XInteractionHandler
+ virtual void SAL_CALL handle(
+ css::uno::Reference<css::task::XInteractionRequest > const & xRequest )
+ throw (css::uno::RuntimeException);
+
+};
+
+/* For use in XExtensionManager::addExtension in the call to
+ XPackage::checkPrerequisites
+ It prevents all user interactions. The license is always accepted.
+ It remembers if there was a platform or a dependency exception in
+ the member m_bException. if there was any other exception then m_bUnknownException
+ is set.
+
+ */
+class SilentCheckPrerequisitesCommandEnv : public BaseCommandEnv
+{
+public:
+ SilentCheckPrerequisitesCommandEnv();
+ // XInteractionHandler
+ virtual void SAL_CALL handle(
+ css::uno::Reference<css::task::XInteractionRequest > const & xRequest )
+ throw (css::uno::RuntimeException);
+
+ // Set to true if a PlatformException or a DependencyException were handled.
+ css::uno::Any m_Exception;
+ // Set to true if an unknown exception was handled.
+ css::uno::Any m_UnknownException;
+};
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/manager/dp_extensionmanager.cxx b/desktop/source/deployment/manager/dp_extensionmanager.cxx
new file mode 100644
index 000000000000..3bfad74a3f32
--- /dev/null
+++ b/desktop/source/deployment/manager/dp_extensionmanager.cxx
@@ -0,0 +1,1575 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include <cppuhelper/implbase1.hxx>
+
+#include "comphelper/servicedecl.hxx"
+#include "cppuhelper/exc_hlp.hxx"
+#include "rtl/bootstrap.hxx"
+#include "com/sun/star/deployment/ExtensionManager.hpp"
+#include "com/sun/star/deployment/XExtensionManager.hpp"
+#include "com/sun/star/deployment/thePackageManagerFactory.hpp"
+#include "com/sun/star/deployment/XPackageManager.hpp"
+#include "com/sun/star/deployment/XPackageManagerFactory.hpp"
+#include "com/sun/star/deployment/XPackage.hpp"
+#include "com/sun/star/deployment/InstallException.hpp"
+#include "com/sun/star/deployment/VersionException.hpp"
+#include "com/sun/star/deployment/LicenseException.hpp"
+#include "com/sun/star/lang/XServiceInfo.hpp"
+#include "com/sun/star/registry/XRegistryKey.hpp"
+#include "com/sun/star/beans/Optional.hpp"
+#include "com/sun/star/task/XInteractionApprove.hpp"
+#include "com/sun/star/beans/Ambiguous.hpp"
+#include "com/sun/star/uno/XComponentContext.hpp"
+#include "com/sun/star/io/XInputStream.hpp"
+#include "com/sun/star/util/XModifyBroadcaster.hpp"
+#include "comphelper/sequence.hxx"
+#include "xmlscript/xml_helper.hxx"
+#include "osl/diagnose.h"
+#include "dp_interact.h"
+#include "dp_resource.h"
+#include "dp_ucb.h"
+#include "dp_identifier.hxx"
+#include "dp_descriptioninfoset.hxx"
+#include "dp_extensionmanager.hxx"
+#include "dp_commandenvironments.hxx"
+#include "dp_properties.hxx"
+#include "boost/bind.hpp"
+
+#include <list>
+#include <boost/unordered_map.hpp>
+#include <algorithm>
+
+namespace deploy = com::sun::star::deployment;
+namespace lang = com::sun::star::lang;
+namespace registry = com::sun::star::registry;
+namespace task = com::sun::star::task;
+namespace ucb = com::sun::star::ucb;
+namespace uno = com::sun::star::uno;
+namespace beans = com::sun::star::beans;
+namespace util = com::sun::star::util;
+namespace css = com::sun::star;
+
+using ::com::sun::star::uno::Reference;
+using ::rtl::OUString;
+
+namespace {
+
+struct CompIdentifiers
+{
+ bool operator() (::std::vector<Reference<deploy::XPackage> > const & a,
+ ::std::vector<Reference<deploy::XPackage> > const & b)
+ {
+ if (getName(a).compareTo(getName(b)) < 0)
+ return true;
+ return false;
+ }
+
+ OUString getName(::std::vector<Reference<deploy::XPackage> > const & a);
+};
+
+OUString CompIdentifiers::getName(::std::vector<Reference<deploy::XPackage> > const & a)
+{
+ OSL_ASSERT(a.size() == 3);
+ //get the first non-null reference
+ Reference<deploy::XPackage> extension;
+ ::std::vector<Reference<deploy::XPackage> >::const_iterator it = a.begin();
+ for (; it != a.end(); it++)
+ {
+ if (it->is())
+ {
+ extension = *it;
+ break;
+ }
+ }
+ OSL_ASSERT(extension.is());
+ return extension->getDisplayName();
+}
+
+void writeLastModified(OUString & url, Reference<ucb::XCommandEnvironment> const & xCmdEnv)
+{
+ //Write the lastmodified file
+ try {
+ ::rtl::Bootstrap::expandMacros(url);
+ ::ucbhelper::Content ucbStamp(url, xCmdEnv );
+ dp_misc::erase_path( url, xCmdEnv );
+ ::rtl::OString stamp("1" );
+ Reference<css::io::XInputStream> xData(
+ ::xmlscript::createInputStream(
+ ::rtl::ByteSequence(
+ reinterpret_cast<sal_Int8 const *>(stamp.getStr()),
+ stamp.getLength() ) ) );
+ ucbStamp.writeStream( xData, true /* replace existing */ );
+ }
+ catch(...)
+ {
+ uno::Any exc(::cppu::getCaughtException());
+ throw deploy::DeploymentException(
+ OUSTR("Failed to update") + url, 0, exc);
+ }
+}
+
+class ExtensionRemoveGuard
+{
+ css::uno::Reference<css::deployment::XPackage> m_extension;
+ css::uno::Reference<css::deployment::XPackageManager> m_xPackageManager;
+
+public:
+ ExtensionRemoveGuard(
+ css::uno::Reference<css::deployment::XPackage> const & extension,
+ css::uno::Reference<css::deployment::XPackageManager> const & xPackageManager):
+ m_extension(extension), m_xPackageManager(xPackageManager) {}
+ ~ExtensionRemoveGuard();
+
+ void reset(css::uno::Reference<css::deployment::XPackage> const & extension) {
+ m_extension = extension;
+ }
+};
+
+ExtensionRemoveGuard::~ExtensionRemoveGuard()
+{
+ try {
+ if (m_xPackageManager.is() && m_extension.is())
+ m_xPackageManager->removePackage(
+ dp_misc::getIdentifier(m_extension), ::rtl::OUString(),
+ css::uno::Reference<css::task::XAbortChannel>(),
+ css::uno::Reference<css::ucb::XCommandEnvironment>());
+ } catch (...) {
+ OSL_ASSERT(0);
+ }
+}
+
+}
+
+namespace dp_manager {
+
+//------------------------------------------------------------------------------
+
+//ToDo: bundled extension
+ExtensionManager::ExtensionManager( Reference< uno::XComponentContext > const& xContext) :
+ ::cppu::WeakComponentImplHelper1< css::deployment::XExtensionManager >(getMutex()),
+ m_xContext( xContext )
+{
+ m_xPackageManagerFactory = deploy::thePackageManagerFactory::get(m_xContext);
+ OSL_ASSERT(m_xPackageManagerFactory.is());
+
+ m_repositoryNames.push_back(OUSTR("user"));
+ m_repositoryNames.push_back(OUSTR("shared"));
+ m_repositoryNames.push_back(OUSTR("bundled"));
+}
+
+//------------------------------------------------------------------------------
+
+ExtensionManager::~ExtensionManager()
+{
+}
+
+Reference<deploy::XPackageManager> ExtensionManager::getUserRepository()
+{
+ return m_xPackageManagerFactory->getPackageManager(OUSTR("user"));
+}
+Reference<deploy::XPackageManager> ExtensionManager::getSharedRepository()
+{
+ return m_xPackageManagerFactory->getPackageManager(OUSTR("shared"));
+}
+Reference<deploy::XPackageManager> ExtensionManager::getBundledRepository()
+{
+ return m_xPackageManagerFactory->getPackageManager(OUSTR("bundled"));
+}
+Reference<deploy::XPackageManager> ExtensionManager::getTmpRepository()
+{
+ return m_xPackageManagerFactory->getPackageManager(OUSTR("tmp"));
+}
+
+Reference<task::XAbortChannel> ExtensionManager::createAbortChannel()
+ throw (uno::RuntimeException)
+{
+ return new dp_misc::AbortChannel;
+}
+
+css::uno::Reference<css::deployment::XPackageManager>
+ExtensionManager::getPackageManager(::rtl::OUString const & repository)
+ throw (css::lang::IllegalArgumentException)
+{
+ Reference<deploy::XPackageManager> xPackageManager;
+ if (repository.equals(OUSTR("user")))
+ xPackageManager = getUserRepository();
+ else if (repository.equals(OUSTR("shared")))
+ xPackageManager = getSharedRepository();
+ else if (repository.equals(OUSTR("bundled")))
+ xPackageManager = getBundledRepository();
+ else
+ throw lang::IllegalArgumentException(
+ OUSTR("No valid repository name provided."),
+ static_cast<cppu::OWeakObject*>(this), 0);
+ return xPackageManager;
+}
+
+/*
+ Enters the XPackage objects into a map. They must be all from the
+ same repository. The value type of the map is a vector, where each vector
+ represents an extension with a particular identifier. The first member
+ represents the user extension, the second the shared extension and the
+ third the bundled extension.
+ */
+void ExtensionManager::addExtensionsToMap(
+ id2extensions & mapExt,
+ uno::Sequence<Reference<deploy::XPackage> > const & seqExt,
+ OUString const & repository)
+{
+ //Determine the index in the vector where these extensions are to be
+ //added.
+ ::std::list<OUString>::const_iterator citNames =
+ m_repositoryNames.begin();
+ int index = 0;
+ for (;citNames != m_repositoryNames.end(); citNames++, index++)
+ {
+ if (citNames->equals(repository))
+ break;
+ }
+
+ for (int i = 0; i < seqExt.getLength(); i++)
+ {
+ Reference<deploy::XPackage> const & xExtension = seqExt[i];
+ OUString id = dp_misc::getIdentifier(xExtension);
+ id2extensions::iterator ivec = mapExt.find(id);
+ if (ivec == mapExt.end())
+ {
+ ::std::vector<Reference<deploy::XPackage> > vec(3);
+ vec[index] = xExtension;
+ mapExt[id] = vec;
+ }
+ else
+ {
+ ivec->second[index] = xExtension;
+ }
+ }
+}
+
+/*
+ returns a list containing extensions with the same identifier from
+ all repositories (user, shared, bundled). If one repository does not
+ have this extension, then the list contains an empty Reference. The list
+ is ordered according to the priority of the repostories:
+ 1. user
+ 2. shared
+ 3. bundled
+
+ The number of elements is always three, unless the number of repository
+ changes.
+ */
+::std::list<Reference<deploy::XPackage> >
+ ExtensionManager::getExtensionsWithSameId(
+ OUString const & identifier, OUString const & fileName,
+ Reference< ucb::XCommandEnvironment> const & /*xCmdEnv*/)
+
+{
+ ::std::list<Reference<deploy::XPackage> > extensionList;
+ Reference<deploy::XPackageManager> lRepos[] = {
+ getUserRepository(), getSharedRepository(), getBundledRepository() };
+ for (int i(0); i != SAL_N_ELEMENTS(lRepos); ++i)
+ {
+ Reference<deploy::XPackage> xPackage;
+ try
+ {
+ xPackage = lRepos[i]->getDeployedPackage(
+ identifier, fileName, Reference<ucb::XCommandEnvironment>());
+ }
+ catch(lang::IllegalArgumentException &)
+ {
+ // thrown if the extension does not exist in this repository
+ }
+ extensionList.push_back(xPackage);
+ }
+ OSL_ASSERT(extensionList.size() == 3);
+ return extensionList;
+}
+
+uno::Sequence<Reference<deploy::XPackage> >
+ExtensionManager::getExtensionsWithSameIdentifier(
+ OUString const & identifier,
+ OUString const & fileName,
+ Reference< ucb::XCommandEnvironment> const & xCmdEnv )
+ throw (
+ deploy::DeploymentException,
+ ucb::CommandFailedException,
+ lang::IllegalArgumentException,
+ uno::RuntimeException)
+{
+ try
+ {
+ ::std::list<Reference<deploy::XPackage> > listExtensions =
+ getExtensionsWithSameId(
+ identifier, fileName, xCmdEnv);
+ sal_Bool bHasExtension = false;
+
+ //throw an IllegalArgumentException if there is no extension at all.
+ typedef ::std::list<Reference<deploy::XPackage> >::const_iterator CIT;
+ for (CIT i = listExtensions.begin(); i != listExtensions.end(); i++)
+ bHasExtension |= i->is();
+ if (!bHasExtension)
+ throw lang::IllegalArgumentException(
+ OUSTR("Could not find extension: ") + identifier + OUSTR(", ") + fileName,
+ static_cast<cppu::OWeakObject*>(this), -1);
+
+ return comphelper::containerToSequence<
+ Reference<deploy::XPackage>,
+ ::std::list<Reference<deploy::XPackage> >
+ > (listExtensions);
+ }
+ catch (deploy::DeploymentException & )
+ {
+ throw;
+ }
+ catch ( ucb::CommandFailedException & )
+ {
+ throw;
+ }
+ catch (lang::IllegalArgumentException &)
+ {
+ throw;
+ }
+ catch (...)
+ {
+ uno::Any exc = ::cppu::getCaughtException();
+ throw deploy::DeploymentException(
+ OUSTR("Extension Manager: exception during getExtensionsWithSameIdentifier"),
+ static_cast<OWeakObject*>(this), exc);
+ }
+}
+
+bool ExtensionManager::isUserDisabled(
+ OUString const & identifier, OUString const & fileName)
+{
+ ::std::list<Reference<deploy::XPackage> > listExtensions;
+
+ try {
+ listExtensions = getExtensionsWithSameId(identifier, fileName);
+ } catch (lang::IllegalArgumentException & ) {
+ }
+ OSL_ASSERT(listExtensions.size() == 3);
+
+ return isUserDisabled( ::comphelper::containerToSequence<
+ Reference<deploy::XPackage>,
+ ::std::list<Reference<deploy::XPackage> >
+ > (listExtensions));
+}
+
+bool ExtensionManager::isUserDisabled(
+ uno::Sequence<Reference<deploy::XPackage> > const & seqExtSameId)
+{
+ OSL_ASSERT(seqExtSameId.getLength() == 3);
+ Reference<deploy::XPackage> const & userExtension = seqExtSameId[0];
+ if (userExtension.is())
+ {
+ beans::Optional<beans::Ambiguous<sal_Bool> > reg =
+ userExtension->isRegistered(Reference<task::XAbortChannel>(),
+ Reference<ucb::XCommandEnvironment>());
+ //If the value is ambiguous is than we assume that the extension
+ //is enabled, but something went wrong during enabling. We do not
+ //automatically disable user extensions.
+ if (reg.IsPresent &&
+ ! reg.Value.IsAmbiguous && ! reg.Value.Value)
+ return true;
+ }
+ return false;
+}
+
+/*
+ This method determines the active extension (XPackage.registerPackage) with a
+ particular identifier.
+
+ The parameter bUserDisabled determines if the user extension is disabled.
+
+ When the user repository contains an extension with the given identifier and
+ it is not disabled by the user, then it is always registered. Otherwise an
+ extension is only registered when there is no registered extension in one of
+ the repositories with a higher priority. That is, if the extension is from
+ the shared repository and an active extension with the same identifer is in
+ the user repository, then the extension is not registered. Similarly a
+ bundled extension is not registered if there is an active extension with the
+ same identifier in the shared or user repository.
+*/
+void ExtensionManager::activateExtension(
+ OUString const & identifier, OUString const & fileName,
+ bool bUserDisabled,
+ bool bStartup,
+ Reference<task::XAbortChannel> const & xAbortChannel,
+ Reference<ucb::XCommandEnvironment> const & xCmdEnv )
+{
+ ::std::list<Reference<deploy::XPackage> > listExtensions;
+ try {
+ listExtensions = getExtensionsWithSameId(identifier, fileName);
+ } catch (lang::IllegalArgumentException &) {
+ }
+ OSL_ASSERT(listExtensions.size() == 3);
+
+ activateExtension(
+ ::comphelper::containerToSequence<
+ Reference<deploy::XPackage>,
+ ::std::list<Reference<deploy::XPackage> >
+ > (listExtensions),
+ bUserDisabled, bStartup, xAbortChannel, xCmdEnv);
+
+ fireModified();
+}
+
+void ExtensionManager::activateExtension(
+ uno::Sequence<Reference<deploy::XPackage> > const & seqExt,
+ bool bUserDisabled,
+ bool bStartup,
+ Reference<task::XAbortChannel> const & xAbortChannel,
+ Reference<ucb::XCommandEnvironment> const & xCmdEnv )
+{
+ bool bActive = false;
+ sal_Int32 len = seqExt.getLength();
+ for (sal_Int32 i = 0; i < len; i++)
+ {
+ Reference<deploy::XPackage> const & aExt = seqExt[i];
+ if (aExt.is())
+ {
+ //get the registration value of the current iteration
+ beans::Optional<beans::Ambiguous<sal_Bool> > optReg =
+ aExt->isRegistered(xAbortChannel, xCmdEnv);
+ //If nothing can be registered then break
+ if (!optReg.IsPresent)
+ break;
+
+ //Check if this is a disabled user extension,
+ if (i == 0 && bUserDisabled)
+ {
+ aExt->revokePackage(xAbortChannel, xCmdEnv);
+ continue;
+ }
+
+ //If we have already determined an active extension then we must
+ //make sure to unregister all extensions with the same id in
+ //repositories with a lower priority
+ if (bActive)
+ {
+ aExt->revokePackage(xAbortChannel, xCmdEnv);
+ }
+ else
+ {
+ //This is the first extension in the ordered list, which becomes
+ //the active extension
+ bActive = true;
+ //Register if not already done.
+ //reregister if the value is ambiguous, which indicates that
+ //something went wrong during last registration.
+ aExt->registerPackage(bStartup, xAbortChannel, xCmdEnv);
+ }
+ }
+ }
+}
+
+Reference<deploy::XPackage> ExtensionManager::backupExtension(
+ OUString const & identifier, OUString const & fileName,
+ Reference<deploy::XPackageManager> const & xPackageManager,
+ Reference<ucb::XCommandEnvironment> const & xCmdEnv )
+{
+ Reference<deploy::XPackage> xBackup;
+ Reference<ucb::XCommandEnvironment> tmpCmdEnv(
+ new TmpRepositoryCommandEnv(xCmdEnv->getInteractionHandler()));
+ Reference<deploy::XPackage> xOldExtension;
+ xOldExtension = xPackageManager->getDeployedPackage(
+ identifier, fileName, tmpCmdEnv);
+
+ if (xOldExtension.is())
+ {
+ xBackup = getTmpRepository()->addPackage(
+ xOldExtension->getURL(), uno::Sequence<beans::NamedValue>(),
+ OUString(), Reference<task::XAbortChannel>(), tmpCmdEnv);
+
+ OSL_ENSURE(xBackup.is(), "Failed to backup extension");
+ }
+ return xBackup;
+}
+
+//The supported package types are actually determined by the registry. However
+//creating a registry
+//(desktop/source/deployment/registry/dp_registry.cxx:PackageRegistryImpl) will
+//create all the backends, so that the registry can obtain from them the package
+//types. Creating the registry will also set up the registry folder containing
+//all the subfolders for the respective backends.
+//Because all repositories support the same backends, we can just delegate this
+//call to one of the repositories.
+uno::Sequence< Reference<deploy::XPackageTypeInfo> >
+ExtensionManager::getSupportedPackageTypes()
+ throw (uno::RuntimeException)
+{
+ return getUserRepository()->getSupportedPackageTypes();
+}
+//Do some necessary checks and user interaction. This function does not
+//aquire the extension manager mutex and that mutex must not be aquired
+//when this function is called. doChecksForAddExtension does synchronous
+//user interactions which may require aquiring the solar mutex.
+//Returns true if the extension can be installed.
+bool ExtensionManager::doChecksForAddExtension(
+ Reference<deploy::XPackageManager> const & xPackageMgr,
+ uno::Sequence<beans::NamedValue> const & properties,
+ css::uno::Reference<css::deployment::XPackage> const & xTmpExtension,
+ Reference<task::XAbortChannel> const & xAbortChannel,
+ Reference<ucb::XCommandEnvironment> const & xCmdEnv,
+ Reference<deploy::XPackage> & out_existingExtension )
+ throw (deploy::DeploymentException,
+ ucb::CommandFailedException,
+ ucb::CommandAbortedException,
+ lang::IllegalArgumentException,
+ uno::RuntimeException)
+{
+ try
+ {
+ Reference<deploy::XPackage> xOldExtension;
+ const OUString sIdentifier = dp_misc::getIdentifier(xTmpExtension);
+ const OUString sFileName = xTmpExtension->getName();
+ const OUString sDisplayName = xTmpExtension->getDisplayName();
+ const OUString sVersion = xTmpExtension->getVersion();
+
+ try
+ {
+ xOldExtension = xPackageMgr->getDeployedPackage(
+ sIdentifier, sFileName, xCmdEnv);
+ out_existingExtension = xOldExtension;
+ }
+ catch (lang::IllegalArgumentException &)
+ {
+ }
+ bool bCanInstall = false;
+
+ //This part is not guarded against other threads removing, adding, disabling ...
+ //etc. the same extension.
+ //checkInstall is safe because it notifies the user if the extension is not yet
+ //installed in the same repository. Because addExtension has its own guard
+ //(m_addMutex), another thread cannot add the extension in the meantime.
+ //checkUpdate is called if the same extension exists in the same
+ //repository. The user is asked if they want to replace it. Another
+ //thread
+ //could already remove the extension. So asking the user was not
+ //necessary. No harm is done. The other thread may also ask the user
+ //if he wants to remove the extension. This depends on the
+ //XCommandEnvironment which it passes to removeExtension.
+ if (xOldExtension.is())
+ {
+ //throws a CommandFailedException if the user cancels
+ //the action.
+ checkUpdate(sVersion, sDisplayName,xOldExtension, xCmdEnv);
+ }
+ else
+ {
+ //throws a CommandFailedException if the user cancels
+ //the action.
+ checkInstall(sDisplayName, xCmdEnv);
+ }
+ //Prevent showing the license if requested.
+ Reference<ucb::XCommandEnvironment> _xCmdEnv(xCmdEnv);
+ ExtensionProperties props(OUString(), properties, Reference<ucb::XCommandEnvironment>());
+
+ dp_misc::DescriptionInfoset info(dp_misc::getDescriptionInfoset(xTmpExtension->getURL()));
+ const ::boost::optional<dp_misc::SimpleLicenseAttributes> licenseAttributes =
+ info.getSimpleLicenseAttributes();
+
+ if (licenseAttributes && licenseAttributes->suppressIfRequired
+ && props.isSuppressedLicense())
+ _xCmdEnv = Reference<ucb::XCommandEnvironment>(
+ new NoLicenseCommandEnv(xCmdEnv->getInteractionHandler()));
+
+ bCanInstall = xTmpExtension->checkPrerequisites(
+ xAbortChannel, _xCmdEnv, xOldExtension.is() || props.isExtensionUpdate()) == 0 ? true : false;
+
+ return bCanInstall;
+ }
+ catch (deploy::DeploymentException& ) {
+ throw;
+ } catch (ucb::CommandFailedException & ) {
+ throw;
+ } catch (ucb::CommandAbortedException & ) {
+ throw;
+ } catch (lang::IllegalArgumentException &) {
+ throw;
+ } catch (uno::RuntimeException &) {
+ throw;
+ } catch (uno::Exception &) {
+ uno::Any excOccurred = ::cppu::getCaughtException();
+ deploy::DeploymentException exc(
+ OUSTR("Extension Manager: exception in doChecksForAddExtension"),
+ static_cast<OWeakObject*>(this), excOccurred);
+ throw exc;
+ } catch (...) {
+ throw uno::RuntimeException(
+ OUSTR("Extension Manager: unexpected exception in doChecksForAddExtension"),
+ static_cast<OWeakObject*>(this));
+ }
+}
+
+// Only add to shared and user repository
+Reference<deploy::XPackage> ExtensionManager::addExtension(
+ OUString const & url, uno::Sequence<beans::NamedValue> const & properties,
+ OUString const & repository,
+ Reference<task::XAbortChannel> const & xAbortChannel,
+ Reference<ucb::XCommandEnvironment> const & xCmdEnv )
+ throw (deploy::DeploymentException,
+ ucb::CommandFailedException,
+ ucb::CommandAbortedException,
+ lang::IllegalArgumentException,
+ uno::RuntimeException)
+{
+ Reference<deploy::XPackage> xNewExtension;
+ //Determine the repository to use
+ Reference<deploy::XPackageManager> xPackageManager;
+ if (repository.equals(OUSTR("user")))
+ xPackageManager = getUserRepository();
+ else if (repository.equals(OUSTR("shared")))
+ xPackageManager = getSharedRepository();
+ else
+ throw lang::IllegalArgumentException(
+ OUSTR("No valid repository name provided."),
+ static_cast<cppu::OWeakObject*>(this), 0);
+ //We must make sure that the xTmpExtension is not create twice, because this
+ //would remove the first one.
+ ::osl::MutexGuard addGuard(m_addMutex);
+
+ Reference<deploy::XPackage> xTmpExtension =
+ getTempExtension(url, xAbortChannel, xCmdEnv);
+ //Make sure the extension is removed from the tmp repository in case
+ //of an exception
+ ExtensionRemoveGuard tmpExtensionRemoveGuard(xTmpExtension, getTmpRepository());
+ const OUString sIdentifier = dp_misc::getIdentifier(xTmpExtension);
+ const OUString sFileName = xTmpExtension->getName();
+ Reference<deploy::XPackage> xOldExtension;
+ Reference<deploy::XPackage> xExtensionBackup;
+
+ uno::Any excOccurred2;
+ bool bUserDisabled = false;
+ bool bCanInstall = doChecksForAddExtension(
+ xPackageManager,
+ properties,
+ xTmpExtension,
+ xAbortChannel,
+ xCmdEnv,
+ xOldExtension );
+
+ {
+ // In this garded section (getMutex) we must not use the argument xCmdEnv
+ // because it may bring up dialogs (XInteractionHandler::handle) this
+ //may potententially deadlock. See issue
+ //http://qa.openoffice.org/issues/show_bug.cgi?id=114933
+ //By not providing xCmdEnv the underlying APIs will throw an exception if
+ //the XInteractionRequest cannot be handled
+ ::osl::MutexGuard guard(getMutex());
+
+ if (bCanInstall)
+ {
+ try
+ {
+ bUserDisabled = isUserDisabled(sIdentifier, sFileName);
+ if (xOldExtension.is())
+ {
+ try
+ {
+ xOldExtension->revokePackage(
+ xAbortChannel, Reference<ucb::XCommandEnvironment>());
+ //save the old user extension in case the user aborts
+ //store the extension in the tmp repository, this will overwrite
+ //xTmpPackage (same identifier). Do not let the user abort or
+ //interact
+ //importing the old extension in the tmp repository will remove
+ //the xTmpExtension
+ //no command environment supplied, only this class shall interact
+ //with the user!
+ xExtensionBackup = getTmpRepository()->importExtension(
+ xOldExtension, Reference<task::XAbortChannel>(),
+ Reference<ucb::XCommandEnvironment>());
+ tmpExtensionRemoveGuard.reset(xExtensionBackup);
+ //xTmpExtension will later be used to check the dependencies
+ //again. However, only xExtensionBackup will be later removed
+ //from the tmp repository
+ xTmpExtension = xExtensionBackup;
+ OSL_ASSERT(xTmpExtension.is());
+ }
+ catch (lang::DisposedException &)
+ {
+ //Another thread might have removed the extension meanwhile
+ }
+ }
+ //check again dependencies but prevent user interaction,
+ //We can disregard the license, because the user must have already
+ //accepted it, when we called checkPrerequisites the first time
+ SilentCheckPrerequisitesCommandEnv * pSilentCommandEnv =
+ new SilentCheckPrerequisitesCommandEnv();
+ Reference<ucb::XCommandEnvironment> silentCommandEnv(pSilentCommandEnv);
+
+ sal_Int32 failedPrereq = xTmpExtension->checkPrerequisites(
+ xAbortChannel, silentCommandEnv, true);
+ if (failedPrereq == 0)
+ {
+ xNewExtension = xPackageManager->addPackage(
+ url, properties, OUString(), xAbortChannel,
+ Reference<ucb::XCommandEnvironment>());
+ //If we add a user extension and there is already one which was
+ //disabled by a user, then the newly installed one is enabled. If we
+ //add to another repository then the user extension remains
+ //disabled.
+ bool bUserDisabled2 = bUserDisabled;
+ if (repository.equals(OUSTR("user")))
+ bUserDisabled2 = false;
+
+ // pass the two values via variables to workaround gcc-4.3.4 specific bug (bnc#655912)
+ OUString sNewExtensionIdentifier = dp_misc::getIdentifier(xNewExtension);
+ OUString sNewExtensionFileName = xNewExtension->getName();
+
+ activateExtension(
+ sNewExtensionIdentifier, sNewExtensionFileName,
+ bUserDisabled2, false, xAbortChannel,
+ Reference<ucb::XCommandEnvironment>());
+ }
+ else
+ {
+ if (pSilentCommandEnv->m_Exception.hasValue())
+ ::cppu::throwException(pSilentCommandEnv->m_Exception);
+ else if ( pSilentCommandEnv->m_UnknownException.hasValue())
+ ::cppu::throwException(pSilentCommandEnv->m_UnknownException);
+ else
+ throw deploy::DeploymentException (
+ OUSTR("Extension Manager: exception during addExtension, ckeckPrerequisites failed"),
+ static_cast<OWeakObject*>(this), uno::Any());
+ }
+ }
+ catch (deploy::DeploymentException& ) {
+ excOccurred2 = ::cppu::getCaughtException();
+ } catch (ucb::CommandFailedException & ) {
+ excOccurred2 = ::cppu::getCaughtException();
+ } catch (ucb::CommandAbortedException & ) {
+ excOccurred2 = ::cppu::getCaughtException();
+ } catch (lang::IllegalArgumentException &) {
+ excOccurred2 = ::cppu::getCaughtException();
+ } catch (uno::RuntimeException &) {
+ excOccurred2 = ::cppu::getCaughtException();
+ } catch (...) {
+ excOccurred2 = ::cppu::getCaughtException();
+ deploy::DeploymentException exc(
+ OUSTR("Extension Manager: exception during addExtension, url: ")
+ + url, static_cast<OWeakObject*>(this), excOccurred2);
+ excOccurred2 <<= exc;
+ }
+ }
+
+ if (excOccurred2.hasValue())
+ {
+ //It does not matter what exception is thrown. We try to
+ //recover the original status.
+ //If the user aborted installation then a ucb::CommandAbortedException
+ //is thrown.
+ //Use a private AbortChannel so the user cannot interrupt.
+ try
+ {
+ if (xExtensionBackup.is())
+ {
+ Reference<deploy::XPackage> xRestored =
+ xPackageManager->importExtension(
+ xExtensionBackup, Reference<task::XAbortChannel>(),
+ Reference<ucb::XCommandEnvironment>());
+ }
+ activateExtension(
+ sIdentifier, sFileName, bUserDisabled, false,
+ Reference<task::XAbortChannel>(), Reference<ucb::XCommandEnvironment>());
+ }
+ catch (...)
+ {
+ }
+ ::cppu::throwException(excOccurred2);
+ }
+ } // leaving the garded section (getMutex())
+
+ try
+ {
+ fireModified();
+
+ }catch (deploy::DeploymentException& ) {
+ throw;
+ } catch (ucb::CommandFailedException & ) {
+ throw;
+ } catch (ucb::CommandAbortedException & ) {
+ throw;
+ } catch (lang::IllegalArgumentException &) {
+ throw;
+ } catch (uno::RuntimeException &) {
+ throw;
+ } catch (uno::Exception &) {
+ uno::Any excOccurred = ::cppu::getCaughtException();
+ deploy::DeploymentException exc(
+ OUSTR("Extension Manager: exception in doChecksForAddExtension"),
+ static_cast<OWeakObject*>(this), excOccurred);
+ throw exc;
+ } catch (...) {
+ throw uno::RuntimeException(
+ OUSTR("Extension Manager: unexpected exception in doChecksForAddExtension"),
+ static_cast<OWeakObject*>(this));
+ }
+
+ return xNewExtension;
+}
+
+void ExtensionManager::removeExtension(
+ OUString const & identifier, OUString const & fileName,
+ OUString const & repository,
+ Reference<task::XAbortChannel> const & xAbortChannel,
+ Reference<ucb::XCommandEnvironment> const & xCmdEnv )
+ throw (deploy::DeploymentException,
+ ucb::CommandFailedException,
+ ucb::CommandAbortedException,
+ lang::IllegalArgumentException,
+ uno::RuntimeException)
+{
+ uno::Any excOccurred1;
+ Reference<deploy::XPackage> xExtensionBackup;
+ Reference<deploy::XPackageManager> xPackageManager;
+ bool bUserDisabled = false;
+ ::osl::MutexGuard guard(getMutex());
+ try
+ {
+//Determine the repository to use
+ if (repository.equals(OUSTR("user")))
+ xPackageManager = getUserRepository();
+ else if (repository.equals(OUSTR("shared")))
+ xPackageManager = getSharedRepository();
+ else
+ throw lang::IllegalArgumentException(
+ OUSTR("No valid repository name provided."),
+ static_cast<cppu::OWeakObject*>(this), 0);
+
+ bUserDisabled = isUserDisabled(identifier, fileName);
+ //Backup the extension, in case the user cancels the action
+ xExtensionBackup = backupExtension(
+ identifier, fileName, xPackageManager, xCmdEnv);
+
+ //revoke the extension if it is active
+ Reference<deploy::XPackage> xOldExtension =
+ xPackageManager->getDeployedPackage(
+ identifier, fileName, xCmdEnv);
+ xOldExtension->revokePackage(xAbortChannel, xCmdEnv);
+
+ xPackageManager->removePackage(
+ identifier, fileName, xAbortChannel, xCmdEnv);
+ activateExtension(identifier, fileName, bUserDisabled, false,
+ xAbortChannel, xCmdEnv);
+ fireModified();
+ }
+ catch (deploy::DeploymentException& ) {
+ excOccurred1 = ::cppu::getCaughtException();
+ } catch (ucb::CommandFailedException & ) {
+ excOccurred1 = ::cppu::getCaughtException();
+ } catch (ucb::CommandAbortedException & ) {
+ excOccurred1 = ::cppu::getCaughtException();
+ } catch (lang::IllegalArgumentException &) {
+ excOccurred1 = ::cppu::getCaughtException();
+ } catch (uno::RuntimeException &) {
+ excOccurred1 = ::cppu::getCaughtException();
+ } catch (...) {
+ excOccurred1 = ::cppu::getCaughtException();
+ deploy::DeploymentException exc(
+ OUSTR("Extension Manager: exception during removeEtension"),
+ static_cast<OWeakObject*>(this), excOccurred1);
+ excOccurred1 <<= exc;
+ }
+
+ if (excOccurred1.hasValue())
+ {
+ //User aborted installation, restore the previous situation.
+ //Use a private AbortChannel so the user cannot interrupt.
+ try
+ {
+ Reference<ucb::XCommandEnvironment> tmpCmdEnv(
+ new TmpRepositoryCommandEnv(xCmdEnv->getInteractionHandler()));
+ if (xExtensionBackup.is())
+ {
+ Reference<deploy::XPackage> xRestored =
+ xPackageManager->importExtension(
+ xExtensionBackup, Reference<task::XAbortChannel>(),
+ tmpCmdEnv);
+ activateExtension(
+ identifier, fileName, bUserDisabled, false,
+ Reference<task::XAbortChannel>(),
+ tmpCmdEnv);
+
+ getTmpRepository()->removePackage(
+ dp_misc::getIdentifier(xExtensionBackup),
+ xExtensionBackup->getName(), xAbortChannel, xCmdEnv);
+ fireModified();
+ }
+ }
+ catch (...)
+ {
+ }
+ ::cppu::throwException(excOccurred1);
+ }
+
+ if (xExtensionBackup.is())
+ getTmpRepository()->removePackage(
+ dp_misc::getIdentifier(xExtensionBackup),
+ xExtensionBackup->getName(), xAbortChannel, xCmdEnv);
+}
+
+// Only enable extensions from shared and user repository
+void ExtensionManager::enableExtension(
+ Reference<deploy::XPackage> const & extension,
+ Reference<task::XAbortChannel> const & xAbortChannel,
+ Reference<ucb::XCommandEnvironment> const & xCmdEnv)
+ throw (deploy::DeploymentException,
+ ucb::CommandFailedException,
+ ucb::CommandAbortedException,
+ lang::IllegalArgumentException,
+ uno::RuntimeException)
+{
+ ::osl::MutexGuard guard(getMutex());
+ bool bUserDisabled = false;
+ uno::Any excOccurred;
+ try
+ {
+ if (!extension.is())
+ return;
+ OUString repository = extension->getRepositoryName();
+ if (!repository.equals(OUSTR("user")))
+ throw lang::IllegalArgumentException(
+ OUSTR("No valid repository name provided."),
+ static_cast<cppu::OWeakObject*>(this), 0);
+
+ bUserDisabled = isUserDisabled(dp_misc::getIdentifier(extension),
+ extension->getName());
+
+ activateExtension(dp_misc::getIdentifier(extension),
+ extension->getName(), false, false,
+ xAbortChannel, xCmdEnv);
+ }
+ catch (deploy::DeploymentException& ) {
+ excOccurred = ::cppu::getCaughtException();
+ } catch (ucb::CommandFailedException & ) {
+ excOccurred = ::cppu::getCaughtException();
+ } catch (ucb::CommandAbortedException & ) {
+ excOccurred = ::cppu::getCaughtException();
+ } catch (lang::IllegalArgumentException &) {
+ excOccurred = ::cppu::getCaughtException();
+ } catch (uno::RuntimeException &) {
+ excOccurred = ::cppu::getCaughtException();
+ } catch (...) {
+ excOccurred = ::cppu::getCaughtException();
+ deploy::DeploymentException exc(
+ OUSTR("Extension Manager: exception during enableExtension"),
+ static_cast<OWeakObject*>(this), excOccurred);
+ excOccurred <<= exc;
+ }
+
+ if (excOccurred.hasValue())
+ {
+ try
+ {
+ activateExtension(dp_misc::getIdentifier(extension),
+ extension->getName(), bUserDisabled, false,
+ xAbortChannel, xCmdEnv);
+ }
+ catch (...)
+ {
+ }
+ ::cppu::throwException(excOccurred);
+ }
+}
+
+/**
+ */
+sal_Int32 ExtensionManager::checkPrerequisitesAndEnable(
+ Reference<deploy::XPackage> const & extension,
+ Reference<task::XAbortChannel> const & xAbortChannel,
+ Reference<ucb::XCommandEnvironment> const & xCmdEnv)
+ throw (deploy::DeploymentException,
+ ucb::CommandFailedException,
+ ucb::CommandAbortedException,
+ lang::IllegalArgumentException,
+ uno::RuntimeException)
+{
+ try
+ {
+ if (!extension.is())
+ return 0;
+ ::osl::MutexGuard guard(getMutex());
+ sal_Int32 ret = 0;
+ Reference<deploy::XPackageManager> mgr =
+ getPackageManager(extension->getRepositoryName());
+ ret = mgr->checkPrerequisites(extension, xAbortChannel, xCmdEnv);
+ if (ret)
+ {
+ //There are some unfulfilled prerequisites, try to revoke
+ extension->revokePackage(xAbortChannel, xCmdEnv);
+ }
+ const OUString id(dp_misc::getIdentifier(extension));
+ activateExtension(id, extension->getName(),
+ isUserDisabled(id, extension->getName()), false,
+ xAbortChannel, xCmdEnv);
+ return ret;
+ }
+ catch (deploy::DeploymentException& ) {
+ throw;
+ } catch (ucb::CommandFailedException & ) {
+ throw;
+ } catch (ucb::CommandAbortedException & ) {
+ throw;
+ } catch (lang::IllegalArgumentException &) {
+ throw;
+ } catch (uno::RuntimeException &) {
+ throw;
+ } catch (...) {
+ uno::Any excOccurred = ::cppu::getCaughtException();
+ deploy::DeploymentException exc(
+ OUSTR("Extension Manager: exception during disableExtension"),
+ static_cast<OWeakObject*>(this), excOccurred);
+ throw exc;
+ }
+}
+
+void ExtensionManager::disableExtension(
+ Reference<deploy::XPackage> const & extension,
+ Reference<task::XAbortChannel> const & xAbortChannel,
+ Reference<ucb::XCommandEnvironment> const & xCmdEnv )
+ throw (deploy::DeploymentException,
+ ucb::CommandFailedException,
+ ucb::CommandAbortedException,
+ lang::IllegalArgumentException,
+ uno::RuntimeException)
+{
+ ::osl::MutexGuard guard(getMutex());
+ uno::Any excOccurred;
+ bool bUserDisabled = false;
+ try
+ {
+ if (!extension.is())
+ return;
+ const OUString repository( extension->getRepositoryName());
+ if (!repository.equals(OUSTR("user")))
+ throw lang::IllegalArgumentException(
+ OUSTR("No valid repository name provided."),
+ static_cast<cppu::OWeakObject*>(this), 0);
+
+ const OUString id(dp_misc::getIdentifier(extension));
+ bUserDisabled = isUserDisabled(id, extension->getName());
+
+ activateExtension(id, extension->getName(), true, false,
+ xAbortChannel, xCmdEnv);
+ }
+ catch (deploy::DeploymentException& ) {
+ excOccurred = ::cppu::getCaughtException();
+ } catch (ucb::CommandFailedException & ) {
+ excOccurred = ::cppu::getCaughtException();
+ } catch (ucb::CommandAbortedException & ) {
+ excOccurred = ::cppu::getCaughtException();
+ } catch (lang::IllegalArgumentException &) {
+ excOccurred = ::cppu::getCaughtException();
+ } catch (uno::RuntimeException &) {
+ excOccurred = ::cppu::getCaughtException();
+ } catch (...) {
+ excOccurred = ::cppu::getCaughtException();
+ deploy::DeploymentException exc(
+ OUSTR("Extension Manager: exception during disableExtension"),
+ static_cast<OWeakObject*>(this), excOccurred);
+ excOccurred <<= exc;
+ }
+
+ if (excOccurred.hasValue())
+ {
+ try
+ {
+ activateExtension(dp_misc::getIdentifier(extension),
+ extension->getName(), bUserDisabled, false,
+ xAbortChannel, xCmdEnv);
+ }
+ catch (...)
+ {
+ }
+ ::cppu::throwException(excOccurred);
+ }
+}
+
+uno::Sequence< Reference<deploy::XPackage> >
+ ExtensionManager::getDeployedExtensions(
+ OUString const & repository,
+ Reference<task::XAbortChannel> const &xAbort,
+ Reference<ucb::XCommandEnvironment> const & xCmdEnv )
+ throw (deploy::DeploymentException,
+ ucb::CommandFailedException,
+ ucb::CommandAbortedException,
+ lang::IllegalArgumentException,
+ uno::RuntimeException)
+{
+ return getPackageManager(repository)->getDeployedPackages(
+ xAbort, xCmdEnv);
+}
+
+Reference<deploy::XPackage>
+ ExtensionManager::getDeployedExtension(
+ OUString const & repository,
+ OUString const & identifier,
+ OUString const & filename,
+ Reference<ucb::XCommandEnvironment> const & xCmdEnv )
+ throw (deploy::DeploymentException,
+ ucb::CommandFailedException,
+ lang::IllegalArgumentException,
+ uno::RuntimeException)
+{
+ return getPackageManager(repository)->getDeployedPackage(
+ identifier, filename, xCmdEnv);
+}
+
+uno::Sequence< uno::Sequence<Reference<deploy::XPackage> > >
+ ExtensionManager::getAllExtensions(
+ Reference<task::XAbortChannel> const & xAbort,
+ Reference<ucb::XCommandEnvironment> const & xCmdEnv )
+ throw (deploy::DeploymentException,
+ ucb::CommandFailedException,
+ ucb::CommandAbortedException,
+ lang::IllegalArgumentException,
+ uno::RuntimeException)
+{
+ try
+ {
+ id2extensions mapExt;
+
+ uno::Sequence<Reference<deploy::XPackage> > userExt =
+ getUserRepository()->getDeployedPackages(xAbort, xCmdEnv);
+ addExtensionsToMap(mapExt, userExt, OUSTR("user"));
+ uno::Sequence<Reference<deploy::XPackage> > sharedExt =
+ getSharedRepository()->getDeployedPackages(xAbort, xCmdEnv);
+ addExtensionsToMap(mapExt, sharedExt, OUSTR("shared"));
+ uno::Sequence<Reference<deploy::XPackage> > bundledExt =
+ getBundledRepository()->getDeployedPackages(xAbort, xCmdEnv);
+ addExtensionsToMap(mapExt, bundledExt, OUSTR("bundled"));
+
+ //copy the values of the map to a vector for sorting
+ ::std::vector< ::std::vector<Reference<deploy::XPackage> > >
+ vecExtensions;
+ id2extensions::const_iterator mapIt = mapExt.begin();
+ for (;mapIt != mapExt.end(); ++mapIt)
+ vecExtensions.push_back(mapIt->second);
+
+ //sort the element according to the identifier
+ ::std::sort(vecExtensions.begin(), vecExtensions.end(), CompIdentifiers());
+
+ ::std::vector< ::std::vector<Reference<deploy::XPackage> > >::const_iterator
+ citVecVec = vecExtensions.begin();
+ sal_Int32 j = 0;
+ uno::Sequence< uno::Sequence<Reference<deploy::XPackage> > > seqSeq(vecExtensions.size());
+ for (;citVecVec != vecExtensions.end(); citVecVec++, j++)
+ {
+ seqSeq[j] = comphelper::containerToSequence(*citVecVec);
+ }
+ return seqSeq;
+
+ } catch (deploy::DeploymentException& ) {
+ throw;
+ } catch (ucb::CommandFailedException & ) {
+ throw;
+ } catch (ucb::CommandAbortedException & ) {
+ throw;
+ } catch (lang::IllegalArgumentException &) {
+ throw;
+ } catch (uno::RuntimeException &) {
+ throw;
+ } catch (...) {
+ uno::Any exc = ::cppu::getCaughtException();
+ throw deploy::DeploymentException(
+ OUSTR("Extension Manager: exception during enableExtension"),
+ static_cast<OWeakObject*>(this), exc);
+ }
+}
+
+//only to be called from unopkg!!!
+void ExtensionManager::reinstallDeployedExtensions(
+ OUString const & repository,
+ Reference<task::XAbortChannel> const & xAbortChannel,
+ Reference<ucb::XCommandEnvironment> const & xCmdEnv )
+ throw (deploy::DeploymentException,
+ ucb::CommandFailedException, ucb::CommandAbortedException,
+ lang::IllegalArgumentException, uno::RuntimeException)
+{
+ try
+ {
+ Reference<deploy::XPackageManager>
+ xPackageManager = getPackageManager(repository);
+
+ ::osl::MutexGuard guard(getMutex());
+ xPackageManager->reinstallDeployedPackages(xAbortChannel, xCmdEnv);
+ //We must sync here, otherwise we will get exceptions when extensions
+ //are removed.
+ dp_misc::syncRepositories(xCmdEnv);
+ const uno::Sequence< Reference<deploy::XPackage> > extensions(
+ xPackageManager->getDeployedPackages(xAbortChannel, xCmdEnv));
+
+ for ( sal_Int32 pos = 0; pos < extensions.getLength(); ++pos )
+ {
+ try
+ {
+ const OUString id = dp_misc::getIdentifier(extensions[ pos ]);
+ const OUString fileName = extensions[ pos ]->getName();
+ OSL_ASSERT(id.getLength());
+ activateExtension(id, fileName, false, true, xAbortChannel, xCmdEnv );
+ }
+ catch (lang::DisposedException &)
+ {
+ }
+ }
+ } catch (deploy::DeploymentException& ) {
+ throw;
+ } catch (ucb::CommandFailedException & ) {
+ throw;
+ } catch (ucb::CommandAbortedException & ) {
+ throw;
+ } catch (lang::IllegalArgumentException &) {
+ throw;
+ } catch (uno::RuntimeException &) {
+ throw;
+ } catch (...) {
+ uno::Any exc = ::cppu::getCaughtException();
+ throw deploy::DeploymentException(
+ OUSTR("Extension Manager: exception during enableExtension"),
+ static_cast<OWeakObject*>(this), exc);
+ }
+}
+
+/** Works on the bundled repository. That is using the variables
+ BUNDLED_EXTENSIONS and BUNDLED_EXTENSIONS_USER.
+ */
+void ExtensionManager::synchronizeBundledPrereg(
+ Reference<task::XAbortChannel> const & xAbortChannel,
+ Reference<ucb::XCommandEnvironment> const & xCmdEnv )
+ throw (deploy::DeploymentException,
+ uno::RuntimeException)
+{
+ try
+ {
+ String sSynchronizingBundled(StrSyncRepository::get());
+ sSynchronizingBundled.SearchAndReplaceAllAscii( "%NAME", OUSTR("bundled"));
+ dp_misc::ProgressLevel progressBundled(xCmdEnv, sSynchronizingBundled);
+
+ Reference<deploy::XPackageManagerFactory> xPackageManagerFactory(
+ deploy::thePackageManagerFactory::get(m_xContext));
+
+ Reference<deploy::XPackageManager> xMgr =
+ xPackageManagerFactory->getPackageManager(OUSTR("bundled_prereg"));
+ xMgr->synchronize(xAbortChannel, xCmdEnv);
+ progressBundled.update(OUSTR("\n\n"));
+
+ uno::Sequence<Reference<deploy::XPackage> > extensions = xMgr->getDeployedPackages(
+ xAbortChannel, xCmdEnv);
+ try
+ {
+ for (sal_Int32 i = 0; i < extensions.getLength(); i++)
+ {
+ extensions[i]->registerPackage(true, xAbortChannel, xCmdEnv);
+ }
+ }
+ catch (...)
+ {
+ OSL_ASSERT(0);
+ }
+ OUString lastSyncBundled(RTL_CONSTASCII_USTRINGPARAM(
+ "$BUNDLED_EXTENSIONS_PREREG/lastsynchronized"));
+ writeLastModified(lastSyncBundled, xCmdEnv);
+
+ } catch (deploy::DeploymentException& ) {
+ throw;
+ } catch (ucb::CommandFailedException & ) {
+ throw;
+ } catch (ucb::CommandAbortedException & ) {
+ throw;
+ } catch (lang::IllegalArgumentException &) {
+ throw;
+ } catch (uno::RuntimeException &) {
+ throw;
+ } catch (...) {
+ uno::Any exc = ::cppu::getCaughtException();
+ throw deploy::DeploymentException(
+ OUSTR("Extension Manager: exception in synchronize"),
+ static_cast<OWeakObject*>(this), exc);
+ }
+}
+
+sal_Bool ExtensionManager::synchronize(
+ Reference<task::XAbortChannel> const & xAbortChannel,
+ Reference<ucb::XCommandEnvironment> const & xCmdEnv )
+ throw (deploy::DeploymentException,
+ ucb::CommandFailedException,
+ ucb::CommandAbortedException,
+ lang::IllegalArgumentException,
+ uno::RuntimeException)
+{
+ try
+ {
+ sal_Bool bModified = sal_False;
+
+ ::osl::MutexGuard guard(getMutex());
+ String sSynchronizingShared(StrSyncRepository::get());
+ sSynchronizingShared.SearchAndReplaceAllAscii( "%NAME", OUSTR("shared"));
+ dp_misc::ProgressLevel progressShared(xCmdEnv, sSynchronizingShared);
+ bModified = getSharedRepository()->synchronize(xAbortChannel, xCmdEnv);
+ progressShared.update(OUSTR("\n\n"));
+
+ String sSynchronizingBundled(StrSyncRepository::get());
+ sSynchronizingBundled.SearchAndReplaceAllAscii( "%NAME", OUSTR("bundled"));
+ dp_misc::ProgressLevel progressBundled(xCmdEnv, sSynchronizingBundled);
+ bModified |= getBundledRepository()->synchronize(xAbortChannel, xCmdEnv);
+ progressBundled.update(OUSTR("\n\n"));
+
+ //Always determine the active extension. This is necessary for the
+ //first-start optimization. The setup creates the registration data for the
+ //bundled extensions (brand_layer/share/prereg/bundled), which is copied to the user
+ //installation (user_installation/extension/bundled) when a user starts OOo
+ //for the first time after running setup. All bundled extensions are registered
+ //at that moment. However, extensions with the same identifier can be in the
+ //shared or user repository, in which case the respective bundled extensions must
+ //be revoked.
+ try
+ {
+ const uno::Sequence<uno::Sequence<Reference<deploy::XPackage> > >
+ seqSeqExt = getAllExtensions(xAbortChannel, xCmdEnv);
+ for (sal_Int32 i = 0; i < seqSeqExt.getLength(); i++)
+ {
+ uno::Sequence<Reference<deploy::XPackage> > const & seqExt =
+ seqSeqExt[i];
+ activateExtension(seqExt, isUserDisabled(seqExt), true,
+ xAbortChannel, xCmdEnv);
+ }
+ }
+ catch (...)
+ {
+ //We catch the exception, so we can write the lastmodified file
+ //so we will no repeat this everytime OOo starts.
+ OSL_FAIL("Extensions Manager: synchronize");
+ }
+ OUString lastSyncBundled(RTL_CONSTASCII_USTRINGPARAM(
+ "$BUNDLED_EXTENSIONS_USER/lastsynchronized"));
+ writeLastModified(lastSyncBundled, xCmdEnv);
+ OUString lastSyncShared(RTL_CONSTASCII_USTRINGPARAM(
+ "$SHARED_EXTENSIONS_USER/lastsynchronized"));
+ writeLastModified(lastSyncShared, xCmdEnv);
+ return bModified;
+ } catch (deploy::DeploymentException& ) {
+ throw;
+ } catch (ucb::CommandFailedException & ) {
+ throw;
+ } catch (ucb::CommandAbortedException & ) {
+ throw;
+ } catch (lang::IllegalArgumentException &) {
+ throw;
+ } catch (uno::RuntimeException &) {
+ throw;
+ } catch (...) {
+ uno::Any exc = ::cppu::getCaughtException();
+ throw deploy::DeploymentException(
+ OUSTR("Extension Manager: exception in synchronize"),
+ static_cast<OWeakObject*>(this), exc);
+ }
+}
+
+// Notify the user when a new extension is to be installed. This is only the
+// case when one uses the system integration to install an extension (double
+// clicking on .oxt file etc.)). The function must only be called if there is no
+// extension with the same identifier already deployed. Then the checkUpdate
+// function will inform the user that the extension is about to be installed In
+// case the user cancels the installation a CommandFailed exception is
+// thrown.
+void ExtensionManager::checkInstall(
+ OUString const & displayName,
+ Reference<ucb::XCommandEnvironment> const & cmdEnv)
+{
+ uno::Any request(
+ deploy::InstallException(
+ OUSTR("Extension ") + displayName +
+ OUSTR(" is about to be installed."),
+ static_cast<OWeakObject *>(this), displayName));
+ bool approve = false, abort = false;
+ if (! dp_misc::interactContinuation(
+ request, task::XInteractionApprove::static_type(),
+ cmdEnv, &approve, &abort ))
+ {
+ OSL_ASSERT( !approve && !abort );
+ throw deploy::DeploymentException(
+ dp_misc::getResourceString(RID_STR_ERROR_WHILE_ADDING) + displayName,
+ static_cast<OWeakObject *>(this), request );
+ }
+ if (abort || !approve)
+ throw ucb::CommandFailedException(
+ dp_misc::getResourceString(RID_STR_ERROR_WHILE_ADDING) + displayName,
+ static_cast<OWeakObject *>(this), request );
+}
+
+/* The function will make the user interaction in case there is an extension
+installed with the same id. This function may only be called if there is already
+an extension.
+*/
+void ExtensionManager::checkUpdate(
+ OUString const & newVersion,
+ OUString const & newDisplayName,
+ Reference<deploy::XPackage> const & oldExtension,
+ Reference<ucb::XCommandEnvironment> const & xCmdEnv )
+{
+ // package already deployed, interact --force:
+ uno::Any request(
+ (deploy::VersionException(
+ dp_misc::getResourceString(
+ RID_STR_PACKAGE_ALREADY_ADDED ) + newDisplayName,
+ static_cast<OWeakObject *>(this), newVersion, newDisplayName,
+ oldExtension ) ) );
+ bool replace = false, abort = false;
+ if (! dp_misc::interactContinuation(
+ request, task::XInteractionApprove::static_type(),
+ xCmdEnv, &replace, &abort )) {
+ OSL_ASSERT( !replace && !abort );
+ throw deploy::DeploymentException(
+ dp_misc::getResourceString(
+ RID_STR_ERROR_WHILE_ADDING) + newDisplayName,
+ static_cast<OWeakObject *>(this), request );
+ }
+ if (abort || !replace)
+ throw ucb::CommandFailedException(
+ dp_misc::getResourceString(
+ RID_STR_PACKAGE_ALREADY_ADDED) + newDisplayName,
+ static_cast<OWeakObject *>(this), request );
+}
+
+Reference<deploy::XPackage> ExtensionManager::getTempExtension(
+ OUString const & url,
+ Reference<task::XAbortChannel> const & xAbortChannel,
+ Reference<ucb::XCommandEnvironment> const & /*xCmdEnv*/)
+
+{
+ Reference<ucb::XCommandEnvironment> tmpCmdEnvA(new TmpRepositoryCommandEnv());
+ Reference<deploy::XPackage> xTmpPackage = getTmpRepository()->addPackage(
+ url, uno::Sequence<beans::NamedValue>(),OUString(), xAbortChannel, tmpCmdEnvA);
+ if (!xTmpPackage.is())
+ {
+ throw deploy::DeploymentException(
+ OUSTR("Extension Manager: Failed to create temporary XPackage for url: ") + url,
+ static_cast<OWeakObject*>(this), uno::Any());
+
+ }
+ return xTmpPackage;
+}
+
+uno::Sequence<Reference<deploy::XPackage> > SAL_CALL
+ExtensionManager::getExtensionsWithUnacceptedLicenses(
+ OUString const & repository,
+ Reference<ucb::XCommandEnvironment> const & xCmdEnv)
+ throw (deploy::DeploymentException,
+ uno::RuntimeException)
+{
+ Reference<deploy::XPackageManager>
+ xPackageManager = getPackageManager(repository);
+ ::osl::MutexGuard guard(getMutex());
+ return xPackageManager->getExtensionsWithUnacceptedLicenses(xCmdEnv);
+}
+
+sal_Bool ExtensionManager::isReadOnlyRepository(::rtl::OUString const & repository)
+ throw (uno::RuntimeException)
+{
+ return getPackageManager(repository)->isReadOnly();
+}
+//------------------------------------------------------------------------------
+
+namespace sdecl = comphelper::service_decl;
+sdecl::class_<ExtensionManager> servicePIP;
+extern sdecl::ServiceDecl const serviceDecl(
+ servicePIP,
+ // a private one:
+ "com.sun.star.comp.deployment.ExtensionManager",
+ "com.sun.star.comp.deployment.ExtensionManager");
+
+//------------------------------------------------------------------------------
+bool singleton_entries(
+ uno::Reference< registry::XRegistryKey > const & xRegistryKey )
+{
+ try {
+ uno::Reference< registry::XRegistryKey > xKey(
+ xRegistryKey->createKey(
+ serviceDecl.getImplementationName() +
+ // xxx todo: use future generated function to get singleton name
+ OUSTR("/UNO/SINGLETONS/"
+ "com.sun.star.deployment.ExtensionManager") ) );
+ xKey->setStringValue( serviceDecl.getSupportedServiceNames()[0] );
+ return true;
+ }
+ catch (registry::InvalidRegistryException & exc) {
+ (void) exc; // avoid warnings
+ OSL_FAIL( ::rtl::OUStringToOString(
+ exc.Message, RTL_TEXTENCODING_UTF8 ).getStr() );
+ return false;
+ }
+}
+
+// XModifyBroadcaster
+//______________________________________________________________________________
+void ExtensionManager::addModifyListener(
+ Reference<util::XModifyListener> const & xListener )
+ throw (uno::RuntimeException)
+{
+ check();
+ rBHelper.addListener( ::getCppuType( &xListener ), xListener );
+}
+
+//______________________________________________________________________________
+void ExtensionManager::removeModifyListener(
+ Reference<util::XModifyListener> const & xListener )
+ throw (uno::RuntimeException)
+{
+ check();
+ rBHelper.removeListener( ::getCppuType( &xListener ), xListener );
+}
+
+void ExtensionManager::check()
+{
+ ::osl::MutexGuard guard( getMutex() );
+ if (rBHelper.bInDispose || rBHelper.bDisposed) {
+ throw lang::DisposedException(
+ OUSTR("ExtensionManager instance has already been disposed!"),
+ static_cast<OWeakObject *>(this) );
+ }
+}
+
+void ExtensionManager::fireModified()
+{
+ ::cppu::OInterfaceContainerHelper * pContainer = rBHelper.getContainer(
+ util::XModifyListener::static_type() );
+ if (pContainer != 0) {
+ pContainer->forEach<util::XModifyListener>(
+ boost::bind(&util::XModifyListener::modified, _1,
+ lang::EventObject(static_cast<OWeakObject *>(this))) );
+ }
+}
+
+} // namespace dp_manager
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/manager/dp_extensionmanager.hxx b/desktop/source/deployment/manager/dp_extensionmanager.hxx
new file mode 100644
index 000000000000..6c6bd5cb41f3
--- /dev/null
+++ b/desktop/source/deployment/manager/dp_extensionmanager.hxx
@@ -0,0 +1,321 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#if ! defined INCLUDED_DP_EXTENSIONMANAGER_H
+#define INCLUDED_DP_EXTENSIONMANAGER_H
+
+#include "dp_manager.hrc"
+#include "dp_misc.h"
+#include "dp_interact.h"
+#include "dp_activepackages.hxx"
+#include "rtl/ref.hxx"
+#include "cppuhelper/compbase1.hxx"
+#include "ucbhelper/content.hxx"
+#include "com/sun/star/deployment/XPackageRegistry.hpp"
+#include "com/sun/star/deployment/XPackageManager.hpp"
+#include "osl/mutex.hxx"
+#include <list>
+
+namespace css = ::com::sun::star;
+
+namespace dp_manager {
+
+typedef ::boost::unordered_map<
+ ::rtl::OUString,
+ ::std::vector<css::uno::Reference<css::deployment::XPackage> >,
+ ::rtl::OUStringHash > id2extensions;
+
+class ExtensionManager : private ::dp_misc::MutexHolder,
+ public ::cppu::WeakComponentImplHelper1< css::deployment::XExtensionManager >
+{
+public:
+ ExtensionManager( css::uno::Reference< css::uno::XComponentContext >const& xContext);
+ virtual ~ExtensionManager();
+
+ static css::uno::Sequence< ::rtl::OUString > getServiceNames();
+ static ::rtl::OUString getImplName();
+
+ void check();
+ void fireModified();
+
+public:
+
+// XModifyBroadcaster
+ virtual void SAL_CALL addModifyListener(
+ css::uno::Reference<css::util::XModifyListener> const & xListener )
+ throw (css::uno::RuntimeException);
+ virtual void SAL_CALL removeModifyListener(
+ css::uno::Reference<css::util::XModifyListener> const & xListener )
+ throw (css::uno::RuntimeException);
+
+//XExtensionManager
+ virtual css::uno::Sequence<
+ css::uno::Reference<css::deployment::XPackageTypeInfo> > SAL_CALL
+ getSupportedPackageTypes()
+ throw (css::uno::RuntimeException);
+
+ virtual css::uno::Reference<css::task::XAbortChannel> SAL_CALL
+ createAbortChannel() throw (css::uno::RuntimeException);
+
+ virtual css::uno::Reference<css::deployment::XPackage> SAL_CALL addExtension(
+ ::rtl::OUString const & url,
+ css::uno::Sequence<css::beans::NamedValue> const & properties,
+ ::rtl::OUString const & repository,
+ css::uno::Reference<css::task::XAbortChannel> const & xAbortChannel,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv )
+ throw (css::deployment::DeploymentException,
+ css::ucb::CommandFailedException,
+ css::ucb::CommandAbortedException,
+ css::lang::IllegalArgumentException,
+ css::uno::RuntimeException);
+
+ virtual void SAL_CALL removeExtension(
+ ::rtl::OUString const & identifier,
+ ::rtl::OUString const & filename,
+ ::rtl::OUString const & repository,
+ css::uno::Reference<css::task::XAbortChannel> const & xAbortChannel,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv )
+ throw (css::deployment::DeploymentException,
+ css::ucb::CommandFailedException,
+ css::ucb::CommandAbortedException,
+ css::lang::IllegalArgumentException,
+ css::uno::RuntimeException);
+
+ virtual void SAL_CALL enableExtension(
+ css::uno::Reference<css::deployment::XPackage> const & extension,
+ css::uno::Reference<css::task::XAbortChannel> const & xAbortChannel,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv )
+ throw (css::deployment::DeploymentException,
+ css::ucb::CommandFailedException,
+ css::ucb::CommandAbortedException,
+ css::lang::IllegalArgumentException,
+ css::uno::RuntimeException);
+
+ virtual void SAL_CALL disableExtension(
+ css::uno::Reference<css::deployment::XPackage> const & extension,
+ css::uno::Reference<css::task::XAbortChannel> const & xAbortChannel,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv )
+ throw (css::deployment::DeploymentException,
+ css::ucb::CommandFailedException,
+ css::ucb::CommandAbortedException,
+ css::lang::IllegalArgumentException,
+ css::uno::RuntimeException);
+
+ virtual sal_Int32 SAL_CALL checkPrerequisitesAndEnable(
+ css::uno::Reference<css::deployment::XPackage> const & extension,
+ css::uno::Reference<css::task::XAbortChannel> const & xAbortChannel,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv )
+ throw (css::deployment::DeploymentException,
+ css::ucb::CommandFailedException,
+ css::ucb::CommandAbortedException,
+ css::lang::IllegalArgumentException,
+ css::uno::RuntimeException);
+
+ virtual css::uno::Sequence< css::uno::Reference<css::deployment::XPackage> >
+ SAL_CALL getDeployedExtensions(
+ ::rtl::OUString const & repository,
+ css::uno::Reference<css::task::XAbortChannel> const &,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv )
+ throw (css::deployment::DeploymentException,
+ css::ucb::CommandFailedException,
+ css::ucb::CommandAbortedException,
+ css::lang::IllegalArgumentException,
+ css::uno::RuntimeException);
+
+ virtual css::uno::Reference< css::deployment::XPackage>
+ SAL_CALL getDeployedExtension(
+ ::rtl::OUString const & repository,
+ ::rtl::OUString const & identifier,
+ ::rtl::OUString const & filename,
+ css::uno::Reference< css::ucb::XCommandEnvironment> const & xCmdEnv )
+ throw (
+ css::deployment::DeploymentException,
+ css::ucb::CommandFailedException,
+ css::lang::IllegalArgumentException,
+ css::uno::RuntimeException);
+
+ virtual css::uno::Sequence<css::uno::Reference<css::deployment::XPackage> >
+ SAL_CALL getExtensionsWithSameIdentifier(
+ ::rtl::OUString const & identifier,
+ ::rtl::OUString const & filename,
+ css::uno::Reference< css::ucb::XCommandEnvironment> const & xCmdEnv )
+ throw (
+ css::deployment::DeploymentException,
+ css::ucb::CommandFailedException,
+ css::lang::IllegalArgumentException,
+ css::uno::RuntimeException);
+
+ virtual css::uno::Sequence< css::uno::Sequence<css::uno::Reference<css::deployment::XPackage> > >
+ SAL_CALL getAllExtensions(
+ css::uno::Reference<css::task::XAbortChannel> const &,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv )
+ throw (css::deployment::DeploymentException,
+ css::ucb::CommandFailedException,
+ css::ucb::CommandAbortedException,
+ css::lang::IllegalArgumentException,
+ css::uno::RuntimeException);
+
+ virtual void SAL_CALL reinstallDeployedExtensions(
+ ::rtl::OUString const & repository,
+ css::uno::Reference< css::task::XAbortChannel> const & xAbortChannel,
+ css::uno::Reference< css::ucb::XCommandEnvironment> const & xCmdEnv )
+ throw (
+ css::deployment::DeploymentException,
+ css::ucb::CommandFailedException,
+ css::ucb::CommandAbortedException,
+ css::lang::IllegalArgumentException,
+ css::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL synchronize(
+ css::uno::Reference<css::task::XAbortChannel> const & xAbortChannel,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv )
+ throw (css::deployment::DeploymentException,
+ css::ucb::CommandFailedException,
+ css::ucb::CommandAbortedException,
+ css::lang::IllegalArgumentException,
+ css::uno::RuntimeException);
+
+ virtual void SAL_CALL synchronizeBundledPrereg(
+ css::uno::Reference<css::task::XAbortChannel> const & xAbortChannel,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv )
+ throw (css::deployment::DeploymentException,
+ css::uno::RuntimeException);
+
+ virtual css::uno::Sequence<css::uno::Reference<css::deployment::XPackage> > SAL_CALL
+ getExtensionsWithUnacceptedLicenses(
+ ::rtl::OUString const & repository,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv)
+ throw (css::deployment::DeploymentException,
+ css::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL isReadOnlyRepository(::rtl::OUString const & repository)
+ throw (css::uno::RuntimeException);
+
+private:
+
+ struct StrSyncRepository : public ::dp_misc::StaticResourceString<
+ StrSyncRepository, RID_STR_SYNCHRONIZING_REPOSITORY> {};
+
+ struct ExtensionInfos
+ {
+ ::rtl::OUString identifier;
+ ::rtl::OUString fileName;
+ ::rtl::OUString displayName;
+ ::rtl::OUString version;
+ };
+
+ css::uno::Reference< css::uno::XComponentContext> m_xContext;
+ css::uno::Reference<css::deployment::XPackageManagerFactory> m_xPackageManagerFactory;
+
+ //only to be used within addExtension
+ ::osl::Mutex m_addMutex;
+ /* contains the names of all repositories (except tmp) in order of there
+ priority. That is, the first element is "user" follod by "shared" and
+ then "bundled"
+ */
+ ::std::list< ::rtl::OUString > m_repositoryNames;
+
+ css::uno::Reference<css::deployment::XPackageManager> getUserRepository();
+ css::uno::Reference<css::deployment::XPackageManager> getSharedRepository();
+ css::uno::Reference<css::deployment::XPackageManager> getBundledRepository();
+ css::uno::Reference<css::deployment::XPackageManager> getTmpRepository();
+
+ bool isUserDisabled(::rtl::OUString const & identifier,
+ ::rtl::OUString const & filename);
+
+ bool isUserDisabled(
+ css::uno::Sequence<css::uno::Reference<css::deployment::XPackage> > const & seqExtSameId);
+
+ void activateExtension(
+ ::rtl::OUString const & identifier,
+ ::rtl::OUString const & fileName,
+ bool bUserDisabled, bool bStartup,
+ css::uno::Reference<css::task::XAbortChannel> const & xAbortChannel,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv);
+
+ void activateExtension(
+ css::uno::Sequence<css::uno::Reference<css::deployment::XPackage> > const & seqExt,
+ bool bUserDisabled, bool bStartup,
+ css::uno::Reference<css::task::XAbortChannel> const & xAbortChannel,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv );
+
+ ::std::list<css::uno::Reference<css::deployment::XPackage> >
+ getExtensionsWithSameId(::rtl::OUString const & identifier,
+ ::rtl::OUString const & fileName,
+ css::uno::Reference< css::ucb::XCommandEnvironment> const & xCmdEnv =
+ css::uno::Reference< css::ucb::XCommandEnvironment>());
+
+ css::uno::Reference<css::deployment::XPackage> backupExtension(
+ ::rtl::OUString const & identifier, ::rtl::OUString const & fileName,
+ css::uno::Reference<css::deployment::XPackageManager> const & xPackageManager,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv);
+
+ void checkInstall(
+ ::rtl::OUString const & displayName,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & cmdEnv);
+
+ void checkUpdate(
+ ::rtl::OUString const & newVersion,
+ ::rtl::OUString const & newDisplayName,
+ css::uno::Reference<css::deployment::XPackage> const & oldExtension,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv);
+
+ css::uno::Reference<css::deployment::XPackage> getTempExtension(
+ ::rtl::OUString const & url,
+ css::uno::Reference<css::task::XAbortChannel> const & xAbortChannel,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv);
+
+ void addExtensionsToMap(
+ id2extensions & mapExt,
+ css::uno::Sequence<css::uno::Reference<css::deployment::XPackage> > const & seqExt,
+ ::rtl::OUString const & repository);
+
+ css::uno::Reference<css::deployment::XPackageManager>
+ getPackageManager(::rtl::OUString const & repository)
+ throw (css::lang::IllegalArgumentException);
+
+ bool doChecksForAddExtension(
+ css::uno::Reference<css::deployment::XPackageManager> const & xPackageMgr,
+ css::uno::Sequence<css::beans::NamedValue> const & properties,
+ css::uno::Reference<css::deployment::XPackage> const & xTmpExtension,
+ css::uno::Reference<css::task::XAbortChannel> const & xAbortChannel,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv,
+ css::uno::Reference<css::deployment::XPackage> & out_existingExtension )
+ throw (css::deployment::DeploymentException,
+ css::ucb::CommandFailedException,
+ css::ucb::CommandAbortedException,
+ css::lang::IllegalArgumentException,
+ css::uno::RuntimeException);
+
+};
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/manager/dp_informationprovider.cxx b/desktop/source/deployment/manager/dp_informationprovider.cxx
new file mode 100644
index 000000000000..0786e7d84fa3
--- /dev/null
+++ b/desktop/source/deployment/manager/dp_informationprovider.cxx
@@ -0,0 +1,368 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include <cppuhelper/implbase3.hxx>
+
+#include "comphelper/servicedecl.hxx"
+
+#include "com/sun/star/deployment/UpdateInformationProvider.hpp"
+#include "com/sun/star/deployment/XPackage.hpp"
+#include "com/sun/star/deployment/XPackageInformationProvider.hpp"
+#include "com/sun/star/deployment/ExtensionManager.hpp"
+#include "com/sun/star/deployment/XUpdateInformationProvider.hpp"
+#include "com/sun/star/lang/XServiceInfo.hpp"
+#include "com/sun/star/registry/XRegistryKey.hpp"
+#include "com/sun/star/task/XAbortChannel.hpp"
+#include "com/sun/star/uno/XComponentContext.hpp"
+#include "com/sun/star/ucb/XCommandEnvironment.hpp"
+#include "com/sun/star/xml/dom/XElement.hpp"
+#include "com/sun/star/xml/dom/XNode.hpp"
+
+#include "com/sun/star/uno/Reference.hxx"
+#include "rtl/ustring.hxx"
+#include "ucbhelper/content.hxx"
+
+#include "dp_dependencies.hxx"
+#include "dp_descriptioninfoset.hxx"
+#include "dp_identifier.hxx"
+#include "dp_version.hxx"
+#include "dp_misc.h"
+#include "dp_update.hxx"
+
+namespace beans = com::sun::star::beans ;
+namespace deployment = com::sun::star::deployment ;
+namespace lang = com::sun::star::lang ;
+namespace registry = com::sun::star::registry ;
+namespace task = com::sun::star::task ;
+namespace css_ucb = com::sun::star::ucb ;
+namespace uno = com::sun::star::uno ;
+namespace xml = com::sun::star::xml ;
+
+#define UNISTRING(s) rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(s))
+
+namespace dp_info {
+
+class PackageInformationProvider :
+ public ::cppu::WeakImplHelper1< deployment::XPackageInformationProvider >
+
+{
+ public:
+ PackageInformationProvider( uno::Reference< uno::XComponentContext >const& xContext);
+ virtual ~PackageInformationProvider();
+
+ static uno::Sequence< rtl::OUString > getServiceNames();
+ static rtl::OUString getImplName();
+
+ // XPackageInformationProvider
+ virtual rtl::OUString SAL_CALL getPackageLocation( const rtl::OUString& extensionId )
+ throw ( uno::RuntimeException );
+ virtual uno::Sequence< uno::Sequence< rtl::OUString > > SAL_CALL isUpdateAvailable( const rtl::OUString& extensionId )
+ throw ( uno::RuntimeException );
+ virtual uno::Sequence< uno::Sequence< rtl::OUString > > SAL_CALL getExtensionList()
+ throw ( uno::RuntimeException );
+//---------
+private:
+
+ uno::Reference< uno::XComponentContext> mxContext;
+
+ rtl::OUString getPackageLocation( const rtl::OUString& repository,
+ const rtl::OUString& _sExtensionId );
+
+ uno::Reference< deployment::XUpdateInformationProvider > mxUpdateInformation;
+};
+
+//------------------------------------------------------------------------------
+
+PackageInformationProvider::PackageInformationProvider( uno::Reference< uno::XComponentContext > const& xContext) :
+ mxContext( xContext ),
+ mxUpdateInformation( deployment::UpdateInformationProvider::create( xContext ) )
+{
+}
+
+//------------------------------------------------------------------------------
+
+PackageInformationProvider::~PackageInformationProvider()
+{
+}
+
+//------------------------------------------------------------------------------
+rtl::OUString PackageInformationProvider::getPackageLocation(
+ const rtl::OUString & repository,
+ const rtl::OUString& _rExtensionId )
+{
+ rtl::OUString aLocationURL;
+ uno::Reference<deployment::XExtensionManager> xManager =
+ deployment::ExtensionManager::get(mxContext);
+
+ if ( xManager.is() )
+ {
+ const uno::Sequence< uno::Reference< deployment::XPackage > > packages(
+ xManager->getDeployedExtensions(
+ repository,
+ uno::Reference< task::XAbortChannel >(),
+ uno::Reference< css_ucb::XCommandEnvironment > () ) );
+
+ for ( int pos = packages.getLength(); pos--; )
+ {
+ try
+ {
+ const rtl::OUString aName = packages[ pos ]->getName();
+ const beans::Optional< rtl::OUString > aID = packages[ pos ]->getIdentifier();
+ if ( aID.IsPresent && aID.Value.compareTo( _rExtensionId ) == 0 )
+ {
+ aLocationURL = packages[ pos ]->getURL();
+ break;
+ }
+ }
+ catch ( uno::RuntimeException & ) {}
+ }
+ }
+
+ return aLocationURL;
+}
+
+//------------------------------------------------------------------------------
+
+rtl::OUString SAL_CALL
+PackageInformationProvider::getPackageLocation( const rtl::OUString& _sExtensionId )
+ throw ( uno::RuntimeException )
+{
+ rtl::OUString aLocationURL = getPackageLocation( UNISTRING("user"), _sExtensionId );
+
+ if ( aLocationURL.getLength() == 0 )
+ {
+ aLocationURL = getPackageLocation( UNISTRING("shared"), _sExtensionId );
+ }
+ if ( aLocationURL.getLength() == 0 )
+ {
+ aLocationURL = getPackageLocation( UNISTRING("bundled"), _sExtensionId );
+ }
+ if ( aLocationURL.getLength() )
+ {
+ ::ucbhelper::Content aContent( aLocationURL, NULL );
+ aLocationURL = aContent.getURL();
+ }
+ return aLocationURL;
+}
+
+//------------------------------------------------------------------------------
+
+uno::Sequence< uno::Sequence< rtl::OUString > > SAL_CALL
+PackageInformationProvider::isUpdateAvailable( const rtl::OUString& _sExtensionId )
+ throw ( uno::RuntimeException )
+{
+ uno::Sequence< uno::Sequence< rtl::OUString > > aList;
+
+ uno::Reference<deployment::XExtensionManager> extMgr =
+ deployment::ExtensionManager::get(mxContext);
+
+ if (!extMgr.is())
+ {
+ OSL_ASSERT(0);
+ return aList;
+ }
+ std::vector<std::pair<uno::Reference<deployment::XPackage>, uno::Any > > errors;
+ dp_misc::UpdateInfoMap updateInfoMap;
+ if (_sExtensionId.getLength())
+ {
+ std::vector<uno::Reference<deployment::XPackage> > vecExtensions;
+ uno::Reference<deployment::XPackage> extension;
+ try
+ {
+ extension = dp_misc::getExtensionWithHighestVersion(
+ extMgr->getExtensionsWithSameIdentifier(
+ _sExtensionId, _sExtensionId, uno::Reference<css_ucb::XCommandEnvironment>()));
+ vecExtensions.push_back(extension);
+ }
+ catch (lang::IllegalArgumentException &)
+ {
+ OSL_ASSERT(0);
+ }
+ updateInfoMap = dp_misc::getOnlineUpdateInfos(
+ mxContext, extMgr, mxUpdateInformation, &vecExtensions, errors);
+ }
+ else
+ {
+ updateInfoMap = dp_misc::getOnlineUpdateInfos(
+ mxContext, extMgr, mxUpdateInformation, NULL, errors);
+ }
+
+ int nCount = 0;
+ for (dp_misc::UpdateInfoMap::iterator i(updateInfoMap.begin()); i != updateInfoMap.end(); ++i)
+ {
+ dp_misc::UpdateInfo const & info = i->second;
+
+ rtl::OUString sOnlineVersion;
+ if (info.info.is())
+ {
+ // check, if there are unsatisfied dependencies and ignore this online update
+ dp_misc::DescriptionInfoset infoset(mxContext, info.info);
+ uno::Sequence< uno::Reference< xml::dom::XElement > >
+ ds( dp_misc::Dependencies::check( infoset ) );
+ if ( ! ds.getLength() )
+ sOnlineVersion = info.version;
+ }
+
+ rtl::OUString sVersionUser;
+ rtl::OUString sVersionShared;
+ rtl::OUString sVersionBundled;
+ uno::Sequence< uno::Reference< deployment::XPackage> > extensions;
+ try {
+ extensions = extMgr->getExtensionsWithSameIdentifier(
+ dp_misc::getIdentifier(info.extension), info.extension->getName(),
+ uno::Reference<css_ucb::XCommandEnvironment>());
+ } catch (lang::IllegalArgumentException& ) {
+ OSL_ASSERT(0);
+ }
+ OSL_ASSERT(extensions.getLength() == 3);
+ if (extensions[0].is() )
+ sVersionUser = extensions[0]->getVersion();
+ if (extensions[1].is() )
+ sVersionShared = extensions[1]->getVersion();
+ if (extensions[2].is() )
+ sVersionBundled = extensions[2]->getVersion();
+
+ bool bSharedReadOnly = extMgr->isReadOnlyRepository(OUSTR("shared"));
+
+ dp_misc::UPDATE_SOURCE sourceUser = dp_misc::isUpdateUserExtension(
+ bSharedReadOnly, sVersionUser, sVersionShared, sVersionBundled, sOnlineVersion);
+ dp_misc::UPDATE_SOURCE sourceShared = dp_misc::isUpdateSharedExtension(
+ bSharedReadOnly, sVersionShared, sVersionBundled, sOnlineVersion);
+
+ rtl::OUString updateVersionUser;
+ rtl::OUString updateVersionShared;
+ if (sourceUser != dp_misc::UPDATE_SOURCE_NONE)
+ updateVersionUser = dp_misc::getHighestVersion(
+ rtl::OUString(), sVersionShared, sVersionBundled, sOnlineVersion);
+ if (sourceShared != dp_misc::UPDATE_SOURCE_NONE)
+ updateVersionShared = dp_misc::getHighestVersion(
+ rtl::OUString(), rtl::OUString(), sVersionBundled, sOnlineVersion);
+ rtl::OUString updateVersion;
+ if (dp_misc::compareVersions(updateVersionUser, updateVersionShared) == dp_misc::GREATER)
+ updateVersion = updateVersionUser;
+ else
+ updateVersion = updateVersionShared;
+ if (updateVersion.getLength())
+ {
+
+ rtl::OUString aNewEntry[2];
+ aNewEntry[0] = i->first;
+ aNewEntry[1] = updateVersion;
+ aList.realloc( ++nCount );
+ aList[ nCount-1 ] = ::uno::Sequence< rtl::OUString >( aNewEntry, 2 );
+ }
+ }
+ return aList;
+}
+
+//------------------------------------------------------------------------------
+uno::Sequence< uno::Sequence< rtl::OUString > > SAL_CALL PackageInformationProvider::getExtensionList()
+ throw ( uno::RuntimeException )
+{
+ const uno::Reference<deployment::XExtensionManager> mgr =
+ deployment::ExtensionManager::get(mxContext);
+
+ if (!mgr.is())
+ return uno::Sequence< uno::Sequence< rtl::OUString > >();
+
+ const uno::Sequence< uno::Sequence< uno::Reference<deployment::XPackage > > >
+ allExt = mgr->getAllExtensions(
+ uno::Reference< task::XAbortChannel >(),
+ uno::Reference< css_ucb::XCommandEnvironment > () );
+
+ uno::Sequence< uno::Sequence< rtl::OUString > > retList;
+
+ sal_Int32 cAllIds = allExt.getLength();
+ retList.realloc(cAllIds);
+
+ for (sal_Int32 i = 0; i < cAllIds; i++)
+ {
+ //The inner sequence contains extensions with the same identifier from
+ //all the different repositories, that is user, share, bundled.
+ const uno::Sequence< uno::Reference< deployment::XPackage > > &
+ seqExtension = allExt[i];
+ sal_Int32 cExt = seqExtension.getLength();
+ OSL_ASSERT(cExt == 3);
+ for (sal_Int32 j = 0; j < cExt; j++)
+ {
+ //ToDo according to the old code the first found extenions is used
+ //even if another one with the same id has a better version.
+ uno::Reference< deployment::XPackage > const & xExtension( seqExtension[j] );
+ if (xExtension.is())
+ {
+ rtl::OUString aNewEntry[2];
+ aNewEntry[0] = dp_misc::getIdentifier(xExtension);
+ aNewEntry[1] = xExtension->getVersion();
+ retList[i] = ::uno::Sequence< rtl::OUString >( aNewEntry, 2 );
+ break;
+ }
+ }
+ }
+ return retList;
+}
+
+
+//------------------------------------------------------------------------------
+
+namespace sdecl = comphelper::service_decl;
+sdecl::class_<PackageInformationProvider> servicePIP;
+extern sdecl::ServiceDecl const serviceDecl(
+ servicePIP,
+ // a private one:
+ "com.sun.star.comp.deployment.PackageInformationProvider",
+ "com.sun.star.comp.deployment.PackageInformationProvider" );
+
+//------------------------------------------------------------------------------
+bool singleton_entries(
+ uno::Reference< registry::XRegistryKey > const & xRegistryKey )
+{
+ try {
+ uno::Reference< registry::XRegistryKey > xKey(
+ xRegistryKey->createKey(
+ serviceDecl.getImplementationName() +
+ // xxx todo: use future generated function to get singleton name
+ UNISTRING("/UNO/SINGLETONS/"
+ "com.sun.star.deployment.PackageInformationProvider") ) );
+ xKey->setStringValue( serviceDecl.getSupportedServiceNames()[0] );
+ return true;
+ }
+ catch (registry::InvalidRegistryException & exc) {
+ (void) exc; // avoid warnings
+ OSL_FAIL( ::rtl::OUStringToOString(
+ exc.Message, RTL_TEXTENCODING_UTF8 ).getStr() );
+ return false;
+ }
+}
+
+} // namespace dp_info
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/manager/dp_manager.cxx b/desktop/source/deployment/manager/dp_manager.cxx
new file mode 100644
index 000000000000..680dbf855d9d
--- /dev/null
+++ b/desktop/source/deployment/manager/dp_manager.cxx
@@ -0,0 +1,1689 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include "dp_ucb.h"
+#include "dp_resource.h"
+#include "dp_platform.hxx"
+#include "dp_manager.h"
+#include "dp_identifier.hxx"
+#include "rtl/ustrbuf.hxx"
+#include "rtl/string.hxx"
+#include "rtl/uri.hxx"
+#include "rtl/bootstrap.hxx"
+#include "osl/diagnose.h"
+#include "osl/file.hxx"
+#include "osl/security.hxx"
+#include "cppuhelper/weakref.hxx"
+#include "cppuhelper/exc_hlp.hxx"
+#include "cppuhelper/implbase1.hxx"
+#include "cppuhelper/interfacecontainer.hxx"
+#include "comphelper/servicedecl.hxx"
+#include "comphelper/sequence.hxx"
+#include "xmlscript/xml_helper.hxx"
+#include "svl/inettype.hxx"
+#include "com/sun/star/lang/DisposedException.hpp"
+#include "com/sun/star/lang/WrappedTargetRuntimeException.hpp"
+#include "com/sun/star/beans/UnknownPropertyException.hpp"
+#include "com/sun/star/util/XUpdatable.hpp"
+#include "com/sun/star/sdbc/XResultSet.hpp"
+#include "com/sun/star/sdbc/XRow.hpp"
+#include "com/sun/star/ucb/XContentAccess.hpp"
+#include "com/sun/star/ucb/NameClash.hpp"
+#include "com/sun/star/deployment/VersionException.hpp"
+#include "com/sun/star/deployment/InstallException.hpp"
+#include "com/sun/star/deployment/Prerequisites.hpp"
+#include "com/sun/star/task/XInteractionApprove.hpp"
+#include "com/sun/star/ucb/UnsupportedCommandException.hpp"
+#include "boost/bind.hpp"
+#include "tools/urlobj.hxx"
+#include "unotools/tempfile.hxx"
+
+#include "osl/file.hxx"
+#include <vector>
+#include <list>
+#include "dp_descriptioninfoset.hxx"
+#include "dp_commandenvironments.hxx"
+#include "dp_properties.hxx"
+
+using namespace ::dp_misc;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::ucb;
+using ::rtl::OUString;
+
+namespace dp_log {
+extern comphelper::service_decl::ServiceDecl const serviceDecl;
+}
+
+namespace dp_registry {
+Reference<deployment::XPackageRegistry> create(
+ OUString const & context,
+ OUString const & cachePath, bool readOnly,
+ Reference<XComponentContext> const & xComponentContext );
+}
+
+namespace dp_manager {
+
+struct MatchTempDir
+{
+ OUString m_str;
+ MatchTempDir( OUString const & str ) : m_str( str ) {}
+ bool operator () ( ActivePackages::Entries::value_type const & v ) const {
+ return v.second.temporaryName.equalsIgnoreAsciiCase( m_str );
+ }
+};
+
+
+namespace {
+OUString getExtensionFolder(OUString const & parentFolder,
+ Reference<ucb::XCommandEnvironment> const & xCmdEnv)
+{
+ ::ucbhelper::Content tempFolder(
+ parentFolder, xCmdEnv );
+ Reference<sdbc::XResultSet> xResultSet(
+ tempFolder.createCursor(
+ Sequence<OUString>( &StrTitle::get(), 1 ),
+ ::ucbhelper::INCLUDE_FOLDERS_ONLY ) );
+
+ OUString title;
+ while (xResultSet->next())
+ {
+ title = Reference<sdbc::XRow>(
+ xResultSet, UNO_QUERY_THROW )->getString(1 /* Title */ ) ;
+ break;
+ }
+ return title;
+}
+}
+//______________________________________________________________________________
+void PackageManagerImpl::initActivationLayer(
+ Reference<XCommandEnvironment> const & xCmdEnv )
+{
+ if (m_activePackages.getLength() == 0)
+ {
+ OSL_ASSERT( m_registryCache.getLength() == 0 );
+ // documents temp activation:
+ m_activePackagesDB.reset( new ActivePackages );
+ ::ucbhelper::Content ucbContent;
+ if (create_ucb_content( &ucbContent, m_context, xCmdEnv,
+ false /* no throw */ ))
+ {
+ // scan for all entries in m_packagesDir:
+ Reference<sdbc::XResultSet> xResultSet(
+ ucbContent.createCursor(
+ Sequence<OUString>( &StrTitle::get(), 1 ),
+ ::ucbhelper::INCLUDE_FOLDERS_AND_DOCUMENTS ) );
+ while (xResultSet->next())
+ {
+ Reference<sdbc::XRow> xRow( xResultSet, UNO_QUERY_THROW );
+ OUString title( xRow->getString( 1 /* Title */ ) );
+ // xxx todo: remove workaround for tdoc
+ if (title.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(
+ "this_is_a_dummy_stream_just_there_"
+ "as_a_workaround_for_a_"
+ "temporary_limitation_of_the_"
+ "storage_api_implementation") ))
+ continue;
+ if (title.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(
+ "META-INF") ) )
+ continue;
+
+ ::ucbhelper::Content sourceContent(
+ Reference<XContentAccess>(
+ xResultSet, UNO_QUERY_THROW )->queryContent(),
+ xCmdEnv );
+
+ OUString mediaType( detectMediaType( sourceContent,
+ false /* no throw */) );
+ if (mediaType.getLength() >0)
+ {
+ ActivePackages::Data dbData;
+ insertToActivationLayer(
+ Sequence<css::beans::NamedValue>(),mediaType, sourceContent,
+ title, &dbData );
+
+ insertToActivationLayerDB( title, dbData );
+ //TODO #i73136#: insertToActivationLayerDB needs id not
+ // title, but the whole m_activePackages.getLength()==0
+ // case (i.e., document-relative deployment) currently
+ // does not work, anyway.
+ }
+ }
+ }
+ }
+ else
+ {
+ // user|share:
+ OSL_ASSERT( m_activePackages.getLength() > 0 );
+ m_activePackages_expanded = expandUnoRcUrl( m_activePackages );
+ m_registrationData_expanded = expandUnoRcUrl(m_registrationData);
+ if (!m_readOnly)
+ create_folder( 0, m_activePackages_expanded, xCmdEnv, true);
+
+ OUString dbName;
+ if (m_context.equals(OUSTR("user")))
+ dbName = m_activePackages_expanded + OUSTR(".db");
+ else
+ {
+ //Create the extension data base in the user installation
+ create_folder( 0, m_registrationData_expanded, xCmdEnv, true);
+ dbName = m_registrationData_expanded + OUSTR("/extensions.db");
+ }
+ //The data base can always be written because it it always in the user installation
+ m_activePackagesDB.reset(
+ new ActivePackages( dbName, false ) );
+
+ if (! m_readOnly && ! m_context.equals(OUSTR("bundled")))
+ {
+ // clean up activation layer, scan for zombie temp dirs:
+ ActivePackages::Entries id2temp( m_activePackagesDB->getEntries() );
+
+ ::ucbhelper::Content tempFolder(
+ m_activePackages_expanded, xCmdEnv );
+ Reference<sdbc::XResultSet> xResultSet(
+ tempFolder.createCursor(
+ Sequence<OUString>( &StrTitle::get(), 1 ),
+ ::ucbhelper::INCLUDE_DOCUMENTS_ONLY ) );
+ // get all temp directories:
+ ::std::vector<OUString> tempEntries;
+ ::std::vector<OUString> removedEntries;
+ while (xResultSet->next())
+ {
+ OUString title(
+ Reference<sdbc::XRow>(
+ xResultSet, UNO_QUERY_THROW )->getString(
+ 1 /* Title */ ) );
+
+ const char extensionRemoved[] = "removed";
+ if (title.endsWithAsciiL(
+ extensionRemoved, sizeof(extensionRemoved) - 1))
+ {
+ //save the file name withouth the "removed" part
+ sal_Int32 index = title.lastIndexOfAsciiL(
+ extensionRemoved, sizeof(extensionRemoved) - 1);
+ OUString remFile = title.copy(0, index);
+ removedEntries.push_back(::rtl::Uri::encode(
+ remFile, rtl_UriCharClassPchar,
+ rtl_UriEncodeIgnoreEscapes,
+ RTL_TEXTENCODING_UTF8 ) );
+ }
+ else
+ {
+ tempEntries.push_back( ::rtl::Uri::encode(
+ title, rtl_UriCharClassPchar,
+ rtl_UriEncodeIgnoreEscapes,
+ RTL_TEXTENCODING_UTF8 ) );
+ }
+ }
+
+ bool bShared = m_context.equals(OUSTR("shared")) ? true : false;
+ for ( ::std::size_t pos = 0; pos < tempEntries.size(); ++pos )
+ {
+ OUString const & tempEntry = tempEntries[ pos ];
+ const MatchTempDir match( tempEntry );
+ if (::std::find_if( id2temp.begin(), id2temp.end(), match ) ==
+ id2temp.end())
+ {
+ const OUString url(
+ makeURL(m_activePackages_expanded, tempEntry ) );
+
+ //In case of shared extensions, new entries are regarded as
+ //added extensions if there is no xxx.tmpremoved file.
+ if (bShared)
+ {
+ if (::std::find(removedEntries.begin(), removedEntries.end(), tempEntry) ==
+ removedEntries.end())
+ {
+ continue;
+ }
+ else
+ {
+ //Make sure only the same user removes the extension, who
+ //previously unregistered it. This is avoid races if multiple instances
+ //of OOo are running which all have write access to the shared installation.
+ //For example, a user removes the extension, but keeps OOo
+ //running. Parts of the extension may still be loaded and used by OOo.
+ //Therefore the extension is only deleted the next time the extension manager is
+ //run after restarting OOo. While OOo is still running, another user starts OOo
+ //which would deleted the extension files. If the same user starts another
+ //instance of OOo then the lock file will prevent this.
+ OUString aUserName;
+ ::osl::Security aSecurity;
+ aSecurity.getUserName( aUserName );
+ ucbhelper::Content remFileContent(
+ url + OUSTR("removed"), Reference<XCommandEnvironment>());
+ ::rtl::ByteSequence data = dp_misc::readFile(remFileContent);
+ ::rtl::OString osData(reinterpret_cast<const sal_Char*>(data.getConstArray()),
+ data.getLength());
+ OUString sData = ::rtl::OStringToOUString(
+ osData, RTL_TEXTENCODING_UTF8);
+ if (!sData.equals(aUserName))
+ continue;
+ }
+ }
+ // temp entry not needed anymore:
+ erase_path( url + OUSTR("_"),
+ Reference<XCommandEnvironment>(),
+ false /* no throw: ignore errors */ );
+ erase_path( url, Reference<XCommandEnvironment>(),
+ false /* no throw: ignore errors */ );
+ //delete the xxx.tmpremoved file
+ erase_path(url + OUSTR("removed"),
+ Reference<XCommandEnvironment>(), false);
+ }
+ }
+ }
+ }
+}
+
+//______________________________________________________________________________
+void PackageManagerImpl::initRegistryBackends()
+{
+ if (m_registryCache.getLength() > 0)
+ create_folder( 0, m_registryCache,
+ Reference<XCommandEnvironment>(), false);
+ m_xRegistry.set( ::dp_registry::create(
+ m_context, m_registryCache, false,
+ m_xComponentContext ) );
+}
+
+//______________________________________________________________________________
+Reference<deployment::XPackageManager> PackageManagerImpl::create(
+ Reference<XComponentContext> const & xComponentContext,
+ OUString const & context )
+{
+ PackageManagerImpl * that = new PackageManagerImpl(
+ xComponentContext, context );
+ Reference<deployment::XPackageManager> xPackageManager( that );
+
+ OUString packages, logFile, stampURL;
+ if (context.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("user") )) {
+ that->m_activePackages = OUSTR(
+ "vnd.sun.star.expand:$UNO_USER_PACKAGES_CACHE/uno_packages");
+ that->m_registrationData = OUSTR(
+ "vnd.sun.star.expand:$UNO_USER_PACKAGES_CACHE");
+ that->m_registryCache = OUSTR(
+ "vnd.sun.star.expand:$UNO_USER_PACKAGES_CACHE/registry");
+ logFile = OUSTR(
+ "vnd.sun.star.expand:$UNO_USER_PACKAGES_CACHE/log.txt");
+ //We use the extension .sys for the file because on Windows Vista a sys
+ //(as well as exe and dll) file
+ //will not be written in the VirtualStore. For example if the process has no
+ //admin right once cannot write to the %programfiles% folder. However, when
+ //virtualization is used, the file will be written into the VirtualStore and
+ //it appears as if one could write to %programfiles%. When we test for write
+ //access to the office/shared folder for shared extensions then this typically
+ //fails because a normal user typically cannot write to this folder. However,
+ //using virtualization it appears that he/she can. Then a shared extension can
+ //be installed but is only visible for the user (because the extension is in
+ //the virtual store).
+ stampURL = OUSTR(
+ "vnd.sun.star.expand:$UNO_USER_PACKAGES_CACHE/stamp.sys");
+ }
+ else if (context.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("shared") )) {
+ that->m_activePackages = OUSTR(
+ "vnd.sun.star.expand:$UNO_SHARED_PACKAGES_CACHE/uno_packages");
+ that->m_registrationData = OUSTR(
+ "vnd.sun.star.expand:$SHARED_EXTENSIONS_USER");
+ that->m_registryCache = OUSTR(
+ "vnd.sun.star.expand:$SHARED_EXTENSIONS_USER/registry");
+ logFile = OUSTR(
+ "vnd.sun.star.expand:$SHARED_EXTENSIONS_USER/log.txt");
+ stampURL = OUSTR(
+ "vnd.sun.star.expand:$UNO_SHARED_PACKAGES_CACHE/stamp.sys");
+ }
+ else if (context.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("bundled") )) {
+ that->m_activePackages = OUSTR(
+ "vnd.sun.star.expand:$BUNDLED_EXTENSIONS");
+ that->m_registrationData = OUSTR(
+ "vnd.sun.star.expand:$BUNDLED_EXTENSIONS_USER");
+ that->m_registryCache = OUSTR(
+ "vnd.sun.star.expand:$BUNDLED_EXTENSIONS_USER/registry");
+ logFile = OUSTR(
+ "vnd.sun.star.expand:$BUNDLED_EXTENSIONS_USER/log.txt");
+ //No stamp file. We assume that bundled is always readonly. It must not be
+ //modified from ExtensionManager but only by the installer
+ }
+ else if (context.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("bundled_prereg") )) {
+ //This is a bundled repository but the registration data
+ //is in the brand layer: share/prereg
+ //It is special because the registration data are copied at the first startup
+ //into the user installation. The processed help and xcu files are not
+ //copied. Instead the backenddb.xml for the help backend references the help
+ //by using $BUNDLED_EXTENSION_PREREG instead $BUNDLED_EXTENSIONS_USER. The
+ //configmgr.ini also used $BUNDLED_EXTENSIONS_PREREG to refer to the xcu file
+ //which contain the replacement for %origin%.
+ that->m_activePackages = OUSTR(
+ "vnd.sun.star.expand:$BUNDLED_EXTENSIONS");
+ that->m_registrationData = OUSTR(
+ "vnd.sun.star.expand:$BUNDLED_EXTENSIONS_PREREG");
+ that->m_registryCache = OUSTR(
+ "vnd.sun.star.expand:$BUNDLED_EXTENSIONS_PREREG/registry");
+ logFile = OUSTR(
+ "vnd.sun.star.expand:$BUNDLED_EXTENSIONS_PREREG/log.txt");
+ }
+ else if (context.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("tmp") )) {
+ that->m_activePackages = OUSTR(
+ "vnd.sun.star.expand:$TMP_EXTENSIONS/extensions");
+ that->m_registrationData = OUSTR(
+ "vnd.sun.star.expand:$TMP_EXTENSIONS");
+ that->m_registryCache = OUSTR(
+ "vnd.sun.star.expand:$TMP_EXTENSIONS/registry");
+ stampURL = OUSTR(
+ "vnd.sun.star.expand:$TMP_EXTENSIONS/stamp.sys");
+ }
+ else if (! context.matchAsciiL(
+ RTL_CONSTASCII_STRINGPARAM("vnd.sun.star.tdoc:/") )) {
+ throw lang::IllegalArgumentException(
+ OUSTR("invalid context given: ") + context,
+ Reference<XInterface>(), static_cast<sal_Int16>(-1) );
+ }
+
+ Reference<XCommandEnvironment> xCmdEnv;
+
+ try {
+ //There is no stampURL for the bundled folder
+ if (stampURL.getLength() > 0)
+ {
+#define CURRENT_STAMP "1"
+ try {
+ //The osl file API does not allow to find out if one can write
+ //into a folder. Therefore we try to write a file. Then we delete
+ //it, so that it does not hinder uninstallation of OOo
+ // probe writing:
+ ::ucbhelper::Content ucbStamp( stampURL, xCmdEnv );
+ ::rtl::OString stamp(
+ RTL_CONSTASCII_STRINGPARAM(CURRENT_STAMP) );
+ Reference<io::XInputStream> xData(
+ ::xmlscript::createInputStream(
+ ::rtl::ByteSequence(
+ reinterpret_cast<sal_Int8 const *>(stamp.getStr()),
+ stamp.getLength() ) ) );
+ ucbStamp.writeStream( xData, true /* replace existing */ );
+ that->m_readOnly = false;
+ erase_path( stampURL, xCmdEnv );
+ }
+ catch (RuntimeException &) {
+ try {
+ erase_path( stampURL, xCmdEnv );
+ } catch (...)
+ {
+ }
+ throw;
+ }
+ catch (Exception &) {
+ that->m_readOnly = true;
+ }
+ }
+
+ if (!that->m_readOnly && logFile.getLength() > 0)
+ {
+ const Any any_logFile(logFile);
+ that->m_xLogFile.set(
+ that->m_xComponentContext->getServiceManager()
+ ->createInstanceWithArgumentsAndContext(
+ dp_log::serviceDecl.getSupportedServiceNames()[0],
+ Sequence<Any>( &any_logFile, 1 ),
+ that->m_xComponentContext ),
+ UNO_QUERY_THROW );
+ xCmdEnv.set( new CmdEnvWrapperImpl( xCmdEnv, that->m_xLogFile ) );
+ }
+
+ that->initRegistryBackends();
+ that->initActivationLayer( xCmdEnv );
+
+ return xPackageManager;
+
+ }
+ catch (RuntimeException &) {
+ throw;
+ }
+ catch (Exception &) {
+ Any exc( ::cppu::getCaughtException() );
+ ::rtl::OUStringBuffer buf;
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[context=\"") );
+ buf.append( context );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
+ "\"] caught unexpected exception!") );
+ throw lang::WrappedTargetRuntimeException(
+ buf.makeStringAndClear(), Reference<XInterface>(), exc );
+ }
+}
+
+//______________________________________________________________________________
+PackageManagerImpl::~PackageManagerImpl()
+{
+}
+
+//______________________________________________________________________________
+void PackageManagerImpl::fireModified()
+{
+ ::cppu::OInterfaceContainerHelper * pContainer = rBHelper.getContainer(
+ util::XModifyListener::static_type() );
+ if (pContainer != 0) {
+ pContainer->forEach<util::XModifyListener>(
+ boost::bind(&util::XModifyListener::modified, _1,
+ lang::EventObject(static_cast<OWeakObject *>(this))) );
+ }
+}
+
+//______________________________________________________________________________
+void PackageManagerImpl::disposing()
+{
+ try {
+// // xxx todo: guarding?
+// ::osl::MutexGuard guard( getMutex() );
+ try_dispose( m_xLogFile );
+ m_xLogFile.clear();
+ try_dispose( m_xRegistry );
+ m_xRegistry.clear();
+ m_activePackagesDB.reset(0);
+ m_xComponentContext.clear();
+
+ t_pm_helper::disposing();
+
+ }
+ catch (RuntimeException &) {
+ throw;
+ }
+ catch (Exception &) {
+ Any exc( ::cppu::getCaughtException() );
+ throw lang::WrappedTargetRuntimeException(
+ OUSTR("caught unexpected exception while disposing..."),
+ static_cast<OWeakObject *>(this), exc );
+ }
+}
+
+// XComponent
+//______________________________________________________________________________
+void PackageManagerImpl::dispose() throw (RuntimeException)
+{
+ check();
+ WeakComponentImplHelperBase::dispose();
+}
+
+//______________________________________________________________________________
+void PackageManagerImpl::addEventListener(
+ Reference<lang::XEventListener> const & xListener ) throw (RuntimeException)
+{
+ check();
+ WeakComponentImplHelperBase::addEventListener( xListener );
+}
+
+//______________________________________________________________________________
+void PackageManagerImpl::removeEventListener(
+ Reference<lang::XEventListener> const & xListener ) throw (RuntimeException)
+{
+ check();
+ WeakComponentImplHelperBase::removeEventListener( xListener );
+}
+
+// XPackageManager
+//______________________________________________________________________________
+OUString PackageManagerImpl::getContext() throw (RuntimeException)
+{
+ check();
+ return m_context;
+}
+
+//______________________________________________________________________________
+Sequence< Reference<deployment::XPackageTypeInfo> >
+PackageManagerImpl::getSupportedPackageTypes() throw (RuntimeException)
+{
+ OSL_ASSERT( m_xRegistry.is() );
+ return m_xRegistry->getSupportedPackageTypes();
+}
+
+//______________________________________________________________________________
+Reference<task::XAbortChannel> PackageManagerImpl::createAbortChannel()
+ throw (RuntimeException)
+{
+ check();
+ return new AbortChannel;
+}
+
+// XModifyBroadcaster
+//______________________________________________________________________________
+void PackageManagerImpl::addModifyListener(
+ Reference<util::XModifyListener> const & xListener )
+ throw (RuntimeException)
+{
+ check();
+ rBHelper.addListener( ::getCppuType( &xListener ), xListener );
+}
+
+//______________________________________________________________________________
+void PackageManagerImpl::removeModifyListener(
+ Reference<util::XModifyListener> const & xListener )
+ throw (RuntimeException)
+{
+ check();
+ rBHelper.removeListener( ::getCppuType( &xListener ), xListener );
+}
+
+//______________________________________________________________________________
+OUString PackageManagerImpl::detectMediaType(
+ ::ucbhelper::Content const & ucbContent_, bool throw_exc )
+{
+ ::ucbhelper::Content ucbContent(ucbContent_);
+ OUString url( ucbContent.getURL() );
+ OUString mediaType;
+ if (url.matchAsciiL( RTL_CONSTASCII_STRINGPARAM("vnd.sun.star.tdoc:") ) ||
+ url.matchAsciiL( RTL_CONSTASCII_STRINGPARAM("vnd.sun.star.pkg:") ))
+ {
+ try {
+ ucbContent.getPropertyValue( OUSTR("MediaType") ) >>= mediaType;
+ }
+ catch (beans::UnknownPropertyException &) {
+ }
+ OSL_ENSURE( mediaType.getLength() > 0, "### no media-type?!" );
+ }
+ if (mediaType.getLength() == 0)
+ {
+ try {
+ Reference<deployment::XPackage> xPackage(
+ m_xRegistry->bindPackage(
+ url, OUString(), false, OUString(), ucbContent.getCommandEnvironment() ) );
+ const Reference<deployment::XPackageTypeInfo> xPackageType(
+ xPackage->getPackageType() );
+ OSL_ASSERT( xPackageType.is() );
+ if (xPackageType.is())
+ mediaType = xPackageType->getMediaType();
+ }
+ catch (lang::IllegalArgumentException & exc) {
+ if (throw_exc)
+ throw;
+ (void) exc;
+ OSL_FAIL( ::rtl::OUStringToOString(
+ exc.Message, RTL_TEXTENCODING_UTF8 ).getStr() );
+ }
+ }
+ return mediaType;
+}
+
+//______________________________________________________________________________
+OUString PackageManagerImpl::insertToActivationLayer(
+ Sequence<beans::NamedValue> const & properties,
+ OUString const & mediaType, ::ucbhelper::Content const & sourceContent_,
+ OUString const & title, ActivePackages::Data * dbData )
+{
+ ::ucbhelper::Content sourceContent(sourceContent_);
+ Reference<XCommandEnvironment> xCmdEnv(
+ sourceContent.getCommandEnvironment() );
+
+ String baseDir(m_activePackages_expanded);
+ ::utl::TempFile aTemp(&baseDir, sal_False);
+ OUString tempEntry = aTemp.GetURL();
+ tempEntry = tempEntry.copy(tempEntry.lastIndexOf('/') + 1);
+ OUString destFolder = makeURL( m_activePackages, tempEntry);
+ destFolder += OUSTR("_");
+
+ // prepare activation folder:
+ ::ucbhelper::Content destFolderContent;
+ create_folder( &destFolderContent, destFolder, xCmdEnv );
+
+ // copy content into activation temp dir:
+ if (mediaType.matchIgnoreAsciiCaseAsciiL(
+ RTL_CONSTASCII_STRINGPARAM(
+ "application/vnd.sun.star.package-bundle") ) ||
+ // xxx todo: more sophisticated parsing
+ mediaType.matchIgnoreAsciiCaseAsciiL(
+ RTL_CONSTASCII_STRINGPARAM(
+ "application/vnd.sun.star.legacy-package-bundle") ))
+ {
+ // inflate content:
+ ::rtl::OUStringBuffer buf;
+ if (!sourceContent.isFolder())
+ {
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("vnd.sun.star.zip://") );
+ buf.append( ::rtl::Uri::encode( sourceContent.getURL(),
+ rtl_UriCharClassRegName,
+ rtl_UriEncodeIgnoreEscapes,
+ RTL_TEXTENCODING_UTF8 ) );
+ }
+ else
+ {
+ //Folder. No need to unzip, just copy
+ buf.append(sourceContent.getURL());
+ }
+ buf.append( static_cast<sal_Unicode>('/') );
+ sourceContent = ::ucbhelper::Content(
+ buf.makeStringAndClear(), xCmdEnv );
+ }
+ if (! destFolderContent.transferContent(
+ sourceContent, ::ucbhelper::InsertOperation_COPY,
+ title, NameClash::OVERWRITE ))
+ throw RuntimeException( OUSTR("UCB transferContent() failed!"), 0 );
+
+
+ // write to DB:
+ //bundled extensions should only be added by the synchronizeAddedExtensions
+ //functions. Moreover, there is no "temporary folder" for bundled extensions.
+ OSL_ASSERT(!m_context.equals(OUSTR("bundled")));
+ OUString sFolderUrl = makeURLAppendSysPathSegment(destFolderContent.getURL(), title);
+ DescriptionInfoset info =
+ dp_misc::getDescriptionInfoset(sFolderUrl);
+ dbData->temporaryName = tempEntry;
+ dbData->fileName = title;
+ dbData->mediaType = mediaType;
+ dbData->version = info.getVersion();
+
+ //No write the properties file next to the extension
+ ExtensionProperties props(sFolderUrl, properties, xCmdEnv);
+ props.write();
+ return destFolder;
+}
+
+//______________________________________________________________________________
+void PackageManagerImpl::insertToActivationLayerDB(
+ OUString const & id, ActivePackages::Data const & dbData )
+{
+ //access to the database must be guarded. See removePackage
+ const ::osl::MutexGuard guard( getMutex() );
+ m_activePackagesDB->put( id, dbData );
+}
+
+//______________________________________________________________________________
+/* The function returns true if there is an extension with the same id already
+ installed which needs to be uninstalled, before the new extension can be installed.
+*/
+bool PackageManagerImpl::isInstalled(
+ Reference<deployment::XPackage> const & package)
+{
+ OUString id(dp_misc::getIdentifier(package));
+ OUString fn(package->getName());
+ bool bInstalled = false;
+ if (m_activePackagesDB->has( id, fn ))
+ {
+ bInstalled = true;
+ }
+ return bInstalled;
+}
+
+// XPackageManager
+//______________________________________________________________________________
+Reference<deployment::XPackage> PackageManagerImpl::importExtension(
+ Reference<deployment::XPackage> const & extension,
+ Reference<task::XAbortChannel> const & xAbortChannel,
+ Reference<XCommandEnvironment> const & xCmdEnv_ )
+ throw (deployment::DeploymentException, CommandFailedException,
+ CommandAbortedException, lang::IllegalArgumentException,
+ RuntimeException)
+{
+ return addPackage(extension->getURL(), Sequence<beans::NamedValue>(),
+ OUString(), xAbortChannel, xCmdEnv_);
+}
+
+/* The function adds an extension but does not register it!!!
+ It may not do any user interaction. This is done in XExtensionManager::addExtension
+*/
+Reference<deployment::XPackage> PackageManagerImpl::addPackage(
+ OUString const & url,
+ css::uno::Sequence<css::beans::NamedValue> const & properties,
+ OUString const & mediaType_,
+ Reference<task::XAbortChannel> const & xAbortChannel,
+ Reference<XCommandEnvironment> const & xCmdEnv_ )
+ throw (deployment::DeploymentException, CommandFailedException,
+ CommandAbortedException, lang::IllegalArgumentException,
+ RuntimeException)
+{
+ check();
+ if (m_readOnly)
+ {
+ OUString message;
+ if (m_context == OUSTR("shared"))
+ message = OUSTR("You need write permissions to install a shared extension!");
+ else
+ message = OUSTR("You need write permissions to install this extension!");
+ throw deployment::DeploymentException(
+ message, static_cast<OWeakObject *>(this), Any() );
+ }
+ Reference<XCommandEnvironment> xCmdEnv;
+ if (m_xLogFile.is())
+ xCmdEnv.set( new CmdEnvWrapperImpl( xCmdEnv_, m_xLogFile ) );
+ else
+ xCmdEnv.set( xCmdEnv_ );
+
+ try {
+ ::ucbhelper::Content sourceContent;
+ create_ucb_content( &sourceContent, url, xCmdEnv ); // throws exc
+ const OUString title(sourceContent.getPropertyValue(
+ StrTitle::get() ).get<OUString>() );
+ const OUString title_enc( ::rtl::Uri::encode(
+ title, rtl_UriCharClassPchar,
+ rtl_UriEncodeIgnoreEscapes,
+ RTL_TEXTENCODING_UTF8 ) );
+ OUString destFolder;
+
+ OUString mediaType(mediaType_);
+ if (mediaType.getLength() == 0)
+ mediaType = detectMediaType( sourceContent );
+
+ Reference<deployment::XPackage> xPackage;
+ // copy file:
+ progressUpdate(
+ getResourceString(RID_STR_COPYING_PACKAGE) + title, xCmdEnv );
+ if (m_activePackages.getLength() == 0)
+ {
+ ::ucbhelper::Content docFolderContent;
+ create_folder( &docFolderContent, m_context, xCmdEnv );
+ // copy into document, first:
+ if (! docFolderContent.transferContent(
+ sourceContent, ::ucbhelper::InsertOperation_COPY,
+ OUString(),
+ NameClash::ASK /* xxx todo: ASK not needed? */))
+ throw RuntimeException(
+ OUSTR("UCB transferContent() failed!"), 0 );
+ // set media-type:
+ ::ucbhelper::Content docContent(
+ makeURL( m_context, title_enc ), xCmdEnv );
+ //TODO #i73136#: using title instead of id can lead to
+ // clashes, but the whole m_activePackages.getLength()==0
+ // case (i.e., document-relative deployment) currently does
+ // not work, anyway.
+ docContent.setPropertyValue(
+ OUSTR("MediaType"), Any(mediaType) );
+
+ // xxx todo: obsolete in the future
+ try {
+ docFolderContent.executeCommand( OUSTR("flush"), Any() );
+ }
+ catch (UnsupportedCommandException &) {
+ }
+ }
+ ActivePackages::Data dbData;
+ destFolder = insertToActivationLayer(
+ properties, mediaType, sourceContent, title, &dbData );
+
+
+ // bind activation package:
+ //Because every shared/user extension will be unpacked in a folder,
+ //which was created with a unique name we will always have two different
+ //XPackage objects, even if the second extension is the same.
+ //Therefore bindPackage does not need a guard here.
+ xPackage = m_xRegistry->bindPackage(
+ makeURL( destFolder, title_enc ), mediaType, false, OUString(), xCmdEnv );
+
+ OSL_ASSERT( xPackage.is() );
+ if (xPackage.is())
+ {
+ bool install = false;
+ try
+ {
+ OUString const id = dp_misc::getIdentifier( xPackage );
+
+ ::osl::MutexGuard g(m_addMutex);
+ if (isInstalled(xPackage))
+ {
+ //Do not guard the complete function with the getMutex
+ removePackage(id, xPackage->getName(), xAbortChannel,
+ xCmdEnv);
+ }
+ install = true;
+ insertToActivationLayerDB(id, dbData);
+ }
+ catch (...)
+ {
+ deletePackageFromCache( xPackage, destFolder );
+ throw;
+ }
+ if (!install)
+ {
+ deletePackageFromCache( xPackage, destFolder );
+ }
+ //ToDo: We should notify only if the extension is registered
+ fireModified();
+ }
+ return xPackage;
+ }
+ catch (RuntimeException &) {
+ throw;
+ }
+ catch (CommandFailedException & exc) {
+ logIntern( Any(exc) );
+ throw;
+ }
+ catch (CommandAbortedException & exc) {
+ logIntern( Any(exc) );
+ throw;
+ }
+ catch (deployment::DeploymentException & exc) {
+ logIntern( Any(exc) );
+ throw;
+ }
+ catch (Exception &) {
+ Any exc( ::cppu::getCaughtException() );
+ logIntern( exc );
+ throw deployment::DeploymentException(
+ getResourceString(RID_STR_ERROR_WHILE_ADDING) + url,
+ static_cast<OWeakObject *>(this), exc );
+ }
+}
+void PackageManagerImpl::deletePackageFromCache(
+ Reference<deployment::XPackage> const & xPackage,
+ OUString const & destFolder)
+{
+ try_dispose( xPackage );
+
+ //we remove the package from the uno cache
+ //no service from the package may be loaded at this time!!!
+ erase_path( destFolder, Reference<XCommandEnvironment>(),
+ false /* no throw: ignore errors */ );
+ //rm last character '_'
+ OUString url = destFolder.copy(0, destFolder.getLength() - 1);
+ erase_path( url, Reference<XCommandEnvironment>(),
+ false /* no throw: ignore errors */ );
+
+}
+//______________________________________________________________________________
+void PackageManagerImpl::removePackage(
+ OUString const & id, ::rtl::OUString const & fileName,
+ Reference<task::XAbortChannel> const & /*xAbortChannel*/,
+ Reference<XCommandEnvironment> const & xCmdEnv_ )
+ throw (deployment::DeploymentException, CommandFailedException,
+ CommandAbortedException, lang::IllegalArgumentException,
+ RuntimeException)
+{
+ check();
+
+ Reference<XCommandEnvironment> xCmdEnv;
+ if (m_xLogFile.is())
+ xCmdEnv.set( new CmdEnvWrapperImpl( xCmdEnv_, m_xLogFile ) );
+ else
+ xCmdEnv.set( xCmdEnv_ );
+
+ try {
+ Reference<deployment::XPackage> xPackage;
+ {
+ const ::osl::MutexGuard guard(getMutex());
+ //Check if this extension exist and throw an IllegalArgumentException
+ //if it does not
+ //If the files of the extension are already removed, or there is a
+ //different extension at the same place, for example after updating the
+ //extension, then the returned object is that which uses the database data.
+ xPackage = getDeployedPackage_(id, fileName, xCmdEnv );
+
+
+ //Because the extension is only removed the next time the extension
+ //manager runs after restarting OOo, we need to indicate that a
+ //shared extension was "deleted". When a user starts OOo, then it
+ //will check if something changed in the shared repository. Based on
+ //the flag file it will then recognize, that the extension was
+ //deleted and can then update the extnesion database of the shared
+ //extensions in the user installation.
+ if ( xPackage.is() && !m_readOnly && !xPackage->isRemoved() && m_context.equals(OUSTR("shared")))
+ {
+ ActivePackages::Data val;
+ m_activePackagesDB->get( & val, id, fileName);
+ OSL_ASSERT(val.temporaryName.getLength());
+ OUString url(makeURL(m_activePackages_expanded,
+ val.temporaryName + OUSTR("removed")));
+ ::ucbhelper::Content contentRemoved(url, xCmdEnv );
+ OUString aUserName;
+ ::osl::Security aSecurity;
+ aSecurity.getUserName( aUserName );
+
+ ::rtl::OString stamp = ::rtl::OUStringToOString(aUserName, RTL_TEXTENCODING_UTF8);
+ Reference<css::io::XInputStream> xData(
+ ::xmlscript::createInputStream(
+ ::rtl::ByteSequence(
+ reinterpret_cast<sal_Int8 const *>(stamp.getStr()),
+ stamp.getLength() ) ) );
+ contentRemoved.writeStream( xData, true /* replace existing */ );
+ }
+ m_activePackagesDB->erase( id, fileName ); // to be removed upon next start
+ //remove any cached data hold by the backend
+ m_xRegistry->packageRemoved(xPackage->getURL(), xPackage->getPackageType()->getMediaType());
+ }
+ try_dispose( xPackage );
+
+ fireModified();
+ }
+ catch (RuntimeException &) {
+ throw;
+ }
+ catch (lang::IllegalArgumentException &) {
+ throw;
+ }
+ catch (CommandFailedException & exc) {
+ logIntern( Any(exc) );
+ throw;
+ }
+ catch (CommandAbortedException & exc) {
+ logIntern( Any(exc) );
+ throw;
+ }
+ catch (deployment::DeploymentException & exc) {
+ logIntern( Any(exc) );
+ throw;
+ }
+ catch (Exception &) {
+ Any exc( ::cppu::getCaughtException() );
+ logIntern( exc );
+ throw deployment::DeploymentException(
+ getResourceString(RID_STR_ERROR_WHILE_REMOVING) + id,
+ static_cast<OWeakObject *>(this), exc );
+ }
+}
+
+//______________________________________________________________________________
+OUString PackageManagerImpl::getDeployPath( ActivePackages::Data const & data )
+{
+ ::rtl::OUStringBuffer buf;
+ buf.append( data.temporaryName );
+ //The bundled extensions are not contained in an additional folder
+ //with a unique name. data.temporaryName contains already the
+ //UTF8 encoded folder name. See PackageManagerImpl::synchronize
+ if (!m_context.equals(OUSTR("bundled"))
+ && !m_context.equals(OUSTR("bundled_prereg")))
+ {
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("_/") );
+ buf.append( ::rtl::Uri::encode( data.fileName, rtl_UriCharClassPchar,
+ rtl_UriEncodeIgnoreEscapes,
+ RTL_TEXTENCODING_UTF8 ) );
+ }
+ return makeURL( m_activePackages, buf.makeStringAndClear() );
+}
+
+//______________________________________________________________________________
+Reference<deployment::XPackage> PackageManagerImpl::getDeployedPackage_(
+ OUString const & id, OUString const & fileName,
+ Reference<XCommandEnvironment> const & xCmdEnv )
+{
+ ActivePackages::Data val;
+ if (m_activePackagesDB->get( &val, id, fileName ))
+ {
+ return getDeployedPackage_( id, val, xCmdEnv, false );
+ }
+ throw lang::IllegalArgumentException(
+ getResourceString(RID_STR_NO_SUCH_PACKAGE) + id,
+ static_cast<OWeakObject *>(this), static_cast<sal_Int16>(-1) );
+}
+
+//______________________________________________________________________________
+Reference<deployment::XPackage> PackageManagerImpl::getDeployedPackage_(
+ OUString const & id, ActivePackages::Data const & data,
+ Reference<XCommandEnvironment> const & xCmdEnv, bool ignoreAlienPlatforms )
+{
+ if (ignoreAlienPlatforms)
+ {
+ String type, subType;
+ INetContentTypeParameterList params;
+ if (INetContentTypes::parse( data.mediaType, type, subType, &params ))
+ {
+ INetContentTypeParameter const * param = params.find(
+ ByteString("platform") );
+ if (param != 0 && !platform_fits( param->m_sValue ))
+ throw lang::IllegalArgumentException(
+ getResourceString(RID_STR_NO_SUCH_PACKAGE) + id,
+ static_cast<OWeakObject *>(this),
+ static_cast<sal_Int16>(-1) );
+ }
+ }
+ Reference<deployment::XPackage> xExtension;
+ try
+ {
+ //Ignore extensions where XPackage::checkPrerequisites failed.
+ //They must not be usable for this user.
+ if (data.failedPrerequisites.equals(OUSTR("0")))
+ {
+ xExtension = m_xRegistry->bindPackage(
+ getDeployPath( data ), data.mediaType, false, OUString(), xCmdEnv );
+ }
+ }
+ catch (deployment::InvalidRemovedParameterException& e)
+ {
+ xExtension = e.Extension;
+ }
+ return xExtension;
+}
+
+//______________________________________________________________________________
+Sequence< Reference<deployment::XPackage> >
+PackageManagerImpl::getDeployedPackages_(
+ Reference<XCommandEnvironment> const & xCmdEnv )
+{
+ ::std::vector< Reference<deployment::XPackage> > packages;
+ ActivePackages::Entries id2temp( m_activePackagesDB->getEntries() );
+ ActivePackages::Entries::const_iterator iPos( id2temp.begin() );
+ ActivePackages::Entries::const_iterator const iEnd( id2temp.end() );
+ for ( ; iPos != iEnd; ++iPos )
+ {
+ if (! iPos->second.failedPrerequisites.equals(OUSTR("0")))
+ continue;
+ try {
+ packages.push_back(
+ getDeployedPackage_(
+ iPos->first, iPos->second, xCmdEnv,
+ true /* xxx todo: think of GUI:
+ ignore other platforms than the current one */ ) );
+ }
+ catch (lang::IllegalArgumentException & exc) {
+ // ignore
+ (void) exc; // avoid warnings
+ OSL_FAIL( ::rtl::OUStringToOString(
+ exc.Message, RTL_TEXTENCODING_UTF8 ).getStr() );
+ }
+ catch (deployment::DeploymentException& exc) {
+ // ignore
+ (void) exc; // avoid warnings
+ OSL_FAIL( ::rtl::OUStringToOString(
+ exc.Message, RTL_TEXTENCODING_UTF8 ).getStr() );
+ }
+ }
+ return comphelper::containerToSequence(packages);
+}
+
+//______________________________________________________________________________
+Reference<deployment::XPackage> PackageManagerImpl::getDeployedPackage(
+ OUString const & id, ::rtl::OUString const & fileName,
+ Reference<XCommandEnvironment> const & xCmdEnv_ )
+ throw (deployment::DeploymentException, CommandFailedException,
+ lang::IllegalArgumentException, RuntimeException)
+{
+ check();
+ Reference<XCommandEnvironment> xCmdEnv;
+ if (m_xLogFile.is())
+ xCmdEnv.set( new CmdEnvWrapperImpl( xCmdEnv_, m_xLogFile ) );
+ else
+ xCmdEnv.set( xCmdEnv_ );
+
+ try {
+ const ::osl::MutexGuard guard( getMutex() );
+ return getDeployedPackage_( id, fileName, xCmdEnv );
+ }
+ catch (RuntimeException &) {
+ throw;
+ }
+ catch (CommandFailedException & exc) {
+ logIntern( Any(exc) );
+ throw;
+ }
+ catch (lang::IllegalArgumentException & exc) {
+ logIntern( Any(exc) );
+ throw;
+ }
+ catch (deployment::DeploymentException & exc) {
+ logIntern( Any(exc) );
+ throw;
+ }
+ catch (Exception &) {
+ Any exc( ::cppu::getCaughtException() );
+ logIntern( exc );
+ throw deployment::DeploymentException(
+ // ought never occur...
+ OUSTR("error while accessing deployed package: ") + id,
+ static_cast<OWeakObject *>(this), exc );
+ }
+}
+
+//______________________________________________________________________________
+Sequence< Reference<deployment::XPackage> >
+PackageManagerImpl::getDeployedPackages(
+ Reference<task::XAbortChannel> const &,
+ Reference<XCommandEnvironment> const & xCmdEnv_ )
+ throw (deployment::DeploymentException, CommandFailedException,
+ CommandAbortedException, lang::IllegalArgumentException,
+ RuntimeException)
+{
+ check();
+ Reference<XCommandEnvironment> xCmdEnv;
+ if (m_xLogFile.is())
+ xCmdEnv.set( new CmdEnvWrapperImpl( xCmdEnv_, m_xLogFile ) );
+ else
+ xCmdEnv.set( xCmdEnv_ );
+
+ try {
+ const ::osl::MutexGuard guard( getMutex() );
+ return getDeployedPackages_( xCmdEnv );
+ }
+ catch (RuntimeException &) {
+ throw;
+ }
+ catch (CommandFailedException & exc) {
+ logIntern( Any(exc) );
+ throw;
+ }
+ catch (CommandAbortedException & exc) {
+ logIntern( Any(exc) );
+ throw;
+ }
+ catch (deployment::DeploymentException & exc) {
+ logIntern( Any(exc) );
+ throw;
+ }
+ catch (Exception &) {
+ Any exc( ::cppu::getCaughtException() );
+ logIntern( exc );
+ throw deployment::DeploymentException(
+ // ought never occur...
+ OUSTR("error while getting all deployed packages: ") + m_context,
+ static_cast<OWeakObject *>(this), exc );
+ }
+}
+
+//______________________________________________________________________________
+
+
+//ToDo: the function must not call registerPackage, do this in
+//XExtensionManager.reinstallDeployedExtensions
+void PackageManagerImpl::reinstallDeployedPackages(
+ Reference<task::XAbortChannel> const & /*xAbortChannel*/,
+ Reference<XCommandEnvironment> const & xCmdEnv_ )
+ throw (deployment::DeploymentException,
+ CommandFailedException, CommandAbortedException,
+ lang::IllegalArgumentException, RuntimeException)
+{
+ check();
+ if (office_is_running())
+ throw RuntimeException(
+ OUSTR("You must close any running Office process before "
+ "reinstalling packages!"), static_cast<OWeakObject *>(this) );
+
+ Reference<XCommandEnvironment> xCmdEnv;
+ if (m_xLogFile.is())
+ xCmdEnv.set( new CmdEnvWrapperImpl( xCmdEnv_, m_xLogFile ) );
+ else
+ xCmdEnv.set( xCmdEnv_ );
+
+ try {
+ ProgressLevel progress(
+ xCmdEnv, OUSTR("Reinstalling all deployed packages...") );
+
+ try_dispose( m_xRegistry );
+ m_xRegistry.clear();
+ if (m_registryCache.getLength() > 0)
+ erase_path( m_registryCache, xCmdEnv );
+ initRegistryBackends();
+ Reference<util::XUpdatable> xUpdatable( m_xRegistry, UNO_QUERY );
+ if (xUpdatable.is())
+ xUpdatable->update();
+
+ //registering is done by the ExtensionManager service.
+ }
+ catch (RuntimeException &) {
+ throw;
+ }
+ catch (CommandFailedException & exc) {
+ logIntern( Any(exc) );
+ throw;
+ }
+ catch (CommandAbortedException & exc) {
+ logIntern( Any(exc) );
+ throw;
+ }
+ catch (deployment::DeploymentException & exc) {
+ logIntern( Any(exc) );
+ throw;
+ }
+ catch (Exception &) {
+ Any exc( ::cppu::getCaughtException() );
+ logIntern( exc );
+ throw deployment::DeploymentException(
+ OUSTR("Error while reinstalling all previously deployed "
+ "packages of context ") + m_context,
+ static_cast<OWeakObject *>(this), exc );
+ }
+}
+
+
+::sal_Bool SAL_CALL PackageManagerImpl::isReadOnly( )
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ return m_readOnly;
+}
+bool PackageManagerImpl::synchronizeRemovedExtensions(
+ Reference<task::XAbortChannel> const & xAbortChannel,
+ Reference<css::ucb::XCommandEnvironment> const & xCmdEnv)
+{
+
+ //find all which are in the extension data base but which
+ //are removed already.
+ OSL_ASSERT(!m_context.equals(OUSTR("user")));
+ bool bModified = false;
+ ActivePackages::Entries id2temp( m_activePackagesDB->getEntries() );
+
+ typedef ActivePackages::Entries::const_iterator ITActive;
+ bool bShared = m_context.equals(OUSTR("shared"));
+
+ for (ITActive i = id2temp.begin(); i != id2temp.end(); ++i)
+ {
+ try
+ {
+ //Get the URL to the extensions folder, first make the url for the
+ //shared repository including the temporary name
+ OUString url = makeURL(m_activePackages, i->second.temporaryName);
+ if (bShared)
+ url = makeURLAppendSysPathSegment( url + OUSTR("_"), i->second.fileName);
+
+ bool bRemoved = false;
+ //Check if the URL to the extension is still the same
+ ::ucbhelper::Content contentExtension;
+
+ if (!create_ucb_content(
+ &contentExtension, url,
+ Reference<XCommandEnvironment>(), false))
+ {
+ bRemoved = true;
+ }
+
+ //The folder is in the extension database, but it can still be deleted.
+ //look for the xxx.tmpremoved file
+ //There can also be the case that a different extension was installed
+ //in a "temp" folder with name that is already used.
+ if (!bRemoved && bShared)
+ {
+ ::ucbhelper::Content contentRemoved;
+
+ if (create_ucb_content(
+ &contentRemoved,
+ m_activePackages_expanded + OUSTR("/") +
+ i->second.temporaryName + OUSTR("removed"),
+ Reference<XCommandEnvironment>(), false))
+ {
+ bRemoved = true;
+ }
+ }
+
+ if (!bRemoved)
+ {
+ //There may be another extensions at the same place
+ dp_misc::DescriptionInfoset infoset =
+ dp_misc::getDescriptionInfoset(url);
+ OSL_ENSURE(infoset.hasDescription() && infoset.getIdentifier(),
+ "Extension Manager: bundled and shared extensions "
+ "must have an identifer and a version");
+ if (infoset.hasDescription() &&
+ infoset.getIdentifier() &&
+ (! i->first.equals(*(infoset.getIdentifier()))
+ || ! i->second.version.equals(infoset.getVersion())))
+ {
+ bRemoved = true;
+ }
+
+ }
+ if (bRemoved)
+ {
+ Reference<deployment::XPackage> xPackage = m_xRegistry->bindPackage(
+ url, i->second.mediaType, true, i->first, xCmdEnv );
+ OSL_ASSERT(xPackage.is()); //Even if the files are removed, we must get the object.
+ xPackage->revokePackage(xAbortChannel, xCmdEnv);
+ removePackage(xPackage->getIdentifier().Value, xPackage->getName(),
+ xAbortChannel, xCmdEnv);
+ bModified |= true;
+ }
+ }
+ catch( uno::Exception & )
+ {
+ OSL_ASSERT(0);
+ }
+ }
+ return bModified;
+}
+
+
+bool PackageManagerImpl::synchronizeAddedExtensions(
+ Reference<task::XAbortChannel> const & xAbortChannel,
+ Reference<css::ucb::XCommandEnvironment> const & xCmdEnv)
+{
+ bool bModified = false;
+ OSL_ASSERT(!m_context.equals(OUSTR("user")));
+
+ ActivePackages::Entries id2temp( m_activePackagesDB->getEntries() );
+ //check if the folder exist at all. The shared extension folder
+ //may not exist for a normal user.
+ if (!create_ucb_content(
+ NULL, m_activePackages_expanded, Reference<css::ucb::XCommandEnvironment>(), false))
+ return bModified;
+ ::ucbhelper::Content tempFolder(
+ m_activePackages_expanded, xCmdEnv );
+
+ Reference<sdbc::XResultSet> xResultSet(
+ tempFolder.createCursor(
+ Sequence<OUString>( &StrTitle::get(), 1 ),
+ ::ucbhelper::INCLUDE_FOLDERS_ONLY ) );
+
+ while (xResultSet->next())
+ {
+ try
+ {
+ OUString title(
+ Reference<sdbc::XRow>(
+ xResultSet, UNO_QUERY_THROW )->getString(
+ 1 /* Title */ ) );
+ //The temporary folders of user and shared have an '_' at then end.
+ //But the name in ActivePackages.temporaryName is saved without.
+ OUString title2 = title;
+ bool bShared = m_context.equals(OUSTR("shared"));
+ if (bShared)
+ {
+ OSL_ASSERT(title2[title2.getLength() -1] == '_');
+ title2 = title2.copy(0, title2.getLength() -1);
+ }
+ OUString titleEncoded = ::rtl::Uri::encode(
+ title2, rtl_UriCharClassPchar,
+ rtl_UriEncodeIgnoreEscapes,
+ RTL_TEXTENCODING_UTF8);
+
+ //It it sufficient to check for the folder name, because when the administor
+ //installed the extension it was already checked if there is one with the
+ //same identifier.
+ const MatchTempDir match(titleEncoded);
+ if (::std::find_if( id2temp.begin(), id2temp.end(), match ) ==
+ id2temp.end())
+ {
+
+ // The folder was not found in the data base, so it must be
+ // an added extension
+ OUString url(m_activePackages_expanded + OUSTR("/") + titleEncoded);
+ OUString sExtFolder;
+ if (bShared) //that is, shared
+ {
+ //Check if the extension was not "deleted" already which is indicated
+ //by a xxx.tmpremoved file
+ ::ucbhelper::Content contentRemoved;
+ if (create_ucb_content(&contentRemoved, url + OUSTR("removed"),
+ Reference<XCommandEnvironment>(), false))
+ continue;
+ sExtFolder = getExtensionFolder(
+ m_activePackages_expanded +
+ OUString(OUSTR("/")) + titleEncoded + OUSTR("_"), xCmdEnv);
+ url = makeURLAppendSysPathSegment(m_activePackages_expanded, title);
+ url = makeURLAppendSysPathSegment(url, sExtFolder);
+ }
+ Reference<deployment::XPackage> xPackage = m_xRegistry->bindPackage(
+ url, OUString(), false, OUString(), xCmdEnv );
+ if (xPackage.is())
+ {
+ //Prepare the database entry
+ ActivePackages::Data dbData;
+
+ dbData.temporaryName = titleEncoded;
+ if (bShared)
+ dbData.fileName = sExtFolder;
+ else
+ dbData.fileName = title;
+ dbData.mediaType = xPackage->getPackageType()->getMediaType();
+ dbData.version = xPackage->getVersion();
+ OSL_ENSURE(dbData.version.getLength() > 0,
+ "Extension Manager: bundled and shared extensions must have "
+ "an identifier and a version");
+
+ OUString id = dp_misc::getIdentifier( xPackage );
+
+ //We provide a special command environment that will prevent
+ //showing a license if simple-licens/@accept-by = "admin"
+ //It will also prevent showing the license for bundled extensions
+ //which is not supported.
+ OSL_ASSERT(!m_context.equals(OUSTR("user")));
+
+ // shall the license be suppressed?
+ DescriptionInfoset info =
+ dp_misc::getDescriptionInfoset(url);
+ ::boost::optional<dp_misc::SimpleLicenseAttributes>
+ attr = info.getSimpleLicenseAttributes();
+ ExtensionProperties props(url,xCmdEnv);
+ bool bNoLicense = false;
+ if (attr && attr->suppressIfRequired && props.isSuppressedLicense())
+ bNoLicense = true;
+
+ Reference<ucb::XCommandEnvironment> licCmdEnv(
+ new LicenseCommandEnv(xCmdEnv->getInteractionHandler(),
+ bNoLicense, m_context));
+ sal_Int32 failedPrereq = xPackage->checkPrerequisites(
+ xAbortChannel, licCmdEnv, false);
+ //Remember that this failed. For example, the user
+ //could have declined the license. Then the next time the
+ //extension folder is investigated we do not want to
+ //try to install the extension again.
+ dbData.failedPrerequisites = OUString::valueOf(failedPrereq);
+ insertToActivationLayerDB(id, dbData);
+ bModified |= true;
+ }
+ }
+ }
+ catch (uno::Exception &)
+ {
+ OSL_ASSERT(0);
+ }
+ }
+ return bModified;
+}
+
+sal_Bool PackageManagerImpl::synchronize(
+ Reference<task::XAbortChannel> const & xAbortChannel,
+ Reference<css::ucb::XCommandEnvironment> const & xCmdEnv)
+ throw (css::deployment::DeploymentException,
+ css::ucb::CommandFailedException,
+ css::ucb::CommandAbortedException,
+ css::uno::RuntimeException)
+{
+ check();
+ bool bModified = false;
+ if (m_context.equals(OUSTR("user")))
+ return bModified;
+ bModified |=
+ synchronizeRemovedExtensions(xAbortChannel, xCmdEnv);
+ bModified |= synchronizeAddedExtensions(xAbortChannel, xCmdEnv);
+
+ return bModified;
+}
+
+Sequence< Reference<deployment::XPackage> > PackageManagerImpl::getExtensionsWithUnacceptedLicenses(
+ Reference<ucb::XCommandEnvironment> const & xCmdEnv)
+ throw (deployment::DeploymentException, RuntimeException)
+{
+ ::std::vector<Reference<deployment::XPackage> > vec;
+
+ try
+ {
+ const ::osl::MutexGuard guard( getMutex() );
+ // clean up activation layer, scan for zombie temp dirs:
+ ActivePackages::Entries id2temp( m_activePackagesDB->getEntries() );
+
+ ActivePackages::Entries::const_iterator i = id2temp.begin();
+ bool bShared = m_context.equals(OUSTR("shared"));
+
+ for (; i != id2temp.end(); ++i )
+ {
+ //Get the database entry
+ ActivePackages::Data const & dbData = i->second;
+ sal_Int32 failedPrereq = dbData.failedPrerequisites.toInt32();
+ //If the installation failed for other reason then the license then we
+ //ignore it.
+ if (failedPrereq ^= deployment::Prerequisites::LICENSE)
+ continue;
+
+ //Prepare the URL to the extension
+ OUString url = makeURL(m_activePackages, i->second.temporaryName);
+ if (bShared)
+ url = makeURLAppendSysPathSegment( url + OUSTR("_"), i->second.fileName);
+
+ Reference<deployment::XPackage> p = m_xRegistry->bindPackage(
+ url, OUString(), false, OUString(), xCmdEnv );
+
+ if (p.is())
+ vec.push_back(p);
+
+ }
+ return ::comphelper::containerToSequence(vec);
+ }
+ catch (deployment::DeploymentException &)
+ {
+ throw;
+ }
+ catch (RuntimeException&)
+ {
+ throw;
+ }
+ catch (...)
+ {
+ Any exc = ::cppu::getCaughtException();
+ deployment::DeploymentException de(
+ OUSTR("PackageManagerImpl::getExtensionsWithUnacceptedLicenses"),
+ static_cast<OWeakObject*>(this), exc);
+ exc <<= de;
+ ::cppu::throwException(exc);
+ }
+
+ return ::comphelper::containerToSequence(vec);
+}
+
+sal_Int32 PackageManagerImpl::checkPrerequisites(
+ css::uno::Reference<css::deployment::XPackage> const & extension,
+ css::uno::Reference<css::task::XAbortChannel> const & xAbortChannel,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv )
+ throw (css::deployment::DeploymentException,
+ css::ucb::CommandFailedException,
+ css::ucb::CommandAbortedException,
+ css::lang::IllegalArgumentException,
+ css::uno::RuntimeException)
+{
+ try
+ {
+ if (!extension.is())
+ return 0;
+ if (!m_context.equals(extension->getRepositoryName()))
+ throw lang::IllegalArgumentException(
+ OUSTR("PackageManagerImpl::checkPrerequisites: extension is not"
+ " from this repository."), 0, 0);
+
+ ActivePackages::Data dbData;
+ OUString id = dp_misc::getIdentifier(extension);
+ if (m_activePackagesDB->get( &dbData, id, OUString()))
+ {
+ //If the license was already displayed, then do not show it again
+ Reference<ucb::XCommandEnvironment> _xCmdEnv = xCmdEnv;
+ sal_Int32 prereq = dbData.failedPrerequisites.toInt32();
+ if ( !(prereq & deployment::Prerequisites::LICENSE))
+ _xCmdEnv = new NoLicenseCommandEnv(xCmdEnv->getInteractionHandler());
+
+ sal_Int32 failedPrereq = extension->checkPrerequisites(
+ xAbortChannel, _xCmdEnv, false);
+ dbData.failedPrerequisites = OUString::valueOf(failedPrereq);
+ insertToActivationLayerDB(id, dbData);
+ }
+ else
+ {
+ throw lang::IllegalArgumentException(
+ OUSTR("PackageManagerImpl::checkPrerequisites: unknown extension"),
+ 0, 0);
+
+ }
+ return 0;
+ }
+ catch (deployment::DeploymentException& ) {
+ throw;
+ } catch (ucb::CommandFailedException & ) {
+ throw;
+ } catch (ucb::CommandAbortedException & ) {
+ throw;
+ } catch (lang::IllegalArgumentException &) {
+ throw;
+ } catch (uno::RuntimeException &) {
+ throw;
+ } catch (...) {
+ uno::Any excOccurred = ::cppu::getCaughtException();
+ deployment::DeploymentException exc(
+ OUSTR("PackageManagerImpl::checkPrerequisites: exception "),
+ static_cast<OWeakObject*>(this), excOccurred);
+ throw exc;
+ }
+}
+
+
+//______________________________________________________________________________
+PackageManagerImpl::CmdEnvWrapperImpl::~CmdEnvWrapperImpl()
+{
+}
+
+//______________________________________________________________________________
+PackageManagerImpl::CmdEnvWrapperImpl::CmdEnvWrapperImpl(
+ Reference<XCommandEnvironment> const & xUserCmdEnv,
+ Reference<XProgressHandler> const & xLogFile )
+ : m_xLogFile( xLogFile )
+{
+ if (xUserCmdEnv.is()) {
+ m_xUserProgress.set( xUserCmdEnv->getProgressHandler() );
+ m_xUserInteractionHandler.set( xUserCmdEnv->getInteractionHandler() );
+ }
+}
+
+// XCommandEnvironment
+//______________________________________________________________________________
+Reference<task::XInteractionHandler>
+PackageManagerImpl::CmdEnvWrapperImpl::getInteractionHandler()
+ throw (RuntimeException)
+{
+ return m_xUserInteractionHandler;
+}
+
+//______________________________________________________________________________
+Reference<XProgressHandler>
+PackageManagerImpl::CmdEnvWrapperImpl::getProgressHandler()
+ throw (RuntimeException)
+{
+ return this;
+}
+
+// XProgressHandler
+//______________________________________________________________________________
+void PackageManagerImpl::CmdEnvWrapperImpl::push( Any const & Status )
+ throw (RuntimeException)
+{
+ if (m_xLogFile.is())
+ m_xLogFile->push( Status );
+ if (m_xUserProgress.is())
+ m_xUserProgress->push( Status );
+}
+
+//______________________________________________________________________________
+void PackageManagerImpl::CmdEnvWrapperImpl::update( Any const & Status )
+ throw (RuntimeException)
+{
+ if (m_xLogFile.is())
+ m_xLogFile->update( Status );
+ if (m_xUserProgress.is())
+ m_xUserProgress->update( Status );
+}
+
+//______________________________________________________________________________
+void PackageManagerImpl::CmdEnvWrapperImpl::pop() throw (RuntimeException)
+{
+ if (m_xLogFile.is())
+ m_xLogFile->pop();
+ if (m_xUserProgress.is())
+ m_xUserProgress->pop();
+}
+
+} // namespace dp_manager
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/manager/dp_manager.h b/desktop/source/deployment/manager/dp_manager.h
new file mode 100755
index 000000000000..3b335d7e2362
--- /dev/null
+++ b/desktop/source/deployment/manager/dp_manager.h
@@ -0,0 +1,296 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#if ! defined INCLUDED_DP_MANAGER_H
+#define INCLUDED_DP_MANAGER_H
+
+#include "dp_manager.hrc"
+#include "dp_misc.h"
+#include "dp_interact.h"
+#include "dp_activepackages.hxx"
+#include "rtl/ref.hxx"
+#include "cppuhelper/compbase1.hxx"
+#include "cppuhelper/implbase2.hxx"
+#include "ucbhelper/content.hxx"
+#include "com/sun/star/deployment/XPackageRegistry.hpp"
+#include "com/sun/star/deployment/XPackageManager.hpp"
+#include <memory>
+
+
+namespace css = ::com::sun::star;
+
+namespace dp_manager {
+
+typedef ::cppu::WeakComponentImplHelper1<
+ css::deployment::XPackageManager > t_pm_helper;
+
+//==============================================================================
+class PackageManagerImpl : private ::dp_misc::MutexHolder, public t_pm_helper
+{
+ css::uno::Reference<css::uno::XComponentContext> m_xComponentContext;
+ ::rtl::OUString m_context;
+ ::rtl::OUString m_registrationData;
+ ::rtl::OUString m_registrationData_expanded;
+ ::rtl::OUString m_registryCache;
+ bool m_readOnly;
+
+ ::rtl::OUString m_activePackages;
+ ::rtl::OUString m_activePackages_expanded;
+ ::std::auto_ptr< ActivePackages > m_activePackagesDB;
+ //This mutex is only used for synchronization in addPackage
+ ::osl::Mutex m_addMutex;
+ css::uno::Reference<css::ucb::XProgressHandler> m_xLogFile;
+ inline void logIntern( css::uno::Any const & status );
+ void fireModified();
+
+ css::uno::Reference<css::deployment::XPackageRegistry> m_xRegistry;
+
+ void initRegistryBackends();
+ void initActivationLayer(
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv );
+ ::rtl::OUString detectMediaType(
+ ::ucbhelper::Content const & ucbContent, bool throw_exc = true );
+ ::rtl::OUString insertToActivationLayer(
+ css::uno::Sequence<css::beans::NamedValue> const & properties,
+ ::rtl::OUString const & mediaType,
+ ::ucbhelper::Content const & sourceContent,
+ ::rtl::OUString const & title, ActivePackages::Data * dbData );
+ void insertToActivationLayerDB(
+ ::rtl::OUString const & id, ActivePackages::Data const & dbData );
+
+ void deletePackageFromCache(
+ css::uno::Reference<css::deployment::XPackage> const & xPackage,
+ ::rtl::OUString const & destFolder );
+
+ bool isInstalled(
+ css::uno::Reference<css::deployment::XPackage> const & package);
+
+ bool synchronizeRemovedExtensions(
+ css::uno::Reference<css::task::XAbortChannel> const & xAbortChannel,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv);
+
+ bool synchronizeAddedExtensions(
+ css::uno::Reference<css::task::XAbortChannel> const & xAbortChannel,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv);
+
+ class CmdEnvWrapperImpl
+ : public ::cppu::WeakImplHelper2< css::ucb::XCommandEnvironment,
+ css::ucb::XProgressHandler >
+ {
+ css::uno::Reference<css::ucb::XProgressHandler> m_xLogFile;
+ css::uno::Reference<css::ucb::XProgressHandler> m_xUserProgress;
+ css::uno::Reference<css::task::XInteractionHandler>
+ m_xUserInteractionHandler;
+
+ public:
+ virtual ~CmdEnvWrapperImpl();
+ CmdEnvWrapperImpl(
+ css::uno::Reference<css::ucb::XCommandEnvironment>
+ const & xUserCmdEnv,
+ css::uno::Reference<css::ucb::XProgressHandler> const & xLogFile );
+
+ // XCommandEnvironment
+ virtual css::uno::Reference<css::task::XInteractionHandler> SAL_CALL
+ getInteractionHandler() throw (css::uno::RuntimeException);
+ virtual css::uno::Reference<css::ucb::XProgressHandler> SAL_CALL
+ getProgressHandler() throw (css::uno::RuntimeException);
+
+ // XProgressHandler
+ virtual void SAL_CALL push( css::uno::Any const & Status )
+ throw (css::uno::RuntimeException);
+ virtual void SAL_CALL update( css::uno::Any const & Status )
+ throw (css::uno::RuntimeException);
+ virtual void SAL_CALL pop() throw (css::uno::RuntimeException);
+ };
+
+protected:
+ inline void check();
+ virtual void SAL_CALL disposing();
+
+ virtual ~PackageManagerImpl();
+ inline PackageManagerImpl(
+ css::uno::Reference<css::uno::XComponentContext>
+ const & xComponentContext, ::rtl::OUString const & context )
+ : t_pm_helper( getMutex() ),
+ m_xComponentContext( xComponentContext ),
+ m_context( context ),
+ m_readOnly( true )
+ {}
+
+public:
+ static css::uno::Reference<css::deployment::XPackageManager> create(
+ css::uno::Reference<css::uno::XComponentContext>
+ const & xComponentContext, ::rtl::OUString const & context );
+
+ // XComponent
+ virtual void SAL_CALL dispose() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL addEventListener(
+ css::uno::Reference<css::lang::XEventListener> const & xListener )
+ throw (css::uno::RuntimeException);
+ virtual void SAL_CALL removeEventListener(
+ css::uno::Reference<css::lang::XEventListener> const & xListener )
+ throw (css::uno::RuntimeException);
+
+ // XModifyBroadcaster
+ virtual void SAL_CALL addModifyListener(
+ css::uno::Reference<css::util::XModifyListener> const & xListener )
+ throw (css::uno::RuntimeException);
+ virtual void SAL_CALL removeModifyListener(
+ css::uno::Reference<css::util::XModifyListener> const & xListener )
+ throw (css::uno::RuntimeException);
+
+ // XPackageManager
+ virtual ::rtl::OUString SAL_CALL getContext()
+ throw (css::uno::RuntimeException);
+ virtual css::uno::Sequence<
+ css::uno::Reference<css::deployment::XPackageTypeInfo> > SAL_CALL
+ getSupportedPackageTypes() throw (css::uno::RuntimeException);
+
+ virtual css::uno::Reference<css::task::XAbortChannel> SAL_CALL
+ createAbortChannel() throw (css::uno::RuntimeException);
+
+ virtual css::uno::Reference<css::deployment::XPackage> SAL_CALL addPackage(
+ ::rtl::OUString const & url,
+ css::uno::Sequence<css::beans::NamedValue> const & properties,
+ ::rtl::OUString const & mediaType,
+ css::uno::Reference<css::task::XAbortChannel> const & xAbortChannel,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv )
+ throw (css::deployment::DeploymentException,
+ css::ucb::CommandFailedException,
+ css::ucb::CommandAbortedException,
+ css::lang::IllegalArgumentException,
+ css::uno::RuntimeException);
+
+ virtual css::uno::Reference<css::deployment::XPackage> SAL_CALL importExtension(
+ css::uno::Reference<css::deployment::XPackage> const & extension,
+ css::uno::Reference<css::task::XAbortChannel> const & xAbortChannel,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv )
+ throw (css::deployment::DeploymentException,
+ css::ucb::CommandFailedException,
+ css::ucb::CommandAbortedException,
+ css::lang::IllegalArgumentException,
+ css::uno::RuntimeException);
+
+ virtual void SAL_CALL removePackage(
+ ::rtl::OUString const & id, ::rtl::OUString const & fileName,
+ css::uno::Reference<css::task::XAbortChannel> const & xAbortChannel,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv )
+ throw (css::deployment::DeploymentException,
+ css::ucb::CommandFailedException,
+ css::ucb::CommandAbortedException,
+ css::lang::IllegalArgumentException,
+ css::uno::RuntimeException);
+
+ ::rtl::OUString getDeployPath( ActivePackages::Data const & data );
+ css::uno::Reference<css::deployment::XPackage> SAL_CALL getDeployedPackage_(
+ ::rtl::OUString const & id, ::rtl::OUString const & fileName,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv );
+ css::uno::Reference<css::deployment::XPackage> getDeployedPackage_(
+ ::rtl::OUString const & id, ActivePackages::Data const & data,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv,
+ bool ignoreAlienPlatforms = false );
+ virtual css::uno::Reference<css::deployment::XPackage> SAL_CALL
+ getDeployedPackage(
+ ::rtl::OUString const & id, ::rtl::OUString const & fileName,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv )
+ throw (css::deployment::DeploymentException,
+ css::ucb::CommandFailedException,
+ css::lang::IllegalArgumentException, css::uno::RuntimeException);
+
+ css::uno::Sequence< css::uno::Reference<css::deployment::XPackage> >
+ getDeployedPackages_(
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv );
+ virtual css::uno::Sequence< css::uno::Reference<css::deployment::XPackage> >
+ SAL_CALL getDeployedPackages(
+ css::uno::Reference<css::task::XAbortChannel> const & xAbortChannel,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv )
+ throw (css::deployment::DeploymentException,
+ css::ucb::CommandFailedException,
+ css::ucb::CommandAbortedException,
+ css::lang::IllegalArgumentException,
+ css::uno::RuntimeException);
+
+ virtual void SAL_CALL reinstallDeployedPackages(
+ css::uno::Reference<css::task::XAbortChannel> const & xAbortChannel,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv )
+ throw (css::deployment::DeploymentException,
+ css::ucb::CommandFailedException,
+ css::ucb::CommandAbortedException,
+ css::lang::IllegalArgumentException,
+ css::uno::RuntimeException);
+
+ virtual ::sal_Bool SAL_CALL isReadOnly( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual ::sal_Bool SAL_CALL synchronize(
+ css::uno::Reference<css::task::XAbortChannel> const & xAbortChannel,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv )
+ throw (css::deployment::DeploymentException,
+ css::ucb::CommandFailedException,
+ css::ucb::CommandAbortedException,
+ css::uno::RuntimeException);
+
+ virtual css::uno::Sequence<css::uno::Reference<css::deployment::XPackage> > SAL_CALL
+ getExtensionsWithUnacceptedLicenses(
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv)
+ throw (css::deployment::DeploymentException,
+ css::uno::RuntimeException);
+
+ virtual sal_Int32 SAL_CALL checkPrerequisites(
+ css::uno::Reference<css::deployment::XPackage> const & extension,
+ css::uno::Reference<css::task::XAbortChannel> const & xAbortChannel,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv )
+ throw (css::deployment::DeploymentException,
+ css::ucb::CommandFailedException,
+ css::ucb::CommandAbortedException,
+ css::lang::IllegalArgumentException,
+ css::uno::RuntimeException);
+ };
+
+//______________________________________________________________________________
+inline void PackageManagerImpl::check()
+{
+ ::osl::MutexGuard guard( getMutex() );
+ if (rBHelper.bInDispose || rBHelper.bDisposed)
+ throw css::lang::DisposedException(
+ OUSTR("PackageManager instance has already been disposed!"),
+ static_cast< ::cppu::OWeakObject * >(this) );
+}
+
+//______________________________________________________________________________
+inline void PackageManagerImpl::logIntern( css::uno::Any const & status )
+{
+ if (m_xLogFile.is())
+ m_xLogFile->update( status );
+}
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/manager/dp_manager.hrc b/desktop/source/deployment/manager/dp_manager.hrc
new file mode 100755
index 000000000000..6131cc381abf
--- /dev/null
+++ b/desktop/source/deployment/manager/dp_manager.hrc
@@ -0,0 +1,39 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#if ! defined INCLUDED_DP_MANAGER_HRC
+#define INCLUDED_DP_MANAGER_HRC
+
+#include "deployment.hrc"
+
+#define RID_STR_ERROR_WHILE_ADDING (RID_DEPLOYMENT_MANAGER_START+0)
+#define RID_STR_ERROR_WHILE_REMOVING (RID_DEPLOYMENT_MANAGER_START+1)
+#define RID_STR_PACKAGE_ALREADY_ADDED (RID_DEPLOYMENT_MANAGER_START+2)
+#define RID_STR_COPYING_PACKAGE (RID_DEPLOYMENT_MANAGER_START+3)
+#define RID_STR_NO_SUCH_PACKAGE (RID_DEPLOYMENT_MANAGER_START+4)
+#define RID_STR_SYNCHRONIZING_REPOSITORY (RID_DEPLOYMENT_MANAGER_START+5)
+#endif
diff --git a/desktop/source/deployment/manager/dp_manager.src b/desktop/source/deployment/manager/dp_manager.src
new file mode 100644
index 000000000000..7d38b880c37a
--- /dev/null
+++ b/desktop/source/deployment/manager/dp_manager.src
@@ -0,0 +1,59 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "dp_manager.hrc"
+
+
+String RID_STR_COPYING_PACKAGE
+{
+ Text [ en-US ] = "Copying: ";
+};
+
+String RID_STR_ERROR_WHILE_ADDING
+{
+ Text [ en-US ] = "Error while adding: ";
+};
+
+String RID_STR_ERROR_WHILE_REMOVING
+{
+ Text [ en-US ] = "Error while removing: ";
+};
+
+String RID_STR_PACKAGE_ALREADY_ADDED
+{
+ Text [ en-US ] = "Extension has already been added: ";
+};
+
+String RID_STR_NO_SUCH_PACKAGE
+{
+ Text [ en-US ] = "There is no such extension deployed: ";
+};
+
+String RID_STR_SYNCHRONIZING_REPOSITORY
+{
+ Text [ en-US ] = "Synchronizing repository for %NAME extensions";
+};
diff --git a/desktop/source/deployment/manager/dp_managerfac.cxx b/desktop/source/deployment/manager/dp_managerfac.cxx
new file mode 100644
index 000000000000..d84abbf0f926
--- /dev/null
+++ b/desktop/source/deployment/manager/dp_managerfac.cxx
@@ -0,0 +1,202 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include "dp_manager.h"
+#include "dp_resource.h"
+#include "cppuhelper/compbase1.hxx"
+#include "comphelper/servicedecl.hxx"
+#include "com/sun/star/deployment/thePackageManagerFactory.hpp"
+
+
+using namespace ::dp_misc;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using ::rtl::OUString;
+
+namespace dp_manager {
+namespace factory {
+
+typedef ::cppu::WeakComponentImplHelper1<
+ deployment::XPackageManagerFactory > t_pmfac_helper;
+
+//==============================================================================
+class PackageManagerFactoryImpl : private MutexHolder, public t_pmfac_helper
+{
+ Reference<XComponentContext> m_xComponentContext;
+
+ Reference<deployment::XPackageManager> m_xUserMgr;
+ Reference<deployment::XPackageManager> m_xSharedMgr;
+ Reference<deployment::XPackageManager> m_xBundledMgr;
+ typedef ::boost::unordered_map<
+ OUString, WeakReference<deployment::XPackageManager>,
+ ::rtl::OUStringHash > t_string2weakref;
+ t_string2weakref m_managers;
+
+protected:
+ inline void check();
+ virtual void SAL_CALL disposing();
+
+public:
+ virtual ~PackageManagerFactoryImpl();
+ PackageManagerFactoryImpl(
+ Reference<XComponentContext> const & xComponentContext );
+
+ // XPackageManagerFactory
+ virtual Reference<deployment::XPackageManager> SAL_CALL getPackageManager(
+ OUString const & context ) throw (RuntimeException);
+};
+
+//==============================================================================
+namespace sdecl = comphelper::service_decl;
+sdecl::class_<PackageManagerFactoryImpl> servicePMFI;
+extern sdecl::ServiceDecl const serviceDecl(
+ servicePMFI,
+ // a private one:
+ "com.sun.star.comp.deployment.PackageManagerFactory",
+ "com.sun.star.comp.deployment.PackageManagerFactory" );
+
+//==============================================================================
+bool singleton_entries(
+ Reference<registry::XRegistryKey> const & xRegistryKey )
+{
+ try {
+ Reference<registry::XRegistryKey> xKey(
+ xRegistryKey->createKey(
+ serviceDecl.getImplementationName() +
+ // xxx todo: use future generated function to get singleton name
+ OUSTR("/UNO/SINGLETONS/"
+ "com.sun.star.deployment.thePackageManagerFactory") ) );
+ xKey->setStringValue( serviceDecl.getSupportedServiceNames()[0] );
+ return true;
+ }
+ catch (registry::InvalidRegistryException & exc) {
+ (void) exc; // avoid warnings
+ OSL_FAIL( ::rtl::OUStringToOString(
+ exc.Message, RTL_TEXTENCODING_UTF8 ).getStr() );
+ return false;
+ }
+}
+
+//______________________________________________________________________________
+PackageManagerFactoryImpl::PackageManagerFactoryImpl(
+ Reference<XComponentContext> const & xComponentContext )
+ : t_pmfac_helper( getMutex() ),
+ m_xComponentContext( xComponentContext )
+{
+}
+
+//______________________________________________________________________________
+PackageManagerFactoryImpl::~PackageManagerFactoryImpl()
+{
+}
+
+//______________________________________________________________________________
+inline void PackageManagerFactoryImpl::check()
+{
+ ::osl::MutexGuard guard( getMutex() );
+ if (rBHelper.bInDispose || rBHelper.bDisposed)
+ {
+ throw lang::DisposedException(
+ OUSTR("PackageManagerFactory instance has already been disposed!"),
+ static_cast<OWeakObject *>(this) );
+ }
+}
+
+//______________________________________________________________________________
+void PackageManagerFactoryImpl::disposing()
+{
+ // dispose all managers:
+ ::osl::MutexGuard guard( getMutex() );
+ t_string2weakref::const_iterator iPos( m_managers.begin() );
+ t_string2weakref::const_iterator const iEnd( m_managers.end() );
+ for ( ; iPos != iEnd; ++iPos )
+ try_dispose( iPos->second );
+ m_managers = t_string2weakref();
+ // the below are already disposed:
+ m_xUserMgr.clear();
+ m_xSharedMgr.clear();
+ m_xBundledMgr.clear();
+}
+
+// XPackageManagerFactory
+//______________________________________________________________________________
+Reference<deployment::XPackageManager>
+PackageManagerFactoryImpl::getPackageManager( OUString const & context )
+ throw (RuntimeException)
+{
+ Reference< deployment::XPackageManager > xRet;
+ ::osl::ResettableMutexGuard guard( getMutex() );
+ check();
+ t_string2weakref::const_iterator const iFind( m_managers.find( context ) );
+ if (iFind != m_managers.end()) {
+ xRet = iFind->second;
+ if (xRet.is())
+ return xRet;
+ }
+
+ guard.clear();
+ xRet.set( PackageManagerImpl::create( m_xComponentContext, context ) );
+ guard.reset();
+ ::std::pair< t_string2weakref::iterator, bool > insertion(
+ m_managers.insert( t_string2weakref::value_type( context, xRet ) ) );
+ if (insertion.second)
+ {
+ OSL_ASSERT( insertion.first->second.get() == xRet );
+ // hold user, shared mgrs for whole process: live deployment
+ if (context.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("user") ))
+ m_xUserMgr = xRet;
+ else if (context.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("shared") ))
+ m_xSharedMgr = xRet;
+ else if (context.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("bundled") ))
+ m_xBundledMgr = xRet;
+ }
+ else
+ {
+ Reference< deployment::XPackageManager > xAlreadyIn(
+ insertion.first->second );
+ if (xAlreadyIn.is())
+ {
+ guard.clear();
+ try_dispose( xRet );
+ xRet = xAlreadyIn;
+ }
+ else
+ {
+ insertion.first->second = xRet;
+ }
+ }
+ return xRet;
+}
+
+} // namespace factory
+} // namespace dp_manager
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/manager/dp_properties.cxx b/desktop/source/deployment/manager/dp_properties.cxx
new file mode 100644
index 000000000000..a2a568287f16
--- /dev/null
+++ b/desktop/source/deployment/manager/dp_properties.cxx
@@ -0,0 +1,171 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include "com/sun/star/ucb/XCommandEnvironment.hpp"
+#include "com/sun/star/lang/IllegalArgumentException.hpp"
+#include "xmlscript/xml_helper.hxx"
+#include "ucbhelper/content.hxx"
+#include <list>
+
+#include "dp_ucb.h"
+#include "rtl/ustrbuf.hxx"
+#include "dp_properties.hxx"
+
+namespace lang = com::sun::star::lang;
+namespace task = com::sun::star::task;
+namespace ucb = com::sun::star::ucb;
+namespace uno = com::sun::star::uno;
+namespace css = com::sun::star;
+
+#define OUSTR(s) rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(s))
+
+using ::com::sun::star::uno::Reference;
+using ::rtl::OUString;
+
+#define PROP_SUPPRESS_LICENSE "SUPPRESS_LICENSE"
+#define PROP_EXTENSION_UPDATE "EXTENSION_UPDATE"
+
+namespace dp_manager {
+
+//Reading the file
+ExtensionProperties::ExtensionProperties(
+ OUString const & urlExtension,
+ Reference<ucb::XCommandEnvironment> const & xCmdEnv) :
+ m_xCmdEnv(xCmdEnv)
+{
+ m_propFileUrl = urlExtension + OUSTR("properties");
+
+ ::std::list< ::std::pair< OUString, OUString> > props;
+ if (! dp_misc::create_ucb_content(NULL, m_propFileUrl, 0, false))
+ return;
+
+ ::ucbhelper::Content contentProps(m_propFileUrl, m_xCmdEnv);
+ dp_misc::readProperties(props, contentProps);
+
+ typedef ::std::list< ::std::pair< OUString, OUString> >::const_iterator CI;
+ for (CI i = props.begin(); i != props.end(); i++)
+ {
+ if (i->first.equals(OUSTR(PROP_SUPPRESS_LICENSE)))
+ m_prop_suppress_license = i->second;
+ }
+}
+
+//Writing the file
+ExtensionProperties::ExtensionProperties(
+ OUString const & urlExtension,
+ uno::Sequence<css::beans::NamedValue> const & properties,
+ Reference<ucb::XCommandEnvironment> const & xCmdEnv) :
+ m_xCmdEnv(xCmdEnv)
+{
+ m_propFileUrl = urlExtension + OUSTR("properties");
+
+ for (sal_Int32 i = 0; i < properties.getLength(); i++)
+ {
+ css::beans::NamedValue const & v = properties[i];
+ if (v.Name.equals(OUSTR(PROP_SUPPRESS_LICENSE)))
+ {
+ m_prop_suppress_license = getPropertyValue(v);
+ }
+ else if (v.Name.equals(OUSTR(PROP_EXTENSION_UPDATE)))
+ {
+ m_prop_extension_update = getPropertyValue(v);
+ }
+ else
+ {
+ throw lang::IllegalArgumentException(
+ OUSTR("Extension Manager: unknown property"), 0, -1);
+ }
+ }
+}
+
+OUString ExtensionProperties::getPropertyValue(css::beans::NamedValue const & v)
+{
+ OUString value(OUSTR("0"));
+ if (v.Value >>= value)
+ {
+ if (value.equals(OUSTR("1")))
+ value = OUSTR("1");
+ }
+ else
+ {
+ throw lang::IllegalArgumentException(
+ OUSTR("Extension Manager: wrong property value"), 0, -1);
+ }
+ return value;
+}
+void ExtensionProperties::write()
+{
+ ::ucbhelper::Content contentProps(m_propFileUrl, m_xCmdEnv);
+ ::rtl::OUStringBuffer buf;
+
+ if (m_prop_suppress_license)
+ {
+ buf.append(OUSTR(PROP_SUPPRESS_LICENSE));
+ buf.append(OUSTR("="));
+ buf.append(*m_prop_suppress_license);
+ }
+
+ ::rtl::OString stamp = ::rtl::OUStringToOString(
+ buf.makeStringAndClear(), RTL_TEXTENCODING_UTF8);
+ Reference<css::io::XInputStream> xData(
+ ::xmlscript::createInputStream(
+ ::rtl::ByteSequence(
+ reinterpret_cast<sal_Int8 const *>(stamp.getStr()),
+ stamp.getLength() ) ) );
+ contentProps.writeStream( xData, true /* replace existing */ );
+}
+
+bool ExtensionProperties::isSuppressedLicense()
+{
+ bool ret = false;
+ if (m_prop_suppress_license)
+ {
+ if (m_prop_suppress_license->equals(OUSTR("1")))
+ ret = true;
+ }
+ return ret;
+}
+
+bool ExtensionProperties::isExtensionUpdate()
+{
+ bool ret = false;
+ if (m_prop_extension_update)
+ {
+ if (m_prop_extension_update->equals(OUSTR("1")))
+ ret = true;
+ }
+ return ret;
+}
+
+} // namespace dp_manager
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/manager/dp_properties.hxx b/desktop/source/deployment/manager/dp_properties.hxx
new file mode 100644
index 000000000000..103227f29226
--- /dev/null
+++ b/desktop/source/deployment/manager/dp_properties.hxx
@@ -0,0 +1,80 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#if ! defined INCLUDED_DP_PROPERTIES_HXX
+#define INCLUDED_DP_PROPERTIES_HXX
+
+
+
+#include "com/sun/star/beans/NamedValue.hpp"
+#include "com/sun/star/ucb/XCommandEnvironment.hpp"
+#include "boost/optional.hpp"
+
+
+namespace css = ::com::sun::star;
+
+namespace dp_manager {
+
+
+
+/**
+
+ */
+class ExtensionProperties
+{
+protected:
+ ::rtl::OUString m_propFileUrl;
+ const css::uno::Reference<css::ucb::XCommandEnvironment> m_xCmdEnv;
+ ::boost::optional< ::rtl::OUString> m_prop_suppress_license;
+ ::boost::optional< ::rtl::OUString> m_prop_extension_update;
+
+ ::rtl::OUString getPropertyValue(css::beans::NamedValue const & v);
+public:
+
+ virtual ~ExtensionProperties() {};
+ ExtensionProperties(::rtl::OUString const & urlExtension,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv);
+
+ ExtensionProperties(::rtl::OUString const & urlExtension,
+ css::uno::Sequence<css::beans::NamedValue> const & properties,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv);
+
+ void write();
+
+ bool isSuppressedLicense();
+
+ bool isExtensionUpdate();
+};
+}
+
+
+
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/manager/makefile.mk b/desktop/source/deployment/manager/makefile.mk
new file mode 100755
index 000000000000..4dc6405e34bf
--- /dev/null
+++ b/desktop/source/deployment/manager/makefile.mk
@@ -0,0 +1,55 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ = ..$/..$/..
+
+PRJNAME = desktop
+TARGET = deployment_manager
+ENABLE_EXCEPTIONS = TRUE
+
+.INCLUDE : settings.mk
+
+.IF "$(SYSTEM_DB)" == "YES"
+CFLAGS+=-DSYSTEM_DB -I$(DB_INCLUDES)
+.ENDIF
+
+SRS1NAME = $(TARGET)
+SRC1FILES = \
+ dp_manager.src
+
+SLOFILES = \
+ $(SLO)$/dp_activepackages.obj \
+ $(SLO)$/dp_manager.obj \
+ $(SLO)$/dp_managerfac.obj \
+ $(SLO)$/dp_informationprovider.obj \
+ $(SLO)$/dp_extensionmanager.obj \
+ $(SLO)$/dp_commandenvironments.obj \
+ $(SLO)$/dp_properties.obj
+
+.INCLUDE : ..$/target.pmk
+.INCLUDE : target.mk
+
diff --git a/desktop/source/deployment/misc/db.cxx b/desktop/source/deployment/misc/db.cxx
new file mode 100644
index 000000000000..909f12f79e18
--- /dev/null
+++ b/desktop/source/deployment/misc/db.cxx
@@ -0,0 +1,273 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include <db.hxx>
+
+#include <rtl/alloc.h>
+#include <cstring>
+#include <errno.h>
+
+namespace berkeleydbproxy {
+
+//----------------------------------------------------------------------------
+ namespace db_internal
+ {
+ static void raise_error(int dberr, const char * where);
+
+ static inline int check_error(int dberr, const char * where)
+ {
+ if (dberr) raise_error(dberr,where);
+ return dberr;
+ }
+ }
+
+//----------------------------------------------------------------------------
+
+char *DbEnv::strerror(int error) {
+ return (db_strerror(error));
+}
+
+//----------------------------------------------------------------------------
+
+Db::Db(DbEnv* pDbenv,u_int32_t flags)
+: m_pDBP(0)
+{
+ db_internal::check_error( db_create(&m_pDBP,pDbenv ? pDbenv->m_pDBENV:0,flags),"Db::Db" );
+}
+
+
+Db::~Db()
+{
+ if (m_pDBP)
+ {
+ // should not happen
+ // TODO: add assert
+ }
+
+}
+
+
+int Db::close(u_int32_t flags)
+{
+ int error = m_pDBP->close(m_pDBP,flags);
+ m_pDBP = 0;
+ return db_internal::check_error(error,"Db::close");
+}
+
+int Db::open(DB_TXN *txnid,
+ const char *file,
+ const char *database,
+ DBTYPE type,
+ u_int32_t flags,
+ int mode)
+{
+ int err = m_pDBP->open(m_pDBP,txnid,file,database,type,flags,mode);
+ return db_internal::check_error( err,"Db::open" );
+}
+
+
+int Db::get(DB_TXN *txnid, Dbt *key, Dbt *data, u_int32_t flags)
+{
+ int err = m_pDBP->get(m_pDBP,txnid,key,data,flags);
+
+ // these are non-exceptional outcomes
+ if (err != DB_NOTFOUND && err != DB_KEYEMPTY)
+ db_internal::check_error( err,"Db::get" );
+
+ return err;
+}
+
+int Db::put(DB_TXN* txnid, Dbt *key, Dbt *data, u_int32_t flags)
+{
+ int err = m_pDBP->put(m_pDBP,txnid,key,data,flags);
+
+ if (err != DB_KEYEXIST) // this is a non-exceptional outcome
+ db_internal::check_error( err,"Db::put" );
+ return err;
+}
+
+int Db::cursor(DB_TXN *txnid, Dbc **cursorp, u_int32_t flags)
+{
+ DBC * dbc = 0;
+ int error = m_pDBP->cursor(m_pDBP,txnid,&dbc,flags);
+
+ if (!db_internal::check_error(error,"Db::cursor"))
+ *cursorp = new Dbc(dbc);
+
+ return error;
+}
+
+
+#define DB_INCOMPLETE (-30999)/* Sync didn't finish. */
+
+int Db::sync(u_int32_t flags)
+{
+ int err;
+ DB *db = m_pDBP;
+
+ if (!db) {
+ db_internal::check_error(EINVAL,"Db::sync");
+ return (EINVAL);
+ }
+ if ((err = db->sync(db, flags)) != 0 && err != DB_INCOMPLETE) {
+ db_internal::check_error(err, "Db::sync");
+ return (err);
+ }
+ return (err);
+}
+
+int Db::del(Dbt *key, u_int32_t flags)
+{
+ DB *db = m_pDBP;
+ int err;
+
+ if ((err = db->del(db, 0, key, flags)) != 0) {
+ // DB_NOTFOUND is a "normal" return, so should not be
+ // thrown as an error
+ if (err != DB_NOTFOUND) {
+ db_internal::check_error(err, "Db::del");
+ return (err);
+ }
+ }
+ return (err);
+}
+
+//----------------------------------------------------------------------------
+
+Dbc::Dbc(DBC * dbc)
+: m_pDBC(dbc)
+{
+}
+
+Dbc::~Dbc()
+{
+}
+
+int Dbc::close()
+{
+ int err = m_pDBC->c_close(m_pDBC);
+ delete this;
+ return db_internal::check_error( err,"Dbcursor::close" );
+}
+
+int Dbc::get(Dbt *key, Dbt *data, u_int32_t flags)
+{
+ int err = m_pDBC->c_get(m_pDBC,key,data,flags);
+
+ // these are non-exceptional outcomes
+ if (err != DB_NOTFOUND && err != DB_KEYEMPTY)
+ db_internal::check_error( err, "Dbcursor::get" );
+
+ return err;
+}
+
+//----------------------------------------------------------------------------
+
+Dbt::Dbt()
+{
+ using namespace std;
+ DBT * thispod = this;
+ memset(thispod, 0, sizeof *thispod);
+}
+
+
+Dbt::Dbt(void *data_arg, u_int32_t size_arg)
+{
+ using namespace std;
+ DBT * thispod = this;
+ memset(thispod, 0, sizeof *thispod);
+ this->set_data(data_arg);
+ this->set_size(size_arg);
+}
+
+Dbt::Dbt(const Dbt & other)
+{
+ using namespace std;
+ const DBT *otherpod = &other;
+ DBT *thispod = this;
+ memcpy(thispod, otherpod, sizeof *thispod);
+}
+
+Dbt& Dbt::operator = (const Dbt & other)
+{
+ if (this != &other)
+ {
+ using namespace std;
+ const DBT *otherpod = &other;
+ DBT *thispod = this;
+ memcpy(thispod, otherpod, sizeof *thispod);
+ }
+ return *this;
+}
+
+Dbt::~Dbt()
+{
+}
+
+void * Dbt::get_data() const
+{
+ return this->data;
+}
+
+void Dbt::set_data(void *value)
+{
+ this->data = value;
+}
+
+u_int32_t Dbt::get_size() const
+{
+ return this->size;
+}
+
+void Dbt::set_size(u_int32_t value)
+{
+ this->size = value;
+}
+
+//----------------------------------------------------------------------------
+void db_internal::raise_error(int dberr, const char * where)
+{
+ if (!where) where = "<unknown>";
+
+ const char * dberrmsg = db_strerror(dberr);
+ if (!dberrmsg || !*dberrmsg) dberrmsg = "<unknown DB error>";
+
+ rtl::OString msg = where;
+ msg += ": ";
+ msg += dberrmsg;
+
+ throw DbException(msg);
+}
+
+//----------------------------------------------------------------------------
+} // namespace ecomp
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/misc/dp_dependencies.cxx b/desktop/source/deployment/misc/dp_dependencies.cxx
new file mode 100644
index 000000000000..6b937547ae93
--- /dev/null
+++ b/desktop/source/deployment/misc/dp_dependencies.cxx
@@ -0,0 +1,180 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include "sal/config.h"
+
+#include "com/sun/star/uno/Reference.hxx"
+#include "com/sun/star/uno/Sequence.hxx"
+#include "com/sun/star/xml/dom/XElement.hpp"
+#include "com/sun/star/xml/dom/XNode.hpp"
+#include "com/sun/star/xml/dom/XNodeList.hpp"
+#include "rtl/bootstrap.hxx"
+#include "rtl/string.h"
+#include "rtl/ustring.h"
+#include "rtl/ustring.hxx"
+#include "sal/types.h"
+#include "tools/string.hxx"
+
+#include "deployment.hrc"
+#include "dp_resource.h"
+
+#include "dp_dependencies.hxx"
+#include "dp_descriptioninfoset.hxx"
+#include "dp_version.hxx"
+
+namespace {
+
+namespace css = ::com::sun::star;
+
+static char const xmlNamespace[] =
+ "http://openoffice.org/extensions/description/2006";
+
+bool
+lcl_versionIsNot(dp_misc::Order i_eOrder, ::rtl::OUString const& i_rVersion)
+{
+ ::rtl::OUString aVersion(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "${$OOO_BASE_DIR/program/" SAL_CONFIGFILE("version")
+ ":Version:OOOPackageVersion}"));
+ ::rtl::Bootstrap::expandMacros(aVersion);
+ return ::dp_misc::compareVersions(aVersion, i_rVersion) != i_eOrder;
+}
+
+bool satisfiesMinimalVersion(::rtl::OUString const& i_rVersion)
+{
+ return lcl_versionIsNot(dp_misc::LESS, i_rVersion);
+}
+
+bool satisfiesMaximalVersion(::rtl::OUString const& i_rVersion)
+{
+ return lcl_versionIsNot(dp_misc::GREATER, i_rVersion);
+}
+
+}
+
+namespace dp_misc {
+
+namespace Dependencies {
+
+css::uno::Sequence< css::uno::Reference< css::xml::dom::XElement > >
+check(::dp_misc::DescriptionInfoset const & infoset) {
+ css::uno::Reference< css::xml::dom::XNodeList > deps(
+ infoset.getDependencies());
+ ::sal_Int32 n = deps->getLength();
+ css::uno::Sequence< css::uno::Reference< css::xml::dom::XElement > >
+ unsatisfied(n);
+ ::sal_Int32 unsat = 0;
+ for (::sal_Int32 i = 0; i < n; ++i) {
+ static rtl::OUString const minimalVersion(
+ RTL_CONSTASCII_USTRINGPARAM("OpenOffice.org-minimal-version"));
+ css::uno::Reference< css::xml::dom::XElement > e(
+ deps->item(i), css::uno::UNO_QUERY_THROW);
+ bool sat = false;
+ if (e->getNamespaceURI().equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM(xmlNamespace))
+ && (e->getTagName() == minimalVersion))
+ {
+ sat = satisfiesMinimalVersion(
+ e->getAttribute(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("value"))));
+ } else if (e->getNamespaceURI().equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM(xmlNamespace))
+ && e->getTagName().equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM(
+ "OpenOffice.org-maximal-version")))
+ {
+ sat = satisfiesMaximalVersion(
+ e->getAttribute(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("value"))));
+ } else if (e->hasAttributeNS(
+ ::rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(xmlNamespace)),
+ minimalVersion))
+ {
+ sat = satisfiesMinimalVersion(
+ e->getAttributeNS(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(xmlNamespace)),
+ minimalVersion));
+ }
+ if (!sat) {
+ unsatisfied[unsat++] = e;
+ }
+ }
+ unsatisfied.realloc(unsat);
+ return unsatisfied;
+}
+
+::rtl::OUString getErrorText( css::uno::Reference< css::xml::dom::XElement > const & dependency )
+{
+ ::rtl::OUString sReason;
+ ::rtl::OUString sValue;
+ ::rtl::OUString sVersion(RTL_CONSTASCII_USTRINGPARAM("%VERSION"));
+ ::rtl::OUString sProductName(RTL_CONSTASCII_USTRINGPARAM("%PRODUCTNAME"));
+
+ if ( dependency->getNamespaceURI().equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( xmlNamespace ) )
+ && dependency->getTagName().equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "OpenOffice.org-minimal-version" ) ) )
+ {
+ sValue = dependency->getAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "value" ) ) );
+ sReason = ::rtl::OUString( ::String(::dp_misc::getResId(RID_DEPLYOMENT_DEPENDENCIES_MIN)) );
+ }
+ else if ( dependency->getNamespaceURI().equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( xmlNamespace ) )
+ && dependency->getTagName().equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "OpenOffice.org-maximal-version" ) ) )
+ {
+ sValue = dependency->getAttribute( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("value") ) );
+ sReason = ::rtl::OUString( ::String(::dp_misc::getResId(RID_DEPLYOMENT_DEPENDENCIES_MAX)) );
+ }
+ else if ( dependency->hasAttributeNS( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( xmlNamespace ) ),
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "OpenOffice.org-minimal-version" ))))
+ {
+ sValue = dependency->getAttributeNS( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( xmlNamespace ) ),
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "OpenOffice.org-minimal-version" ) ) );
+ sReason = ::rtl::OUString( ::String(::dp_misc::getResId(RID_DEPLYOMENT_DEPENDENCIES_MIN)) );
+ }
+ else
+ return ::rtl::OUString( ::String(::dp_misc::getResId(RID_DEPLYOMENT_DEPENDENCIES_UNKNOWN)) );
+
+ if ( sValue.getLength() == 0 )
+ sValue = ::rtl::OUString( ::String(::dp_misc::getResId(RID_DEPLYOMENT_DEPENDENCIES_UNKNOWN)) );
+
+ sal_Int32 nPos = sReason.indexOf( sVersion );
+ if ( nPos >= 0 )
+ sReason = sReason.replaceAt( nPos, sVersion.getLength(), sValue );
+ nPos = sReason.indexOf( sProductName );
+ if ( nPos >= 0 )
+ sReason = sReason.replaceAt( nPos, sProductName.getLength(), BrandName::get() );
+ return sReason;
+}
+
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/misc/dp_descriptioninfoset.cxx b/desktop/source/deployment/misc/dp_descriptioninfoset.cxx
new file mode 100644
index 000000000000..3c6d21fe6dc6
--- /dev/null
+++ b/desktop/source/deployment/misc/dp_descriptioninfoset.cxx
@@ -0,0 +1,866 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include "dp_descriptioninfoset.hxx"
+
+#include "dp_resource.h"
+#include "sal/config.h"
+
+#include "comphelper/sequence.hxx"
+#include "comphelper/makesequence.hxx"
+#include "comphelper/processfactory.hxx"
+#include "boost/optional.hpp"
+#include "com/sun/star/beans/Optional.hpp"
+#include "com/sun/star/lang/XMultiComponentFactory.hpp"
+#include "com/sun/star/lang/Locale.hpp"
+#include "com/sun/star/uno/Reference.hxx"
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include "com/sun/star/uno/Sequence.hxx"
+#include "com/sun/star/uno/XComponentContext.hpp"
+#include "com/sun/star/uno/XInterface.hpp"
+#include "com/sun/star/xml/dom/DOMException.hpp"
+#include "com/sun/star/xml/dom/XNode.hpp"
+#include "com/sun/star/xml/dom/XNodeList.hpp"
+#include "com/sun/star/xml/dom/XDocumentBuilder.hpp"
+#include "com/sun/star/xml/xpath/XXPathAPI.hpp"
+#include "com/sun/star/ucb/InteractiveAugmentedIOException.hpp"
+#include "cppuhelper/implbase1.hxx"
+#include "cppuhelper/implbase2.hxx"
+#include "cppuhelper/weak.hxx"
+#include "cppuhelper/exc_hlp.hxx"
+#include "rtl/ustring.h"
+#include "rtl/ustring.hxx"
+#include "sal/types.h"
+#include "ucbhelper/content.hxx"
+
+namespace {
+
+namespace css = ::com::sun::star;
+using css::uno::Reference;
+using ::rtl::OUString;
+
+class EmptyNodeList: public ::cppu::WeakImplHelper1< css::xml::dom::XNodeList >
+{
+public:
+ EmptyNodeList();
+
+ virtual ~EmptyNodeList();
+
+ virtual ::sal_Int32 SAL_CALL getLength() throw (css::uno::RuntimeException);
+
+ virtual css::uno::Reference< css::xml::dom::XNode > SAL_CALL
+ item(::sal_Int32 index) throw (css::uno::RuntimeException);
+
+private:
+ EmptyNodeList(EmptyNodeList &); // not defined
+ void operator =(EmptyNodeList &); // not defined
+};
+
+EmptyNodeList::EmptyNodeList() {}
+
+EmptyNodeList::~EmptyNodeList() {}
+
+::sal_Int32 EmptyNodeList::getLength() throw (css::uno::RuntimeException) {
+ return 0;
+}
+
+css::uno::Reference< css::xml::dom::XNode > EmptyNodeList::item(::sal_Int32)
+ throw (css::uno::RuntimeException)
+{
+ throw css::uno::RuntimeException(
+ ::rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "bad EmptyNodeList com.sun.star.xml.dom.XNodeList.item call")),
+ static_cast< ::cppu::OWeakObject * >(this));
+}
+
+::rtl::OUString getNodeValue(
+ css::uno::Reference< css::xml::dom::XNode > const & node)
+{
+ OSL_ASSERT(node.is());
+ try {
+ return node->getNodeValue();
+ } catch (css::xml::dom::DOMException & e) {
+ throw css::uno::RuntimeException(
+ (::rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.xml.dom.DOMException: ")) +
+ e.Message),
+ css::uno::Reference< css::uno::XInterface >());
+ }
+}
+
+/**The class uses the UCB to access the description.xml file in an
+ extension. The UCB must have been initialized already. It also
+ requires that the extension has already be unzipped to a particular
+ location.
+ */
+class ExtensionDescription
+{
+public:
+ /**throws an exception if the description.xml is not
+ available, cannot be read, does not contain the expected data,
+ or any other error occurred. Therefore it shoult only be used with
+ new extensions.
+
+ Throws com::sun::star::uno::RuntimeException,
+ com::sun::star::deployment::DeploymentException,
+ dp_registry::backend::bundle::NoDescriptionException.
+ */
+ ExtensionDescription(
+ const css::uno::Reference<css::uno::XComponentContext>& xContext,
+ const ::rtl::OUString& installDir,
+ const css::uno::Reference< css::ucb::XCommandEnvironment >& xCmdEnv);
+
+ ~ExtensionDescription();
+
+ css::uno::Reference<css::xml::dom::XNode> getRootElement() const
+ {
+ return m_xRoot;
+ }
+
+ ::rtl::OUString getExtensionRootUrl() const
+ {
+ return m_sExtensionRootUrl;
+ }
+
+
+private:
+ css::uno::Reference<css::xml::dom::XNode> m_xRoot;
+ ::rtl::OUString m_sExtensionRootUrl;
+};
+
+class NoDescriptionException
+{
+};
+
+class FileDoesNotExistFilter
+ : public ::cppu::WeakImplHelper2< css::ucb::XCommandEnvironment,
+ css::task::XInteractionHandler >
+
+{
+ bool m_bExist;
+ css::uno::Reference< css::ucb::XCommandEnvironment > m_xCommandEnv;
+
+public:
+ virtual ~FileDoesNotExistFilter();
+ FileDoesNotExistFilter(
+ const css::uno::Reference< css::ucb::XCommandEnvironment >& xCmdEnv);
+
+ bool exist();
+ // XCommandEnvironment
+ virtual css::uno::Reference<css::task::XInteractionHandler > SAL_CALL
+ getInteractionHandler() throw (css::uno::RuntimeException);
+ virtual css::uno::Reference<css::ucb::XProgressHandler >
+ SAL_CALL getProgressHandler() throw (css::uno::RuntimeException);
+
+ // XInteractionHandler
+ virtual void SAL_CALL handle(
+ css::uno::Reference<css::task::XInteractionRequest > const & xRequest )
+ throw (css::uno::RuntimeException);
+};
+
+ExtensionDescription::ExtensionDescription(
+ const Reference<css::uno::XComponentContext>& xContext,
+ const OUString& installDir,
+ const Reference< css::ucb::XCommandEnvironment >& xCmdEnv)
+{
+ try {
+ m_sExtensionRootUrl = installDir;
+ //may throw ::com::sun::star::ucb::ContentCreationException
+ //If there is no description.xml then ucb will start an interaction which
+ //brings up a dialog.We want to prevent this. Therefore we wrap the xCmdEnv
+ //and filter the respective exception out.
+ OUString sDescriptionUri(installDir + OUSTR("/description.xml"));
+ Reference<css::ucb::XCommandEnvironment> xFilter =
+ static_cast<css::ucb::XCommandEnvironment*>(
+ new FileDoesNotExistFilter(xCmdEnv));
+ ::ucbhelper::Content descContent(sDescriptionUri, xFilter);
+
+ //throws an com::sun::star::uno::Exception if the file is not available
+ Reference<css::io::XInputStream> xIn;
+ try
+ { //throws com.sun.star.ucb.InteractiveAugmentedIOException
+ xIn = descContent.openStream();
+ }
+ catch (css::uno::Exception& )
+ {
+ if ( ! static_cast<FileDoesNotExistFilter*>(xFilter.get())->exist())
+ throw NoDescriptionException();
+ throw;
+ }
+ if (!xIn.is())
+ {
+ throw css::uno::Exception(
+ OUSTR("Could not get XInputStream for description.xml of extension ") +
+ sDescriptionUri, 0);
+ }
+
+ //get root node of description.xml
+ Reference<css::xml::dom::XDocumentBuilder> xDocBuilder(
+ xContext->getServiceManager()->createInstanceWithContext(
+ OUSTR("com.sun.star.xml.dom.DocumentBuilder"),
+ xContext ), css::uno::UNO_QUERY);
+ if (!xDocBuilder.is())
+ throw css::uno::Exception(OUSTR(" Could not create service com.sun.star.xml.dom.DocumentBuilder"), 0);
+
+ if (xDocBuilder->isNamespaceAware() == sal_False)
+ {
+ throw css::uno::Exception(
+ OUSTR("Service com.sun.star.xml.dom.DocumentBuilder is not namespace aware."), 0);
+ }
+
+ Reference<css::xml::dom::XDocument> xDoc = xDocBuilder->parse(xIn);
+ if (!xDoc.is())
+ {
+ throw css::uno::Exception(sDescriptionUri + OUSTR(" contains data which cannot be parsed. "), 0);
+ }
+
+ //check for proper root element and namespace
+ Reference<css::xml::dom::XElement> xRoot = xDoc->getDocumentElement();
+ if (!xRoot.is())
+ {
+ throw css::uno::Exception(
+ sDescriptionUri + OUSTR(" contains no root element."), 0);
+ }
+
+ if ( ! xRoot->getTagName().equals(OUSTR("description")))
+ {
+ throw css::uno::Exception(
+ sDescriptionUri + OUSTR(" does not contain the root element <description>."), 0);
+ }
+
+ m_xRoot = Reference<css::xml::dom::XNode>(
+ xRoot, css::uno::UNO_QUERY_THROW);
+ OUString nsDescription = xRoot->getNamespaceURI();
+
+ //check if this namespace is supported
+ if ( ! nsDescription.equals(OUSTR("http://openoffice.org/extensions/description/2006")))
+ {
+ throw css::uno::Exception(sDescriptionUri + OUSTR(" contains a root element with an unsupported namespace. "), 0);
+ }
+ } catch (css::uno::RuntimeException &) {
+ throw;
+ } catch (css::deployment::DeploymentException &) {
+ throw;
+ } catch (css::uno::Exception & e) {
+ css::uno::Any a(cppu::getCaughtException());
+ throw css::deployment::DeploymentException(
+ e.Message, Reference< css::uno::XInterface >(), a);
+ }
+}
+
+ExtensionDescription::~ExtensionDescription()
+{
+}
+
+//======================================================================
+FileDoesNotExistFilter::FileDoesNotExistFilter(
+ const Reference< css::ucb::XCommandEnvironment >& xCmdEnv):
+ m_bExist(true), m_xCommandEnv(xCmdEnv)
+{}
+
+FileDoesNotExistFilter::~FileDoesNotExistFilter()
+{
+};
+
+bool FileDoesNotExistFilter::exist()
+{
+ return m_bExist;
+}
+ // XCommandEnvironment
+Reference<css::task::XInteractionHandler >
+ FileDoesNotExistFilter::getInteractionHandler() throw (css::uno::RuntimeException)
+{
+ return static_cast<css::task::XInteractionHandler*>(this);
+}
+
+Reference<css::ucb::XProgressHandler >
+ FileDoesNotExistFilter::getProgressHandler() throw (css::uno::RuntimeException)
+{
+ return m_xCommandEnv.is()
+ ? m_xCommandEnv->getProgressHandler()
+ : Reference<css::ucb::XProgressHandler>();
+}
+
+// XInteractionHandler
+//If the interaction was caused by a non-existing file which is specified in the ctor
+//of FileDoesNotExistFilter, then we do nothing
+void FileDoesNotExistFilter::handle(
+ Reference<css::task::XInteractionRequest > const & xRequest )
+ throw (css::uno::RuntimeException)
+{
+ css::uno::Any request( xRequest->getRequest() );
+
+ css::ucb::InteractiveAugmentedIOException ioexc;
+ if ((request>>= ioexc) && ioexc.Code == css::ucb::IOErrorCode_NOT_EXISTING )
+ {
+ m_bExist = false;
+ return;
+ }
+ Reference<css::task::XInteractionHandler> xInteraction;
+ if (m_xCommandEnv.is()) {
+ xInteraction = m_xCommandEnv->getInteractionHandler();
+ }
+ if (xInteraction.is()) {
+ xInteraction->handle(xRequest);
+ }
+}
+
+}
+
+namespace dp_misc {
+
+DescriptionInfoset getDescriptionInfoset(OUString const & sExtensionFolderURL)
+{
+ Reference< css::xml::dom::XNode > root;
+ Reference<css::uno::XComponentContext> context =
+ comphelper_getProcessComponentContext();
+ OSL_ASSERT(context.is());
+ try {
+ root =
+ ExtensionDescription(
+ context, sExtensionFolderURL,
+ Reference< css::ucb::XCommandEnvironment >()).
+ getRootElement();
+ } catch (NoDescriptionException &) {
+ } catch (css::deployment::DeploymentException & e) {
+ throw css::uno::RuntimeException(
+ (OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.deployment.DeploymentException: ")) +
+ e.Message), 0);
+ }
+ return DescriptionInfoset(context, root);
+}
+
+DescriptionInfoset::DescriptionInfoset(
+ css::uno::Reference< css::uno::XComponentContext > const & context,
+ css::uno::Reference< css::xml::dom::XNode > const & element):
+ m_element(element)
+{
+ css::uno::Reference< css::lang::XMultiComponentFactory > manager(
+ context->getServiceManager(), css::uno::UNO_QUERY_THROW);
+ if (m_element.is()) {
+ m_xpath = css::uno::Reference< css::xml::xpath::XXPathAPI >(
+ manager->createInstanceWithContext(
+ ::rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.xml.xpath.XPathAPI")),
+ context),
+ css::uno::UNO_QUERY_THROW);
+ m_xpath->registerNS(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("desc")),
+ element->getNamespaceURI());
+ m_xpath->registerNS(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("xlink")),
+ ::rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM("http://www.w3.org/1999/xlink")));
+ }
+}
+
+DescriptionInfoset::~DescriptionInfoset() {}
+
+::boost::optional< ::rtl::OUString > DescriptionInfoset::getIdentifier() const {
+ return getOptionalValue(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("desc:identifier/@value")));
+}
+
+::rtl::OUString DescriptionInfoset::getNodeValueFromExpression(::rtl::OUString const & expression) const
+{
+ css::uno::Reference< css::xml::dom::XNode > n;
+ if (m_element.is()) {
+ try {
+ n = m_xpath->selectSingleNode(m_element, expression);
+ } catch (css::xml::xpath::XPathException &) {
+ // ignore
+ }
+ }
+ return n.is() ? getNodeValue(n) : ::rtl::OUString();
+}
+
+
+::rtl::OUString DescriptionInfoset::getVersion() const
+{
+ return getNodeValueFromExpression( ::rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM("desc:version/@value")));
+}
+
+css::uno::Sequence< ::rtl::OUString > DescriptionInfoset::getSupportedPlaforms() const
+{
+ //When there is no description.xml then we assume that we support all platforms
+ if (! m_element.is())
+ {
+ return comphelper::makeSequence(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("all")));
+ }
+
+ //Check if the <platform> element was provided. If not the default is "all" platforms
+ css::uno::Reference< css::xml::dom::XNode > nodePlatform(
+ m_xpath->selectSingleNode(m_element, ::rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM("desc:platform"))));
+ if (!nodePlatform.is())
+ {
+ return comphelper::makeSequence(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("all")));
+ }
+
+ //There is a platform element.
+ const ::rtl::OUString value = getNodeValueFromExpression(::rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM("desc:platform/@value")));
+ //parse the string, it can contained multiple strings separated by commas
+ ::std::vector< ::rtl::OUString> vec;
+ sal_Int32 nIndex = 0;
+ do
+ {
+ ::rtl::OUString aToken = value.getToken( 0, ',', nIndex );
+ aToken = aToken.trim();
+ if (aToken.getLength())
+ vec.push_back(aToken);
+
+ }
+ while (nIndex >= 0);
+
+ return comphelper::containerToSequence(vec);
+}
+
+css::uno::Reference< css::xml::dom::XNodeList >
+DescriptionInfoset::getDependencies() const {
+ if (m_element.is()) {
+ try {
+ return m_xpath->selectNodeList(m_element, ::rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM("desc:dependencies/*")));
+ } catch (css::xml::xpath::XPathException &) {
+ // ignore
+ }
+ }
+ return new EmptyNodeList;
+}
+
+css::uno::Sequence< ::rtl::OUString >
+DescriptionInfoset::getUpdateInformationUrls() const {
+ return getUrls(
+ ::rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "desc:update-information/desc:src/@xlink:href")));
+}
+
+css::uno::Sequence< ::rtl::OUString >
+DescriptionInfoset::getUpdateDownloadUrls() const
+{
+ return getUrls(
+ ::rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "desc:update-download/desc:src/@xlink:href")));
+}
+
+::rtl::OUString DescriptionInfoset::getIconURL( sal_Bool bHighContrast ) const
+{
+ css::uno::Sequence< ::rtl::OUString > aStrList = getUrls( ::rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "desc:icon/desc:default/@xlink:href")));
+ css::uno::Sequence< ::rtl::OUString > aStrListHC = getUrls( ::rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "desc:icon/desc:high-contrast/@xlink:href")));
+
+ if ( bHighContrast && aStrListHC.hasElements() && aStrListHC[0].getLength() )
+ return aStrListHC[0];
+
+ if ( aStrList.hasElements() && aStrList[0].getLength() )
+ return aStrList[0];
+
+ return ::rtl::OUString();
+}
+
+::boost::optional< ::rtl::OUString > DescriptionInfoset::getLocalizedUpdateWebsiteURL()
+ const
+{
+ bool bParentExists = false;
+ const ::rtl::OUString sURL (getLocalizedHREFAttrFromChild(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "/desc:description/desc:update-website")), &bParentExists ));
+
+ if (sURL.getLength() > 0)
+ return ::boost::optional< ::rtl::OUString >(sURL);
+ else
+ return bParentExists ? ::boost::optional< ::rtl::OUString >(::rtl::OUString()) :
+ ::boost::optional< ::rtl::OUString >();
+}
+
+::boost::optional< ::rtl::OUString > DescriptionInfoset::getOptionalValue(
+ ::rtl::OUString const & expression) const
+{
+ css::uno::Reference< css::xml::dom::XNode > n;
+ if (m_element.is()) {
+ try {
+ n = m_xpath->selectSingleNode(m_element, expression);
+ } catch (css::xml::xpath::XPathException &) {
+ // ignore
+ }
+ }
+ return n.is()
+ ? ::boost::optional< ::rtl::OUString >(getNodeValue(n))
+ : ::boost::optional< ::rtl::OUString >();
+}
+
+css::uno::Sequence< ::rtl::OUString > DescriptionInfoset::getUrls(
+ ::rtl::OUString const & expression) const
+{
+ css::uno::Reference< css::xml::dom::XNodeList > ns;
+ if (m_element.is()) {
+ try {
+ ns = m_xpath->selectNodeList(m_element, expression);
+ } catch (css::xml::xpath::XPathException &) {
+ // ignore
+ }
+ }
+ css::uno::Sequence< ::rtl::OUString > urls(ns.is() ? ns->getLength() : 0);
+ for (::sal_Int32 i = 0; i < urls.getLength(); ++i) {
+ urls[i] = getNodeValue(ns->item(i));
+ }
+ return urls;
+}
+
+::std::pair< ::rtl::OUString, ::rtl::OUString > DescriptionInfoset::getLocalizedPublisherNameAndURL() const
+{
+ css::uno::Reference< css::xml::dom::XNode > node =
+ getLocalizedChild(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("desc:publisher")));
+
+ ::rtl::OUString sPublisherName;
+ ::rtl::OUString sURL;
+ if (node.is())
+ {
+ const ::rtl::OUString exp1(RTL_CONSTASCII_USTRINGPARAM("text()"));
+ css::uno::Reference< css::xml::dom::XNode > xPathName;
+ try {
+ xPathName = m_xpath->selectSingleNode(node, exp1);
+ } catch (css::xml::xpath::XPathException &) {
+ // ignore
+ }
+ OSL_ASSERT(xPathName.is());
+ if (xPathName.is())
+ sPublisherName = xPathName->getNodeValue();
+
+ const ::rtl::OUString exp2(RTL_CONSTASCII_USTRINGPARAM("@xlink:href"));
+ css::uno::Reference< css::xml::dom::XNode > xURL;
+ try {
+ xURL = m_xpath->selectSingleNode(node, exp2);
+ } catch (css::xml::xpath::XPathException &) {
+ // ignore
+ }
+ OSL_ASSERT(xURL.is());
+ if (xURL.is())
+ sURL = xURL->getNodeValue();
+ }
+ return ::std::make_pair(sPublisherName, sURL);
+}
+
+::rtl::OUString DescriptionInfoset::getLocalizedReleaseNotesURL() const
+{
+ return getLocalizedHREFAttrFromChild(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "/desc:description/desc:release-notes")), NULL);
+}
+
+::rtl::OUString DescriptionInfoset::getLocalizedDisplayName() const
+{
+ css::uno::Reference< css::xml::dom::XNode > node =
+ getLocalizedChild(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("desc:display-name")));
+ if (node.is())
+ {
+ const ::rtl::OUString exp(RTL_CONSTASCII_USTRINGPARAM("text()"));
+ css::uno::Reference< css::xml::dom::XNode > xtext;
+ try {
+ xtext = m_xpath->selectSingleNode(node, exp);
+ } catch (css::xml::xpath::XPathException &) {
+ // ignore
+ }
+ if (xtext.is())
+ return xtext->getNodeValue();
+ }
+ return ::rtl::OUString();
+}
+
+::rtl::OUString DescriptionInfoset::getLocalizedLicenseURL() const
+{
+ return getLocalizedHREFAttrFromChild(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "/desc:description/desc:registration/desc:simple-license")), NULL);
+
+}
+
+::boost::optional<SimpleLicenseAttributes>
+DescriptionInfoset::getSimpleLicenseAttributes() const
+{
+ //Check if the node exist
+ css::uno::Reference< css::xml::dom::XNode > n;
+ if (m_element.is()) {
+ try {
+ n = m_xpath->selectSingleNode(m_element,
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "/desc:description/desc:registration/desc:simple-license/@accept-by")));
+ } catch (css::xml::xpath::XPathException &) {
+ // ignore
+ }
+ if (n.is())
+ {
+ SimpleLicenseAttributes attributes;
+ attributes.acceptBy =
+ getNodeValueFromExpression(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "/desc:description/desc:registration/desc:simple-license/@accept-by")));
+
+ ::boost::optional< ::rtl::OUString > suppressOnUpdate = getOptionalValue(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "/desc:description/desc:registration/desc:simple-license/@suppress-on-update")));
+ if (suppressOnUpdate)
+ attributes.suppressOnUpdate = (*suppressOnUpdate).trim().equalsIgnoreAsciiCase(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("true")));
+ else
+ attributes.suppressOnUpdate = false;
+
+ ::boost::optional< ::rtl::OUString > suppressIfRequired = getOptionalValue(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "/desc:description/desc:registration/desc:simple-license/@suppress-if-required")));
+ if (suppressIfRequired)
+ attributes.suppressIfRequired = (*suppressIfRequired).trim().equalsIgnoreAsciiCase(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("true")));
+ else
+ attributes.suppressIfRequired = false;
+
+ return ::boost::optional<SimpleLicenseAttributes>(attributes);
+ }
+ }
+ return ::boost::optional<SimpleLicenseAttributes>();
+}
+
+::rtl::OUString DescriptionInfoset::getLocalizedDescriptionURL() const
+{
+ return getLocalizedHREFAttrFromChild(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "/desc:description/desc:extension-description")), NULL);
+}
+
+css::uno::Reference< css::xml::dom::XNode >
+DescriptionInfoset::getLocalizedChild( const ::rtl::OUString & sParent) const
+{
+ if ( ! m_element.is() || !sParent.getLength())
+ return css::uno::Reference< css::xml::dom::XNode > ();
+
+ css::uno::Reference< css::xml::dom::XNode > xParent;
+ try {
+ xParent = m_xpath->selectSingleNode(m_element, sParent);
+ } catch (css::xml::xpath::XPathException &) {
+ // ignore
+ }
+ css::uno::Reference<css::xml::dom::XNode> nodeMatch;
+ if (xParent.is())
+ {
+ const ::rtl::OUString sLocale = getOfficeLocaleString();
+ nodeMatch = matchFullLocale(xParent, sLocale);
+
+ //office: en-DE, en, en-DE-altmark
+ if (! nodeMatch.is())
+ {
+ const css::lang::Locale officeLocale = getOfficeLocale();
+ nodeMatch = matchCountryAndLanguage(xParent, officeLocale);
+ if ( ! nodeMatch.is())
+ {
+ nodeMatch = matchLanguage(xParent, officeLocale);
+ if (! nodeMatch.is())
+ nodeMatch = getChildWithDefaultLocale(xParent);
+ }
+ }
+ }
+
+ return nodeMatch;
+}
+
+css::uno::Reference<css::xml::dom::XNode>
+DescriptionInfoset::matchFullLocale(css::uno::Reference< css::xml::dom::XNode >
+ const & xParent, ::rtl::OUString const & sLocale) const
+{
+ OSL_ASSERT(xParent.is());
+ const ::rtl::OUString exp1(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("*[@lang=\""))
+ + sLocale +
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("\"]")));
+ try {
+ return m_xpath->selectSingleNode(xParent, exp1);
+ } catch (css::xml::xpath::XPathException &) {
+ // ignore
+ return 0;
+ }
+}
+
+css::uno::Reference<css::xml::dom::XNode>
+DescriptionInfoset::matchCountryAndLanguage(
+ css::uno::Reference< css::xml::dom::XNode > const & xParent, css::lang::Locale const & officeLocale) const
+{
+ OSL_ASSERT(xParent.is());
+ css::uno::Reference<css::xml::dom::XNode> nodeMatch;
+
+ if (officeLocale.Country.getLength())
+ {
+ const ::rtl::OUString sLangCountry(officeLocale.Language +
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("-")) +
+ officeLocale.Country);
+ //first try exact match for lang-country
+ const ::rtl::OUString exp1(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("*[@lang=\""))
+ + sLangCountry +
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("\"]")));
+ try {
+ nodeMatch = m_xpath->selectSingleNode(xParent, exp1);
+ } catch (css::xml::xpath::XPathException &) {
+ // ignore
+ }
+
+ //try to match in strings that also have a variant, for example en-US matches in
+ //en-US-montana
+ if (!nodeMatch.is())
+ {
+ const ::rtl::OUString exp2(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("*[starts-with(@lang,\""))
+ + sLangCountry +
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("-\")]")));
+ try {
+ nodeMatch = m_xpath->selectSingleNode(xParent, exp2);
+ } catch (css::xml::xpath::XPathException &) {
+ // ignore
+ }
+ }
+ }
+
+ return nodeMatch;
+}
+
+
+css::uno::Reference<css::xml::dom::XNode>
+DescriptionInfoset::matchLanguage(
+ css::uno::Reference< css::xml::dom::XNode > const & xParent, css::lang::Locale const & officeLocale) const
+{
+ OSL_ASSERT(xParent.is());
+ css::uno::Reference<css::xml::dom::XNode> nodeMatch;
+
+ //first try exact match for lang
+ const ::rtl::OUString exp1(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("*[@lang=\""))
+ + officeLocale.Language
+ + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("\"]")));
+ try {
+ nodeMatch = m_xpath->selectSingleNode(xParent, exp1);
+ } catch (css::xml::xpath::XPathException &) {
+ // ignore
+ }
+
+ //try to match in strings that also have a country and/orvariant, for example en matches in
+ //en-US-montana, en-US, en-montana
+ if (!nodeMatch.is())
+ {
+ const ::rtl::OUString exp2(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("*[starts-with(@lang,\""))
+ + officeLocale.Language
+ + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("-\")]")));
+ try {
+ nodeMatch = m_xpath->selectSingleNode(xParent, exp2);
+ } catch (css::xml::xpath::XPathException &) {
+ // ignore
+ }
+ }
+ return nodeMatch;
+}
+
+css::uno::Reference<css::xml::dom::XNode>
+DescriptionInfoset::getChildWithDefaultLocale(css::uno::Reference< css::xml::dom::XNode >
+ const & xParent) const
+{
+ OSL_ASSERT(xParent.is());
+ if (xParent->getNodeName().equals(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("simple-license"))))
+ {
+ css::uno::Reference<css::xml::dom::XNode> nodeDefault;
+ try {
+ nodeDefault = m_xpath->selectSingleNode(xParent, ::rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM("@default-license-id")));
+ } catch (css::xml::xpath::XPathException &) {
+ // ignore
+ }
+ if (nodeDefault.is())
+ {
+ //The old way
+ const ::rtl::OUString exp1(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("desc:license-text[@license-id = \""))
+ + nodeDefault->getNodeValue()
+ + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("\"]")));
+ try {
+ return m_xpath->selectSingleNode(xParent, exp1);
+ } catch (css::xml::xpath::XPathException &) {
+ // ignore
+ }
+ }
+ }
+
+ const ::rtl::OUString exp2(RTL_CONSTASCII_USTRINGPARAM("*[1]"));
+ try {
+ return m_xpath->selectSingleNode(xParent, exp2);
+ } catch (css::xml::xpath::XPathException &) {
+ // ignore
+ return 0;
+ }
+}
+
+::rtl::OUString DescriptionInfoset::getLocalizedHREFAttrFromChild(
+ ::rtl::OUString const & sXPathParent, bool * out_bParentExists)
+ const
+{
+ css::uno::Reference< css::xml::dom::XNode > node =
+ getLocalizedChild(sXPathParent);
+
+ ::rtl::OUString sURL;
+ if (node.is())
+ {
+ if (out_bParentExists)
+ *out_bParentExists = true;
+ const ::rtl::OUString exp(RTL_CONSTASCII_USTRINGPARAM("@xlink:href"));
+ css::uno::Reference< css::xml::dom::XNode > xURL;
+ try {
+ xURL = m_xpath->selectSingleNode(node, exp);
+ } catch (css::xml::xpath::XPathException &) {
+ // ignore
+ }
+ OSL_ASSERT(xURL.is());
+ if (xURL.is())
+ sURL = xURL->getNodeValue();
+ }
+ else
+ {
+ if (out_bParentExists)
+ *out_bParentExists = false;
+ }
+ return sURL;
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/misc/dp_identifier.cxx b/desktop/source/deployment/misc/dp_identifier.cxx
new file mode 100644
index 000000000000..b24ccd7def52
--- /dev/null
+++ b/desktop/source/deployment/misc/dp_identifier.cxx
@@ -0,0 +1,76 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include "sal/config.h"
+
+#include "boost/optional.hpp"
+#include "com/sun/star/beans/Optional.hpp"
+#include "com/sun/star/deployment/XPackage.hpp"
+#include "com/sun/star/uno/Reference.hxx"
+#include "osl/diagnose.h"
+#include "rtl/string.h"
+#include "rtl/ustrbuf.hxx"
+#include "rtl/ustring.hxx"
+
+#include "dp_identifier.hxx"
+
+namespace {
+ namespace css = ::com::sun::star;
+}
+
+namespace dp_misc {
+
+::rtl::OUString generateIdentifier(
+ ::boost::optional< ::rtl::OUString > const & optional,
+ ::rtl::OUString const & fileName)
+{
+ return optional ? *optional : generateLegacyIdentifier(fileName);
+}
+
+::rtl::OUString getIdentifier(
+ css::uno::Reference< css::deployment::XPackage > const & package)
+{
+ OSL_ASSERT(package.is());
+ css::beans::Optional< ::rtl::OUString > id(package->getIdentifier());
+ return id.IsPresent
+ ? id.Value : generateLegacyIdentifier(package->getName());
+}
+
+::rtl::OUString generateLegacyIdentifier(::rtl::OUString const & fileName) {
+ rtl::OUStringBuffer b;
+ b.appendAscii(RTL_CONSTASCII_STRINGPARAM("org.openoffice.legacy."));
+ b.append(fileName);
+ return b.makeStringAndClear();
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/misc/dp_interact.cxx b/desktop/source/deployment/misc/dp_interact.cxx
new file mode 100644
index 000000000000..c42ccd249cb7
--- /dev/null
+++ b/desktop/source/deployment/misc/dp_interact.cxx
@@ -0,0 +1,187 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include "dp_interact.h"
+#include "cppuhelper/exc_hlp.hxx"
+#include "cppuhelper/implbase1.hxx"
+#include "com/sun/star/task/XInteractionAbort.hpp"
+
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::ucb;
+using ::rtl::OUString;
+
+namespace dp_misc {
+namespace {
+
+//==============================================================================
+class InteractionContinuationImpl : public ::cppu::OWeakObject,
+ public task::XInteractionContinuation
+{
+ const Type m_type;
+ bool * m_pselect;
+
+public:
+ inline InteractionContinuationImpl( Type const & type, bool * pselect )
+ : m_type( type ),
+ m_pselect( pselect )
+ { OSL_ASSERT(
+ ::getCppuType(
+ static_cast< Reference<task::XInteractionContinuation>
+ const *>(0) ).isAssignableFrom(m_type) ); }
+
+ // XInterface
+ virtual void SAL_CALL acquire() throw ();
+ virtual void SAL_CALL release() throw ();
+ virtual Any SAL_CALL queryInterface( Type const & type )
+ throw (RuntimeException);
+
+ // XInteractionContinuation
+ virtual void SAL_CALL select() throw (RuntimeException);
+};
+
+// XInterface
+//______________________________________________________________________________
+void InteractionContinuationImpl::acquire() throw ()
+{
+ OWeakObject::acquire();
+}
+
+//______________________________________________________________________________
+void InteractionContinuationImpl::release() throw ()
+{
+ OWeakObject::release();
+}
+
+//______________________________________________________________________________
+Any InteractionContinuationImpl::queryInterface( Type const & type )
+ throw (RuntimeException)
+{
+ if (type.isAssignableFrom( m_type )) {
+ Reference<task::XInteractionContinuation> xThis(this);
+ return Any( &xThis, type );
+ }
+ else
+ return OWeakObject::queryInterface(type);
+}
+
+// XInteractionContinuation
+//______________________________________________________________________________
+void InteractionContinuationImpl::select() throw (RuntimeException)
+{
+ *m_pselect = true;
+}
+
+//==============================================================================
+class InteractionRequest :
+ public ::cppu::WeakImplHelper1<task::XInteractionRequest>
+{
+ Any m_request;
+ Sequence< Reference<task::XInteractionContinuation> > m_conts;
+
+public:
+ inline InteractionRequest(
+ Any const & request,
+ Sequence< Reference<task::XInteractionContinuation> > const & conts )
+ : m_request( request ),
+ m_conts( conts )
+ {}
+
+ // XInteractionRequest
+ virtual Any SAL_CALL getRequest()
+ throw (RuntimeException);
+ virtual Sequence< Reference<task::XInteractionContinuation> >
+ SAL_CALL getContinuations() throw (RuntimeException);
+};
+
+// XInteractionRequest
+//______________________________________________________________________________
+Any InteractionRequest::getRequest() throw (RuntimeException)
+{
+ return m_request;
+}
+
+//______________________________________________________________________________
+Sequence< Reference< task::XInteractionContinuation > >
+InteractionRequest::getContinuations() throw (RuntimeException)
+{
+ return m_conts;
+}
+
+} // anon namespace
+
+//==============================================================================
+bool interactContinuation( Any const & request,
+ Type const & continuation,
+ Reference<XCommandEnvironment> const & xCmdEnv,
+ bool * pcont, bool * pabort )
+{
+ OSL_ASSERT(
+ task::XInteractionContinuation::static_type().isAssignableFrom(
+ continuation ) );
+ if (xCmdEnv.is()) {
+ Reference<task::XInteractionHandler> xInteractionHandler(
+ xCmdEnv->getInteractionHandler() );
+ if (xInteractionHandler.is()) {
+ bool cont = false;
+ bool abort = false;
+ Sequence< Reference<task::XInteractionContinuation> > conts( 2 );
+ conts[ 0 ] = new InteractionContinuationImpl(
+ continuation, &cont );
+ conts[ 1 ] = new InteractionContinuationImpl(
+ task::XInteractionAbort::static_type(), &abort );
+ xInteractionHandler->handle(
+ new InteractionRequest( request, conts ) );
+ if (cont || abort) {
+ if (pcont != 0)
+ *pcont = cont;
+ if (pabort != 0)
+ *pabort = abort;
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+// XAbortChannel
+//______________________________________________________________________________
+void AbortChannel::sendAbort() throw (RuntimeException)
+{
+ m_aborted = true;
+ if (m_xNext.is())
+ m_xNext->sendAbort();
+}
+
+} // dp_misc
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/misc/dp_misc.cxx b/desktop/source/deployment/misc/dp_misc.cxx
new file mode 100644
index 000000000000..1a46cdda3d5a
--- /dev/null
+++ b/desktop/source/deployment/misc/dp_misc.cxx
@@ -0,0 +1,632 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+
+#include "dp_misc.h"
+#include "dp_version.hxx"
+#include "dp_interact.h"
+#include "rtl/uri.hxx"
+#include "rtl/digest.h"
+#include "rtl/random.h"
+#include "rtl/bootstrap.hxx"
+#include "unotools/bootstrap.hxx"
+#include "osl/file.hxx"
+#include "osl/pipe.hxx"
+#include "osl/security.hxx"
+#include "osl/thread.hxx"
+#include "osl/mutex.hxx"
+#include "com/sun/star/ucb/CommandAbortedException.hpp"
+#include "com/sun/star/task/XInteractionHandler.hpp"
+#include "com/sun/star/bridge/UnoUrlResolver.hpp"
+#include "com/sun/star/bridge/XUnoUrlResolver.hpp"
+#include "com/sun/star/deployment/ExtensionManager.hpp"
+#include "com/sun/star/task/XRestartManager.hpp"
+#include "boost/scoped_array.hpp"
+#include "boost/shared_ptr.hpp"
+#include <comphelper/processfactory.hxx>
+
+#ifdef WNT
+#define UNICODE
+#define _UNICODE
+#define WIN32_LEAN_AND_MEAN
+#include <Windows.h>
+#endif
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using ::rtl::OUString;
+using ::rtl::OString;
+
+
+#define SOFFICE1 "soffice.exe"
+#define SOFFICE2 "soffice.bin"
+#define SBASE "sbase.exe"
+#define SCALC "scalc.exe"
+#define SDRAW "sdraw.exe"
+#define SIMPRESS "simpress.exe"
+#define SWRITER "swriter.exe"
+
+namespace dp_misc {
+namespace {
+
+struct UnoRc : public rtl::StaticWithInit<
+ const boost::shared_ptr<rtl::Bootstrap>, UnoRc> {
+ const boost::shared_ptr<rtl::Bootstrap> operator () () {
+ OUString unorc( RTL_CONSTASCII_USTRINGPARAM(
+ "$OOO_BASE_DIR/program/" SAL_CONFIGFILE("uno")) );
+ ::rtl::Bootstrap::expandMacros( unorc );
+ ::boost::shared_ptr< ::rtl::Bootstrap > ret(
+ new ::rtl::Bootstrap( unorc ) );
+ OSL_ASSERT( ret->getHandle() != 0 );
+ return ret;
+ }
+};
+
+struct OfficePipeId : public rtl::StaticWithInit<const OUString, OfficePipeId> {
+ const OUString operator () ();
+};
+
+const OUString OfficePipeId::operator () ()
+{
+ OUString userPath;
+ ::utl::Bootstrap::PathStatus aLocateResult =
+ ::utl::Bootstrap::locateUserInstallation( userPath );
+ if (!(aLocateResult == ::utl::Bootstrap::PATH_EXISTS ||
+ aLocateResult == ::utl::Bootstrap::PATH_VALID))
+ {
+ throw Exception(OUSTR("Extension Manager: Could not obtain path for UserInstallation."), 0);
+ }
+
+ rtlDigest digest = rtl_digest_create( rtl_Digest_AlgorithmMD5 );
+ if (digest <= 0) {
+ throw RuntimeException(
+ OUSTR("cannot get digest rtl_Digest_AlgorithmMD5!"), 0 );
+ }
+
+ sal_uInt8 const * data =
+ reinterpret_cast<sal_uInt8 const *>(userPath.getStr());
+ sal_Size size = (userPath.getLength() * sizeof (sal_Unicode));
+ sal_uInt32 md5_key_len = rtl_digest_queryLength( digest );
+ ::boost::scoped_array<sal_uInt8> md5_buf( new sal_uInt8 [ md5_key_len ] );
+
+ rtl_digest_init( digest, data, static_cast<sal_uInt32>(size) );
+ rtl_digest_update( digest, data, static_cast<sal_uInt32>(size) );
+ rtl_digest_get( digest, md5_buf.get(), md5_key_len );
+ rtl_digest_destroy( digest );
+
+ // create hex-value string from the MD5 value to keep
+ // the string size minimal
+ ::rtl::OUStringBuffer buf;
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("SingleOfficeIPC_") );
+ for ( sal_uInt32 i = 0; i < md5_key_len; ++i ) {
+ buf.append( static_cast<sal_Int32>(md5_buf[ i ]), 0x10 );
+ }
+ return buf.makeStringAndClear();
+}
+
+bool existsOfficePipe()
+{
+ OUString const & pipeId = OfficePipeId::get();
+ if (pipeId.getLength() == 0)
+ return false;
+ ::osl::Security sec;
+ ::osl::Pipe pipe( pipeId, osl_Pipe_OPEN, sec );
+ return pipe.is();
+}
+
+
+//Returns true if the Folder was more recently modified then
+//the lastsynchronized file. That is the repository needs to
+//be synchronized.
+bool compareExtensionFolderWithLastSynchronizedFile(
+ OUString const & folderURL, OUString const & fileURL)
+{
+ bool bNeedsSync = false;
+ ::osl::DirectoryItem itemExtFolder;
+ ::osl::File::RC err1 =
+ ::osl::DirectoryItem::get(folderURL, itemExtFolder);
+ //If it does not exist, then there is nothing to be done
+ if (err1 == ::osl::File::E_NOENT)
+ {
+ return false;
+ }
+ else if (err1 != ::osl::File::E_None)
+ {
+ OSL_FAIL("Cannot access extension folder");
+ return true; //sync just in case
+ }
+
+ //If last synchronized does not exist, then OOo is started for the first time
+ ::osl::DirectoryItem itemFile;
+ ::osl::File::RC err2 = ::osl::DirectoryItem::get(fileURL, itemFile);
+ if (err2 == ::osl::File::E_NOENT)
+ {
+ return true;
+
+ }
+ else if (err2 != ::osl::File::E_None)
+ {
+ OSL_FAIL("Cannot access file lastsynchronized");
+ return true; //sync just in case
+ }
+
+ //compare the modification time of the extension folder and the last
+ //modified file
+ ::osl::FileStatus statFolder(FileStatusMask_ModifyTime);
+ ::osl::FileStatus statFile(FileStatusMask_ModifyTime);
+ if (itemExtFolder.getFileStatus(statFolder) == ::osl::File::E_None)
+ {
+ if (itemFile.getFileStatus(statFile) == ::osl::File::E_None)
+ {
+ TimeValue timeFolder = statFolder.getModifyTime();
+ TimeValue timeFile = statFile.getModifyTime();
+
+ if (timeFile.Seconds < timeFolder.Seconds)
+ bNeedsSync = true;
+ }
+ else
+ {
+ OSL_ASSERT(0);
+ bNeedsSync = true;
+ }
+ }
+ else
+ {
+ OSL_ASSERT(0);
+ bNeedsSync = true;
+ }
+ return bNeedsSync;
+}
+
+bool needToSyncRepostitory(OUString const & name)
+{
+ OUString folder;
+ OUString file;
+ if (name.equals(OUString(RTL_CONSTASCII_USTRINGPARAM("bundled"))))
+ {
+ folder = OUString(
+ RTL_CONSTASCII_USTRINGPARAM("$BUNDLED_EXTENSIONS"));
+ file = OUString (
+ RTL_CONSTASCII_USTRINGPARAM(
+ "$BUNDLED_EXTENSIONS_USER/lastsynchronized"));
+ }
+ else if (name.equals(OUString(RTL_CONSTASCII_USTRINGPARAM("shared"))))
+ {
+ folder = OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "$UNO_SHARED_PACKAGES_CACHE/uno_packages"));
+ file = OUString (
+ RTL_CONSTASCII_USTRINGPARAM(
+ "$SHARED_EXTENSIONS_USER/lastsynchronized"));
+ }
+ else
+ {
+ OSL_ASSERT(0);
+ return true;
+ }
+ ::rtl::Bootstrap::expandMacros(folder);
+ ::rtl::Bootstrap::expandMacros(file);
+ return compareExtensionFolderWithLastSynchronizedFile(
+ folder, file);
+}
+
+
+} // anon namespace
+
+//==============================================================================
+
+namespace {
+inline OUString encodeForRcFile( OUString const & str )
+{
+ // escape $\{} (=> rtl bootstrap files)
+ ::rtl::OUStringBuffer buf;
+ sal_Int32 pos = 0;
+ const sal_Int32 len = str.getLength();
+ for ( ; pos < len; ++pos ) {
+ sal_Unicode c = str[ pos ];
+ switch (c) {
+ case '$':
+ case '\\':
+ case '{':
+ case '}':
+ buf.append( static_cast<sal_Unicode>('\\') );
+ break;
+ }
+ buf.append( c );
+ }
+ return buf.makeStringAndClear();
+}
+}
+
+//==============================================================================
+OUString makeURL( OUString const & baseURL, OUString const & relPath_ )
+{
+ ::rtl::OUStringBuffer buf;
+ if (baseURL.getLength() > 1 && baseURL[ baseURL.getLength() - 1 ] == '/')
+ buf.append( baseURL.copy( 0, baseURL.getLength() - 1 ) );
+ else
+ buf.append( baseURL );
+ OUString relPath(relPath_);
+ if (relPath.getLength() > 0 && relPath[ 0 ] == '/')
+ relPath = relPath.copy( 1 );
+ if (relPath.getLength() > 0)
+ {
+ buf.append( static_cast<sal_Unicode>('/') );
+ if (baseURL.matchAsciiL(
+ RTL_CONSTASCII_STRINGPARAM("vnd.sun.star.expand:") )) {
+ // encode for macro expansion: relPath is supposed to have no
+ // macros, so encode $, {} \ (bootstrap mimic)
+ relPath = encodeForRcFile(relPath);
+
+ // encode once more for vnd.sun.star.expand schema:
+ // vnd.sun.star.expand:$UNO_...
+ // will expand to file-url
+ relPath = ::rtl::Uri::encode( relPath, rtl_UriCharClassUric,
+ rtl_UriEncodeIgnoreEscapes,
+ RTL_TEXTENCODING_UTF8 );
+ }
+ buf.append( relPath );
+ }
+ return buf.makeStringAndClear();
+}
+
+OUString makeURLAppendSysPathSegment( OUString const & baseURL, OUString const & relPath_ )
+{
+ OUString segment = relPath_;
+ OSL_ASSERT(segment.indexOf(static_cast<sal_Unicode>('/')) == -1);
+
+ ::rtl::Uri::encode(
+ segment, rtl_UriCharClassPchar, rtl_UriEncodeIgnoreEscapes,
+ RTL_TEXTENCODING_UTF8);
+ return makeURL(baseURL, segment);
+}
+
+
+
+//==============================================================================
+OUString expandUnoRcTerm( OUString const & term_ )
+{
+ OUString term(term_);
+ UnoRc::get()->expandMacrosFrom( term );
+ return term;
+}
+
+OUString makeRcTerm( OUString const & url )
+{
+ OSL_ASSERT( url.matchAsciiL( RTL_CONSTASCII_STRINGPARAM(
+ "vnd.sun.star.expand:") ) );
+ if (url.matchAsciiL( RTL_CONSTASCII_STRINGPARAM("vnd.sun.star.expand:") )) {
+ // cut protocol:
+ OUString rcterm( url.copy( sizeof ("vnd.sun.star.expand:") - 1 ) );
+ // decode uric class chars:
+ rcterm = ::rtl::Uri::decode(
+ rcterm, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8 );
+ return rcterm;
+ }
+ else
+ return url;
+}
+
+//==============================================================================
+OUString expandUnoRcUrl( OUString const & url )
+{
+ if (url.matchAsciiL( RTL_CONSTASCII_STRINGPARAM("vnd.sun.star.expand:") )) {
+ // cut protocol:
+ OUString rcurl( url.copy( sizeof ("vnd.sun.star.expand:") - 1 ) );
+ // decode uric class chars:
+ rcurl = ::rtl::Uri::decode(
+ rcurl, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8 );
+ // expand macro string:
+ UnoRc::get()->expandMacrosFrom( rcurl );
+ return rcurl;
+ }
+ else {
+ return url;
+ }
+}
+
+//==============================================================================
+bool office_is_running()
+{
+ //We need to check if we run within the office process. Then we must not use the pipe, because
+ //this could cause a deadlock. This is actually a workaround for i82778
+ OUString sFile;
+ oslProcessError err = osl_getExecutableFile(& sFile.pData);
+ bool ret = false;
+ if (osl_Process_E_None == err)
+ {
+ sFile = sFile.copy(sFile.lastIndexOf('/') + 1);
+ if (
+#if defined UNIX
+ sFile.equals(OUString(RTL_CONSTASCII_USTRINGPARAM(SOFFICE2)))
+#elif defined WNT || defined OS2
+ //osl_getExecutableFile should deliver "soffice.bin" on windows
+ //even if swriter.exe, scalc.exe etc. was started. This is a bug
+ //in osl_getExecutableFile
+ sFile.equals(OUString(RTL_CONSTASCII_USTRINGPARAM(SOFFICE1)))
+ || sFile.equals(OUString(RTL_CONSTASCII_USTRINGPARAM(SOFFICE2)))
+ || sFile.equals(OUString(RTL_CONSTASCII_USTRINGPARAM(SBASE)))
+ || sFile.equals(OUString(RTL_CONSTASCII_USTRINGPARAM(SCALC)))
+ || sFile.equals(OUString(RTL_CONSTASCII_USTRINGPARAM(SDRAW)))
+ || sFile.equals(OUString(RTL_CONSTASCII_USTRINGPARAM(SIMPRESS)))
+ || sFile.equals(OUString(RTL_CONSTASCII_USTRINGPARAM(SWRITER)))
+#else
+#error "Unsupported platform"
+#endif
+
+ )
+ ret = true;
+ else
+ ret = existsOfficePipe();
+ }
+ else
+ {
+ OSL_FAIL("NOT osl_Process_E_None ");
+ //if osl_getExecutable file than we take the risk of creating a pipe
+ ret = existsOfficePipe();
+ }
+ return ret;
+}
+
+//==============================================================================
+oslProcess raiseProcess(
+ OUString const & appURL, Sequence<OUString> const & args )
+{
+ ::osl::Security sec;
+ oslProcess hProcess = 0;
+ oslProcessError rc = osl_executeProcess(
+ appURL.pData,
+ reinterpret_cast<rtl_uString **>(
+ const_cast<OUString *>(args.getConstArray()) ),
+ args.getLength(),
+ osl_Process_DETACHED,
+ sec.getHandle(),
+ 0, // => current working dir
+ 0, 0, // => no env vars
+ &hProcess );
+
+ switch (rc) {
+ case osl_Process_E_None:
+ break;
+ case osl_Process_E_NotFound:
+ throw RuntimeException( OUSTR("image not found!"), 0 );
+ case osl_Process_E_TimedOut:
+ throw RuntimeException( OUSTR("timout occurred!"), 0 );
+ case osl_Process_E_NoPermission:
+ throw RuntimeException( OUSTR("permission denied!"), 0 );
+ case osl_Process_E_Unknown:
+ throw RuntimeException( OUSTR("unknown error!"), 0 );
+ case osl_Process_E_InvalidError:
+ default:
+ throw RuntimeException( OUSTR("unmapped error!"), 0 );
+ }
+
+ return hProcess;
+}
+
+//==============================================================================
+OUString generateRandomPipeId()
+{
+ // compute some good pipe id:
+ static rtlRandomPool s_hPool = rtl_random_createPool();
+ if (s_hPool == 0)
+ throw RuntimeException( OUSTR("cannot create random pool!?"), 0 );
+ sal_uInt8 bytes[ 32 ];
+ if (rtl_random_getBytes(
+ s_hPool, bytes, ARLEN(bytes) ) != rtl_Random_E_None) {
+ throw RuntimeException( OUSTR("random pool error!?"), 0 );
+ }
+ ::rtl::OUStringBuffer buf;
+ for ( sal_uInt32 i = 0; i < ARLEN(bytes); ++i ) {
+ buf.append( static_cast<sal_Int32>(bytes[ i ]), 0x10 );
+ }
+ return buf.makeStringAndClear();
+}
+
+//==============================================================================
+Reference<XInterface> resolveUnoURL(
+ OUString const & connectString,
+ Reference<XComponentContext> const & xLocalContext,
+ AbortChannel * abortChannel )
+{
+ Reference<bridge::XUnoUrlResolver> xUnoUrlResolver(
+ bridge::UnoUrlResolver::create( xLocalContext ) );
+
+ for (;;)
+ {
+ if (abortChannel != 0 && abortChannel->isAborted()) {
+ throw ucb::CommandAbortedException(
+ OUSTR("abort!"), Reference<XInterface>() );
+ }
+ try {
+ return xUnoUrlResolver->resolve( connectString );
+ }
+ catch (connection::NoConnectException &) {
+ TimeValue tv = { 0 /* secs */, 500000000 /* nanosecs */ };
+ ::osl::Thread::wait( tv );
+ }
+ }
+}
+
+#ifdef WNT
+void writeConsoleWithStream(::rtl::OUString const & sText, HANDLE stream)
+{
+ DWORD nWrittenChars = 0;
+ WriteFile(stream, sText.getStr(),
+ sText.getLength() * 2, &nWrittenChars, NULL);
+}
+#else
+void writeConsoleWithStream(::rtl::OUString const & sText, FILE * stream)
+{
+ OString s = OUStringToOString(sText, osl_getThreadTextEncoding());
+ fprintf(stream, "%s", s.getStr());
+ fflush(stream);
+}
+#endif
+
+#ifdef WNT
+void writeConsoleWithStream(::rtl::OString const & sText, HANDLE stream)
+{
+ writeConsoleWithStream(OStringToOUString(
+ sText, RTL_TEXTENCODING_UTF8), stream);
+}
+#else
+void writeConsoleWithStream(::rtl::OString const & sText, FILE * stream)
+{
+ fprintf(stream, "%s", sText.getStr());
+ fflush(stream);
+}
+#endif
+
+void writeConsole(::rtl::OUString const & sText)
+{
+#ifdef WNT
+ writeConsoleWithStream(sText, GetStdHandle(STD_OUTPUT_HANDLE));
+#else
+ writeConsoleWithStream(sText, stdout);
+#endif
+}
+
+void writeConsole(::rtl::OString const & sText)
+{
+#ifdef WNT
+ writeConsoleWithStream(sText, GetStdHandle(STD_OUTPUT_HANDLE));
+#else
+ writeConsoleWithStream(sText, stdout);
+#endif
+}
+
+void writeConsoleError(::rtl::OUString const & sText)
+{
+#ifdef WNT
+ writeConsoleWithStream(sText, GetStdHandle(STD_ERROR_HANDLE));
+#else
+ writeConsoleWithStream(sText, stderr);
+#endif
+}
+
+
+void writeConsoleError(::rtl::OString const & sText)
+{
+#ifdef WNT
+ writeConsoleWithStream(sText, GetStdHandle(STD_ERROR_HANDLE));
+#else
+ writeConsoleWithStream(sText, stderr);
+#endif
+}
+
+
+
+OUString readConsole()
+{
+#ifdef WNT
+ sal_Unicode aBuffer[1024];
+ DWORD dwRead = 0;
+ //unopkg.com feeds unopkg.exe with wchar_t|s
+ if (ReadFile( GetStdHandle(STD_INPUT_HANDLE), &aBuffer, sizeof(aBuffer), &dwRead, NULL ) )
+ {
+ OSL_ASSERT((dwRead % 2) == 0);
+ OUString value( aBuffer, dwRead / 2);
+ return value.trim();
+ }
+#else
+ char buf[1024];
+ rtl_zeroMemory(buf, 1024);
+ // read one char less so that the last char in buf is always zero
+ if (fgets(buf, 1024, stdin) != NULL)
+ {
+ OUString value = ::rtl::OStringToOUString(::rtl::OString(buf), osl_getThreadTextEncoding());
+ return value.trim();
+ }
+#endif
+ return OUString();
+}
+
+void TRACE(::rtl::OUString const & sText)
+{
+ (void) sText;
+#if OSL_DEBUG_LEVEL > 1
+ writeConsole(sText);
+#endif
+}
+
+void TRACE(::rtl::OString const & sText)
+{
+ (void) sText;
+#if OSL_DEBUG_LEVEL > 1
+ writeConsole(sText);
+#endif
+}
+
+void syncRepositories(Reference<ucb::XCommandEnvironment> const & xCmdEnv)
+{
+ OUString sDisable;
+ ::rtl::Bootstrap::get( OUSTR( "DISABLE_EXTENSION_SYNCHRONIZATION" ), sDisable, OUString() );
+ if (sDisable.getLength() > 0)
+ return;
+
+ Reference<deployment::XExtensionManager> xExtensionManager;
+ //synchronize shared before bundled otherewise there are
+ //more revoke and registration calls.
+ sal_Bool bModified = false;
+ if (needToSyncRepostitory(OUString(RTL_CONSTASCII_USTRINGPARAM("shared")))
+ || needToSyncRepostitory(OUString(RTL_CONSTASCII_USTRINGPARAM("bundled"))))
+ {
+ xExtensionManager =
+ deployment::ExtensionManager::get(
+ comphelper_getProcessComponentContext());
+
+ if (xExtensionManager.is())
+ {
+ bModified = xExtensionManager->synchronize(
+ Reference<task::XAbortChannel>(), xCmdEnv);
+ }
+ }
+
+ if (bModified)
+ {
+ Reference<task::XRestartManager> restarter(
+ comphelper_getProcessComponentContext()->getValueByName(
+ OUSTR( "/singletons/com.sun.star.task.OfficeRestartManager") ), UNO_QUERY );
+ if (restarter.is())
+ {
+ OSL_TRACE( "Request restart for modified extensions manager" );
+ restarter->requestRestart(xCmdEnv.is() == sal_True ? xCmdEnv->getInteractionHandler() :
+ Reference<task::XInteractionHandler>());
+ }
+ }
+}
+
+
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/misc/dp_misc.hrc b/desktop/source/deployment/misc/dp_misc.hrc
new file mode 100755
index 000000000000..55fabac5c5b5
--- /dev/null
+++ b/desktop/source/deployment/misc/dp_misc.hrc
@@ -0,0 +1,33 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#if ! defined INCLUDED_DP_MISC_HRC
+#define INCLUDED_DP_MISC_HRC
+
+#include "deployment.hrc"
+
+#endif
diff --git a/desktop/source/deployment/misc/dp_misc.src b/desktop/source/deployment/misc/dp_misc.src
new file mode 100644
index 000000000000..d18fc4c45f16
--- /dev/null
+++ b/desktop/source/deployment/misc/dp_misc.src
@@ -0,0 +1,40 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "dp_misc.hrc"
+
+String RID_DEPLYOMENT_DEPENDENCIES_UNKNOWN {
+ Text[en-US] = "Unknown";
+};
+
+String RID_DEPLYOMENT_DEPENDENCIES_MIN {
+ Text[en-US] = "Extension requires at least %PRODUCTNAME %VERSION";
+};
+
+String RID_DEPLYOMENT_DEPENDENCIES_MAX {
+ Text[en-US] = "Extension doesn't support versions greater than: %PRODUCTNAME %VERSION";
+};
diff --git a/desktop/source/deployment/misc/dp_platform.cxx b/desktop/source/deployment/misc/dp_platform.cxx
new file mode 100644
index 000000000000..d191dd680aa0
--- /dev/null
+++ b/desktop/source/deployment/misc/dp_platform.cxx
@@ -0,0 +1,256 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include "dp_misc.h"
+#include "dp_platform.hxx"
+#include "rtl/ustring.hxx"
+#include "rtl/ustrbuf.hxx"
+#include "rtl/instance.hxx"
+#include "rtl/bootstrap.hxx"
+
+#define PLATFORM_ALL "all"
+#define PLATFORM_WIN_X86 "windows_x86"
+#define PLATFORM_WIN_X86_64 "windows_x86_64"
+#define PLATFORM_LINUX_X86 "linux_x86"
+#define PLATFORM_LINUX_X86_64 "linux_x86_64"
+#define PLATFORM_KFREEBSD_X86 "kfreebsd_x86"
+#define PLATFORM_KFREEBSD_X86_64 "kfreebsd_x86_64"
+#define PLATFORM_LINUX_SPARC "linux_sparc"
+#define PLATFORM_LINUX_POWERPC "linux_powerpc"
+#define PLATFORM_LINUX_POWERPC64 "linux_powerpc64"
+#define PLATFORM_LINUX_ARM_EABI "linux_arm_eabi"
+#define PLATFORM_LINUX_ARM_OABI "linux_arm_oabi"
+#define PLATFORM_LINUX_MIPS_EL "linux_mips_el"
+#define PLATFORM_LINUX_MIPS_EB "linux_mips_eb"
+#define PLATFORM_LINUX_IA64 "linux_ia64"
+#define PLATFORM_LINUX_M68K "linux_m68k"
+#define PLATFORM_LINUX_S390 "linux_s390"
+#define PLATFORM_LINUX_S390x "linux_s390x"
+#define PLATFORM_LINUX_HPPA "linux_hppa"
+#define PLATFORM_LINUX_ALPHA "linux_alpha"
+
+
+
+#define PLATFORM_SOLARIS_SPARC "solaris_sparc"
+#define PLATFORM_SOLARIS_SPARC64 "solaris_sparc64"
+#define PLATFORM_SOLARIS_X86 "solaris_x86"
+#define PLATFORM_FREEBSD_X86 "freebsd_x86"
+#define PLATFORM_FREEBSD_X86_64 "freebsd_x86_64"
+#define PLATFORM_NETBSD_X86 "netbsd_x86"
+#define PLATFORM_NETBSD_X86_64 "netbsd_x86_64"
+#define PLATFORM_MACOSX_X86 "macosx_x86"
+#define PLATFORM_MACOSX_PPC "macosx_powerpc"
+#define PLATFORM_OS2_X86 "os2_x86"
+#define PLATFORM_OPENBSD_X86 "openbsd_x86"
+#define PLATFORM_OPENBSD_X86_64 "openbsd_x86_64"
+#define PLATFORM_DRAGONFLY_X86 "dragonfly_x86"
+#define PLATFORM_DRAGONFLY_X86_64 "dragonfly_x86_64"
+
+
+#define PLATFORM_AIX_POWERPC "aix_powerpc"
+
+
+
+
+
+
+
+#define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
+using ::rtl::OUString;
+namespace css = ::com::sun::star;
+
+namespace dp_misc
+{
+namespace
+{
+ struct StrOperatingSystem :
+ public rtl::StaticWithInit<const OUString, StrOperatingSystem> {
+ const OUString operator () () {
+ OUString os( RTL_CONSTASCII_USTRINGPARAM("$_OS") );
+ ::rtl::Bootstrap::expandMacros( os );
+ return os;
+ }
+ };
+
+ struct StrCPU :
+ public rtl::StaticWithInit<const OUString, StrCPU> {
+ const OUString operator () () {
+ OUString arch( RTL_CONSTASCII_USTRINGPARAM("$_ARCH") );
+ ::rtl::Bootstrap::expandMacros( arch );
+ return arch;
+ }
+ };
+
+
+ struct StrPlatform : public rtl::StaticWithInit<
+ const OUString, StrPlatform> {
+ const OUString operator () () {
+ ::rtl::OUStringBuffer buf;
+ buf.append( StrOperatingSystem::get() );
+ buf.append( static_cast<sal_Unicode>('_') );
+ buf.append( StrCPU::get() );
+ return buf.makeStringAndClear();
+ }
+ };
+
+ bool checkOSandCPU(OUString const & os, OUString const & cpu)
+ {
+ return os.equals(StrOperatingSystem::get())
+ && cpu.equals(StrCPU::get());
+ }
+
+ bool isValidPlatform(OUString const & token )
+ {
+ bool ret = false;
+ if (token.equals(OUSTR(PLATFORM_ALL)))
+ ret = true;
+ else if (token.equals(OUSTR(PLATFORM_WIN_X86)))
+ ret = checkOSandCPU(OUSTR("Windows"), OUSTR("x86"));
+ else if (token.equals(OUSTR(PLATFORM_WIN_X86_64)))
+ ret = checkOSandCPU(OUSTR("Windows"), OUSTR("x86_64"));
+ else if (token.equals(OUSTR(PLATFORM_LINUX_X86)))
+ ret = checkOSandCPU(OUSTR("Linux"), OUSTR("x86"));
+ else if (token.equals(OUSTR(PLATFORM_LINUX_X86_64)))
+ ret = checkOSandCPU(OUSTR("Linux"), OUSTR("X86_64"));
+ else if (token.equals(OUSTR(PLATFORM_KFREEBSD_X86)))
+ ret = checkOSandCPU(OUSTR("kFreeBSD"), OUSTR("x86"));
+ else if (token.equals(OUSTR(PLATFORM_KFREEBSD_X86_64)))
+ ret = checkOSandCPU(OUSTR("kFreeBSD"), OUSTR("X86_64"));
+ else if (token.equals(OUSTR(PLATFORM_LINUX_SPARC)))
+ ret = checkOSandCPU(OUSTR("Linux"), OUSTR("SPARC"));
+ else if (token.equals(OUSTR(PLATFORM_LINUX_POWERPC)))
+ ret = checkOSandCPU(OUSTR("Linux"), OUSTR("PowerPC"));
+ else if (token.equals(OUSTR(PLATFORM_LINUX_POWERPC64)))
+ ret = checkOSandCPU(OUSTR("Linux"), OUSTR("PowerPC_64"));
+ else if (token.equals(OUSTR(PLATFORM_LINUX_ARM_EABI)))
+ ret = checkOSandCPU(OUSTR("Linux"), OUSTR("ARM_EABI"));
+ else if (token.equals(OUSTR(PLATFORM_LINUX_ARM_OABI)))
+ ret = checkOSandCPU(OUSTR("Linux"), OUSTR("ARM_OABI"));
+ else if (token.equals(OUSTR(PLATFORM_LINUX_MIPS_EL)))
+ ret = checkOSandCPU(OUSTR("Linux"), OUSTR("MIPS_EL"));
+ else if (token.equals(OUSTR(PLATFORM_LINUX_MIPS_EB)))
+ ret = checkOSandCPU(OUSTR("Linux"), OUSTR("MIPS_EB"));
+ else if (token.equals(OUSTR(PLATFORM_LINUX_IA64)))
+ ret = checkOSandCPU(OUSTR("Linux"), OUSTR("IA64"));
+ else if (token.equals(OUSTR(PLATFORM_LINUX_M68K)))
+ ret = checkOSandCPU(OUSTR("Linux"), OUSTR("M68K"));
+ else if (token.equals(OUSTR(PLATFORM_LINUX_S390)))
+ ret = checkOSandCPU(OUSTR("Linux"), OUSTR("S390"));
+ else if (token.equals(OUSTR(PLATFORM_LINUX_S390x)))
+ ret = checkOSandCPU(OUSTR("Linux"), OUSTR("S390x"));
+ else if (token.equals(OUSTR(PLATFORM_LINUX_HPPA)))
+ ret = checkOSandCPU(OUSTR("Linux"), OUSTR("HPPA"));
+ else if (token.equals(OUSTR(PLATFORM_LINUX_ALPHA)))
+ ret = checkOSandCPU(OUSTR("Linux"), OUSTR("ALPHA"));
+ else if (token.equals(OUSTR(PLATFORM_SOLARIS_SPARC)))
+ ret = checkOSandCPU(OUSTR("Solaris"), OUSTR("SPARC"));
+ else if (token.equals(OUSTR(PLATFORM_SOLARIS_SPARC64)))
+ ret = checkOSandCPU(OUSTR("Solaris"), OUSTR("SPARC64"));
+ else if (token.equals(OUSTR(PLATFORM_SOLARIS_X86)))
+ ret = checkOSandCPU(OUSTR("Solaris"), OUSTR("x86"));
+ else if (token.equals(OUSTR(PLATFORM_FREEBSD_X86)))
+ ret = checkOSandCPU(OUSTR("FreeBSD"), OUSTR("x86"));
+ else if (token.equals(OUSTR(PLATFORM_FREEBSD_X86_64)))
+ ret = checkOSandCPU(OUSTR("FreeBSD"), OUSTR("X86_64"));
+ else if (token.equals(OUSTR(PLATFORM_NETBSD_X86)))
+ ret = checkOSandCPU(OUSTR("NetBSD"), OUSTR("x86"));
+ else if (token.equals(OUSTR(PLATFORM_NETBSD_X86_64)))
+ ret = checkOSandCPU(OUSTR("NetBSD"), OUSTR("X86_64"));
+ else if (token.equals(OUSTR(PLATFORM_MACOSX_X86)))
+ ret = checkOSandCPU(OUSTR("MacOSX"), OUSTR("x86"));
+ else if (token.equals(OUSTR(PLATFORM_MACOSX_PPC)))
+ ret = checkOSandCPU(OUSTR("MacOSX"), OUSTR("PowerPC"));
+ else if (token.equals(OUSTR(PLATFORM_OS2_X86)))
+ ret = checkOSandCPU(OUSTR("OS2"), OUSTR("x86"));
+ else if (token.equals(OUSTR(PLATFORM_AIX_POWERPC)))
+ ret = checkOSandCPU(OUSTR("AIX"), OUSTR("PowerPC"));
+ else if (token.equals(OUSTR(PLATFORM_OPENBSD_X86)))
+ ret = checkOSandCPU(OUSTR("OpenBSD"), OUSTR("x86"));
+ else if (token.equals(OUSTR(PLATFORM_OPENBSD_X86_64)))
+ ret = checkOSandCPU(OUSTR("OpenBSD"), OUSTR("X86_64"));
+ else if (token.equals(OUSTR(PLATFORM_DRAGONFLY_X86)))
+ ret = checkOSandCPU(OUSTR("DragonFly"), OUSTR("x86"));
+ else if (token.equals(OUSTR(PLATFORM_DRAGONFLY_X86_64)))
+ ret = checkOSandCPU(OUSTR("DragonFly"), OUSTR("X86_64"));
+ else
+ {
+ OSL_FAIL("Extension Manager: The extension supports an unknown platform. "
+ "Check the platform element in the description.xml");
+ ret = false;
+ }
+ return ret;
+ }
+
+} // anon namespace
+//=============================================================================
+
+OUString const & getPlatformString()
+{
+ return StrPlatform::get();
+}
+
+bool platform_fits( OUString const & platform_string )
+{
+ sal_Int32 index = 0;
+ for (;;)
+ {
+ const OUString token(
+ platform_string.getToken( 0, ',', index ).trim() );
+ // check if this platform:
+ if (token.equalsIgnoreAsciiCase( StrPlatform::get() ) ||
+ (token.indexOf( '_' ) < 0 && /* check OS part only */
+ token.equalsIgnoreAsciiCase( StrOperatingSystem::get() )))
+ {
+ return true;
+ }
+ if (index < 0)
+ break;
+ }
+ return false;
+}
+
+bool hasValidPlatform( css::uno::Sequence<OUString> const & platformStrings)
+{
+ bool ret = false;
+ for (sal_Int32 i = 0; i < platformStrings.getLength(); i++)
+ {
+ if (isValidPlatform(platformStrings[i]))
+ {
+ ret = true;
+ break;
+ }
+ }
+ return ret;
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/misc/dp_resource.cxx b/desktop/source/deployment/misc/dp_resource.cxx
new file mode 100644
index 000000000000..82c5847811e5
--- /dev/null
+++ b/desktop/source/deployment/misc/dp_resource.cxx
@@ -0,0 +1,235 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include "dp_misc.h"
+#include "dp_resource.h"
+#include "osl/module.hxx"
+#include "osl/mutex.hxx"
+#include "rtl/ustring.h"
+#include "cppuhelper/implbase1.hxx"
+#include "unotools/configmgr.hxx"
+
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using ::rtl::OUString;
+
+namespace dp_misc {
+namespace {
+
+struct OfficeLocale :
+ public rtl::StaticWithInit<const OUString, OfficeLocale> {
+ const OUString operator () () {
+ OUString slang;
+ if (! (::utl::ConfigManager::GetDirectConfigProperty(
+ ::utl::ConfigManager::LOCALE ) >>= slang))
+ throw RuntimeException( OUSTR("Cannot determine language!"), 0 );
+ //fallback, the locale is currently only set when the user starts the
+ //office for the first time.
+ if (slang.getLength() == 0)
+ slang = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("en-US"));
+ return slang;
+ }
+};
+
+struct DeploymentResMgr : public rtl::StaticWithInit<
+ ResMgr *, DeploymentResMgr> {
+ ResMgr * operator () () {
+ return ResMgr::CreateResMgr( "deployment", getOfficeLocale() );
+ }
+};
+
+osl::Mutex s_mutex;
+
+} // anon namespace
+
+//==============================================================================
+ResId getResId( sal_uInt16 id )
+{
+ const osl::MutexGuard guard( s_mutex );
+ return ResId( id, *DeploymentResMgr::get() );
+}
+
+//==============================================================================
+String getResourceString( sal_uInt16 id )
+{
+ const osl::MutexGuard guard( s_mutex );
+ String ret( ResId( id, *DeploymentResMgr::get() ) );
+ if (ret.SearchAscii( "%PRODUCTNAME" ) != STRING_NOTFOUND) {
+ static String s_brandName;
+ if (s_brandName.Len() == 0) {
+ OUString brandName(
+ ::utl::ConfigManager::GetDirectConfigProperty(
+ ::utl::ConfigManager::PRODUCTNAME ).get<OUString>() );
+ s_brandName = brandName;
+ }
+ ret.SearchAndReplaceAllAscii( "%PRODUCTNAME", s_brandName );
+ }
+ return ret;
+}
+
+//throws an Exception on failure
+//primary subtag 2 or three letters(A-Z, a-z), i or x
+void checkPrimarySubtag(::rtl::OUString const & tag)
+{
+ sal_Int32 len = tag.getLength();
+ sal_Unicode const * arLang = tag.getStr();
+ if (len < 1 || len > 3)
+ throw Exception(OUSTR("Invalid language string."), 0);
+
+ if (len == 1
+ && (arLang[0] != 'i' && arLang[0] != 'x'))
+ throw Exception(OUSTR("Invalid language string."), 0);
+
+ if (len == 2 || len == 3)
+ {
+ for (sal_Int32 i = 0; i < len; i++)
+ {
+ if ( !((arLang[i] >= 'A' && arLang[i] <= 'Z')
+ || (arLang[i] >= 'a' && arLang[i] <= 'z')))
+ {
+ throw Exception(OUSTR("Invalid language string."), 0);
+ }
+ }
+ }
+}
+
+//throws an Exception on failure
+//second subtag 2 letter country code or 3-8 letter other code(A-Z, a-z, 0-9)
+void checkSecondSubtag(::rtl::OUString const & tag, bool & bIsCountry)
+{
+ sal_Int32 len = tag.getLength();
+ sal_Unicode const * arLang = tag.getStr();
+ if (len < 2 || len > 8)
+ throw Exception(OUSTR("Invalid language string."), 0);
+ //country code
+ bIsCountry = false;
+ if (len == 2)
+ {
+ for (sal_Int32 i = 0; i < 2; i++)
+ {
+ if (!( (arLang[i] >= 'A' && arLang[i] <= 'Z')
+ || (arLang[i] >= 'a' && arLang[i] <= 'z')))
+ {
+ throw Exception(OUSTR("Invalid language string."), 0);
+ }
+ }
+ bIsCountry = true;
+ }
+
+ if (len > 2)
+ {
+ for (sal_Int32 i = 0; i < len; i++)
+ {
+ if (!( (arLang[i] >= 'A' && arLang[i] <= 'Z')
+ || (arLang[i] >= 'a' && arLang[i] <= 'z')
+ || (arLang[i] >= '0' && arLang[i] <= '9') ))
+ {
+ throw Exception(OUSTR("Invalid language string."), 0);
+ }
+ }
+ }
+}
+
+void checkThirdSubtag(::rtl::OUString const & tag)
+{
+ sal_Int32 len = tag.getLength();
+ sal_Unicode const * arLang = tag.getStr();
+ if (len < 1 || len > 8)
+ throw Exception(OUSTR("Invalid language string."), 0);
+
+ for (sal_Int32 i = 0; i < len; i++)
+ {
+ if (!( (arLang[i] >= 'A' && arLang[i] <= 'Z')
+ || (arLang[i] >= 'a' && arLang[i] <= 'z')
+ || (arLang[i] >= '0' && arLang[i] <= '9') ))
+ {
+ throw Exception(OUSTR("Invalid language string."), 0);
+ }
+ }
+}
+
+//=============================================================================
+
+//We parse the string acording to RFC 3066
+//We only use the primary sub-tag and two subtags. That is lang-country-variant
+//We do some simple tests if the string is correct. Actually this should do a
+//validating parser
+//We may have the case that there is no country tag, for example en-welsh
+::com::sun::star::lang::Locale toLocale( ::rtl::OUString const & slang )
+{
+ OUString _sLang = slang.trim();
+ ::com::sun::star::lang::Locale locale;
+ sal_Int32 nIndex = 0;
+ OUString lang = _sLang.getToken( 0, '-', nIndex );
+ checkPrimarySubtag(lang);
+ locale.Language = lang;
+ OUString country = _sLang.getToken( 0, '-', nIndex );
+ if (country.getLength() > 0)
+ {
+ bool bIsCountry = false;
+ checkSecondSubtag(country, bIsCountry);
+ if (bIsCountry)
+ {
+ locale.Country = country;
+ }
+ else
+ {
+ locale.Variant = country;
+ }
+ }
+ if (locale.Variant.getLength() == 0)
+ {
+ OUString variant = _sLang.getToken( 0, '-', nIndex );
+ if (variant.getLength() > 0)
+ {
+ checkThirdSubtag(variant);
+ locale.Variant = variant;
+ }
+ }
+
+ return locale;
+}
+
+//==============================================================================
+lang::Locale getOfficeLocale()
+{
+ return toLocale(OfficeLocale::get());
+}
+
+::rtl::OUString getOfficeLocaleString()
+{
+ return OfficeLocale::get();
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/misc/dp_ucb.cxx b/desktop/source/deployment/misc/dp_ucb.cxx
new file mode 100644
index 000000000000..fa3896aab8c4
--- /dev/null
+++ b/desktop/source/deployment/misc/dp_ucb.cxx
@@ -0,0 +1,323 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include "dp_misc.hrc"
+#include "dp_misc.h"
+#include "dp_ucb.h"
+#include "rtl/uri.hxx"
+#include "rtl/ustrbuf.hxx"
+#include "ucbhelper/content.hxx"
+#include "xmlscript/xml_helper.hxx"
+#include "com/sun/star/io/XInputStream.hpp"
+#include "com/sun/star/ucb/CommandFailedException.hpp"
+#include "com/sun/star/ucb/ContentInfo.hpp"
+#include "com/sun/star/ucb/ContentInfoAttribute.hpp"
+
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::ucb;
+using ::rtl::OUString;
+
+namespace dp_misc
+{
+
+const OUString StrTitle::operator () ()
+{
+ return OUSTR("Title");
+}
+
+//==============================================================================
+bool create_ucb_content(
+ ::ucbhelper::Content * ret_ucbContent, OUString const & url,
+ Reference<XCommandEnvironment> const & xCmdEnv,
+ bool throw_exc )
+{
+ try {
+ // Existense check...
+ // content ctor/isFolder() will throw exception in case the resource
+ // does not exist.
+
+ // dilemma: no chance to use the given iahandler here, because it would
+ // raise no such file dialogs, else no interaction for
+ // passwords, ...? xxx todo
+ ::ucbhelper::Content ucbContent(
+ url, Reference<XCommandEnvironment>() );
+
+ ucbContent.isFolder();
+
+ if (ret_ucbContent != 0)
+ {
+ ucbContent.setCommandEnvironment( xCmdEnv );
+ *ret_ucbContent = ucbContent;
+ }
+ return true;
+ }
+ catch (RuntimeException &) {
+ throw;
+ }
+ catch (Exception &) {
+ if (throw_exc)
+ throw;
+ }
+ return false;
+}
+
+//==============================================================================
+bool create_folder(
+ ::ucbhelper::Content * ret_ucb_content, OUString const & url_,
+ Reference<XCommandEnvironment> const & xCmdEnv, bool throw_exc )
+{
+ ::ucbhelper::Content ucb_content;
+ if (create_ucb_content(
+ &ucb_content, url_, xCmdEnv, false /* no throw */ ))
+ {
+ if (ucb_content.isFolder()) {
+ if (ret_ucb_content != 0)
+ *ret_ucb_content = ucb_content;
+ return true;
+ }
+ }
+
+ OUString url( url_ );
+ // xxx todo: find parent
+ sal_Int32 slash = url.lastIndexOf( '/' );
+ if (slash < 0) {
+ // fallback:
+ url = expandUnoRcUrl( url );
+ slash = url.lastIndexOf( '/' );
+ }
+ if (slash < 0) {
+ // invalid: has to be at least "auth:/..."
+ if (throw_exc)
+ throw ContentCreationException(
+ OUSTR("Cannot create folder (invalid path): ") + url,
+ Reference<XInterface>(), ContentCreationError_UNKNOWN );
+ return false;
+ }
+ ::ucbhelper::Content parentContent;
+ if (! create_folder(
+ &parentContent, url.copy( 0, slash ), xCmdEnv, throw_exc ))
+ return false;
+ const Any title( ::rtl::Uri::decode( url.copy( slash + 1 ),
+ rtl_UriDecodeWithCharset,
+ RTL_TEXTENCODING_UTF8 ) );
+ const Sequence<ContentInfo> infos(
+ parentContent.queryCreatableContentsInfo() );
+ for ( sal_Int32 pos = 0; pos < infos.getLength(); ++pos )
+ {
+ // look KIND_FOLDER:
+ ContentInfo const & info = infos[ pos ];
+ if ((info.Attributes & ContentInfoAttribute::KIND_FOLDER) != 0)
+ {
+ // make sure the only required bootstrap property is "Title":
+ Sequence<beans::Property> const & rProps = info.Properties;
+ if (rProps.getLength() != 1 ||
+ !rProps[ 0 ].Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM("Title") ))
+ continue;
+
+ try {
+ if (parentContent.insertNewContent(
+ info.Type,
+ Sequence<OUString>( &StrTitle::get(), 1 ),
+ Sequence<Any>( &title, 1 ),
+ ucb_content )) {
+ if (ret_ucb_content != 0)
+ *ret_ucb_content = ucb_content;
+ return true;
+ }
+ }
+ catch (RuntimeException &) {
+ throw;
+ }
+ catch (CommandFailedException &) {
+ // Interaction Handler already handled the error
+ // that has occurred...
+ }
+ catch (Exception &) {
+ if (throw_exc)
+ throw;
+ return false;
+ }
+ }
+ }
+ if (throw_exc)
+ throw ContentCreationException(
+ OUSTR("Cannot create folder: ") + url,
+ Reference<XInterface>(), ContentCreationError_UNKNOWN );
+ return false;
+}
+
+//==============================================================================
+bool erase_path( OUString const & url,
+ Reference<XCommandEnvironment> const & xCmdEnv,
+ bool throw_exc )
+{
+ ::ucbhelper::Content ucb_content;
+ if (create_ucb_content( &ucb_content, url, xCmdEnv, false /* no throw */ ))
+ {
+ try {
+ ucb_content.executeCommand(
+ OUSTR("delete"), Any( true /* delete physically */ ) );
+ }
+ catch (RuntimeException &) {
+ throw;
+ }
+ catch (Exception &) {
+ if (throw_exc)
+ throw;
+ return false;
+ }
+ }
+ return true;
+}
+
+//==============================================================================
+::rtl::ByteSequence readFile( ::ucbhelper::Content & ucb_content )
+{
+ ::rtl::ByteSequence bytes;
+ Reference<io::XOutputStream> xStream(
+ ::xmlscript::createOutputStream( &bytes ) );
+ if (! ucb_content.openStream( xStream ))
+ throw RuntimeException(
+ OUSTR(
+ "::ucbhelper::Content::openStream( XOutputStream ) failed!"),
+ 0 );
+ return bytes;
+}
+
+//==============================================================================
+bool readLine( OUString * res, OUString const & startingWith,
+ ::ucbhelper::Content & ucb_content, rtl_TextEncoding textenc )
+{
+ // read whole file:
+ ::rtl::ByteSequence bytes( readFile( ucb_content ) );
+ OUString file( reinterpret_cast<sal_Char const *>(bytes.getConstArray()),
+ bytes.getLength(), textenc );
+ sal_Int32 pos = 0;
+ for (;;)
+ {
+ if (file.match( startingWith, pos ))
+ {
+ ::rtl::OUStringBuffer buf;
+ sal_Int32 start = pos;
+ pos += startingWith.getLength();
+ for (;;)
+ {
+ pos = file.indexOf( LF, pos );
+ if (pos < 0) { // EOF
+ buf.append( file.copy( start ) );
+ }
+ else
+ {
+ if (pos > 0 && file[ pos - 1 ] == CR)
+ {
+ // consume extra CR
+ buf.append( file.copy( start, pos - start - 1 ) );
+ ++pos;
+ }
+ else
+ buf.append( file.copy( start, pos - start ) );
+ ++pos; // consume LF
+ // check next line:
+ if (pos < file.getLength() &&
+ (file[ pos ] == ' ' || file[ pos ] == '\t'))
+ {
+ buf.append( static_cast<sal_Unicode>(' ') );
+ ++pos;
+ start = pos;
+ continue;
+ }
+ }
+ break;
+ }
+ *res = buf.makeStringAndClear();
+ return true;
+ }
+ // next line:
+ sal_Int32 next_lf = file.indexOf( LF, pos );
+ if (next_lf < 0) // EOF
+ break;
+ pos = next_lf + 1;
+ }
+ return false;
+}
+
+bool readProperties( ::std::list< ::std::pair< ::rtl::OUString, ::rtl::OUString> > & out_result,
+ ::ucbhelper::Content & ucb_content )
+{
+ // read whole file:
+ ::rtl::ByteSequence bytes( readFile( ucb_content ) );
+ OUString file( reinterpret_cast<sal_Char const *>(bytes.getConstArray()),
+ bytes.getLength(), RTL_TEXTENCODING_UTF8);
+ sal_Int32 pos = 0;
+
+ for (;;)
+ {
+
+ ::rtl::OUStringBuffer buf;
+ sal_Int32 start = pos;
+
+ bool bEOF = false;
+ pos = file.indexOf( LF, pos );
+ if (pos < 0) { // EOF
+ buf.append( file.copy( start ) );
+ bEOF = true;
+ }
+ else
+ {
+ if (pos > 0 && file[ pos - 1 ] == CR)
+ // consume extra CR
+ buf.append( file.copy( start, pos - start - 1 ) );
+ else
+ buf.append( file.copy( start, pos - start ) );
+ pos++;
+ }
+ OUString aLine = buf.makeStringAndClear();
+
+ sal_Int32 posEqual = aLine.indexOf('=');
+ if (posEqual > 0 && (posEqual + 1) < aLine.getLength())
+ {
+ OUString name = aLine.copy(0, posEqual);
+ OUString value = aLine.copy(posEqual + 1);
+ out_result.push_back(::std::make_pair(name, value));
+ }
+
+ if (bEOF)
+ break;
+ }
+ return false;
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/misc/dp_update.cxx b/desktop/source/deployment/misc/dp_update.cxx
new file mode 100644
index 000000000000..8aee216e44cc
--- /dev/null
+++ b/desktop/source/deployment/misc/dp_update.cxx
@@ -0,0 +1,425 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+
+#include "dp_update.hxx"
+#include "dp_version.hxx"
+#include "dp_identifier.hxx"
+#include "dp_descriptioninfoset.hxx"
+
+#include "rtl/bootstrap.hxx"
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using ::rtl::OUString;
+using ::rtl::OString;
+
+
+namespace dp_misc {
+namespace {
+
+int determineHighestVersion(
+ ::rtl::OUString const & userVersion,
+ ::rtl::OUString const & sharedVersion,
+ ::rtl::OUString const & bundledVersion,
+ ::rtl::OUString const & onlineVersion)
+{
+ int index = 0;
+ OUString greatest = userVersion;
+ if (dp_misc::compareVersions(sharedVersion, greatest) == dp_misc::GREATER)
+ {
+ index = 1;
+ greatest = sharedVersion;
+ }
+ if (dp_misc::compareVersions(bundledVersion, greatest) == dp_misc::GREATER)
+ {
+ index = 2;
+ greatest = bundledVersion;
+ }
+ if (dp_misc::compareVersions(onlineVersion, greatest) == dp_misc::GREATER)
+ {
+ index = 3;
+ }
+ return index;
+}
+
+Sequence< Reference< xml::dom::XElement > >
+getUpdateInformation( Reference<deployment::XUpdateInformationProvider > const & updateInformation,
+ Sequence< OUString > const & urls,
+ OUString const & identifier,
+ uno::Any & out_error)
+{
+ try {
+ return updateInformation->getUpdateInformation(urls, identifier);
+ } catch (uno::RuntimeException &) {
+ throw;
+ } catch (ucb::CommandFailedException & e) {
+ out_error = e.Reason;
+ } catch (ucb::CommandAbortedException &) {
+ } catch (uno::Exception & e) {
+ out_error = uno::makeAny(e);
+ }
+ return
+ Sequence<Reference< xml::dom::XElement > >();
+}
+
+void getOwnUpdateInfos(
+ Reference<uno::XComponentContext> const & xContext,
+ Reference<deployment::XUpdateInformationProvider > const & updateInformation,
+ UpdateInfoMap& inout_map, std::vector<std::pair<Reference<deployment::XPackage>, uno::Any> > & out_errors,
+ bool & out_allFound)
+{
+ bool allHaveOwnUpdateInformation = true;
+ for (UpdateInfoMap::iterator i = inout_map.begin(); i != inout_map.end(); ++i)
+ {
+ OSL_ASSERT(i->second.extension.is());
+ Sequence<OUString> urls(i->second.extension->getUpdateInformationURLs());
+ if (urls.getLength())
+ {
+ const OUString id = dp_misc::getIdentifier(i->second.extension);
+ uno::Any anyError;
+ //It is unclear from the idl if there can be a null reference returned.
+ //However all valid information should be the same
+ Sequence<Reference< xml::dom::XElement > >
+ infos(getUpdateInformation(updateInformation, urls, id, anyError));
+ if (anyError.hasValue())
+ out_errors.push_back(std::make_pair(i->second.extension, anyError));
+
+ for (sal_Int32 j = 0; j < infos.getLength(); ++j)
+ {
+ dp_misc::DescriptionInfoset infoset(
+ xContext,
+ Reference< xml::dom::XNode >(infos[j], UNO_QUERY_THROW));
+ if (!infoset.hasDescription())
+ continue;
+ boost::optional< OUString > id2(infoset.getIdentifier());
+ if (!id2)
+ continue;
+ OSL_ASSERT(*id2 == id);
+ if (*id2 == id)
+ {
+ i->second.version = infoset.getVersion();
+ i->second.info = Reference< xml::dom::XNode >(
+ infos[j], UNO_QUERY_THROW);
+ }
+ break;
+ }
+ }
+ else
+ {
+ allHaveOwnUpdateInformation &= false;
+ }
+ }
+ out_allFound = allHaveOwnUpdateInformation;
+}
+
+void getDefaultUpdateInfos(
+ Reference<uno::XComponentContext> const & xContext,
+ Reference<deployment::XUpdateInformationProvider > const & updateInformation,
+ UpdateInfoMap& inout_map,
+ std::vector<std::pair<Reference<deployment::XPackage>, uno::Any> > & out_errors)
+{
+ const rtl::OUString sDefaultURL(dp_misc::getExtensionDefaultUpdateURL());
+ OSL_ASSERT(sDefaultURL.getLength());
+
+ Any anyError;
+ Sequence< Reference< xml::dom::XElement > >
+ infos(
+ getUpdateInformation(
+ updateInformation,
+ Sequence< OUString >(&sDefaultURL, 1), OUString(), anyError));
+ if (anyError.hasValue())
+ out_errors.push_back(std::make_pair(Reference<deployment::XPackage>(), anyError));
+ for (sal_Int32 i = 0; i < infos.getLength(); ++i)
+ {
+ Reference< xml::dom::XNode > node(infos[i], UNO_QUERY_THROW);
+ dp_misc::DescriptionInfoset infoset(xContext, node);
+ boost::optional< OUString > id(infoset.getIdentifier());
+ if (!id) {
+ continue;
+ }
+ UpdateInfoMap::iterator j = inout_map.find(*id);
+ if (j != inout_map.end())
+ {
+ //skip those extension which provide its own update urls
+ if (j->second.extension->getUpdateInformationURLs().getLength())
+ continue;
+ OUString v(infoset.getVersion());
+ //look for the highest version in the online repository
+ if (dp_misc::compareVersions(v, j->second.version) ==
+ dp_misc::GREATER)
+ {
+ j->second.version = v;
+ j->second.info = node;
+ }
+ }
+ }
+}
+
+bool containsBundledOnly(Sequence<Reference<deployment::XPackage> > const & sameIdExtensions)
+{
+ OSL_ASSERT(sameIdExtensions.getLength() == 3);
+ return !sameIdExtensions[0].is() && !sameIdExtensions[1].is() && sameIdExtensions[2].is();
+}
+
+/** Returns true if the list of extensions are bundled extensions and there are no
+ other extensions with the same identifier in the shared or user repository.
+ If extensionList is NULL, then it is checked if there are only bundled extensions.
+*/
+bool onlyBundledExtensions(
+ Reference<deployment::XExtensionManager> const & xExtMgr,
+ std::vector< Reference<deployment::XPackage > > const * extensionList)
+{
+ OSL_ASSERT(xExtMgr.is());
+ bool onlyBundled = true;
+ if (extensionList)
+ {
+ typedef std::vector<Reference<deployment::XPackage > >::const_iterator CIT;
+ for (CIT i(extensionList->begin()), aEnd(extensionList->end()); onlyBundled && i != aEnd; ++i)
+ {
+ Sequence<Reference<deployment::XPackage> > seqExt = xExtMgr->getExtensionsWithSameIdentifier(
+ dp_misc::getIdentifier(*i), (*i)->getName(), Reference<ucb::XCommandEnvironment>());
+
+ onlyBundled = containsBundledOnly(seqExt);
+ }
+ }
+ else
+ {
+ const uno::Sequence< uno::Sequence< Reference<deployment::XPackage > > > seqAllExt =
+ xExtMgr->getAllExtensions(Reference<task::XAbortChannel>(), Reference<ucb::XCommandEnvironment>());
+
+ for (int pos(0), nLen(seqAllExt.getLength()); onlyBundled && pos != nLen; ++pos)
+ {
+ onlyBundled = containsBundledOnly(seqAllExt[pos]);
+ }
+ }
+ return onlyBundled;
+}
+
+} // anon namespace
+
+
+OUString getExtensionDefaultUpdateURL()
+{
+ ::rtl::OUString sUrl(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "${$BRAND_BASE_DIR/program/" SAL_CONFIGFILE("version")
+ ":Version:ExtensionUpdateURL}"));
+ ::rtl::Bootstrap::expandMacros(sUrl);
+ return sUrl;
+}
+
+/* returns the index of the greatest version, starting with 0
+
+ */
+UPDATE_SOURCE isUpdateUserExtension(
+ bool bReadOnlyShared,
+ ::rtl::OUString const & userVersion,
+ ::rtl::OUString const & sharedVersion,
+ ::rtl::OUString const & bundledVersion,
+ ::rtl::OUString const & onlineVersion)
+{
+ UPDATE_SOURCE retVal = UPDATE_SOURCE_NONE;
+ if (bReadOnlyShared)
+ {
+ if (userVersion.getLength())
+ {
+ int index = determineHighestVersion(
+ userVersion, sharedVersion, bundledVersion, onlineVersion);
+ if (index == 1)
+ retVal = UPDATE_SOURCE_SHARED;
+ else if (index == 2)
+ retVal = UPDATE_SOURCE_BUNDLED;
+ else if (index == 3)
+ retVal = UPDATE_SOURCE_ONLINE;
+ }
+ else if (sharedVersion.getLength())
+ {
+ int index = determineHighestVersion(
+ OUString(), sharedVersion, bundledVersion, onlineVersion);
+ if (index == 2)
+ retVal = UPDATE_SOURCE_BUNDLED;
+ else if (index == 3)
+ retVal = UPDATE_SOURCE_ONLINE;
+
+ }
+ }
+ else
+ {
+ if (userVersion.getLength())
+ {
+ int index = determineHighestVersion(
+ userVersion, sharedVersion, bundledVersion, onlineVersion);
+ if (index == 1)
+ retVal = UPDATE_SOURCE_SHARED;
+ else if (index == 2)
+ retVal = UPDATE_SOURCE_BUNDLED;
+ else if (index == 3)
+ retVal = UPDATE_SOURCE_ONLINE;
+ }
+ }
+
+ return retVal;
+}
+
+UPDATE_SOURCE isUpdateSharedExtension(
+ bool bReadOnlyShared,
+ ::rtl::OUString const & sharedVersion,
+ ::rtl::OUString const & bundledVersion,
+ ::rtl::OUString const & onlineVersion)
+{
+ if (bReadOnlyShared)
+ return UPDATE_SOURCE_NONE;
+ UPDATE_SOURCE retVal = UPDATE_SOURCE_NONE;
+
+ if (sharedVersion.getLength())
+ {
+ int index = determineHighestVersion(
+ OUString(), sharedVersion, bundledVersion, onlineVersion);
+ if (index == 2)
+ retVal = UPDATE_SOURCE_BUNDLED;
+ else if (index == 3)
+ retVal = UPDATE_SOURCE_ONLINE;
+ }
+ return retVal;
+}
+
+Reference<deployment::XPackage>
+getExtensionWithHighestVersion(
+ Sequence<Reference<deployment::XPackage> > const & seqExt)
+{
+ if (seqExt.getLength() == 0)
+ return Reference<deployment::XPackage>();
+
+ Reference<deployment::XPackage> greatest;
+ sal_Int32 len = seqExt.getLength();
+
+ for (sal_Int32 i = 0; i < len; i++)
+ {
+ if (!greatest.is())
+ {
+ greatest = seqExt[i];
+ continue;
+ }
+ Reference<deployment::XPackage> const & current = seqExt[i];
+ //greatest has a value
+ if (! current.is())
+ continue;
+
+ if (dp_misc::compareVersions(current->getVersion(), greatest->getVersion()) == dp_misc::GREATER)
+ greatest = current;
+ }
+ return greatest;
+}
+
+UpdateInfo::UpdateInfo( Reference< deployment::XPackage> const & ext):
+extension(ext)
+{
+}
+
+
+
+UpdateInfoMap getOnlineUpdateInfos(
+ Reference<uno::XComponentContext> const &xContext,
+ Reference<deployment::XExtensionManager> const & xExtMgr,
+ Reference<deployment::XUpdateInformationProvider > const & updateInformation,
+ std::vector<Reference<deployment::XPackage > > const * extensionList,
+ std::vector<std::pair< Reference<deployment::XPackage>, uno::Any> > & out_errors)
+{
+ OSL_ASSERT(xExtMgr.is());
+ UpdateInfoMap infoMap;
+ if (!xExtMgr.is() || onlyBundledExtensions(xExtMgr, extensionList))
+ return infoMap;
+
+ if (!extensionList)
+ {
+ const uno::Sequence< uno::Sequence< Reference<deployment::XPackage > > > seqAllExt = xExtMgr->getAllExtensions(
+ Reference<task::XAbortChannel>(), Reference<ucb::XCommandEnvironment>());
+
+ //fill the UpdateInfoMap. key = extension identifier, value = UpdateInfo
+ for (int pos = seqAllExt.getLength(); pos --; )
+ {
+ uno::Sequence<Reference<deployment::XPackage> > const & seqExt = seqAllExt[pos];
+
+ Reference<deployment::XPackage> extension = getExtensionWithHighestVersion(seqExt);
+ OSL_ASSERT(extension.is());
+
+ std::pair<UpdateInfoMap::iterator, bool> insertRet = infoMap.insert(
+ UpdateInfoMap::value_type(
+ dp_misc::getIdentifier(extension), UpdateInfo(extension)));
+ OSL_ASSERT(insertRet.second == true);
+ (void)insertRet;
+ }
+ }
+ else
+ {
+ typedef std::vector<Reference<deployment::XPackage > >::const_iterator CIT;
+ for (CIT i = extensionList->begin(); i != extensionList->end(); ++i)
+ {
+ OSL_ASSERT(i->is());
+ std::pair<UpdateInfoMap::iterator, bool> insertRet = infoMap.insert(
+ UpdateInfoMap::value_type(
+ dp_misc::getIdentifier(*i), UpdateInfo(*i)));
+ OSL_ASSERT(insertRet.second == true);
+ (void)insertRet;
+ }
+ }
+
+ //Now find the update information for the extensions which provide their own
+ //URLs to update information.
+ bool allInfosObtained = false;
+ getOwnUpdateInfos(xContext, updateInformation, infoMap, out_errors, allInfosObtained);
+
+ if (!allInfosObtained)
+ getDefaultUpdateInfos(xContext, updateInformation, infoMap, out_errors);
+ return infoMap;
+}
+OUString getHighestVersion(
+ ::rtl::OUString const & userVersion,
+ ::rtl::OUString const & sharedVersion,
+ ::rtl::OUString const & bundledVersion,
+ ::rtl::OUString const & onlineVersion)
+{
+ int index = determineHighestVersion(userVersion, sharedVersion, bundledVersion, onlineVersion);
+ switch (index)
+ {
+ case 0: return userVersion;
+ case 1: return sharedVersion;
+ case 2: return bundledVersion;
+ case 3: return onlineVersion;
+ default: OSL_ASSERT(0);
+ }
+
+ return OUString();
+}
+} //namespace dp_misc
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/misc/dp_version.cxx b/desktop/source/deployment/misc/dp_version.cxx
new file mode 100644
index 000000000000..5c563b7dafb7
--- /dev/null
+++ b/desktop/source/deployment/misc/dp_version.cxx
@@ -0,0 +1,77 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include "sal/config.h"
+
+#include "com/sun/star/deployment/XPackage.hpp"
+#include "rtl/ustring.hxx"
+
+#include "dp_version.hxx"
+
+namespace {
+
+namespace css = ::com::sun::star;
+
+::rtl::OUString getElement(::rtl::OUString const & version, ::sal_Int32 * index)
+{
+ while (*index < version.getLength() && version[*index] == '0') {
+ ++*index;
+ }
+ return version.getToken(0, '.', *index);
+}
+
+}
+
+namespace dp_misc {
+
+::dp_misc::Order compareVersions(
+ ::rtl::OUString const & version1, ::rtl::OUString const & version2)
+{
+ for (::sal_Int32 i1 = 0, i2 = 0; i1 >= 0 || i2 >= 0;) {
+ ::rtl::OUString e1(getElement(version1, &i1));
+ ::rtl::OUString e2(getElement(version2, &i2));
+ if (e1.getLength() < e2.getLength()) {
+ return ::dp_misc::LESS;
+ } else if (e1.getLength() > e2.getLength()) {
+ return ::dp_misc::GREATER;
+ } else if (e1 < e2) {
+ return ::dp_misc::LESS;
+ } else if (e1 > e2) {
+ return ::dp_misc::GREATER;
+ }
+ }
+ return ::dp_misc::EQUAL;
+}
+
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/misc/makefile.mk b/desktop/source/deployment/misc/makefile.mk
new file mode 100755
index 000000000000..3e4bd68cb4c0
--- /dev/null
+++ b/desktop/source/deployment/misc/makefile.mk
@@ -0,0 +1,95 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ = ..$/..$/..
+
+PRJNAME = desktop
+TARGET = deployment_misc
+USE_DEFFILE = TRUE
+ENABLE_EXCEPTIONS = TRUE
+VISIBILITY_HIDDEN=TRUE
+
+.IF "$(GUI)"=="OS2"
+TARGET = deplmisc
+.ENDIF
+
+.INCLUDE : settings.mk
+
+# Reduction of exported symbols:
+CDEFS += -DDESKTOP_DEPLOYMENTMISC_DLLIMPLEMENTATION
+
+.IF "$(SYSTEM_DB)" == "YES"
+CFLAGS+=-DSYSTEM_DB -I$(DB_INCLUDES)
+.ENDIF
+
+SRS1NAME = $(TARGET)
+SRC1FILES = \
+ dp_misc.src
+
+.IF "$(GUI)"=="OS2"
+SHL1TARGET = $(TARGET)
+.ELSE
+SHL1TARGET = deploymentmisc$(DLLPOSTFIX)
+.ENDIF
+SHL1OBJS = \
+ $(SLO)$/dp_misc.obj \
+ $(SLO)$/dp_resource.obj \
+ $(SLO)$/dp_identifier.obj \
+ $(SLO)$/dp_interact.obj \
+ $(SLO)$/dp_ucb.obj \
+ $(SLO)$/db.obj \
+ $(SLO)$/dp_version.obj \
+ $(SLO)$/dp_descriptioninfoset.obj \
+ $(SLO)$/dp_dependencies.obj \
+ $(SLO)$/dp_platform.obj \
+ $(SLO)$/dp_update.obj
+
+SHL1STDLIBS = \
+ $(BERKELEYLIB) \
+ $(CPPUHELPERLIB) \
+ $(CPPULIB) \
+ $(SALLIB) \
+ $(TOOLSLIB) \
+ $(UCBHELPERLIB) \
+ $(UNOTOOLSLIB) \
+ $(XMLSCRIPTLIB) \
+ $(COMPHELPERLIB)
+.IF "$(GUI)"=="OS2"
+SHL1IMPLIB = ideploymentmisc$(DLLPOSTFIX)
+LIB1TARGET = $(SLB)$/_deplmisc.lib
+LIB1OBJFILES = $(SHL1OBJS)
+DEFLIB1NAME = _deplmisc
+.ELSE
+SHL1IMPLIB = i$(SHL1TARGET)
+.ENDIF
+DEF1NAME = $(SHL1TARGET)
+
+SLOFILES = $(SHL1OBJS)
+
+.INCLUDE : ..$/target.pmk
+.INCLUDE : target.mk
+
diff --git a/desktop/source/deployment/registry/component/dp_compbackenddb.cxx b/desktop/source/deployment/registry/component/dp_compbackenddb.cxx
new file mode 100644
index 000000000000..749ec3896e16
--- /dev/null
+++ b/desktop/source/deployment/registry/component/dp_compbackenddb.cxx
@@ -0,0 +1,161 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include "rtl/string.h"
+#include "rtl/bootstrap.hxx"
+#include "cppuhelper/exc_hlp.hxx"
+#include "com/sun/star/uno/XComponentContext.hpp"
+#include "com/sun/star/xml/dom/XDocumentBuilder.hpp"
+#include "com/sun/star/xml/xpath/XXPathAPI.hpp"
+#include "dp_misc.h"
+
+#include "dp_compbackenddb.hxx"
+
+
+namespace css = ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using ::rtl::OUString;
+
+#define EXTENSION_REG_NS "http://openoffice.org/extensionmanager/component-registry/2010"
+#define NS_PREFIX "comp"
+#define ROOT_ELEMENT_NAME "component-backend-db"
+#define KEY_ELEMENT_NAME "component"
+
+namespace dp_registry {
+namespace backend {
+namespace component {
+
+ComponentBackendDb::ComponentBackendDb(
+ Reference<XComponentContext> const & xContext,
+ ::rtl::OUString const & url):BackendDb(xContext, url)
+{
+
+}
+
+OUString ComponentBackendDb::getDbNSName()
+{
+ return OUSTR(EXTENSION_REG_NS);
+}
+
+OUString ComponentBackendDb::getNSPrefix()
+{
+ return OUSTR(NS_PREFIX);
+}
+
+OUString ComponentBackendDb::getRootElementName()
+{
+ return OUSTR(ROOT_ELEMENT_NAME);
+}
+
+OUString ComponentBackendDb::getKeyElementName()
+{
+ return OUSTR(KEY_ELEMENT_NAME);
+}
+
+void ComponentBackendDb::addEntry(::rtl::OUString const & url, Data const & data)
+{
+ try{
+ if (!activateEntry(url))
+ {
+ Reference<css::xml::dom::XNode> componentNode = writeKeyElement(url);
+ writeSimpleElement(OUSTR("java-type-library"),
+ OUString::valueOf((sal_Bool) data.javaTypeLibrary),
+ componentNode);
+
+ writeSimpleList(
+ data.implementationNames,
+ OUSTR("implementation-names"),
+ OUSTR("name"),
+ componentNode);
+
+ writeVectorOfPair(
+ data.singletons,
+ OUSTR("singletons"),
+ OUSTR("item"),
+ OUSTR("key"),
+ OUSTR("value"),
+ componentNode);
+
+ save();
+ }
+ }
+ catch(css::uno::Exception &)
+ {
+ Any exc( ::cppu::getCaughtException() );
+ throw css::deployment::DeploymentException(
+ OUSTR("Extension Manager: failed to write data entry in backend db: ") +
+ m_urlDb, 0, exc);
+ }
+}
+
+ComponentBackendDb::Data ComponentBackendDb::getEntry(::rtl::OUString const & url)
+{
+ try
+ {
+ ComponentBackendDb::Data retData;
+ Reference<css::xml::dom::XNode> aNode = getKeyElement(url);
+ if (aNode.is())
+ {
+ bool bJava = readSimpleElement(OUSTR("java-type-library"), aNode)
+ .equals(OUSTR("true")) ? true : false;
+ retData.javaTypeLibrary = bJava;
+
+ retData.implementationNames =
+ readList(
+ aNode,
+ OUSTR("implementation-names"),
+ OUSTR("name"));
+
+ retData.singletons =
+ readVectorOfPair(
+ aNode,
+ OUSTR("singletons"),
+ OUSTR("item"),
+ OUSTR("key"),
+ OUSTR("value"));
+ }
+ return retData;
+ }
+ catch(css::uno::Exception &)
+ {
+ Any exc( ::cppu::getCaughtException() );
+ throw css::deployment::DeploymentException(
+ OUSTR("Extension Manager: failed to read data entry in backend db: ") +
+ m_urlDb, 0, exc);
+ }
+}
+
+
+} // namespace bundle
+} // namespace backend
+} // namespace dp_registry
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/registry/component/dp_compbackenddb.hxx b/desktop/source/deployment/registry/component/dp_compbackenddb.hxx
new file mode 100644
index 000000000000..2e0e39eea29c
--- /dev/null
+++ b/desktop/source/deployment/registry/component/dp_compbackenddb.hxx
@@ -0,0 +1,122 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#if ! defined INCLUDED_DP_COMPBACKENDDB_HXX
+#define INCLUDED_DP_COMPBACKENDDB_HXX
+
+#include "rtl/ustring.hxx"
+#include "rtl/string.hxx"
+#include <vector>
+#include <list>
+#include "dp_backenddb.hxx"
+
+namespace css = ::com::sun::star;
+
+namespace com { namespace sun { namespace star {
+ namespace uno {
+ class XComponentContext;
+ }
+ namespace xml { namespace dom {
+ class XDocument;
+ class XNode;
+ }}
+ namespace xml { namespace xpath {
+ class XXPathAPI;
+ }}
+}}}
+
+namespace dp_registry {
+namespace backend {
+namespace component {
+
+/* The XML file stores the extensions which are currently registered.
+ They will be removed when they are revoked.
+ The format looks like this:
+
+<?xml version="1.0"?>
+<component-backend-db xmlns="http://openoffice.org/extensionmanager/component-registry/2010">
+ <component url="vnd.sun.star.expand:$UNO_USER_PACKAGES_CACHE/uno_packages/5CD5.tmp_/leaves1.oxt/extensionoptions.jar">
+ <name>FileName</name>
+ <java-type-library>true</java-type-library>
+ <implementation-names>
+ <name>com.sun.star.comp.extensionoptions.OptionsEventHandler$_OptionsEventHandler</name>
+ ...
+ </implementation-names>
+ <singletons>
+ <item>
+ <key>com.sun.star.java.theJavaVirtualMachine</key>
+ <value>com.sun.star.java.JavaVirtualMachine</value>
+ </item>
+ ...
+ </singletons>
+ </component>
+
+ <component ...>
+ ...
+</component-backend-db>
+ */
+class ComponentBackendDb: public dp_registry::backend::BackendDb
+{
+protected:
+ virtual ::rtl::OUString getDbNSName();
+ virtual ::rtl::OUString getNSPrefix();
+ virtual ::rtl::OUString getRootElementName();
+ virtual ::rtl::OUString getKeyElementName();
+
+public:
+ struct Data
+ {
+ Data(): javaTypeLibrary(false) {};
+
+ ::std::list< ::rtl::OUString> implementationNames;
+ /* every singleton has a key and a value
+ */
+ ::std::vector< ::std::pair< ::rtl::OUString, ::rtl::OUString> >singletons;
+ bool javaTypeLibrary;
+ };
+
+public:
+
+ ComponentBackendDb( css::uno::Reference<css::uno::XComponentContext> const & xContext,
+ ::rtl::OUString const & url);
+
+ void addEntry(::rtl::OUString const & url, Data const & data);
+
+ Data getEntry(::rtl::OUString const & url);
+
+
+};
+
+
+
+}
+}
+}
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/registry/component/dp_component.cxx b/desktop/source/deployment/registry/component/dp_component.cxx
new file mode 100644
index 000000000000..4591ff4fd101
--- /dev/null
+++ b/desktop/source/deployment/registry/component/dp_component.cxx
@@ -0,0 +1,1993 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include "dp_component.hrc"
+#include "dp_backend.h"
+#include "dp_platform.hxx"
+#include "dp_ucb.h"
+#include "rtl/string.hxx"
+#include "rtl/strbuf.hxx"
+#include "rtl/ustrbuf.hxx"
+#include "rtl/uri.hxx"
+#include "cppuhelper/exc_hlp.hxx"
+#include "ucbhelper/content.hxx"
+#include "comphelper/anytostring.hxx"
+#include "comphelper/servicedecl.hxx"
+#include "comphelper/sequence.hxx"
+#include "xmlscript/xml_helper.hxx"
+#include "svl/inettype.hxx"
+#include "com/sun/star/lang/WrappedTargetRuntimeException.hpp"
+#include "com/sun/star/container/XNameContainer.hpp"
+#include "com/sun/star/container/XHierarchicalNameAccess.hpp"
+#include "com/sun/star/container/XSet.hpp"
+#include "com/sun/star/registry/XSimpleRegistry.hpp"
+#include "com/sun/star/registry/XImplementationRegistration.hpp"
+#include "com/sun/star/loader/XImplementationLoader.hpp"
+#include "com/sun/star/io/XInputStream.hpp"
+#include "com/sun/star/ucb/NameClash.hpp"
+#include "com/sun/star/util/XMacroExpander.hpp"
+#include <list>
+#include <boost/unordered_map.hpp>
+#include <vector>
+#include <memory>
+#include <algorithm>
+#include "dp_compbackenddb.hxx"
+
+using namespace ::dp_misc;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::ucb;
+using ::rtl::OUString;
+namespace css = com::sun::star;
+
+namespace dp_registry {
+namespace backend {
+namespace component {
+namespace {
+
+typedef ::std::list<OUString> t_stringlist;
+typedef ::std::vector< ::std::pair<OUString, OUString> > t_stringpairvec;
+
+#define IMPLEMENTATION_NAME "com.sun.star.comp.deployment.component.PackageRegistryBackend"
+
+/** return a vector of bootstrap variables which have been provided
+ as command arguments.
+*/
+::std::vector<OUString> getCmdBootstrapVariables()
+{
+ ::std::vector<OUString> ret;
+ sal_uInt32 count = osl_getCommandArgCount();
+ for (sal_uInt32 i = 0; i < count; i++)
+ {
+ OUString arg;
+ osl_getCommandArg(i, &arg.pData);
+ if (arg.matchAsciiL("-env:", 5))
+ ret.push_back(arg);
+ }
+ return ret;
+}
+
+bool jarManifestHeaderPresent(
+ OUString const & url, OUString const & name,
+ Reference<XCommandEnvironment> const & xCmdEnv )
+{
+ ::rtl::OUStringBuffer buf;
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("vnd.sun.star.zip://") );
+ buf.append(
+ ::rtl::Uri::encode(
+ url, rtl_UriCharClassRegName, rtl_UriEncodeIgnoreEscapes,
+ RTL_TEXTENCODING_UTF8 ) );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("/META-INF/MANIFEST.MF") );
+ ::ucbhelper::Content manifestContent;
+ OUString line;
+ return
+ create_ucb_content(
+ &manifestContent, buf.makeStringAndClear(), xCmdEnv,
+ false /* no throw */ )
+ && readLine( &line, name, manifestContent, RTL_TEXTENCODING_ASCII_US );
+}
+
+//==============================================================================
+class BackendImpl : public ::dp_registry::backend::PackageRegistryBackend
+{
+ class ComponentPackageImpl : public ::dp_registry::backend::Package
+ {
+ BackendImpl * getMyBackend() const;
+
+ const OUString m_loader;
+
+ enum reg {
+ REG_UNINIT, REG_VOID, REG_REGISTERED, REG_NOT_REGISTERED, REG_MAYBE_REGISTERED
+ } m_registered;
+
+ void getComponentInfo(
+ ComponentBackendDb::Data * data,
+ std::vector< css::uno::Reference< css::uno::XInterface > > *
+ factories,
+ Reference<XComponentContext> const & xContext );
+
+ virtual void SAL_CALL disposing();
+
+ // Package
+ virtual beans::Optional< beans::Ambiguous<sal_Bool> > isRegistered_(
+ ::osl::ResettableMutexGuard & guard,
+ ::rtl::Reference<AbortChannel> const & abortChannel,
+ Reference<XCommandEnvironment> const & xCmdEnv );
+ virtual void processPackage_(
+ ::osl::ResettableMutexGuard & guard,
+ bool registerPackage,
+ bool startup,
+ ::rtl::Reference<AbortChannel> const & abortChannel,
+ Reference<XCommandEnvironment> const & xCmdEnv );
+
+ const Reference<registry::XSimpleRegistry> getRDB() const;
+
+ //Provides the read-only registry (e.g. not the one based on the duplicated
+ //rdb files
+ const Reference<registry::XSimpleRegistry> getRDB_RO() const;
+
+ public:
+ ComponentPackageImpl(
+ ::rtl::Reference<PackageRegistryBackend> const & myBackend,
+ OUString const & url, OUString const & name,
+ Reference<deployment::XPackageTypeInfo> const & xPackageType,
+ OUString const & loader, bool bRemoved,
+ OUString const & identifier);
+ };
+ friend class ComponentPackageImpl;
+
+ class ComponentsPackageImpl : public ::dp_registry::backend::Package
+ {
+ BackendImpl * getMyBackend() const;
+
+ // Package
+ virtual beans::Optional< beans::Ambiguous<sal_Bool> > isRegistered_(
+ ::osl::ResettableMutexGuard & guard,
+ ::rtl::Reference<AbortChannel> const & abortChannel,
+ Reference<XCommandEnvironment> const & xCmdEnv );
+ virtual void processPackage_(
+ ::osl::ResettableMutexGuard & guard,
+ bool registerPackage,
+ bool startup,
+ ::rtl::Reference<AbortChannel> const & abortChannel,
+ Reference<XCommandEnvironment> const & xCmdEnv );
+ public:
+ ComponentsPackageImpl(
+ ::rtl::Reference<PackageRegistryBackend> const & myBackend,
+ OUString const & url, OUString const & name,
+ Reference<deployment::XPackageTypeInfo> const & xPackageType,
+ bool bRemoved, OUString const & identifier);
+ };
+ friend class ComponentsPackageImpl;
+
+ class TypelibraryPackageImpl : public ::dp_registry::backend::Package
+ {
+ BackendImpl * getMyBackend() const;
+
+ const bool m_jarFile;
+ Reference<container::XHierarchicalNameAccess> m_xTDprov;
+
+ virtual void SAL_CALL disposing();
+
+ // Package
+ virtual beans::Optional< beans::Ambiguous<sal_Bool> > isRegistered_(
+ ::osl::ResettableMutexGuard & guard,
+ ::rtl::Reference<AbortChannel> const & abortChannel,
+ Reference<XCommandEnvironment> const & xCmdEnv );
+ virtual void processPackage_(
+ ::osl::ResettableMutexGuard & guard,
+ bool registerPackage,
+ bool startup,
+ ::rtl::Reference<AbortChannel> const & abortChannel,
+ Reference<XCommandEnvironment> const & xCmdEnv );
+
+ public:
+ TypelibraryPackageImpl(
+ ::rtl::Reference<PackageRegistryBackend> const & myBackend,
+ OUString const & url, OUString const & name,
+ Reference<deployment::XPackageTypeInfo> const & xPackageType,
+ bool jarFile, bool bRemoved,
+ OUString const & identifier);
+ };
+ friend class TypelibraryPackageImpl;
+
+ /** Serves for unregistering packages that were registered on a
+ different platform. This can happen if one has remotely mounted
+ /home, for example.
+ */
+ class OtherPlatformPackageImpl : public ::dp_registry::backend::Package
+ {
+ public:
+ OtherPlatformPackageImpl(
+ ::rtl::Reference<PackageRegistryBackend> const & myBackend,
+ OUString const & url, OUString const & name,
+ Reference<deployment::XPackageTypeInfo> const & xPackageType,
+ bool bRemoved, OUString const & identifier, OUString const& rPlatform);
+
+ private:
+ BackendImpl * getMyBackend() const;
+
+ const Reference<registry::XSimpleRegistry> impl_openRDB() const;
+ const Reference<XInterface> impl_createInstance(OUString const& rService) const;
+
+ // Package
+ virtual beans::Optional< beans::Ambiguous<sal_Bool> > isRegistered_(
+ ::osl::ResettableMutexGuard & guard,
+ ::rtl::Reference<AbortChannel> const & abortChannel,
+ Reference<XCommandEnvironment> const & xCmdEnv );
+ virtual void processPackage_(
+ ::osl::ResettableMutexGuard & guard,
+ bool registerPackage,
+ bool startup,
+ ::rtl::Reference<AbortChannel> const & abortChannel,
+ Reference<XCommandEnvironment> const & xCmdEnv );
+
+ private:
+ OUString const m_aPlatform;
+ };
+ friend class OtherPlatformPackageImpl;
+
+ t_stringlist m_jar_typelibs;
+ t_stringlist m_rdb_typelibs;
+ t_stringlist m_components;
+
+ enum RcItem { RCITEM_JAR_TYPELIB, RCITEM_RDB_TYPELIB, RCITEM_COMPONENTS };
+
+ t_stringlist & getRcItemList( RcItem kind ) {
+ switch (kind)
+ {
+ case RCITEM_JAR_TYPELIB:
+ return m_jar_typelibs;
+ case RCITEM_RDB_TYPELIB:
+ return m_rdb_typelibs;
+ default: // case RCITEM_COMPONENTS
+ return m_components;
+ }
+ }
+
+ bool m_unorc_inited;
+ bool m_unorc_modified;
+ bool bSwitchedRdbFiles;
+
+ typedef ::boost::unordered_map< OUString, Reference<XInterface>,
+ ::rtl::OUStringHash > t_string2object;
+ t_string2object m_backendObjects;
+
+ // PackageRegistryBackend
+ virtual Reference<deployment::XPackage> bindPackage_(
+ OUString const & url, OUString const & mediaType,
+ sal_Bool bRemoved, OUString const & identifier,
+ Reference<XCommandEnvironment> const & xCmdEnv );
+
+ virtual void SAL_CALL disposing();
+
+ const Reference<deployment::XPackageTypeInfo> m_xDynComponentTypeInfo;
+ const Reference<deployment::XPackageTypeInfo> m_xJavaComponentTypeInfo;
+ const Reference<deployment::XPackageTypeInfo> m_xPythonComponentTypeInfo;
+ const Reference<deployment::XPackageTypeInfo> m_xComponentsTypeInfo;
+ const Reference<deployment::XPackageTypeInfo> m_xRDBTypelibTypeInfo;
+ const Reference<deployment::XPackageTypeInfo> m_xJavaTypelibTypeInfo;
+ Sequence< Reference<deployment::XPackageTypeInfo> > m_typeInfos;
+
+ OUString m_commonRDB;
+ OUString m_nativeRDB;
+
+ //URLs of the read-only rdbs (e.g. not the ones of the duplicated files)
+ OUString m_commonRDB_RO;
+ OUString m_nativeRDB_RO;
+
+ std::auto_ptr<ComponentBackendDb> m_backendDb;
+
+ void addDataToDb(OUString const & url, ComponentBackendDb::Data const & data);
+ ComponentBackendDb::Data readDataFromDb(OUString const & url);
+ void revokeEntryFromDb(OUString const & url);
+
+
+ //These rdbs are for writing new service entries. The rdb files are copies
+ //which are created when services are added or removed.
+ Reference<registry::XSimpleRegistry> m_xCommonRDB;
+ Reference<registry::XSimpleRegistry> m_xNativeRDB;
+
+ //These rdbs are created on the read-only rdbs which are already used
+ //by UNO since the startup of the current session.
+ Reference<registry::XSimpleRegistry> m_xCommonRDB_RO;
+ Reference<registry::XSimpleRegistry> m_xNativeRDB_RO;
+
+
+ void unorc_verify_init( Reference<XCommandEnvironment> const & xCmdEnv );
+ void unorc_flush( Reference<XCommandEnvironment> const & xCmdEnv );
+
+ Reference<XInterface> getObject( OUString const & id );
+ Reference<XInterface> insertObject(
+ OUString const & id, Reference<XInterface> const & xObject );
+ void releaseObject( OUString const & id );
+
+ bool addToUnoRc( RcItem kind, OUString const & url,
+ Reference<XCommandEnvironment> const & xCmdEnv );
+ bool removeFromUnoRc( RcItem kind, OUString const & url,
+ Reference<XCommandEnvironment> const & xCmdEnv );
+ bool hasInUnoRc( RcItem kind, OUString const & url );
+
+ css::uno::Reference< css::registry::XRegistryKey > openRegistryKey(
+ css::uno::Reference< css::registry::XRegistryKey > const & base,
+ rtl::OUString const & path);
+
+ void extractComponentData(
+ css::uno::Reference< css::uno::XComponentContext > const & context,
+ css::uno::Reference< css::registry::XRegistryKey > const & registry,
+ ComponentBackendDb::Data * data,
+ std::vector< css::uno::Reference< css::uno::XInterface > > * factories,
+ css::uno::Reference< css::loader::XImplementationLoader > const *
+ componentLoader,
+ rtl::OUString const * componentUrl);
+
+ void componentLiveInsertion(
+ ComponentBackendDb::Data const & data,
+ std::vector< css::uno::Reference< css::uno::XInterface > > const &
+ factories);
+
+ void componentLiveRemoval(ComponentBackendDb::Data const & data);
+
+public:
+ BackendImpl( Sequence<Any> const & args,
+ Reference<XComponentContext> const & xComponentContext );
+
+ // XPackageRegistry
+ virtual Sequence< Reference<deployment::XPackageTypeInfo> > SAL_CALL
+ getSupportedPackageTypes() throw (RuntimeException);
+
+ virtual void SAL_CALL packageRemoved(OUString const & url, OUString const & mediaType)
+ throw (deployment::DeploymentException,
+ uno::RuntimeException);
+
+ using PackageRegistryBackend::disposing;
+
+ //Will be called from ComponentPackageImpl
+ void initServiceRdbFiles();
+
+ //Creates the READ ONLY registries (m_xCommonRDB_RO,m_xNativeRDB_RO)
+ void initServiceRdbFiles_RO();
+};
+
+//______________________________________________________________________________
+
+BackendImpl::ComponentPackageImpl::ComponentPackageImpl(
+ ::rtl::Reference<PackageRegistryBackend> const & myBackend,
+ OUString const & url, OUString const & name,
+ Reference<deployment::XPackageTypeInfo> const & xPackageType,
+ OUString const & loader, bool bRemoved,
+ OUString const & identifier)
+ : Package( myBackend, url, name, name /* display-name */,
+ xPackageType, bRemoved, identifier),
+ m_loader( loader ),
+ m_registered( REG_UNINIT )
+{}
+
+const Reference<registry::XSimpleRegistry>
+BackendImpl::ComponentPackageImpl::getRDB() const
+{
+ BackendImpl * that = getMyBackend();
+
+ //Late "initialization" of the services rdb files
+ //This is to prevent problems when running several
+ //instances of OOo with root rights in parallel. This
+ //would otherwise cause problems when copying the rdbs.
+ //See http://qa.openoffice.org/issues/show_bug.cgi?id=99257
+ {
+ const ::osl::MutexGuard guard( getMutex() );
+ if (!that->bSwitchedRdbFiles)
+ {
+ that->bSwitchedRdbFiles = true;
+ that->initServiceRdbFiles();
+ }
+ }
+ if (m_loader.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM("com.sun.star.loader.SharedLibrary") ))
+ return that->m_xNativeRDB;
+ else
+ return that->m_xCommonRDB;
+}
+
+//Returns the read only RDB.
+const Reference<registry::XSimpleRegistry>
+BackendImpl::ComponentPackageImpl::getRDB_RO() const
+{
+ BackendImpl * that = getMyBackend();
+
+ if (m_loader.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM("com.sun.star.loader.SharedLibrary") ))
+ return that->m_xNativeRDB_RO;
+ else
+ return that->m_xCommonRDB_RO;
+}
+
+BackendImpl * BackendImpl::ComponentPackageImpl::getMyBackend() const
+{
+ BackendImpl * pBackend = static_cast<BackendImpl *>(m_myBackend.get());
+ if (NULL == pBackend)
+ {
+ //Throws a DisposedException
+ check();
+ //We should never get here...
+ throw RuntimeException(
+ OUSTR("Failed to get the BackendImpl"),
+ static_cast<OWeakObject*>(const_cast<ComponentPackageImpl *>(this)));
+ }
+ return pBackend;
+}
+
+
+//______________________________________________________________________________
+void BackendImpl::ComponentPackageImpl::disposing()
+{
+ Package::disposing();
+}
+
+//______________________________________________________________________________
+void BackendImpl::TypelibraryPackageImpl::disposing()
+{
+ m_xTDprov.clear();
+ Package::disposing();
+}
+
+//______________________________________________________________________________
+void BackendImpl::disposing()
+{
+ try {
+ m_backendObjects = t_string2object();
+ if (m_xNativeRDB.is()) {
+ m_xNativeRDB->close();
+ m_xNativeRDB.clear();
+ }
+ if (m_xCommonRDB.is()) {
+ m_xCommonRDB->close();
+ m_xCommonRDB.clear();
+ }
+ unorc_flush( Reference<XCommandEnvironment>() );
+
+ PackageRegistryBackend::disposing();
+ }
+ catch (RuntimeException &) {
+ throw;
+ }
+ catch (Exception &) {
+ Any exc( ::cppu::getCaughtException() );
+ throw lang::WrappedTargetRuntimeException(
+ OUSTR("caught unexpected exception while disposing..."),
+ static_cast<OWeakObject *>(this), exc );
+ }
+}
+
+
+void BackendImpl::initServiceRdbFiles()
+{
+ const Reference<XCommandEnvironment> xCmdEnv;
+
+ ::ucbhelper::Content cacheDir( getCachePath(), xCmdEnv );
+ ::ucbhelper::Content oldRDB;
+ // switch common rdb:
+ if (m_commonRDB_RO.getLength() > 0)
+ {
+ create_ucb_content(
+ &oldRDB, makeURL( getCachePath(), m_commonRDB_RO),
+ xCmdEnv, false /* no throw */ );
+ }
+ m_commonRDB = m_commonRDB_RO.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM("common.rdb") )
+ ? OUSTR("common_.rdb") : OUSTR("common.rdb");
+ if (oldRDB.get().is())
+ {
+ if (! cacheDir.transferContent(
+ oldRDB, ::ucbhelper::InsertOperation_COPY,
+ m_commonRDB, NameClash::OVERWRITE ))
+ {
+
+ throw RuntimeException(
+ OUSTR("UCB transferContent() failed!"), 0 );
+ }
+ oldRDB = ::ucbhelper::Content();
+ }
+ // switch native rdb:
+ if (m_nativeRDB_RO.getLength() > 0)
+ {
+ create_ucb_content(
+ &oldRDB, makeURL(getCachePath(), m_nativeRDB_RO),
+ xCmdEnv, false /* no throw */ );
+ }
+ const OUString plt_rdb( getPlatformString() + OUSTR(".rdb") );
+ const OUString plt_rdb_( getPlatformString() + OUSTR("_.rdb") );
+ m_nativeRDB = m_nativeRDB_RO.equals( plt_rdb ) ? plt_rdb_ : plt_rdb;
+ if (oldRDB.get().is())
+ {
+ if (! cacheDir.transferContent(
+ oldRDB, ::ucbhelper::InsertOperation_COPY,
+ m_nativeRDB, NameClash::OVERWRITE ))
+ throw RuntimeException(
+ OUSTR("UCB transferContent() failed!"), 0 );
+ }
+
+ // UNO is bootstrapped, flush for next process start:
+ m_unorc_modified = true;
+ unorc_flush( Reference<XCommandEnvironment>() );
+
+
+ // common rdb for java, native rdb for shared lib components
+ if (m_commonRDB.getLength() > 0) {
+ m_xCommonRDB.set(
+ m_xComponentContext->getServiceManager()
+ ->createInstanceWithContext(
+ OUSTR("com.sun.star.registry.SimpleRegistry"),
+ m_xComponentContext ), UNO_QUERY_THROW );
+ m_xCommonRDB->open(
+ makeURL( expandUnoRcUrl(getCachePath()), m_commonRDB ),
+ false, true);
+ }
+ if (m_nativeRDB.getLength() > 0) {
+ m_xNativeRDB.set(
+ m_xComponentContext->getServiceManager()
+ ->createInstanceWithContext(
+ OUSTR("com.sun.star.registry.SimpleRegistry"),
+ m_xComponentContext ), UNO_QUERY_THROW );
+ m_xNativeRDB->open(
+ makeURL( expandUnoRcUrl(getCachePath()), m_nativeRDB ),
+ false, true);
+ }
+}
+
+void BackendImpl::initServiceRdbFiles_RO()
+{
+ const Reference<XCommandEnvironment> xCmdEnv;
+
+ // common rdb for java, native rdb for shared lib components
+ if (m_commonRDB_RO.getLength() > 0)
+ {
+ m_xCommonRDB_RO.set(
+ m_xComponentContext->getServiceManager()
+ ->createInstanceWithContext(
+ OUSTR("com.sun.star.registry.SimpleRegistry"),
+ m_xComponentContext), UNO_QUERY_THROW);
+ m_xCommonRDB_RO->open(
+ makeURL(expandUnoRcUrl(getCachePath()), m_commonRDB_RO),
+ sal_True, //read-only
+ sal_True); // create data source if necessary
+ }
+ if (m_nativeRDB_RO.getLength() > 0)
+ {
+ m_xNativeRDB_RO.set(
+ m_xComponentContext->getServiceManager()
+ ->createInstanceWithContext(
+ OUSTR("com.sun.star.registry.SimpleRegistry"),
+ m_xComponentContext), UNO_QUERY_THROW);
+ m_xNativeRDB_RO->open(
+ makeURL(expandUnoRcUrl(getCachePath()), m_nativeRDB_RO),
+ sal_True, //read-only
+ sal_True); // create data source if necessary
+ }
+}
+
+//______________________________________________________________________________
+BackendImpl::BackendImpl(
+ Sequence<Any> const & args,
+ Reference<XComponentContext> const & xComponentContext )
+ : PackageRegistryBackend( args, xComponentContext ),
+ m_unorc_inited( false ),
+ m_unorc_modified( false ),
+ bSwitchedRdbFiles(false),
+ m_xDynComponentTypeInfo( new Package::TypeInfo(
+ OUSTR("application/"
+ "vnd.sun.star.uno-component;"
+ "type=native;platform=") +
+ getPlatformString(),
+ OUSTR("*" SAL_DLLEXTENSION),
+ getResourceString(RID_STR_DYN_COMPONENT),
+ RID_IMG_COMPONENT) ),
+ m_xJavaComponentTypeInfo( new Package::TypeInfo(
+ OUSTR("application/"
+ "vnd.sun.star.uno-component;"
+ "type=Java"),
+ OUSTR("*.jar"),
+ getResourceString(RID_STR_JAVA_COMPONENT),
+ RID_IMG_JAVA_COMPONENT) ),
+ m_xPythonComponentTypeInfo( new Package::TypeInfo(
+ OUSTR("application/"
+ "vnd.sun.star.uno-component;"
+ "type=Python"),
+ OUSTR("*.py"),
+ getResourceString(
+ RID_STR_PYTHON_COMPONENT),
+ RID_IMG_COMPONENT ) ),
+ m_xComponentsTypeInfo( new Package::TypeInfo(
+ OUSTR("application/"
+ "vnd.sun.star.uno-components"),
+ OUSTR("*.components"),
+ getResourceString(RID_STR_COMPONENTS),
+ RID_IMG_COMPONENT ) ),
+ m_xRDBTypelibTypeInfo( new Package::TypeInfo(
+ OUSTR("application/"
+ "vnd.sun.star.uno-typelibrary;"
+ "type=RDB"),
+ OUSTR("*.rdb"),
+ getResourceString(RID_STR_RDB_TYPELIB),
+ RID_IMG_TYPELIB ) ),
+ m_xJavaTypelibTypeInfo( new Package::TypeInfo(
+ OUSTR("application/"
+ "vnd.sun.star.uno-typelibrary;"
+ "type=Java"),
+ OUSTR("*.jar"),
+ getResourceString(RID_STR_JAVA_TYPELIB),
+ RID_IMG_JAVA_TYPELIB ) ),
+ m_typeInfos( 6 )
+{
+ m_typeInfos[ 0 ] = m_xDynComponentTypeInfo;
+ m_typeInfos[ 1 ] = m_xJavaComponentTypeInfo;
+ m_typeInfos[ 2 ] = m_xPythonComponentTypeInfo;
+ m_typeInfos[ 3 ] = m_xComponentsTypeInfo;
+ m_typeInfos[ 4 ] = m_xRDBTypelibTypeInfo;
+ m_typeInfos[ 5 ] = m_xJavaTypelibTypeInfo;
+
+ const Reference<XCommandEnvironment> xCmdEnv;
+
+ if (transientMode())
+ {
+ // in-mem rdbs:
+ // common rdb for java, native rdb for shared lib components
+ m_xCommonRDB.set(
+ xComponentContext->getServiceManager()->createInstanceWithContext(
+ OUSTR("com.sun.star.registry.SimpleRegistry"),
+ xComponentContext ), UNO_QUERY_THROW );
+ m_xCommonRDB->open( OUString() /* in-mem */,
+ false /* ! read-only */, true /* create */ );
+ m_xNativeRDB.set(
+ xComponentContext->getServiceManager()->createInstanceWithContext(
+ OUSTR("com.sun.star.registry.SimpleRegistry"),
+ xComponentContext ), UNO_QUERY_THROW );
+ m_xNativeRDB->open( OUString() /* in-mem */,
+ false /* ! read-only */, true /* create */ );
+ }
+ else
+ {
+ //do this before initServiceRdbFiles_RO, because it determines
+ //m_commonRDB and m_nativeRDB
+ unorc_verify_init( xCmdEnv );
+
+ initServiceRdbFiles_RO();
+
+ OUString dbFile = makeURL(getCachePath(), OUSTR("backenddb.xml"));
+ m_backendDb.reset(
+ new ComponentBackendDb(getComponentContext(), dbFile));
+ }
+}
+
+void BackendImpl::addDataToDb(
+ OUString const & url, ComponentBackendDb::Data const & data)
+{
+ if (m_backendDb.get())
+ m_backendDb->addEntry(url, data);
+}
+
+ComponentBackendDb::Data BackendImpl::readDataFromDb(OUString const & url)
+{
+ ComponentBackendDb::Data data;
+ if (m_backendDb.get())
+ data = m_backendDb->getEntry(url);
+ return data;
+}
+
+void BackendImpl::revokeEntryFromDb(OUString const & url)
+{
+ if (m_backendDb.get())
+ m_backendDb->revokeEntry(url);
+}
+
+// XPackageRegistry
+//______________________________________________________________________________
+Sequence< Reference<deployment::XPackageTypeInfo> >
+BackendImpl::getSupportedPackageTypes() throw (RuntimeException)
+{
+ return m_typeInfos;
+}
+
+void BackendImpl::packageRemoved(OUString const & url, OUString const & /*mediaType*/)
+ throw (deployment::DeploymentException,
+ uno::RuntimeException)
+{
+ if (m_backendDb.get())
+ m_backendDb->removeEntry(url);
+}
+
+// PackageRegistryBackend
+//______________________________________________________________________________
+Reference<deployment::XPackage> BackendImpl::bindPackage_(
+ OUString const & url, OUString const & mediaType_,
+ sal_Bool bRemoved, OUString const & identifier,
+ Reference<XCommandEnvironment> const & xCmdEnv )
+{
+ OUString mediaType(mediaType_);
+ if (mediaType.getLength() == 0 ||
+ mediaType.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM(
+ "application/vnd.sun.star.uno-component") ) ||
+ mediaType.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM(
+ "application/vnd.sun.star.uno-typelibrary") ))
+ {
+ // detect exact media-type:
+ ::ucbhelper::Content ucbContent;
+ if (create_ucb_content( &ucbContent, url, xCmdEnv )) {
+ const OUString title( ucbContent.getPropertyValue(
+ StrTitle::get() ).get<OUString>() );
+ if (title.endsWithIgnoreAsciiCaseAsciiL(
+ RTL_CONSTASCII_STRINGPARAM(SAL_DLLEXTENSION) ))
+ {
+ mediaType = OUSTR("application/vnd.sun.star.uno-component;"
+ "type=native;platform=") +
+ getPlatformString();
+ }
+ else if (title.endsWithIgnoreAsciiCaseAsciiL(
+ RTL_CONSTASCII_STRINGPARAM(".jar") ))
+ {
+ if (jarManifestHeaderPresent(
+ url, OUSTR("RegistrationClassName"), xCmdEnv ))
+ mediaType = OUSTR(
+ "application/vnd.sun.star.uno-component;type=Java");
+ if (mediaType.getLength() == 0)
+ mediaType = OUSTR(
+ "application/vnd.sun.star.uno-typelibrary;type=Java");
+ }
+ else if (title.endsWithIgnoreAsciiCaseAsciiL(
+ RTL_CONSTASCII_STRINGPARAM(".py") ))
+ mediaType =
+ OUSTR("application/vnd.sun.star.uno-component;type=Python");
+ else if (title.endsWithIgnoreAsciiCaseAsciiL(
+ RTL_CONSTASCII_STRINGPARAM(".rdb") ))
+ mediaType =
+ OUSTR("application/vnd.sun.star.uno-typelibrary;type=RDB");
+ }
+ if (mediaType.getLength() == 0)
+ throw lang::IllegalArgumentException(
+ StrCannotDetectMediaType::get() + url,
+ static_cast<OWeakObject *>(this), static_cast<sal_Int16>(-1) );
+ }
+
+ String type, subType;
+ INetContentTypeParameterList params;
+ if (INetContentTypes::parse( mediaType, type, subType, &params ))
+ {
+ if (type.EqualsIgnoreCaseAscii("application"))
+ {
+ OUString name;
+ if (!bRemoved)
+ {
+ ::ucbhelper::Content ucbContent( url, xCmdEnv );
+ name = ucbContent.getPropertyValue(
+ StrTitle::get() ).get<OUString>();
+ }
+
+ if (subType.EqualsIgnoreCaseAscii("vnd.sun.star.uno-component"))
+ {
+ // xxx todo: probe and evaluate component xml description
+
+ INetContentTypeParameter const * param = params.find(
+ ByteString("platform") );
+ bool bPlatformFits(param == 0);
+ String aPlatform;
+ if (!bPlatformFits) // platform is specified, we have to check
+ {
+ aPlatform = param->m_sValue;
+ bPlatformFits = platform_fits(aPlatform);
+ }
+ // If the package is being removed, do not care whether
+ // platform fits. We won't be using it anyway.
+ if (bPlatformFits || bRemoved) {
+ param = params.find( ByteString("type") );
+ if (param != 0)
+ {
+ String const & value = param->m_sValue;
+ if (value.EqualsIgnoreCaseAscii("native")) {
+ if (bPlatformFits)
+ return new BackendImpl::ComponentPackageImpl(
+ this, url, name, m_xDynComponentTypeInfo,
+ OUSTR("com.sun.star.loader.SharedLibrary"),
+ bRemoved, identifier);
+ else
+ return new BackendImpl::OtherPlatformPackageImpl(
+ this, url, name, m_xDynComponentTypeInfo,
+ bRemoved, identifier, aPlatform);
+ }
+ if (value.EqualsIgnoreCaseAscii("Java")) {
+ return new BackendImpl::ComponentPackageImpl(
+ this, url, name, m_xJavaComponentTypeInfo,
+ OUSTR("com.sun.star.loader.Java2"),
+ bRemoved, identifier);
+ }
+ if (value.EqualsIgnoreCaseAscii("Python")) {
+ return new BackendImpl::ComponentPackageImpl(
+ this, url, name, m_xPythonComponentTypeInfo,
+ OUSTR("com.sun.star.loader.Python"),
+ bRemoved, identifier);
+ }
+ }
+ }
+ }
+ else if (subType.EqualsIgnoreCaseAscii(
+ "vnd.sun.star.uno-components"))
+ {
+ INetContentTypeParameter const * param = params.find(
+ ByteString("platform") );
+ if (param == 0 || platform_fits( param->m_sValue )) {
+ return new BackendImpl::ComponentsPackageImpl(
+ this, url, name, m_xComponentsTypeInfo, bRemoved,
+ identifier);
+ }
+ }
+ else if (subType.EqualsIgnoreCaseAscii(
+ "vnd.sun.star.uno-typelibrary"))
+ {
+ INetContentTypeParameter const * param = params.find(
+ ByteString("type") );
+ if (param != 0) {
+ String const & value = param->m_sValue;
+ if (value.EqualsIgnoreCaseAscii("RDB"))
+ {
+ return new BackendImpl::TypelibraryPackageImpl(
+ this, url, name, m_xRDBTypelibTypeInfo,
+ false /* rdb */, bRemoved, identifier);
+ }
+ if (value.EqualsIgnoreCaseAscii("Java")) {
+ return new BackendImpl::TypelibraryPackageImpl(
+ this, url, name, m_xJavaTypelibTypeInfo,
+ true /* jar */, bRemoved, identifier);
+ }
+ }
+ }
+ }
+ }
+ throw lang::IllegalArgumentException(
+ StrUnsupportedMediaType::get() + mediaType,
+ static_cast<OWeakObject *>(this),
+ static_cast<sal_Int16>(-1) );
+}
+
+
+//______________________________________________________________________________
+void BackendImpl::unorc_verify_init(
+ Reference<XCommandEnvironment> const & xCmdEnv )
+{
+ if (transientMode())
+ return;
+ const ::osl::MutexGuard guard( getMutex() );
+ if (! m_unorc_inited)
+ {
+ // common rc:
+ ::ucbhelper::Content ucb_content;
+ if (create_ucb_content(
+ &ucb_content,
+ makeURL( getCachePath(), OUSTR("unorc") ),
+ xCmdEnv, false /* no throw */ ))
+ {
+ OUString line;
+ if (readLine( &line, OUSTR("UNO_JAVA_CLASSPATH="), ucb_content,
+ RTL_TEXTENCODING_UTF8 ))
+ {
+ sal_Int32 index = sizeof ("UNO_JAVA_CLASSPATH=") - 1;
+ do {
+ OUString token( line.getToken( 0, ' ', index ).trim() );
+ if (token.getLength() > 0)
+ {
+ if (create_ucb_content(
+ 0, expandUnoRcTerm(token), xCmdEnv,
+ false /* no throw */ ))
+ {
+ //The jar file may not exist anymore if a shared or bundled
+ //extension was removed, but it can still be in the unorc
+ //After running XExtensionManager::synchronize, the unorc is
+ //cleaned up
+ m_jar_typelibs.push_back( token );
+ }
+ }
+ }
+ while (index >= 0);
+ }
+ if (readLine( &line, OUSTR("UNO_TYPES="), ucb_content,
+ RTL_TEXTENCODING_UTF8 )) {
+ sal_Int32 index = sizeof ("UNO_TYPES=") - 1;
+ do {
+ OUString token( line.getToken( 0, ' ', index ).trim() );
+ if (token.getLength() > 0)
+ {
+ if (token[ 0 ] == '?')
+ token = token.copy( 1 );
+ if (create_ucb_content(
+ 0, expandUnoRcTerm(token), xCmdEnv,
+ false /* no throw */ ))
+ {
+ //The RDB file may not exist anymore if a shared or bundled
+ //extension was removed, but it can still be in the unorc.
+ //After running XExtensionManager::synchronize, the unorc is
+ //cleaned up
+ m_rdb_typelibs.push_back( token );
+ }
+ }
+ }
+ while (index >= 0);
+ }
+ if (readLine( &line, OUSTR("UNO_SERVICES="), ucb_content,
+ RTL_TEXTENCODING_UTF8 ))
+ {
+ // The UNO_SERVICES line always has the BNF form
+ // "UNO_SERVICES="
+ // ("?$ORIGIN/" <common-rdb>)? -- first
+ // "${$ORIGIN/${_OS}_${_ARCH}rc:UNO_SERVICES}"? -- second
+ // ("?" ("BUNDLED_EXTENSIONS" | -- third
+ // "UNO_SHARED_PACKAGES_CACHE" | "UNO_USER_PACKAGES_CACHE")
+ // ...)*
+ // so can unambiguously be split into its thre parts:
+ int state = 1;
+ for (sal_Int32 i = RTL_CONSTASCII_LENGTH("UNO_SERVICES=");
+ i >= 0;)
+ {
+ rtl::OUString token(line.getToken(0, ' ', i));
+ if (token.getLength() != 0)
+ {
+ if (state == 1 &&
+ token.matchAsciiL(
+ RTL_CONSTASCII_STRINGPARAM("?$ORIGIN/")))
+ {
+ m_commonRDB_RO = token.copy(
+ RTL_CONSTASCII_LENGTH("?$ORIGIN/"));
+ state = 2;
+ }
+ else if (state <= 2 &&
+ token.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM(
+ "${$ORIGIN/${_OS}_${_ARCH}rc:"
+ "UNO_SERVICES}")))
+ {
+ state = 3;
+ }
+ else
+ {
+ if (token[0] == '?')
+ {
+ token = token.copy(1);
+ }
+ m_components.push_back(token);
+ state = 3;
+ }
+ }
+ }
+ }
+
+ // native rc:
+ if (create_ucb_content(
+ &ucb_content,
+ makeURL( getCachePath(), getPlatformString() + OUSTR("rc")),
+ xCmdEnv, false /* no throw */ )) {
+ if (readLine( &line, OUSTR("UNO_SERVICES="), ucb_content,
+ RTL_TEXTENCODING_UTF8 )) {
+ m_nativeRDB_RO = line.copy(
+ sizeof ("UNO_SERVICES=?$ORIGIN/") - 1 );
+ }
+ }
+ }
+ m_unorc_modified = false;
+ m_unorc_inited = true;
+ }
+}
+
+//______________________________________________________________________________
+void BackendImpl::unorc_flush( Reference<XCommandEnvironment> const & xCmdEnv )
+{
+ if (transientMode())
+ return;
+ if (!m_unorc_inited || !m_unorc_modified)
+ return;
+
+ ::rtl::OStringBuffer buf;
+
+ buf.append(RTL_CONSTASCII_STRINGPARAM("ORIGIN="));
+ OUString sOrigin = dp_misc::makeRcTerm(m_cachePath);
+ ::rtl::OString osOrigin = ::rtl::OUStringToOString(sOrigin, RTL_TEXTENCODING_UTF8);
+ buf.append(osOrigin);
+ buf.append(LF);
+
+ if (! m_jar_typelibs.empty())
+ {
+ t_stringlist::const_iterator iPos( m_jar_typelibs.begin() );
+ t_stringlist::const_iterator const iEnd( m_jar_typelibs.end() );
+ buf.append( RTL_CONSTASCII_STRINGPARAM("UNO_JAVA_CLASSPATH=") );
+ while (iPos != iEnd) {
+ // encoded ASCII file-urls:
+ const ::rtl::OString item(
+ ::rtl::OUStringToOString( *iPos, RTL_TEXTENCODING_ASCII_US ) );
+ buf.append( item );
+ ++iPos;
+ if (iPos != iEnd)
+ buf.append( ' ' );
+ }
+ buf.append(LF);
+ }
+ if (! m_rdb_typelibs.empty())
+ {
+ t_stringlist::const_iterator iPos( m_rdb_typelibs.begin() );
+ t_stringlist::const_iterator const iEnd( m_rdb_typelibs.end() );
+ buf.append( RTL_CONSTASCII_STRINGPARAM("UNO_TYPES=") );
+ while (iPos != iEnd) {
+ buf.append( '?' );
+ // encoded ASCII file-urls:
+ const ::rtl::OString item(
+ ::rtl::OUStringToOString( *iPos, RTL_TEXTENCODING_ASCII_US ) );
+ buf.append( item );
+ ++iPos;
+ if (iPos != iEnd)
+ buf.append( ' ' );
+ }
+ buf.append(LF);
+ }
+
+ // If we duplicated the common or native rdb then we must use those urls
+ //otherwise we use those of the original files. That is, m_commonRDB_RO and
+ //m_nativeRDB_RO;
+ OUString sCommonRDB(m_commonRDB.getLength() > 0 ? m_commonRDB : m_commonRDB_RO);
+ OUString sNativeRDB(m_nativeRDB.getLength() > 0 ? m_nativeRDB : m_nativeRDB_RO);
+
+ if (sCommonRDB.getLength() > 0 || sNativeRDB.getLength() > 0 ||
+ !m_components.empty())
+ {
+ buf.append( RTL_CONSTASCII_STRINGPARAM("UNO_SERVICES=") );
+ bool space = false;
+ if (sCommonRDB.getLength() > 0)
+ {
+ buf.append( RTL_CONSTASCII_STRINGPARAM("?$ORIGIN/") );
+ buf.append( ::rtl::OUStringToOString(
+ sCommonRDB, RTL_TEXTENCODING_ASCII_US ) );
+ space = true;
+ }
+ if (sNativeRDB.getLength() > 0)
+ {
+ if (space)
+ {
+ buf.append(' ');
+ }
+ buf.append( RTL_CONSTASCII_STRINGPARAM(
+ "${$ORIGIN/${_OS}_${_ARCH}rc:UNO_SERVICES}") );
+ space = true;
+
+ // write native rc:
+ ::rtl::OStringBuffer buf2;
+ buf2.append(RTL_CONSTASCII_STRINGPARAM("ORIGIN="));
+ buf2.append(osOrigin);
+ buf2.append(LF);
+ buf2.append( RTL_CONSTASCII_STRINGPARAM("UNO_SERVICES=?$ORIGIN/") );
+ buf2.append( ::rtl::OUStringToOString(
+ sNativeRDB, RTL_TEXTENCODING_ASCII_US ) );
+ buf2.append(LF);
+
+ const Reference<io::XInputStream> xData(
+ ::xmlscript::createInputStream(
+ ::rtl::ByteSequence(
+ reinterpret_cast<sal_Int8 const *>(buf2.getStr()),
+ buf2.getLength() ) ) );
+ ::ucbhelper::Content ucb_content(
+ makeURL( getCachePath(), getPlatformString() + OUSTR("rc") ),
+ xCmdEnv );
+ ucb_content.writeStream( xData, true /* replace existing */ );
+ }
+ for (t_stringlist::iterator i(m_components.begin());
+ i != m_components.end(); ++i)
+ {
+ if (space)
+ {
+ buf.append(' ');
+ }
+ buf.append('?');
+ buf.append(rtl::OUStringToOString(*i, RTL_TEXTENCODING_UTF8));
+ space = true;
+ }
+ buf.append(LF);
+ }
+
+ // write unorc:
+ const Reference<io::XInputStream> xData(
+ ::xmlscript::createInputStream(
+ ::rtl::ByteSequence(
+ reinterpret_cast<sal_Int8 const *>(buf.getStr()),
+ buf.getLength() ) ) );
+ ::ucbhelper::Content ucb_content(
+ makeURL( getCachePath(), OUSTR("unorc") ), xCmdEnv );
+ ucb_content.writeStream( xData, true /* replace existing */ );
+
+ m_unorc_modified = false;
+}
+
+//______________________________________________________________________________
+bool BackendImpl::addToUnoRc( RcItem kind, OUString const & url_,
+ Reference<XCommandEnvironment> const & xCmdEnv )
+{
+ const OUString rcterm( dp_misc::makeRcTerm(url_) );
+ const ::osl::MutexGuard guard( getMutex() );
+ unorc_verify_init( xCmdEnv );
+ t_stringlist & rSet = getRcItemList(kind);
+ if (::std::find( rSet.begin(), rSet.end(), rcterm ) == rSet.end()) {
+ rSet.push_front( rcterm ); // prepend to list, thus overriding
+ // write immediately:
+ m_unorc_modified = true;
+ unorc_flush( xCmdEnv );
+ return true;
+ }
+ else
+ return false;
+}
+
+//______________________________________________________________________________
+bool BackendImpl::removeFromUnoRc(
+ RcItem kind, OUString const & url_,
+ Reference<XCommandEnvironment> const & xCmdEnv )
+{
+ const OUString rcterm( dp_misc::makeRcTerm(url_) );
+ const ::osl::MutexGuard guard( getMutex() );
+ unorc_verify_init( xCmdEnv );
+ getRcItemList(kind).remove( rcterm );
+ // write immediately:
+ m_unorc_modified = true;
+ unorc_flush( xCmdEnv );
+ return true;
+}
+
+//______________________________________________________________________________
+bool BackendImpl::hasInUnoRc(
+ RcItem kind, OUString const & url_ )
+{
+ const OUString rcterm( dp_misc::makeRcTerm(url_) );
+ const ::osl::MutexGuard guard( getMutex() );
+ t_stringlist const & rSet = getRcItemList(kind);
+ return ::std::find( rSet.begin(), rSet.end(), rcterm ) != rSet.end();
+}
+
+css::uno::Reference< css::registry::XRegistryKey > BackendImpl::openRegistryKey(
+ css::uno::Reference< css::registry::XRegistryKey > const & base,
+ rtl::OUString const & path)
+{
+ OSL_ASSERT(base.is());
+ css::uno::Reference< css::registry::XRegistryKey > key(base->openKey(path));
+ if (!key.is()) {
+ throw css::deployment::DeploymentException(
+ (rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM("missing registry entry ")) +
+ path + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" under ")) +
+ base->getKeyName()),
+ static_cast< OWeakObject * >(this), Any());
+ }
+ return key;
+}
+
+void BackendImpl::extractComponentData(
+ css::uno::Reference< css::uno::XComponentContext > const & context,
+ css::uno::Reference< css::registry::XRegistryKey > const & registry,
+ ComponentBackendDb::Data * data,
+ std::vector< css::uno::Reference< css::uno::XInterface > > * factories,
+ css::uno::Reference< css::loader::XImplementationLoader > const *
+ componentLoader,
+ rtl::OUString const * componentUrl)
+{
+ OSL_ASSERT(context.is() && registry.is() && data != 0 && factories != 0);
+ rtl::OUString registryName(registry->getKeyName());
+ sal_Int32 prefix = registryName.getLength();
+ if (!registryName.endsWithAsciiL(RTL_CONSTASCII_STRINGPARAM("/"))) {
+ prefix += RTL_CONSTASCII_LENGTH("/");
+ }
+ css::uno::Sequence< css::uno::Reference< css::registry::XRegistryKey > >
+ keys(registry->openKeys());
+ css::uno::Reference< css::lang::XMultiComponentFactory > smgr(
+ context->getServiceManager(), css::uno::UNO_QUERY_THROW);
+ for (sal_Int32 i = 0; i < keys.getLength(); ++i) {
+ rtl::OUString name(keys[i]->getKeyName().copy(prefix));
+ data->implementationNames.push_back(name);
+ css::uno::Reference< css::registry::XRegistryKey > singletons(
+ keys[i]->openKey(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("UNO/SINGLETONS"))));
+ if (singletons.is()) {
+ sal_Int32 prefix2 = keys[i]->getKeyName().getLength() +
+ RTL_CONSTASCII_LENGTH("/UNO/SINGLETONS/");
+ css::uno::Sequence<
+ css::uno::Reference< css::registry::XRegistryKey > >
+ singletonKeys(singletons->openKeys());
+ for (sal_Int32 j = 0; j < singletonKeys.getLength(); ++j) {
+ data->singletons.push_back(
+ std::pair< rtl::OUString, rtl::OUString >(
+ singletonKeys[j]->getKeyName().copy(prefix2), name));
+ }
+ }
+ css::uno::Reference< css::loader::XImplementationLoader > loader;
+ if (componentLoader == 0) {
+ rtl::OUString activator(
+ openRegistryKey(
+ keys[i],
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM("UNO/ACTIVATOR")))->
+ getAsciiValue());
+ loader.set(
+ smgr->createInstanceWithContext(activator, context),
+ css::uno::UNO_QUERY);
+ if (!loader.is()) {
+ throw css::deployment::DeploymentException(
+ (rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "cannot instantiate loader ")) +
+ activator),
+ static_cast< OWeakObject * >(this), Any());
+ }
+ } else {
+ OSL_ASSERT(componentLoader->is());
+ loader = *componentLoader;
+ }
+ factories->push_back(
+ loader->activate(
+ name, rtl::OUString(),
+ (componentUrl == 0
+ ? (openRegistryKey(
+ keys[i],
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM("UNO/LOCATION")))->
+ getAsciiValue())
+ : *componentUrl),
+ keys[i]));
+ }
+}
+
+void BackendImpl::componentLiveInsertion(
+ ComponentBackendDb::Data const & data,
+ std::vector< css::uno::Reference< css::uno::XInterface > > const &
+ factories)
+{
+ css::uno::Reference< css::container::XSet > set(
+ getComponentContext()->getServiceManager(), css::uno::UNO_QUERY_THROW);
+ std::vector< css::uno::Reference< css::uno::XInterface > >::const_iterator
+ factory(factories.begin());
+ for (t_stringlist::const_iterator i(data.implementationNames.begin());
+ i != data.implementationNames.end(); ++i)
+ {
+ try {
+ set->insert(css::uno::Any(*factory++));
+ } catch (container::ElementExistException &) {
+ OSL_TRACE(
+ "implementation %s already registered",
+ rtl::OUStringToOString(*i, RTL_TEXTENCODING_UTF8).getStr());
+ }
+ }
+ if (!data.singletons.empty()) {
+ css::uno::Reference< css::container::XNameContainer >
+ rootContext(
+ getComponentContext()->getValueByName(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("_root"))),
+ css::uno::UNO_QUERY);
+ if (rootContext.is()) {
+ for (t_stringpairvec::const_iterator i(data.singletons.begin());
+ i != data.singletons.end(); ++i)
+ {
+ rtl::OUString name(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/singletons/")) +
+ i->first);
+ try {
+ rootContext->removeByName(
+ name +
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM("/arguments")));
+ } catch (container::NoSuchElementException &) {}
+ try {
+ rootContext->insertByName(
+ (name +
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM("/service"))),
+ css::uno::Any(i->second));
+ } catch (container::ElementExistException &) {
+ rootContext->replaceByName(
+ (name +
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM("/service"))),
+ css::uno::Any(i->second));
+ }
+ try {
+ rootContext->insertByName(name, css::uno::Any());
+ } catch (container::ElementExistException &) {
+ OSL_TRACE(
+ "singleton %s already registered",
+ rtl::OUStringToOString(
+ i->first, RTL_TEXTENCODING_UTF8).getStr());
+ rootContext->replaceByName(name, css::uno::Any());
+ }
+ }
+ }
+ }
+}
+
+void BackendImpl::componentLiveRemoval(ComponentBackendDb::Data const & data) {
+ css::uno::Reference< css::container::XSet > set(
+ getComponentContext()->getServiceManager(), css::uno::UNO_QUERY_THROW);
+ for (t_stringlist::const_iterator i(data.implementationNames.begin());
+ i != data.implementationNames.end(); ++i)
+ {
+ try {
+ set->remove(css::uno::Any(*i));
+ } catch (css::container::NoSuchElementException &) {
+ // ignore if factory has not been live deployed
+ }
+ }
+ if (!data.singletons.empty()) {
+ css::uno::Reference< css::container::XNameContainer > rootContext(
+ getComponentContext()->getValueByName(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("_root"))),
+ css::uno::UNO_QUERY);
+ if (rootContext.is()) {
+ for (t_stringpairvec::const_iterator i(data.singletons.begin());
+ i != data.singletons.end(); ++i)
+ {
+ rtl::OUString name(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/singletons/")) +
+ i->first);
+ try {
+ rootContext->removeByName(
+ name +
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM("/arguments")));
+ rootContext->removeByName(
+ name +
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/service")));
+ rootContext->removeByName(name);
+ } catch (container::NoSuchElementException &) {}
+ }
+ }
+ }
+}
+
+//______________________________________________________________________________
+void BackendImpl::releaseObject( OUString const & id )
+{
+ const ::osl::MutexGuard guard( getMutex() );
+ m_backendObjects.erase( id );
+}
+
+//______________________________________________________________________________
+Reference<XInterface> BackendImpl::getObject( OUString const & id )
+{
+ const ::osl::MutexGuard guard( getMutex() );
+ const t_string2object::const_iterator iFind( m_backendObjects.find( id ) );
+ if (iFind == m_backendObjects.end())
+ return Reference<XInterface>();
+ else
+ return iFind->second;
+}
+
+//______________________________________________________________________________
+Reference<XInterface> BackendImpl::insertObject(
+ OUString const & id, Reference<XInterface> const & xObject )
+{
+ const ::osl::MutexGuard guard( getMutex() );
+ const ::std::pair<t_string2object::iterator, bool> insertion(
+ m_backendObjects.insert( t_string2object::value_type(
+ id, xObject ) ) );
+ return insertion.first->second;
+}
+
+//------------------------------------------------------------------------------
+Reference<XComponentContext> raise_uno_process(
+ Reference<XComponentContext> const & xContext,
+ ::rtl::Reference<AbortChannel> const & abortChannel )
+{
+ OSL_ASSERT( xContext.is() );
+
+ ::rtl::OUString url(
+ Reference<util::XMacroExpander>(
+ xContext->getValueByName(
+ OUSTR("/singletons/com.sun.star.util.theMacroExpander") ),
+ UNO_QUERY_THROW )->
+ expandMacros( OUSTR("$URE_BIN_DIR/uno") ) );
+
+ ::rtl::OUStringBuffer buf;
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("uno:pipe,name=") );
+ OUString pipeId( generateRandomPipeId() );
+ buf.append( pipeId );
+ buf.appendAscii(
+ RTL_CONSTASCII_STRINGPARAM(";urp;uno.ComponentContext") );
+ const OUString connectStr( buf.makeStringAndClear() );
+
+ // raise core UNO process to register/run a component,
+ // javavm service uses unorc next to executable to retrieve deployed
+ // jar typelibs
+
+ ::std::vector<OUString> args;
+#if OSL_DEBUG_LEVEL <= 1
+ args.push_back( OUSTR("--quiet") );
+#endif
+ args.push_back( OUSTR("--singleaccept") );
+ args.push_back( OUSTR("-u") );
+ args.push_back( connectStr );
+ // don't inherit from unorc:
+ args.push_back( OUSTR("-env:INIFILENAME=") );
+
+ //now add the bootstrap variables which were supplied on the command line
+ ::std::vector<OUString> bootvars = getCmdBootstrapVariables();
+ args.insert(args.end(), bootvars.begin(), bootvars.end());
+
+ oslProcess hProcess = raiseProcess(
+ url, comphelper::containerToSequence(args) );
+ try {
+ return Reference<XComponentContext>(
+ resolveUnoURL( connectStr, xContext, abortChannel.get() ),
+ UNO_QUERY_THROW );
+ }
+ catch (...) {
+ // try to terminate process:
+ if ( osl_terminateProcess( hProcess ) != osl_Process_E_None )
+ {
+ OSL_ASSERT( false );
+ }
+ throw;
+ }
+}
+
+//------------------------------------------------------------------------------
+void BackendImpl::ComponentPackageImpl::getComponentInfo(
+ ComponentBackendDb::Data * data,
+ std::vector< css::uno::Reference< css::uno::XInterface > > * factories,
+ Reference<XComponentContext> const & xContext )
+{
+ const Reference<loader::XImplementationLoader> xLoader(
+ xContext->getServiceManager()->createInstanceWithContext(
+ m_loader, xContext ), UNO_QUERY );
+ if (! xLoader.is())
+ {
+ throw css::deployment::DeploymentException(
+ (rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM("cannot instantiate loader ")) +
+ m_loader),
+ static_cast< OWeakObject * >(this), Any());
+ }
+
+ // HACK: highly dependent on stoc/source/servicemanager
+ // and stoc/source/implreg implementation which rely on the same
+ // services.rdb format!
+ // .../UNO/LOCATION and .../UNO/ACTIVATOR appear not to be written by
+ // writeRegistryInfo, however, but are knwon, fixed values here, so
+ // can be passed into extractComponentData
+ rtl::OUString url(getURL());
+ const Reference<registry::XSimpleRegistry> xMemReg(
+ xContext->getServiceManager()->createInstanceWithContext(
+ OUSTR("com.sun.star.registry.SimpleRegistry"), xContext ),
+ UNO_QUERY_THROW );
+ xMemReg->open( OUString() /* in mem */, false, true );
+ xLoader->writeRegistryInfo( xMemReg->getRootKey(), OUString(), url );
+ getMyBackend()->extractComponentData(
+ xContext, xMemReg->getRootKey(), data, factories, &xLoader, &url);
+}
+
+// Package
+//______________________________________________________________________________
+//We could use here BackendImpl::hasActiveEntry. However, this check is just as well.
+//And it also shows the problem if another extension has overwritten an implementation
+//entry, because it contains the same service implementation
+beans::Optional< beans::Ambiguous<sal_Bool> >
+BackendImpl::ComponentPackageImpl::isRegistered_(
+ ::osl::ResettableMutexGuard &,
+ ::rtl::Reference<AbortChannel> const & abortChannel,
+ Reference<XCommandEnvironment> const & )
+{
+ if (m_registered == REG_UNINIT)
+ {
+ m_registered = REG_NOT_REGISTERED;
+ bool bAmbiguousComponentName = false;
+ const Reference<registry::XSimpleRegistry> xRDB( getRDB_RO() );
+ if (xRDB.is())
+ {
+ // lookup rdb for location URL:
+ const Reference<registry::XRegistryKey> xRootKey(
+ xRDB->getRootKey() );
+ const Reference<registry::XRegistryKey> xImplKey(
+ xRootKey->openKey( OUSTR("IMPLEMENTATIONS") ) );
+ Sequence<OUString> implNames;
+ if (xImplKey.is() && xImplKey->isValid())
+ implNames = xImplKey->getKeyNames();
+ OUString const * pImplNames = implNames.getConstArray();
+ sal_Int32 pos = implNames.getLength();
+ for ( ; pos--; )
+ {
+ checkAborted( abortChannel );
+ const OUString key(
+ pImplNames[ pos ] + OUSTR("/UNO/LOCATION") );
+ const Reference<registry::XRegistryKey> xKey(
+ xRootKey->openKey(key) );
+ if (xKey.is() && xKey->isValid())
+ {
+ const OUString location( xKey->getAsciiValue() );
+ if (location.equalsIgnoreAsciiCase( getURL() ))
+ {
+ break;
+ }
+ else
+ {
+ //try to match only the file name
+ OUString thisUrl(getURL());
+ OUString thisFileName(thisUrl.copy(thisUrl.lastIndexOf('/')));
+
+ OUString locationFileName(location.copy(location.lastIndexOf('/')));
+ if (locationFileName.equalsIgnoreAsciiCase(thisFileName))
+ bAmbiguousComponentName = true;
+ }
+ }
+ }
+ if (pos >= 0)
+ m_registered = REG_REGISTERED;
+ else if (bAmbiguousComponentName)
+ m_registered = REG_MAYBE_REGISTERED;
+ }
+ }
+
+ //Different extensions can use the same service implementations. Then the extensions
+ //which was installed last will overwrite the one from the other extension. That is
+ //the registry will contain the path (the location) of the library or jar of the
+ //second extension. In this case isRegistered called for the lib of the first extension
+ //would return "not registered". That would mean that during uninstallation
+ //XPackage::registerPackage is not called, because it just was not registered. This is,
+ //however, necessary for jar files. Registering and unregistering update
+ //uno_packages/cache/registry/com.sun.star.comp.deployment.component.PackageRegistryBackend/unorc
+ //Therefore, we will return always "is ambiguous" if the path of this component cannot
+ //be found in the registry and if there is another path and both have the same file name (but
+ //the rest of the path is different).
+ //If the caller cannot precisely determine that this package was registered, then it must
+ //call registerPackage.
+ sal_Bool bAmbiguous = m_registered == REG_VOID // REG_VOID == we are in the progress of unregistration
+ || m_registered == REG_MAYBE_REGISTERED;
+ return beans::Optional< beans::Ambiguous<sal_Bool> >(
+ true /* IsPresent */,
+ beans::Ambiguous<sal_Bool>(
+ m_registered == REG_REGISTERED, bAmbiguous) );
+}
+
+//______________________________________________________________________________
+void BackendImpl::ComponentPackageImpl::processPackage_(
+ ::osl::ResettableMutexGuard &,
+ bool doRegisterPackage,
+ bool startup,
+ ::rtl::Reference<AbortChannel> const & abortChannel,
+ Reference<XCommandEnvironment> const & xCmdEnv )
+{
+ BackendImpl * that = getMyBackend();
+ rtl::OUString url(getURL());
+ if (doRegisterPackage) {
+ ComponentBackendDb::Data data;
+ css::uno::Reference< css::uno::XComponentContext > context;
+ if (startup) {
+ context = that->getComponentContext();
+ } else {
+ context.set(that->getObject(url), css::uno::UNO_QUERY);
+ if (!context.is()) {
+ context.set(
+ that->insertObject(
+ url,
+ raise_uno_process(
+ that->getComponentContext(), abortChannel)),
+ css::uno::UNO_QUERY_THROW);
+ }
+ }
+ css::uno::Reference< css::registry::XImplementationRegistration>(
+ context->getServiceManager()->createInstanceWithContext(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.ImplementationRegistration")),
+ context),
+ css::uno::UNO_QUERY_THROW)->registerImplementation(
+ m_loader, url, getRDB());
+ // Only write to unorc after successful registration; it may fail if
+ // there is no suitable java
+ if (m_loader.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM("com.sun.star.loader.Java2")) &&
+ !jarManifestHeaderPresent(url, OUSTR("UNO-Type-Path"), xCmdEnv))
+ {
+ that->addToUnoRc(RCITEM_JAR_TYPELIB, url, xCmdEnv);
+ data.javaTypeLibrary = true;
+ }
+ std::vector< css::uno::Reference< css::uno::XInterface > > factories;
+ getComponentInfo(&data, &factories, context);
+ if (!startup) {
+ that->componentLiveInsertion(data, factories);
+ }
+ m_registered = REG_REGISTERED;
+ that->addDataToDb(url, data);
+ } else { // revoke
+ m_registered = REG_VOID;
+ ComponentBackendDb::Data data(that->readDataFromDb(url));
+ css::uno::Reference< css::uno::XComponentContext > context(
+ that->getObject(url), css::uno::UNO_QUERY);
+ bool remoteContext = context.is();
+ if (!remoteContext) {
+ context = that->getComponentContext();
+ }
+ if (!startup) {
+ that->componentLiveRemoval(data);
+ }
+ css::uno::Reference< css::registry::XImplementationRegistration >(
+ context->getServiceManager()->createInstanceWithContext(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.ImplementationRegistration")),
+ context),
+ css::uno::UNO_QUERY_THROW)->revokeImplementation(url, getRDB());
+ if (data.javaTypeLibrary) {
+ that->removeFromUnoRc(RCITEM_JAR_TYPELIB, url, xCmdEnv);
+ }
+ if (remoteContext) {
+ that->releaseObject(url);
+ }
+ m_registered = REG_NOT_REGISTERED;
+ getMyBackend()->revokeEntryFromDb(url);
+ }
+}
+
+BackendImpl::TypelibraryPackageImpl::TypelibraryPackageImpl(
+ ::rtl::Reference<PackageRegistryBackend> const & myBackend,
+ OUString const & url, OUString const & name,
+ Reference<deployment::XPackageTypeInfo> const & xPackageType,
+ bool jarFile, bool bRemoved, OUString const & identifier)
+ : Package( myBackend, url, name, name /* display-name */,
+ xPackageType, bRemoved, identifier),
+ m_jarFile( jarFile )
+{
+}
+
+// Package
+BackendImpl * BackendImpl::TypelibraryPackageImpl::getMyBackend() const
+{
+ BackendImpl * pBackend = static_cast<BackendImpl *>(m_myBackend.get());
+ if (NULL == pBackend)
+ {
+ //May throw a DisposedException
+ check();
+ //We should never get here...
+ throw RuntimeException(
+ OUSTR("Failed to get the BackendImpl"),
+ static_cast<OWeakObject*>(const_cast<TypelibraryPackageImpl *>(this)));
+ }
+ return pBackend;
+}
+//______________________________________________________________________________
+beans::Optional< beans::Ambiguous<sal_Bool> >
+BackendImpl::TypelibraryPackageImpl::isRegistered_(
+ ::osl::ResettableMutexGuard &,
+ ::rtl::Reference<AbortChannel> const &,
+ Reference<XCommandEnvironment> const & )
+{
+ BackendImpl * that = getMyBackend();
+ return beans::Optional< beans::Ambiguous<sal_Bool> >(
+ true /* IsPresent */,
+ beans::Ambiguous<sal_Bool>(
+ that->hasInUnoRc(
+ m_jarFile ? RCITEM_JAR_TYPELIB : RCITEM_RDB_TYPELIB, getURL() ),
+ false /* IsAmbiguous */ ) );
+}
+
+//______________________________________________________________________________
+void BackendImpl::TypelibraryPackageImpl::processPackage_(
+ ::osl::ResettableMutexGuard &,
+ bool doRegisterPackage,
+ bool /*startup*/,
+ ::rtl::Reference<AbortChannel> const &,
+ Reference<XCommandEnvironment> const & xCmdEnv )
+{
+ BackendImpl * that = getMyBackend();
+ const OUString url( getURL() );
+
+ if (doRegisterPackage)
+ {
+ // live insertion:
+ if (m_jarFile) {
+ // xxx todo add to classpath at runtime: ???
+ //SB: It is probably not worth it to add the live inserted type
+ // library JAR to the UnoClassLoader in the soffice process. Any
+ // live inserted component JAR that might reference this type
+ // library JAR runs in its own uno process, so there is probably no
+ // Java code in the soffice process that would see any UNO types
+ // introduced by this type library JAR.
+ }
+ else // RDB:
+ {
+ Reference<XComponentContext> const & xContext =
+ that->getComponentContext();
+ if (! m_xTDprov.is())
+ {
+ m_xTDprov.set( that->getObject( url ), UNO_QUERY );
+ if (! m_xTDprov.is())
+ {
+ const Reference<registry::XSimpleRegistry> xReg(
+ xContext->getServiceManager()
+ ->createInstanceWithContext(
+ OUSTR("com.sun.star.registry.SimpleRegistry"),
+ xContext ), UNO_QUERY_THROW );
+ xReg->open( expandUnoRcUrl(url),
+ true /* read-only */, false /* ! create */ );
+ const Any arg(xReg);
+ Reference<container::XHierarchicalNameAccess> xTDprov(
+ xContext->getServiceManager()
+ ->createInstanceWithArgumentsAndContext(
+ OUSTR("com.sun.star.comp.stoc."
+ "RegistryTypeDescriptionProvider"),
+ Sequence<Any>( &arg, 1 ), xContext ), UNO_QUERY );
+ OSL_ASSERT( xTDprov.is() );
+ if (xTDprov.is())
+ m_xTDprov.set( that->insertObject( url, xTDprov ),
+ UNO_QUERY_THROW );
+ }
+ }
+ if (m_xTDprov.is()) {
+ Reference<container::XSet> xSet(
+ xContext->getValueByName(
+ OUSTR("/singletons/com.sun.star."
+ "reflection.theTypeDescriptionManager") ),
+ UNO_QUERY_THROW );
+ xSet->insert( Any(m_xTDprov) );
+ }
+ }
+
+ that->addToUnoRc( m_jarFile ? RCITEM_JAR_TYPELIB : RCITEM_RDB_TYPELIB,
+ url, xCmdEnv );
+ }
+ else // revokePackage()
+ {
+ that->removeFromUnoRc(
+ m_jarFile ? RCITEM_JAR_TYPELIB : RCITEM_RDB_TYPELIB, url, xCmdEnv );
+
+ // revoking types at runtime, possible, sensible?
+ if (!m_xTDprov.is())
+ m_xTDprov.set( that->getObject( url ), UNO_QUERY );
+ if (m_xTDprov.is()) {
+ // remove live:
+ const Reference<container::XSet> xSet(
+ that->getComponentContext()->getValueByName(
+ OUSTR("/singletons/com.sun.star."
+ "reflection.theTypeDescriptionManager") ),
+ UNO_QUERY_THROW );
+ xSet->remove( Any(m_xTDprov) );
+
+ that->releaseObject( url );
+ m_xTDprov.clear();
+ }
+ }
+}
+
+BackendImpl::OtherPlatformPackageImpl::OtherPlatformPackageImpl(
+ ::rtl::Reference<PackageRegistryBackend> const & myBackend,
+ OUString const & url, OUString const & name,
+ Reference<deployment::XPackageTypeInfo> const & xPackageType,
+ bool bRemoved, OUString const & identifier, OUString const& rPlatform)
+ : Package(myBackend, url, name, name, xPackageType, bRemoved, identifier)
+ , m_aPlatform(rPlatform)
+{
+ OSL_PRECOND(bRemoved, "this class can only be used for removing packages!");
+}
+
+BackendImpl *
+BackendImpl::OtherPlatformPackageImpl::getMyBackend() const
+{
+ BackendImpl * pBackend = static_cast<BackendImpl *>(m_myBackend.get());
+ if (NULL == pBackend)
+ {
+ //Throws a DisposedException
+ check();
+ //We should never get here...
+ throw RuntimeException(
+ OUSTR("Failed to get the BackendImpl"),
+ static_cast<OWeakObject*>(const_cast<OtherPlatformPackageImpl*>(this)));
+ }
+ return pBackend;
+}
+
+Reference<registry::XSimpleRegistry> const
+BackendImpl::OtherPlatformPackageImpl::impl_openRDB() const
+{
+ OUString const aRDB(m_aPlatform + OUString(RTL_CONSTASCII_USTRINGPARAM(".rdb")));
+ OUString const aRDBPath(makeURL(getMyBackend()->getCachePath(), aRDB));
+
+ Reference<registry::XSimpleRegistry> xRegistry;
+
+ try
+ {
+ xRegistry.set(
+ impl_createInstance(
+ OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.registry.SimpleRegistry"))),
+ UNO_QUERY)
+ ;
+ if (xRegistry.is())
+ xRegistry->open(expandUnoRcUrl(aRDBPath), false, false);
+ }
+ catch (registry::InvalidRegistryException const&)
+ {
+ // If the registry does not exist, we do not need to bother at all
+ xRegistry.set(0);
+ }
+
+ OSL_POSTCOND(xRegistry.is(), "could not create registry for the package's platform");
+ return xRegistry;
+}
+
+Reference<XInterface> const
+BackendImpl::OtherPlatformPackageImpl::impl_createInstance(OUString const& rService)
+const
+{
+ Reference<XComponentContext> const xContext(getMyBackend()->getComponentContext());
+ OSL_ASSERT(xContext.is());
+ Reference<XInterface> xService;
+ if (xContext.is())
+ xService.set(xContext->getServiceManager()->createInstanceWithContext(rService, xContext));
+ return xService;
+}
+
+beans::Optional<beans::Ambiguous<sal_Bool> >
+BackendImpl::OtherPlatformPackageImpl::isRegistered_(
+ ::osl::ResettableMutexGuard& /* guard */,
+ ::rtl::Reference<AbortChannel> const& /* abortChannel */,
+ Reference<XCommandEnvironment> const& /* xCmdEnv */ )
+{
+ return beans::Optional<beans::Ambiguous<sal_Bool> >(sal_True,
+ beans::Ambiguous<sal_Bool>(sal_True, sal_False));
+}
+
+void
+BackendImpl::OtherPlatformPackageImpl::processPackage_(
+ ::osl::ResettableMutexGuard& /* guard */,
+ bool bRegisterPackage,
+ bool /* bStartup */,
+ ::rtl::Reference<AbortChannel> const& /* abortChannel */,
+ Reference<XCommandEnvironment> const& /* xCmdEnv */)
+{
+ OSL_PRECOND(!bRegisterPackage, "this class can only be used for removing packages!");
+ (void) bRegisterPackage;
+
+ OUString const aURL(getURL());
+
+ Reference<registry::XSimpleRegistry> const xServicesRDB(impl_openRDB());
+ Reference<registry::XImplementationRegistration> const xImplReg(
+ impl_createInstance(
+ OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.registry.ImplementationRegistration"))),
+ UNO_QUERY)
+ ;
+ if (xImplReg.is() && xServicesRDB.is())
+ xImplReg->revokeImplementation(aURL, xServicesRDB);
+ if (xServicesRDB.is())
+ xServicesRDB->close();
+
+ getMyBackend()->revokeEntryFromDb(aURL);
+}
+
+BackendImpl * BackendImpl::ComponentsPackageImpl::getMyBackend() const
+{
+ BackendImpl * pBackend = static_cast<BackendImpl *>(m_myBackend.get());
+ if (NULL == pBackend)
+ {
+ //Throws a DisposedException
+ check();
+ //We should never get here...
+ throw RuntimeException(
+ OUSTR("Failed to get the BackendImpl"),
+ static_cast<OWeakObject*>(const_cast<ComponentsPackageImpl *>(this)));
+ }
+ return pBackend;
+}
+
+beans::Optional< beans::Ambiguous<sal_Bool> >
+BackendImpl::ComponentsPackageImpl::isRegistered_(
+ ::osl::ResettableMutexGuard &,
+ ::rtl::Reference<AbortChannel> const &,
+ Reference<XCommandEnvironment> const & )
+{
+ return beans::Optional< beans::Ambiguous<sal_Bool> >(
+ true,
+ beans::Ambiguous<sal_Bool>(
+ getMyBackend()->hasInUnoRc(RCITEM_COMPONENTS, getURL()), false));
+}
+
+void BackendImpl::ComponentsPackageImpl::processPackage_(
+ ::osl::ResettableMutexGuard &,
+ bool doRegisterPackage,
+ bool startup,
+ ::rtl::Reference<AbortChannel> const & abortChannel,
+ Reference<XCommandEnvironment> const & xCmdEnv )
+{
+ BackendImpl * that = getMyBackend();
+ rtl::OUString url(getURL());
+ if (doRegisterPackage) {
+ ComponentBackendDb::Data data;
+ data.javaTypeLibrary = false;
+ std::vector< css::uno::Reference< css::uno::XInterface > > factories;
+ css::uno::Reference< css::uno::XComponentContext > context(
+ that->getObject(url), css::uno::UNO_QUERY);
+ if (!context.is()) {
+ context.set(
+ that->insertObject(
+ url,
+ raise_uno_process(
+ that->getComponentContext(), abortChannel)),
+ css::uno::UNO_QUERY_THROW);
+ }
+ css::uno::Reference< css::registry::XSimpleRegistry > registry(
+ css::uno::Reference< css::lang::XMultiComponentFactory >(
+ that->getComponentContext()->getServiceManager(),
+ css::uno::UNO_SET_THROW)->createInstanceWithContext(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.SimpleRegistry")),
+ that->getComponentContext()),
+ css::uno::UNO_QUERY_THROW);
+ registry->open(expandUnoRcUrl(url), true, false);
+ getMyBackend()->extractComponentData(
+ context,
+ that->openRegistryKey(
+ registry->getRootKey(),
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("IMPLEMENTATIONS"))),
+ &data, &factories, 0, 0);
+ registry->close();
+ if (!startup) {
+ that->componentLiveInsertion(data, factories);
+ }
+ that->addDataToDb(url, data);
+ that->addToUnoRc(RCITEM_COMPONENTS, url, xCmdEnv);
+ } else { // revoke
+ that->removeFromUnoRc(RCITEM_COMPONENTS, url, xCmdEnv);
+ if (!startup) {
+ that->componentLiveRemoval(that->readDataFromDb(url));
+ }
+ that->releaseObject(url);
+ that->revokeEntryFromDb(url);
+ }
+}
+
+BackendImpl::ComponentsPackageImpl::ComponentsPackageImpl(
+ ::rtl::Reference<PackageRegistryBackend> const & myBackend,
+ OUString const & url, OUString const & name,
+ Reference<deployment::XPackageTypeInfo> const & xPackageType,
+ bool bRemoved, OUString const & identifier)
+ : Package( myBackend, url, name, name /* display-name */,
+ xPackageType, bRemoved, identifier)
+{}
+
+} // anon namespace
+
+namespace sdecl = comphelper::service_decl;
+sdecl::class_<BackendImpl, sdecl::with_args<true> > serviceBI;
+extern sdecl::ServiceDecl const serviceDecl(
+ serviceBI,
+ IMPLEMENTATION_NAME,
+ BACKEND_SERVICE_NAME );
+
+} // namespace component
+} // namespace backend
+} // namespace dp_registry
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/registry/component/dp_component.hrc b/desktop/source/deployment/registry/component/dp_component.hrc
new file mode 100755
index 000000000000..4a8c4184a994
--- /dev/null
+++ b/desktop/source/deployment/registry/component/dp_component.hrc
@@ -0,0 +1,40 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#if ! defined INCLUDED_DP_COMPONENT_HRC
+#define INCLUDED_DP_COMPONENT_HRC
+
+#include "deployment.hrc"
+
+#define RID_STR_DYN_COMPONENT (RID_DEPLOYMENT_COMPONENT_START+10)
+#define RID_STR_JAVA_COMPONENT (RID_DEPLOYMENT_COMPONENT_START+11)
+#define RID_STR_PYTHON_COMPONENT (RID_DEPLOYMENT_COMPONENT_START+12)
+#define RID_STR_COMPONENTS (RID_DEPLOYMENT_COMPONENT_START+13)
+#define RID_STR_RDB_TYPELIB (RID_DEPLOYMENT_COMPONENT_START+20)
+#define RID_STR_JAVA_TYPELIB (RID_DEPLOYMENT_COMPONENT_START+21)
+
+#endif
diff --git a/desktop/source/deployment/registry/component/dp_component.src b/desktop/source/deployment/registry/component/dp_component.src
new file mode 100644
index 000000000000..9e9ab1a82bbf
--- /dev/null
+++ b/desktop/source/deployment/registry/component/dp_component.src
@@ -0,0 +1,59 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "dp_component.hrc"
+
+String RID_STR_DYN_COMPONENT
+{
+ Text [ en-US ] = "UNO Dynamic Library Component";
+};
+
+String RID_STR_JAVA_COMPONENT
+{
+ Text [ en-US ] = "UNO Java Component";
+};
+
+String RID_STR_PYTHON_COMPONENT
+{
+ Text [ en-US ] = "UNO Python Component";
+};
+
+String RID_STR_COMPONENTS
+{
+ Text [ en-US ] = "UNO Components";
+};
+
+String RID_STR_RDB_TYPELIB
+{
+ Text [ en-US ] = "UNO RDB Type Library";
+};
+
+String RID_STR_JAVA_TYPELIB
+{
+ Text [ en-US ] = "UNO Java Type Library";
+};
+
diff --git a/desktop/source/deployment/registry/component/makefile.mk b/desktop/source/deployment/registry/component/makefile.mk
new file mode 100755
index 000000000000..b7ee5c203cd5
--- /dev/null
+++ b/desktop/source/deployment/registry/component/makefile.mk
@@ -0,0 +1,48 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ = ..$/..$/..$/..
+
+PRJNAME = desktop
+TARGET = deployment_registry_component
+ENABLE_EXCEPTIONS = TRUE
+
+.INCLUDE : settings.mk
+
+SRS1NAME = $(TARGET)
+SRC1FILES = \
+ dp_component.src
+
+INCPRE += ..$/..$/inc
+
+SLOFILES = \
+ $(SLO)$/dp_component.obj \
+ $(SLO)$/dp_compbackenddb.obj
+
+.INCLUDE : ..$/..$/target.pmk
+.INCLUDE : target.mk
+
diff --git a/desktop/source/deployment/registry/configuration/dp_configuration.cxx b/desktop/source/deployment/registry/configuration/dp_configuration.cxx
new file mode 100644
index 000000000000..bcf44d359b23
--- /dev/null
+++ b/desktop/source/deployment/registry/configuration/dp_configuration.cxx
@@ -0,0 +1,812 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+//TODO: Large parts of this file were copied from dp_component.cxx; those parts
+// should be consolidated.
+
+#include "dp_configuration.hrc"
+#include "dp_backend.h"
+#include "dp_persmap.h"
+#include "dp_ucb.h"
+#include "rtl/string.hxx"
+#include "rtl/ustrbuf.hxx"
+#include "rtl/uri.hxx"
+#include "rtl/memory.h"
+#include "osl/file.hxx"
+#include "cppuhelper/exc_hlp.hxx"
+#include "ucbhelper/content.hxx"
+#include "comphelper/anytostring.hxx"
+#include "comphelper/servicedecl.hxx"
+#include "xmlscript/xml_helper.hxx"
+#include "svl/inettype.hxx"
+#include "com/sun/star/configuration/Update.hpp"
+#include "com/sun/star/ucb/NameClash.hpp"
+#include "com/sun/star/io/XActiveDataSink.hpp"
+#include "com/sun/star/lang/WrappedTargetRuntimeException.hpp"
+#include "com/sun/star/util/XRefreshable.hpp"
+#include <list>
+#include <memory>
+
+#include "dp_configurationbackenddb.hxx"
+
+using namespace ::dp_misc;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::ucb;
+using ::rtl::OUString;
+
+namespace dp_registry {
+namespace backend {
+namespace configuration {
+namespace {
+
+typedef ::std::list<OUString> t_stringlist;
+
+//==============================================================================
+class BackendImpl : public ::dp_registry::backend::PackageRegistryBackend
+{
+ class PackageImpl : public ::dp_registry::backend::Package
+ {
+ BackendImpl * getMyBackend() const ;
+
+ const bool m_isSchema;
+
+ // Package
+ virtual beans::Optional< beans::Ambiguous<sal_Bool> > isRegistered_(
+ ::osl::ResettableMutexGuard & guard,
+ ::rtl::Reference<AbortChannel> const & abortChannel,
+ Reference<XCommandEnvironment> const & xCmdEnv );
+ virtual void processPackage_(
+ ::osl::ResettableMutexGuard & guard,
+ bool registerPackage,
+ bool startup,
+ ::rtl::Reference<AbortChannel> const & abortChannel,
+ Reference<XCommandEnvironment> const & xCmdEnv );
+
+ public:
+ inline PackageImpl(
+ ::rtl::Reference<PackageRegistryBackend> const & myBackend,
+ OUString const & url, OUString const & name,
+ Reference<deployment::XPackageTypeInfo> const & xPackageType,
+ bool isSchema, bool bRemoved, OUString const & identifier)
+ : Package( myBackend, url, name, name /* display-name */,
+ xPackageType, bRemoved, identifier),
+ m_isSchema( isSchema )
+ {}
+ };
+ friend class PackageImpl;
+
+ t_stringlist m_xcs_files;
+ t_stringlist m_xcu_files;
+ t_stringlist & getFiles( bool xcs ) {
+ return xcs ? m_xcs_files : m_xcu_files;
+ }
+
+ bool m_configmgrini_inited;
+ bool m_configmgrini_modified;
+ std::auto_ptr<ConfigurationBackendDb> m_backendDb;
+
+ // PackageRegistryBackend
+ virtual Reference<deployment::XPackage> bindPackage_(
+ OUString const & url, OUString const & mediaType, sal_Bool bRemoved,
+ OUString const & identifier,
+ Reference<XCommandEnvironment> const & xCmdEnv );
+
+ ::std::auto_ptr<PersistentMap> m_registeredPackages;
+ // for backwards compatibility
+
+ virtual void SAL_CALL disposing();
+
+ const Reference<deployment::XPackageTypeInfo> m_xConfDataTypeInfo;
+ const Reference<deployment::XPackageTypeInfo> m_xConfSchemaTypeInfo;
+ Sequence< Reference<deployment::XPackageTypeInfo> > m_typeInfos;
+
+ void configmgrini_verify_init(
+ Reference<XCommandEnvironment> const & xCmdEnv );
+ void configmgrini_flush( Reference<XCommandEnvironment> const & xCmdEnv );
+
+ /* The paramter isURL is false in the case of adding the conf:ini-entry
+ value from the backend db. This entry already contains the path as it
+ is used in the configmgr.ini.
+ */
+ bool addToConfigmgrIni( bool isSchema, bool isURL, OUString const & url,
+ Reference<XCommandEnvironment> const & xCmdEnv );
+ bool removeFromConfigmgrIni( bool isSchema, OUString const & url,
+ Reference<XCommandEnvironment> const & xCmdEnv );
+
+ void addDataToDb(OUString const & url, ConfigurationBackendDb::Data const & data);
+ ::boost::optional<ConfigurationBackendDb::Data> readDataFromDb(OUString const & url);
+ void revokeEntryFromDb(OUString const & url);
+ bool hasActiveEntry(OUString const & url);
+ bool activateEntry(OUString const & url);
+
+public:
+ BackendImpl( Sequence<Any> const & args,
+ Reference<XComponentContext> const & xComponentContext );
+
+ // XPackageRegistry
+ virtual Sequence< Reference<deployment::XPackageTypeInfo> > SAL_CALL
+ getSupportedPackageTypes() throw (RuntimeException);
+ virtual void SAL_CALL packageRemoved(OUString const & url, OUString const & mediaType)
+ throw (deployment::DeploymentException,
+ uno::RuntimeException);
+
+ using PackageRegistryBackend::disposing;
+};
+
+//______________________________________________________________________________
+void BackendImpl::disposing()
+{
+ try {
+ configmgrini_flush( Reference<XCommandEnvironment>() );
+
+ PackageRegistryBackend::disposing();
+ }
+ catch (RuntimeException &) {
+ throw;
+ }
+ catch (Exception &) {
+ Any exc( ::cppu::getCaughtException() );
+ throw lang::WrappedTargetRuntimeException(
+ OUSTR("caught unexpected exception while disposing..."),
+ static_cast<OWeakObject *>(this), exc );
+ }
+}
+
+//______________________________________________________________________________
+BackendImpl::BackendImpl(
+ Sequence<Any> const & args,
+ Reference<XComponentContext> const & xComponentContext )
+ : PackageRegistryBackend( args, xComponentContext ),
+ m_configmgrini_inited( false ),
+ m_configmgrini_modified( false ),
+ m_xConfDataTypeInfo( new Package::TypeInfo(
+ OUSTR("application/"
+ "vnd.sun.star.configuration-data"),
+ OUSTR("*.xcu"),
+ getResourceString(RID_STR_CONF_DATA),
+ RID_IMG_CONF_XML ) ),
+ m_xConfSchemaTypeInfo( new Package::TypeInfo(
+ OUSTR("application/"
+ "vnd.sun.star.configuration-schema"),
+ OUSTR("*.xcs"),
+ getResourceString(RID_STR_CONF_SCHEMA),
+ RID_IMG_CONF_XML ) ),
+ m_typeInfos( 2 )
+{
+ m_typeInfos[ 0 ] = m_xConfDataTypeInfo;
+ m_typeInfos[ 1 ] = m_xConfSchemaTypeInfo;
+
+ const Reference<XCommandEnvironment> xCmdEnv;
+
+ if (transientMode())
+ {
+ //TODO
+ }
+ else
+ {
+ OUString dbFile = makeURL(getCachePath(), OUSTR("backenddb.xml"));
+ m_backendDb.reset(
+ new ConfigurationBackendDb(getComponentContext(), dbFile));
+ //clean up data folders which are no longer used.
+ //This must not be done in the same process where the help files
+ //are still registers. Only after revoking and restarting OOo the folders
+ //can be removed. This works now, because the extension manager is a singleton
+ //and the backends are only create once per process.
+ ::std::list<OUString> folders = m_backendDb->getAllDataUrls();
+ deleteUnusedFolders(OUString(), folders);
+
+
+ configmgrini_verify_init( xCmdEnv );
+ m_registeredPackages.reset(
+ new PersistentMap(
+ makeURL( getCachePath(), OUSTR("registered_packages.db") ),
+ false ) );
+ }
+}
+
+void BackendImpl::addDataToDb(
+ OUString const & url, ConfigurationBackendDb::Data const & data)
+{
+ if (m_backendDb.get())
+ m_backendDb->addEntry(url, data);
+}
+
+::boost::optional<ConfigurationBackendDb::Data> BackendImpl::readDataFromDb(
+ OUString const & url)
+{
+ ::boost::optional<ConfigurationBackendDb::Data> data;
+ if (m_backendDb.get())
+ data = m_backendDb->getEntry(url);
+ return data;
+}
+
+void BackendImpl::revokeEntryFromDb(OUString const & url)
+{
+ if (m_backendDb.get())
+ m_backendDb->revokeEntry(url);
+}
+
+bool BackendImpl::hasActiveEntry(OUString const & url)
+{
+ if (m_backendDb.get())
+ return m_backendDb->hasActiveEntry(url);
+ return false;
+}
+
+bool BackendImpl::activateEntry(OUString const & url)
+{
+ if (m_backendDb.get())
+ return m_backendDb->activateEntry(url);
+ return false;
+}
+
+
+
+// XPackageRegistry
+//______________________________________________________________________________
+Sequence< Reference<deployment::XPackageTypeInfo> >
+BackendImpl::getSupportedPackageTypes() throw (RuntimeException)
+{
+ return m_typeInfos;
+}
+void BackendImpl::packageRemoved(OUString const & url, OUString const & /*mediaType*/)
+ throw (deployment::DeploymentException,
+ uno::RuntimeException)
+{
+ if (m_backendDb.get())
+ m_backendDb->removeEntry(url);
+}
+
+// PackageRegistryBackend
+//______________________________________________________________________________
+Reference<deployment::XPackage> BackendImpl::bindPackage_(
+ OUString const & url, OUString const & mediaType_,
+ sal_Bool bRemoved, OUString const & identifier,
+ Reference<XCommandEnvironment> const & xCmdEnv )
+{
+ OUString mediaType( mediaType_ );
+ if (mediaType.getLength() == 0)
+ {
+ // detect media-type:
+ ::ucbhelper::Content ucbContent;
+ if (create_ucb_content( &ucbContent, url, xCmdEnv ))
+ {
+ const OUString title( ucbContent.getPropertyValue(
+ StrTitle::get() ).get<OUString>() );
+ if (title.endsWithIgnoreAsciiCaseAsciiL(
+ RTL_CONSTASCII_STRINGPARAM(".xcu") )) {
+ mediaType = OUSTR("application/"
+ "vnd.sun.star.configuration-data");
+ }
+ if (title.endsWithIgnoreAsciiCaseAsciiL(
+ RTL_CONSTASCII_STRINGPARAM(".xcs") )) {
+ mediaType = OUSTR("application/"
+ "vnd.sun.star.configuration-schema");
+ }
+ }
+ if (mediaType.getLength() == 0)
+ throw lang::IllegalArgumentException(
+ StrCannotDetectMediaType::get() + url,
+ static_cast<OWeakObject *>(this), static_cast<sal_Int16>(-1) );
+ }
+
+ String type, subType;
+ INetContentTypeParameterList params;
+ if (INetContentTypes::parse( mediaType, type, subType, &params ))
+ {
+ if (type.EqualsIgnoreCaseAscii("application"))
+ {
+ OUString name;
+ if (!bRemoved)
+ {
+ ::ucbhelper::Content ucbContent( url, xCmdEnv );
+ name = ucbContent.getPropertyValue(
+ StrTitle::get() ).get<OUString>();
+ }
+
+ ::ucbhelper::Content ucbContent( url, xCmdEnv );
+ if (subType.EqualsIgnoreCaseAscii(
+ "vnd.sun.star.configuration-data"))
+ {
+ return new PackageImpl(
+ this, url, name, m_xConfDataTypeInfo, false /* data file */,
+ bRemoved, identifier);
+ }
+ else if (subType.EqualsIgnoreCaseAscii(
+ "vnd.sun.star.configuration-schema")) {
+ return new PackageImpl(
+ this, url, name, m_xConfSchemaTypeInfo, true /* schema file */,
+ bRemoved, identifier);
+ }
+ }
+ }
+ throw lang::IllegalArgumentException(
+ StrUnsupportedMediaType::get() + mediaType,
+ static_cast<OWeakObject *>(this),
+ static_cast<sal_Int16>(-1) );
+}
+
+
+//______________________________________________________________________________
+void BackendImpl::configmgrini_verify_init(
+ Reference<XCommandEnvironment> const & xCmdEnv )
+{
+ if (transientMode())
+ return;
+ const ::osl::MutexGuard guard( getMutex() );
+ if (! m_configmgrini_inited)
+ {
+ // common rc:
+ ::ucbhelper::Content ucb_content;
+ if (create_ucb_content(
+ &ucb_content,
+ makeURL( getCachePath(), OUSTR("configmgr.ini") ),
+ xCmdEnv, false /* no throw */ ))
+ {
+ OUString line;
+ if (readLine( &line, OUSTR("SCHEMA="), ucb_content,
+ RTL_TEXTENCODING_UTF8 ))
+ {
+ sal_Int32 index = sizeof ("SCHEMA=") - 1;
+ do {
+ OUString token( line.getToken( 0, ' ', index ).trim() );
+ if (token.getLength() > 0) {
+ //The file may not exist anymore if a shared or bundled
+ //extension was removed, but it can still be in the configmgrini.
+ //After running XExtensionManager::synchronize, the configmgrini is
+ //cleaned up
+ m_xcs_files.push_back( token );
+ }
+ }
+ while (index >= 0);
+ }
+ if (readLine( &line, OUSTR("DATA="), ucb_content,
+ RTL_TEXTENCODING_UTF8 )) {
+ sal_Int32 index = sizeof ("DATA=") - 1;
+ do {
+ OUString token( line.getToken( 0, ' ', index ).trim() );
+ if (token.getLength() > 0)
+ {
+ if (token[ 0 ] == '?')
+ token = token.copy( 1 );
+ //The file may not exist anymore if a shared or bundled
+ //extension was removed, but it can still be in the configmgrini.
+ //After running XExtensionManager::synchronize, the configmgrini is
+ //cleaned up
+ m_xcu_files.push_back( token );
+ }
+ }
+ while (index >= 0);
+ }
+ }
+ m_configmgrini_modified = false;
+ m_configmgrini_inited = true;
+ }
+}
+
+//______________________________________________________________________________
+void BackendImpl::configmgrini_flush(
+ Reference<XCommandEnvironment> const & xCmdEnv )
+{
+ if (transientMode())
+ return;
+ if (!m_configmgrini_inited || !m_configmgrini_modified)
+ return;
+
+ ::rtl::OStringBuffer buf;
+ if (! m_xcs_files.empty())
+ {
+ t_stringlist::const_iterator iPos( m_xcs_files.begin() );
+ t_stringlist::const_iterator const iEnd( m_xcs_files.end() );
+ buf.append( RTL_CONSTASCII_STRINGPARAM("SCHEMA=") );
+ while (iPos != iEnd) {
+ // encoded ASCII file-urls:
+ const ::rtl::OString item(
+ ::rtl::OUStringToOString( *iPos, RTL_TEXTENCODING_ASCII_US ) );
+ buf.append( item );
+ ++iPos;
+ if (iPos != iEnd)
+ buf.append( ' ' );
+ }
+ buf.append(LF);
+ }
+ if (! m_xcu_files.empty())
+ {
+ t_stringlist::const_iterator iPos( m_xcu_files.begin() );
+ t_stringlist::const_iterator const iEnd( m_xcu_files.end() );
+ buf.append( RTL_CONSTASCII_STRINGPARAM("DATA=") );
+ while (iPos != iEnd) {
+ // encoded ASCII file-urls:
+ const ::rtl::OString item(
+ ::rtl::OUStringToOString( *iPos, RTL_TEXTENCODING_ASCII_US ) );
+ buf.append( item );
+ ++iPos;
+ if (iPos != iEnd)
+ buf.append( ' ' );
+ }
+ buf.append(LF);
+ }
+
+ // write configmgr.ini:
+ const Reference<io::XInputStream> xData(
+ ::xmlscript::createInputStream(
+ ::rtl::ByteSequence(
+ reinterpret_cast<sal_Int8 const *>(buf.getStr()),
+ buf.getLength() ) ) );
+ ::ucbhelper::Content ucb_content(
+ makeURL( getCachePath(), OUSTR("configmgr.ini") ), xCmdEnv );
+ ucb_content.writeStream( xData, true /* replace existing */ );
+
+ m_configmgrini_modified = false;
+}
+
+//______________________________________________________________________________
+bool BackendImpl::addToConfigmgrIni( bool isSchema, bool isURL, OUString const & url_,
+ Reference<XCommandEnvironment> const & xCmdEnv )
+{
+ const OUString rcterm( isURL ? dp_misc::makeRcTerm(url_) : url_ );
+ const ::osl::MutexGuard guard( getMutex() );
+ configmgrini_verify_init( xCmdEnv );
+ t_stringlist & rSet = getFiles(isSchema);
+ if (::std::find( rSet.begin(), rSet.end(), rcterm ) == rSet.end()) {
+ rSet.push_front( rcterm ); // prepend to list, thus overriding
+ // write immediately:
+ m_configmgrini_modified = true;
+ configmgrini_flush( xCmdEnv );
+ return true;
+ }
+ else
+ return false;
+}
+
+//______________________________________________________________________________
+bool BackendImpl::removeFromConfigmgrIni(
+ bool isSchema, OUString const & url_,
+ Reference<XCommandEnvironment> const & xCmdEnv )
+{
+ const OUString rcterm( dp_misc::makeRcTerm(url_) );
+ const ::osl::MutexGuard guard( getMutex() );
+ configmgrini_verify_init( xCmdEnv );
+ t_stringlist & rSet = getFiles(isSchema);
+ t_stringlist::iterator i(std::find(rSet.begin(), rSet.end(), rcterm));
+ if (i == rSet.end() && !isSchema)
+ {
+ //in case the xcu contained %origin% then the configmr.ini contains the
+ //url to the file in the user installation (e.g. $BUNDLED_EXTENSIONS_USER)
+ //However, m_url (getURL()) contains the URL for the file in the actual
+ //extension installatation.
+ ::boost::optional<ConfigurationBackendDb::Data> data = readDataFromDb(url_);
+ if (data)
+ i = std::find(rSet.begin(), rSet.end(), data->iniEntry);
+ }
+ if (i == rSet.end()) {
+ return false;
+ }
+ rSet.erase(i);
+ // write immediately:
+ m_configmgrini_modified = true;
+ configmgrini_flush( xCmdEnv );
+ return true;
+}
+
+
+// Package
+//______________________________________________________________________________
+
+BackendImpl * BackendImpl::PackageImpl::getMyBackend() const
+{
+ BackendImpl * pBackend = static_cast<BackendImpl *>(m_myBackend.get());
+ if (NULL == pBackend)
+ {
+ //May throw a DisposedException
+ check();
+ //We should never get here...
+ throw RuntimeException(
+ OUSTR("Failed to get the BackendImpl"),
+ static_cast<OWeakObject*>(const_cast<PackageImpl *>(this)));
+ }
+ return pBackend;
+}
+
+beans::Optional< beans::Ambiguous<sal_Bool> >
+BackendImpl::PackageImpl::isRegistered_(
+ ::osl::ResettableMutexGuard &,
+ ::rtl::Reference<AbortChannel> const &,
+ Reference<XCommandEnvironment> const & )
+{
+ BackendImpl * that = getMyBackend();
+ const rtl::OUString url(getURL());
+
+ bool bReg = false;
+ if (that->hasActiveEntry(getURL()))
+ bReg = true;
+ if (!bReg)
+ //fallback for user extension registered in berkeley DB
+ bReg = that->m_registeredPackages->has(
+ rtl::OUStringToOString( url, RTL_TEXTENCODING_UTF8 ));
+
+ return beans::Optional< beans::Ambiguous<sal_Bool> >(
+ true, beans::Ambiguous<sal_Bool>( bReg, false ) );
+}
+
+//------------------------------------------------------------------------------
+OUString encodeForXml( OUString const & text )
+{
+ // encode conforming xml:
+ sal_Int32 len = text.getLength();
+ ::rtl::OUStringBuffer buf;
+ for ( sal_Int32 pos = 0; pos < len; ++pos )
+ {
+ sal_Unicode c = text[ pos ];
+ switch (c) {
+ case '<':
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("&lt;") );
+ break;
+ case '>':
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("&gt;") );
+ break;
+ case '&':
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("&amp;") );
+ break;
+ case '\'':
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("&apos;") );
+ break;
+ case '\"':
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("&quot;") );
+ break;
+ default:
+ buf.append( c );
+ break;
+ }
+ }
+ return buf.makeStringAndClear();
+}
+
+//______________________________________________________________________________
+OUString replaceOrigin(
+ OUString const & url, OUString const & destFolder, Reference< XCommandEnvironment > const & xCmdEnv, bool & out_replaced)
+{
+ // looking for %origin%:
+ ::ucbhelper::Content ucb_content( url, xCmdEnv );
+ ::rtl::ByteSequence bytes( readFile( ucb_content ) );
+ ::rtl::ByteSequence filtered( bytes.getLength() * 2,
+ ::rtl::BYTESEQ_NODEFAULT );
+ bool use_filtered = false;
+ ::rtl::OString origin;
+ sal_Char const * pBytes = reinterpret_cast<sal_Char const *>(
+ bytes.getConstArray());
+ sal_Size nBytes = bytes.getLength();
+ sal_Int32 write_pos = 0;
+ while (nBytes > 0)
+ {
+ sal_Int32 index = rtl_str_indexOfChar_WithLength( pBytes, nBytes, '%' );
+ if (index < 0) {
+ if (! use_filtered) // opt
+ break;
+ index = nBytes;
+ }
+
+ if ((write_pos + index) > filtered.getLength())
+ filtered.realloc( (filtered.getLength() + index) * 2 );
+ rtl_copyMemory( filtered.getArray() + write_pos, pBytes, index );
+ write_pos += index;
+ pBytes += index;
+ nBytes -= index;
+ if (nBytes == 0)
+ break;
+
+ // consume %:
+ ++pBytes;
+ --nBytes;
+ sal_Char const * pAdd = "%";
+ sal_Int32 nAdd = 1;
+ if (nBytes > 1 && pBytes[ 0 ] == '%')
+ {
+ // %% => %
+ ++pBytes;
+ --nBytes;
+ use_filtered = true;
+ }
+ else if (rtl_str_shortenedCompare_WithLength(
+ pBytes, nBytes,
+ RTL_CONSTASCII_STRINGPARAM("origin%"),
+ sizeof ("origin%") - 1 ) == 0)
+ {
+ if (origin.getLength() == 0) {
+ // encode only once
+ origin = ::rtl::OUStringToOString(
+ encodeForXml( url.copy( 0, url.lastIndexOf( '/' ) ) ),
+ // xxx todo: encode always for UTF-8? => lookup doc-header?
+ RTL_TEXTENCODING_UTF8 );
+ }
+ pAdd = origin.getStr();
+ nAdd = origin.getLength();
+ pBytes += (sizeof ("origin%") - 1);
+ nBytes -= (sizeof ("origin%") - 1);
+ use_filtered = true;
+ }
+ if ((write_pos + nAdd) > filtered.getLength())
+ filtered.realloc( (filtered.getLength() + nAdd) * 2 );
+ rtl_copyMemory( filtered.getArray() + write_pos, pAdd, nAdd );
+ write_pos += nAdd;
+ }
+ if (!use_filtered)
+ return url;
+ if (write_pos < filtered.getLength())
+ filtered.realloc( write_pos );
+ rtl::OUString newUrl(url);
+ if (destFolder.getLength())
+ {
+ //get the file name of the xcu and add it to the url of the temporary folder
+ sal_Int32 i = url.lastIndexOf('/');
+ newUrl = destFolder + url.copy(i);
+ }
+
+ ucbhelper::Content(newUrl, xCmdEnv).writeStream(
+ xmlscript::createInputStream(filtered), true);
+ out_replaced = true;
+ return newUrl;
+}
+
+//______________________________________________________________________________
+void BackendImpl::PackageImpl::processPackage_(
+ ::osl::ResettableMutexGuard &,
+ bool doRegisterPackage,
+ bool startup,
+ ::rtl::Reference<AbortChannel> const &,
+ Reference<XCommandEnvironment> const & xCmdEnv )
+{
+ BackendImpl * that = getMyBackend();
+ OUString url( getURL() );
+
+ if (doRegisterPackage)
+ {
+ if (getMyBackend()->activateEntry(getURL()))
+ {
+ ::boost::optional<ConfigurationBackendDb::Data> data = that->readDataFromDb(url);
+ OSL_ASSERT(data);
+ that->addToConfigmgrIni( m_isSchema, false, data->iniEntry, xCmdEnv );
+ }
+ else
+ {
+ ConfigurationBackendDb::Data data;
+ if (!m_isSchema)
+ {
+ const OUString sModFolder = that->createFolder(OUString(), xCmdEnv);
+ bool out_replaced = false;
+ url = replaceOrigin(url, sModFolder, xCmdEnv, out_replaced);
+ if (out_replaced)
+ data.dataUrl = sModFolder;
+ else
+ deleteTempFolder(sModFolder);
+ }
+ //No need for live-deployment for bundled extension, because OOo
+ //restarts after installation
+ if (that->m_eContext != CONTEXT_BUNDLED
+ && that->m_eContext != CONTEXT_BUNDLED_PREREG
+ && !startup)
+ {
+ if (m_isSchema)
+ {
+ com::sun::star::configuration::Update::get(
+ that->m_xComponentContext)->insertExtensionXcsFile(
+ that->m_eContext == CONTEXT_SHARED, expandUnoRcUrl(url));
+ }
+ else
+ {
+ com::sun::star::configuration::Update::get(
+ that->m_xComponentContext)->insertExtensionXcuFile(
+ that->m_eContext == CONTEXT_SHARED, expandUnoRcUrl(url));
+ }
+ }
+ that->addToConfigmgrIni( m_isSchema, true, url, xCmdEnv );
+ data.iniEntry = dp_misc::makeRcTerm(url);
+ that->addDataToDb(getURL(), data);
+ }
+ }
+ else // revoke
+ {
+ if (!that->removeFromConfigmgrIni(m_isSchema, url, xCmdEnv)) {
+ t_string2string_map entries(
+ that->m_registeredPackages->getEntries());
+ for (t_string2string_map::iterator i(entries.begin());
+ i != entries.end(); ++i)
+ {
+ //If the xcu file was installed before the configmgr was chaned
+ //to use the configmgr.ini, one needed to rebuild to whole directory
+ //structur containing the xcu, xcs files from all extensions. Now,
+ //we just add all other xcu/xcs files to the configmgr.ini instead of
+ //rebuilding the directory structure.
+ rtl::OUString url2(
+ rtl::OStringToOUString(i->first, RTL_TEXTENCODING_UTF8));
+ if (url2 != url) {
+ bool schema = i->second.equalsIgnoreAsciiCase(
+ "vnd.sun.star.configuration-schema");
+ OUString url_replaced(url2);
+ ConfigurationBackendDb::Data data;
+ if (!schema)
+ {
+ const OUString sModFolder = that->createFolder(OUString(), xCmdEnv);
+ bool out_replaced = false;
+ url_replaced = replaceOrigin(
+ url2, sModFolder, xCmdEnv, out_replaced);
+ if (out_replaced)
+ data.dataUrl = sModFolder;
+ else
+ deleteTempFolder(sModFolder);
+ }
+ that->addToConfigmgrIni(schema, true, url_replaced, xCmdEnv);
+ data.iniEntry = dp_misc::makeRcTerm(url_replaced);
+ that->addDataToDb(url2, data);
+ }
+ that->m_registeredPackages->erase(i->first);
+ }
+ try
+ {
+ ::ucbhelper::Content(
+ makeURL( that->getCachePath(), OUSTR("registry") ),
+ xCmdEnv ).executeCommand(
+ OUSTR("delete"), Any( true /* delete physically */ ) );
+ }
+ catch(Exception&)
+ {
+ OSL_ASSERT(0);
+ }
+ }
+
+ ::boost::optional<ConfigurationBackendDb::Data> data = that->readDataFromDb(url);
+ //If an xcu file was life deployed then always a data entry is written.
+ //If the xcu file was already in the configmr.ini then there is also
+ //a data entry
+ if (!m_isSchema && data)
+ {
+ com::sun::star::configuration::Update::get(
+ that->m_xComponentContext)->removeExtensionXcuFile(expandUnoRcTerm(data->iniEntry));
+ }
+ that->revokeEntryFromDb(url);
+ }
+}
+
+} // anon namespace
+
+namespace sdecl = comphelper::service_decl;
+sdecl::class_<BackendImpl, sdecl::with_args<true> > serviceBI;
+extern sdecl::ServiceDecl const serviceDecl(
+ serviceBI,
+ "com.sun.star.comp.deployment.configuration.PackageRegistryBackend",
+ BACKEND_SERVICE_NAME );
+
+} // namespace configuration
+} // namespace backend
+} // namespace dp_registry
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/registry/configuration/dp_configuration.hrc b/desktop/source/deployment/registry/configuration/dp_configuration.hrc
new file mode 100755
index 000000000000..01e1905228b3
--- /dev/null
+++ b/desktop/source/deployment/registry/configuration/dp_configuration.hrc
@@ -0,0 +1,36 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#if ! defined INCLUDED_DP_CONFIGURATION_HRC
+#define INCLUDED_DP_CONFIGURATION_HRC
+
+#include "deployment.hrc"
+
+#define RID_STR_CONF_SCHEMA (RID_DEPLOYMENT_CONF_START+10)
+#define RID_STR_CONF_DATA (RID_DEPLOYMENT_CONF_START+11)
+
+#endif
diff --git a/desktop/source/deployment/registry/configuration/dp_configuration.src b/desktop/source/deployment/registry/configuration/dp_configuration.src
new file mode 100644
index 000000000000..7ff749b18459
--- /dev/null
+++ b/desktop/source/deployment/registry/configuration/dp_configuration.src
@@ -0,0 +1,39 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "dp_configuration.hrc"
+
+String RID_STR_CONF_SCHEMA
+{
+ Text [ en-US ] = "Configuration Schema";
+};
+
+String RID_STR_CONF_DATA
+{
+ Text [ en-US ] = "Configuration Data";
+};
+
diff --git a/desktop/source/deployment/registry/configuration/dp_configurationbackenddb.cxx b/desktop/source/deployment/registry/configuration/dp_configurationbackenddb.cxx
new file mode 100644
index 000000000000..bfb1ed9df70e
--- /dev/null
+++ b/desktop/source/deployment/registry/configuration/dp_configurationbackenddb.cxx
@@ -0,0 +1,181 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include "rtl/string.h"
+#include "rtl/bootstrap.hxx"
+#include "cppuhelper/exc_hlp.hxx"
+#include "com/sun/star/uno/XComponentContext.hpp"
+#include "com/sun/star/xml/dom/XDocumentBuilder.hpp"
+#include "com/sun/star/xml/xpath/XXPathAPI.hpp"
+#include "dp_misc.h"
+
+#include "dp_configurationbackenddb.hxx"
+
+
+namespace css = ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using ::rtl::OUString;
+
+#define EXTENSION_REG_NS "http://openoffice.org/extensionmanager/configuration-registry/2010"
+#define NS_PREFIX "conf"
+#define ROOT_ELEMENT_NAME "configuration-backend-db"
+#define KEY_ELEMENT_NAME "configuration"
+
+namespace dp_registry {
+namespace backend {
+namespace configuration {
+
+ConfigurationBackendDb::ConfigurationBackendDb(
+ Reference<XComponentContext> const & xContext,
+ ::rtl::OUString const & url):BackendDb(xContext, url)
+{
+
+}
+
+OUString ConfigurationBackendDb::getDbNSName()
+{
+ return OUSTR(EXTENSION_REG_NS);
+}
+
+OUString ConfigurationBackendDb::getNSPrefix()
+{
+ return OUSTR(NS_PREFIX);
+}
+
+OUString ConfigurationBackendDb::getRootElementName()
+{
+ return OUSTR(ROOT_ELEMENT_NAME);
+}
+
+OUString ConfigurationBackendDb::getKeyElementName()
+{
+ return OUSTR(KEY_ELEMENT_NAME);
+}
+
+
+void ConfigurationBackendDb::addEntry(::rtl::OUString const & url, Data const & data)
+{
+ try{
+ if (!activateEntry(url))
+ {
+ Reference<css::xml::dom::XNode> helpNode
+ = writeKeyElement(url);
+
+ writeSimpleElement(OUSTR("data-url"), data.dataUrl, helpNode);
+ writeSimpleElement(OUSTR("ini-entry"), data.iniEntry, helpNode);
+ save();
+ }
+ }
+ catch (css::deployment::DeploymentException& )
+ {
+ throw;
+ }
+ catch(css::uno::Exception &)
+ {
+ Any exc( ::cppu::getCaughtException() );
+ throw css::deployment::DeploymentException(
+ OUSTR("Extension Manager: failed to write data entry in configuration backend db: ") +
+ m_urlDb, 0, exc);
+ }
+}
+
+
+::boost::optional<ConfigurationBackendDb::Data>
+ConfigurationBackendDb::getEntry(::rtl::OUString const & url)
+{
+ try
+ {
+ ConfigurationBackendDb::Data retData;
+ Reference<css::xml::dom::XNode> aNode = getKeyElement(url);
+ if (aNode.is())
+ {
+ retData.dataUrl = readSimpleElement(OUSTR("data-url"), aNode);
+ retData.iniEntry = readSimpleElement(OUSTR("ini-entry"), aNode);
+ }
+ else
+ {
+ return ::boost::optional<Data>();
+ }
+ return ::boost::optional<Data>(retData);
+ }
+ catch (css::deployment::DeploymentException& )
+ {
+ throw;
+ }
+ catch(css::uno::Exception &)
+ {
+ Any exc( ::cppu::getCaughtException() );
+ throw css::deployment::DeploymentException(
+ OUSTR("Extension Manager: failed to read data entry in configuration backend db: ") +
+ m_urlDb, 0, exc);
+ }
+}
+
+::std::list<OUString> ConfigurationBackendDb::getAllDataUrls()
+{
+ try
+ {
+ ::std::list<OUString> listRet;
+ Reference<css::xml::dom::XDocument> doc = getDocument();
+ Reference<css::xml::dom::XNode> root = doc->getFirstChild();
+
+ Reference<css::xml::xpath::XXPathAPI> xpathApi = getXPathAPI();
+ const OUString sPrefix = getNSPrefix();
+ OUString sExpression(
+ sPrefix + OUSTR(":configuration/") + sPrefix + OUSTR(":data-url/text()"));
+ Reference<css::xml::dom::XNodeList> nodes =
+ xpathApi->selectNodeList(root, sExpression);
+ if (nodes.is())
+ {
+ sal_Int32 length = nodes->getLength();
+ for (sal_Int32 i = 0; i < length; i++)
+ listRet.push_back(nodes->item(i)->getNodeValue());
+ }
+ return listRet;
+ }
+ catch (css::deployment::DeploymentException& )
+ {
+ throw;
+ }
+ catch(css::uno::Exception &)
+ {
+ Any exc( ::cppu::getCaughtException() );
+ throw css::deployment::DeploymentException(
+ OUSTR("Extension Manager: failed to read data entry in configuration backend db: ") +
+ m_urlDb, 0, exc);
+ }
+}
+
+} // namespace configuration
+} // namespace backend
+} // namespace dp_registry
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/registry/configuration/dp_configurationbackenddb.hxx b/desktop/source/deployment/registry/configuration/dp_configurationbackenddb.hxx
new file mode 100644
index 000000000000..00a5515b3780
--- /dev/null
+++ b/desktop/source/deployment/registry/configuration/dp_configurationbackenddb.hxx
@@ -0,0 +1,94 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#if ! defined INCLUDED_DP_CONFIGURATIONBACKENDDB_HXX
+#define INCLUDED_DP_CONFIGURATIONBACKENDDB_HXX
+
+#include "rtl/ustring.hxx"
+#include "rtl/string.hxx"
+#include <list>
+#include "boost/optional.hpp"
+#include "dp_backenddb.hxx"
+
+namespace css = ::com::sun::star;
+
+namespace com { namespace sun { namespace star {
+ namespace uno {
+ class XComponentContext;
+ }
+}}}
+
+namespace dp_registry {
+namespace backend {
+namespace configuration {
+
+/* The XML file stores the extensions which are currently registered.
+ They will be removed when they are revoked.
+ */
+class ConfigurationBackendDb: public dp_registry::backend::BackendDb
+{
+protected:
+ virtual ::rtl::OUString getDbNSName();
+
+ virtual ::rtl::OUString getNSPrefix();
+
+ virtual ::rtl::OUString getRootElementName();
+
+ virtual ::rtl::OUString getKeyElementName();
+
+public:
+ struct Data
+ {
+ /* the URL to the folder containing the xcu or xcs files which contained
+ %origin%
+ */
+ ::rtl::OUString dataUrl;
+ /* the URL of the xcu or xcs file which is written in to the configmgr.ini
+ */
+ ::rtl::OUString iniEntry;
+ };
+
+public:
+
+ ConfigurationBackendDb( css::uno::Reference<css::uno::XComponentContext> const & xContext,
+ ::rtl::OUString const & url);
+
+ void addEntry(::rtl::OUString const & url, Data const & data);
+
+ ::boost::optional<Data> getEntry(::rtl::OUString const & url);
+ ::std::list< ::rtl::OUString> getAllDataUrls();
+};
+
+
+
+}
+}
+}
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/registry/configuration/makefile.mk b/desktop/source/deployment/registry/configuration/makefile.mk
new file mode 100755
index 000000000000..9bcbd50d4230
--- /dev/null
+++ b/desktop/source/deployment/registry/configuration/makefile.mk
@@ -0,0 +1,52 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ = ..$/..$/..$/..
+
+PRJNAME = desktop
+TARGET = deployment_registry_configuration
+ENABLE_EXCEPTIONS = TRUE
+
+INCPRE += ..$/..$/inc
+
+.INCLUDE : settings.mk
+
+.IF "$(SYSTEM_DB)" == "YES"
+CFLAGS+=-DSYSTEM_DB -I$(DB_INCLUDES)
+.ENDIF
+
+SRS1NAME = $(TARGET)
+SRC1FILES = \
+ dp_configuration.src
+
+SLOFILES = \
+ $(SLO)$/dp_configuration.obj \
+ $(SLO)$/dp_configurationbackenddb.obj
+
+.INCLUDE : ..$/..$/target.pmk
+.INCLUDE : target.mk
+
diff --git a/desktop/source/deployment/registry/dp_backend.cxx b/desktop/source/deployment/registry/dp_backend.cxx
new file mode 100644
index 000000000000..cbb0bf53abad
--- /dev/null
+++ b/desktop/source/deployment/registry/dp_backend.cxx
@@ -0,0 +1,827 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include "dp_backend.h"
+#include "dp_ucb.h"
+#include "rtl/uri.hxx"
+#include "rtl/bootstrap.hxx"
+#include "osl/file.hxx"
+#include "cppuhelper/exc_hlp.hxx"
+#include "comphelper/servicedecl.hxx"
+#include "comphelper/unwrapargs.hxx"
+#include "ucbhelper/content.hxx"
+#include "com/sun/star/lang/WrappedTargetRuntimeException.hpp"
+#include "com/sun/star/deployment/InvalidRemovedParameterException.hpp"
+#include "com/sun/star/deployment/thePackageManagerFactory.hpp"
+#include "com/sun/star/ucb/InteractiveAugmentedIOException.hpp"
+#include "com/sun/star/ucb/IOErrorCode.hpp"
+#include "com/sun/star/beans/StringPair.hpp"
+#include "com/sun/star/sdbc/XResultSet.hpp"
+#include "com/sun/star/sdbc/XRow.hpp"
+#include "unotools/tempfile.hxx"
+
+
+using namespace ::dp_misc;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::ucb;
+using ::rtl::OUString;
+
+namespace dp_registry {
+namespace backend {
+
+//______________________________________________________________________________
+PackageRegistryBackend::~PackageRegistryBackend()
+{
+}
+
+//______________________________________________________________________________
+void PackageRegistryBackend::disposing( lang::EventObject const & event )
+ throw (RuntimeException)
+{
+ Reference<deployment::XPackage> xPackage(
+ event.Source, UNO_QUERY_THROW );
+ OUString url( xPackage->getURL() );
+ ::osl::MutexGuard guard( getMutex() );
+ if ( m_bound.erase( url ) != 1 )
+ {
+ OSL_ASSERT( false );
+ }
+}
+
+//______________________________________________________________________________
+PackageRegistryBackend::PackageRegistryBackend(
+ Sequence<Any> const & args,
+ Reference<XComponentContext> const & xContext )
+ : t_BackendBase( getMutex() ),
+ m_xComponentContext( xContext ),
+ m_eContext( CONTEXT_UNKNOWN ),
+ m_readOnly( false )
+{
+ boost::optional<OUString> cachePath;
+ boost::optional<bool> readOnly;
+ comphelper::unwrapArgs( args, m_context, cachePath, readOnly );
+ if (cachePath)
+ m_cachePath = *cachePath;
+ if (readOnly)
+ m_readOnly = *readOnly;
+
+ if (m_context.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("user") ))
+ m_eContext = CONTEXT_USER;
+ else if (m_context.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("shared") ))
+ m_eContext = CONTEXT_SHARED;
+ else if (m_context.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("bundled") ))
+ m_eContext = CONTEXT_BUNDLED;
+ else if (m_context.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("tmp") ))
+ m_eContext = CONTEXT_TMP;
+ else if (m_context.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("bundled_prereg") ))
+ m_eContext = CONTEXT_BUNDLED_PREREG;
+ else if (m_context.matchIgnoreAsciiCaseAsciiL(
+ RTL_CONSTASCII_STRINGPARAM("vnd.sun.star.tdoc:/") ))
+ m_eContext = CONTEXT_DOCUMENT;
+ else
+ m_eContext = CONTEXT_UNKNOWN;
+}
+
+//______________________________________________________________________________
+void PackageRegistryBackend::check()
+{
+ ::osl::MutexGuard guard( getMutex() );
+ if (rBHelper.bInDispose || rBHelper.bDisposed) {
+ throw lang::DisposedException(
+ OUSTR("PackageRegistryBackend instance has already been disposed!"),
+ static_cast<OWeakObject *>(this) );
+ }
+}
+
+//______________________________________________________________________________
+void PackageRegistryBackend::disposing()
+{
+ try {
+ for ( t_string2ref::const_iterator i = m_bound.begin(); i != m_bound.end(); ++i)
+ i->second->removeEventListener(this);
+ m_bound.clear();
+ m_xComponentContext.clear();
+ WeakComponentImplHelperBase::disposing();
+ }
+ catch (RuntimeException &) {
+ throw;
+ }
+ catch (Exception &) {
+ Any exc( ::cppu::getCaughtException() );
+ throw lang::WrappedTargetRuntimeException(
+ OUSTR("caught unexpected exception while disposing!"),
+ static_cast<OWeakObject *>(this), exc );
+ }
+}
+
+// XPackageRegistry
+//______________________________________________________________________________
+Reference<deployment::XPackage> PackageRegistryBackend::bindPackage(
+ OUString const & url, OUString const & mediaType, sal_Bool bRemoved,
+ OUString const & identifier, Reference<XCommandEnvironment> const & xCmdEnv )
+ throw (deployment::DeploymentException,
+ deployment::InvalidRemovedParameterException,
+ ucb::CommandFailedException,
+ lang::IllegalArgumentException, RuntimeException)
+{
+ ::osl::ResettableMutexGuard guard( getMutex() );
+ check();
+
+ t_string2ref::const_iterator const iFind( m_bound.find( url ) );
+ if (iFind != m_bound.end())
+ {
+ Reference<deployment::XPackage> xPackage( iFind->second );
+ if (xPackage.is())
+ {
+ if (mediaType.getLength() &&
+ mediaType != xPackage->getPackageType()->getMediaType())
+ throw lang::IllegalArgumentException
+ (OUSTR("XPackageRegistry::bindPackage: media type does not match"),
+ static_cast<OWeakObject*>(this), 1);
+ if (xPackage->isRemoved() != bRemoved)
+ throw deployment::InvalidRemovedParameterException(
+ OUSTR("XPackageRegistry::bindPackage: bRemoved parameter does not match"),
+ static_cast<OWeakObject*>(this), xPackage->isRemoved(), xPackage);
+ return xPackage;
+ }
+ }
+
+ guard.clear();
+
+ Reference<deployment::XPackage> xNewPackage;
+ try {
+ xNewPackage = bindPackage_( url, mediaType, bRemoved,
+ identifier, xCmdEnv );
+ }
+ catch (RuntimeException &) {
+ throw;
+ }
+ catch (lang::IllegalArgumentException &) {
+ throw;
+ }
+ catch (CommandFailedException &) {
+ throw;
+ }
+ catch (deployment::DeploymentException &) {
+ throw;
+ }
+ catch (Exception &) {
+ Any exc( ::cppu::getCaughtException() );
+ throw deployment::DeploymentException(
+ OUSTR("Error binding package: ") + url,
+ static_cast<OWeakObject *>(this), exc );
+ }
+
+ guard.reset();
+
+ ::std::pair< t_string2ref::iterator, bool > insertion(
+ m_bound.insert( t_string2ref::value_type( url, xNewPackage ) ) );
+ if (insertion.second)
+ { // first insertion
+ OSL_ASSERT( Reference<XInterface>(insertion.first->second)
+ == xNewPackage );
+ }
+ else
+ { // found existing entry
+ Reference<deployment::XPackage> xPackage( insertion.first->second );
+ if (xPackage.is())
+ return xPackage;
+ insertion.first->second = xNewPackage;
+ }
+
+ guard.clear();
+ xNewPackage->addEventListener( this ); // listen for disposing events
+ return xNewPackage;
+}
+
+OUString PackageRegistryBackend::createFolder(
+ OUString const & relUrl,
+ Reference<ucb::XCommandEnvironment> const & xCmdEnv)
+{
+ const OUString sDataFolder = makeURL(getCachePath(), relUrl);
+ //make sure the folder exist
+ ucbhelper::Content dataContent;
+ ::dp_misc::create_folder(&dataContent, sDataFolder, xCmdEnv);
+
+ const OUString sDataFolderURL = dp_misc::expandUnoRcUrl(sDataFolder);
+ const String baseDir(sDataFolder);
+ const ::utl::TempFile aTemp(&baseDir, sal_True);
+ const OUString url = aTemp.GetURL();
+ return sDataFolder + url.copy(url.lastIndexOf('/'));
+}
+
+//folderURL can have the extension .tmp or .tmp_
+//Before OOo 3.4 the created a tmp file with osl_createTempFile and
+//then created a Folder with a same name and a trailing '_'
+//If the folderURL has no '_' then there is no corresponding tmp file.
+void PackageRegistryBackend::deleteTempFolder(
+ OUString const & folderUrl)
+{
+ if (folderUrl.getLength())
+ {
+ erase_path( folderUrl, Reference<XCommandEnvironment>(),
+ false /* no throw: ignore errors */ );
+
+ if (folderUrl[folderUrl.getLength() - 1] == '_')
+ {
+ const OUString tempFile = folderUrl.copy(0, folderUrl.getLength() - 1);
+ erase_path( tempFile, Reference<XCommandEnvironment>(),
+ false /* no throw: ignore errors */ );
+ }
+ }
+}
+
+//usedFolders can contain folder names which have the extension .tmp or .tmp_
+//Before OOo 3.4 we created a tmp file with osl_createTempFile and
+//then created a Folder with a same name and a trailing '_'
+//If the folderURL has no '_' then there is no corresponding tmp file.
+void PackageRegistryBackend::deleteUnusedFolders(
+ OUString const & relUrl,
+ ::std::list< OUString> const & usedFolders)
+{
+ try
+ {
+ const OUString sDataFolder = makeURL(getCachePath(), relUrl);
+ ::ucbhelper::Content tempFolder(
+ sDataFolder, Reference<ucb::XCommandEnvironment>());
+ Reference<sdbc::XResultSet> xResultSet(
+ tempFolder.createCursor(
+ Sequence<OUString>( &StrTitle::get(), 1 ),
+ ::ucbhelper::INCLUDE_FOLDERS_ONLY ) );
+ // get all temp directories:
+ ::std::vector<OUString> tempEntries;
+
+ const char tmp[] = ".tmp";
+
+ while (xResultSet->next())
+ {
+ OUString title(
+ Reference<sdbc::XRow>(
+ xResultSet, UNO_QUERY_THROW )->getString(
+ 1 /* Title */ ) );
+
+ if (title.endsWithAsciiL(RTL_CONSTASCII_STRINGPARAM(tmp)))
+ tempEntries.push_back(
+ makeURLAppendSysPathSegment(sDataFolder, title));
+ }
+
+ for ( ::std::size_t pos = 0; pos < tempEntries.size(); ++pos )
+ {
+ if (::std::find( usedFolders.begin(), usedFolders.end(), tempEntries[pos] ) ==
+ usedFolders.end())
+ {
+ deleteTempFolder(tempEntries[pos]);
+ }
+ }
+ }
+ catch (ucb::InteractiveAugmentedIOException& e)
+ {
+ //In case the folder containing all the data folder does not
+ //exist yet, we ignore the exception
+ if (e.Code != ucb::IOErrorCode_NOT_EXISTING)
+ throw e;
+ }
+
+}
+
+
+//______________________________________________________________________________
+Package::~Package()
+{
+}
+
+//______________________________________________________________________________
+Package::Package( ::rtl::Reference<PackageRegistryBackend> const & myBackend,
+ OUString const & url,
+ OUString const & rName,
+ OUString const & displayName,
+ Reference<deployment::XPackageTypeInfo> const & xPackageType,
+ bool bRemoved,
+ OUString const & identifier)
+ : t_PackageBase( getMutex() ),
+ m_myBackend( myBackend ),
+ m_url( url ),
+ m_name( rName ),
+ m_displayName( displayName ),
+ m_xPackageType( xPackageType ),
+ m_bRemoved(bRemoved),
+ m_identifier(identifier)
+{
+ if (m_bRemoved)
+ {
+ //We use the last segment of the URL
+ OSL_ASSERT(m_name.getLength() == 0);
+ OUString name = m_url;
+ rtl::Bootstrap::expandMacros(name);
+ sal_Int32 index = name.lastIndexOf('/');
+ if (index != -1 && index < name.getLength())
+ m_name = name.copy(index + 1);
+ }
+}
+
+//______________________________________________________________________________
+void Package::disposing()
+{
+ m_myBackend.clear();
+ WeakComponentImplHelperBase::disposing();
+}
+
+//______________________________________________________________________________
+void Package::check() const
+{
+ ::osl::MutexGuard guard( getMutex() );
+ if (rBHelper.bInDispose || rBHelper.bDisposed) {
+ throw lang::DisposedException(
+ OUSTR("Package instance has already been disposed!"),
+ static_cast<OWeakObject *>(const_cast<Package *>(this)));
+ }
+}
+
+// XComponent
+//______________________________________________________________________________
+void Package::dispose() throw (RuntimeException)
+{
+ check();
+ WeakComponentImplHelperBase::dispose();
+}
+
+//______________________________________________________________________________
+void Package::addEventListener(
+ Reference<lang::XEventListener> const & xListener ) throw (RuntimeException)
+{
+ check();
+ WeakComponentImplHelperBase::addEventListener( xListener );
+}
+
+//______________________________________________________________________________
+void Package::removeEventListener(
+ Reference<lang::XEventListener> const & xListener ) throw (RuntimeException)
+{
+ check();
+ WeakComponentImplHelperBase::removeEventListener( xListener );
+}
+
+// XModifyBroadcaster
+//______________________________________________________________________________
+void Package::addModifyListener(
+ Reference<util::XModifyListener> const & xListener )
+ throw (RuntimeException)
+{
+ check();
+ rBHelper.addListener( ::getCppuType( &xListener ), xListener );
+}
+
+//______________________________________________________________________________
+void Package::removeModifyListener(
+ Reference<util::XModifyListener> const & xListener )
+ throw (RuntimeException)
+{
+ check();
+ rBHelper.removeListener( ::getCppuType( &xListener ), xListener );
+}
+
+//______________________________________________________________________________
+void Package::checkAborted(
+ ::rtl::Reference<AbortChannel> const & abortChannel )
+{
+ if (abortChannel.is() && abortChannel->isAborted()) {
+ throw CommandAbortedException(
+ OUSTR("abort!"), static_cast<OWeakObject *>(this) );
+ }
+}
+
+// XPackage
+//______________________________________________________________________________
+Reference<task::XAbortChannel> Package::createAbortChannel()
+ throw (RuntimeException)
+{
+ check();
+ return new AbortChannel;
+}
+
+//______________________________________________________________________________
+sal_Bool Package::isBundle() throw (RuntimeException)
+{
+ return false; // default
+}
+
+//______________________________________________________________________________
+::sal_Int32 Package::checkPrerequisites(
+ const css::uno::Reference< css::task::XAbortChannel >&,
+ const css::uno::Reference< css::ucb::XCommandEnvironment >&,
+ sal_Bool)
+ throw (css::deployment::DeploymentException,
+ css::deployment::ExtensionRemovedException,
+ css::ucb::CommandFailedException,
+ css::ucb::CommandAbortedException,
+ css::uno::RuntimeException)
+{
+ if (m_bRemoved)
+ throw deployment::ExtensionRemovedException();
+ return 0;
+}
+
+//______________________________________________________________________________
+::sal_Bool Package::checkDependencies(
+ const css::uno::Reference< css::ucb::XCommandEnvironment >& )
+ throw (css::deployment::DeploymentException,
+ css::deployment::ExtensionRemovedException,
+ css::ucb::CommandFailedException,
+ css::uno::RuntimeException)
+{
+ if (m_bRemoved)
+ throw deployment::ExtensionRemovedException();
+ return true;
+}
+
+
+//______________________________________________________________________________
+Sequence< Reference<deployment::XPackage> > Package::getBundle(
+ Reference<task::XAbortChannel> const &,
+ Reference<XCommandEnvironment> const & )
+ throw (deployment::DeploymentException,
+ CommandFailedException, CommandAbortedException,
+ lang::IllegalArgumentException, RuntimeException)
+{
+ return Sequence< Reference<deployment::XPackage> >();
+}
+
+//______________________________________________________________________________
+OUString Package::getName() throw (RuntimeException)
+{
+ return m_name;
+}
+
+beans::Optional<OUString> Package::getIdentifier() throw (RuntimeException)
+{
+ if (m_bRemoved)
+ return beans::Optional<OUString>(true, m_identifier);
+
+ return beans::Optional<OUString>();
+}
+
+//______________________________________________________________________________
+OUString Package::getVersion() throw (
+ deployment::ExtensionRemovedException,
+ RuntimeException)
+{
+ if (m_bRemoved)
+ throw deployment::ExtensionRemovedException();
+ return OUString();
+}
+
+//______________________________________________________________________________
+OUString Package::getURL() throw (RuntimeException)
+{
+ return m_url;
+}
+
+//______________________________________________________________________________
+OUString Package::getDisplayName() throw (
+ deployment::ExtensionRemovedException, RuntimeException)
+{
+ if (m_bRemoved)
+ throw deployment::ExtensionRemovedException();
+ return m_displayName;
+}
+
+//______________________________________________________________________________
+OUString Package::getDescription() throw (
+ deployment::ExtensionRemovedException,RuntimeException)
+{
+ if (m_bRemoved)
+ throw deployment::ExtensionRemovedException();
+ return OUString();
+}
+
+//______________________________________________________________________________
+OUString Package::getLicenseText() throw (
+ deployment::ExtensionRemovedException,RuntimeException)
+{
+ if (m_bRemoved)
+ throw deployment::ExtensionRemovedException();
+ return OUString();
+}
+
+//______________________________________________________________________________
+Sequence<OUString> Package::getUpdateInformationURLs() throw (
+ deployment::ExtensionRemovedException, RuntimeException)
+{
+ if (m_bRemoved)
+ throw deployment::ExtensionRemovedException();
+ return Sequence<OUString>();
+}
+
+//______________________________________________________________________________
+css::beans::StringPair Package::getPublisherInfo() throw (
+ deployment::ExtensionRemovedException, RuntimeException)
+{
+ if (m_bRemoved)
+ throw deployment::ExtensionRemovedException();
+ css::beans::StringPair aEmptyPair;
+ return aEmptyPair;
+}
+
+//______________________________________________________________________________
+uno::Reference< css::graphic::XGraphic > Package::getIcon( sal_Bool /*bHighContrast*/ )
+ throw (deployment::ExtensionRemovedException, RuntimeException )
+{
+ if (m_bRemoved)
+ throw deployment::ExtensionRemovedException();
+
+ uno::Reference< css::graphic::XGraphic > aEmpty;
+ return aEmpty;
+}
+
+//______________________________________________________________________________
+Reference<deployment::XPackageTypeInfo> Package::getPackageType()
+ throw (RuntimeException)
+{
+ return m_xPackageType;
+}
+
+//______________________________________________________________________________
+void Package::exportTo(
+ OUString const & destFolderURL, OUString const & newTitle,
+ sal_Int32 nameClashAction, Reference<XCommandEnvironment> const & xCmdEnv )
+ throw (deployment::ExtensionRemovedException,
+ CommandFailedException, CommandAbortedException, RuntimeException)
+{
+ if (m_bRemoved)
+ throw deployment::ExtensionRemovedException();
+
+ ::ucbhelper::Content destFolder( destFolderURL, xCmdEnv );
+ ::ucbhelper::Content sourceContent( getURL(), xCmdEnv );
+ if (! destFolder.transferContent(
+ sourceContent, ::ucbhelper::InsertOperation_COPY,
+ newTitle, nameClashAction ))
+ throw RuntimeException( OUSTR("UCB transferContent() failed!"), 0 );
+}
+
+//______________________________________________________________________________
+void Package::fireModified()
+{
+ ::cppu::OInterfaceContainerHelper * container = rBHelper.getContainer(
+ ::getCppuType( static_cast<Reference<
+ util::XModifyListener> const *>(0) ) );
+ if (container != 0) {
+ Sequence< Reference<XInterface> > elements(
+ container->getElements() );
+ lang::EventObject evt( static_cast<OWeakObject *>(this) );
+ for ( sal_Int32 pos = 0; pos < elements.getLength(); ++pos )
+ {
+ Reference<util::XModifyListener> xListener(
+ elements[ pos ], UNO_QUERY );
+ if (xListener.is())
+ xListener->modified( evt );
+ }
+ }
+}
+
+// XPackage
+//______________________________________________________________________________
+beans::Optional< beans::Ambiguous<sal_Bool> > Package::isRegistered(
+ Reference<task::XAbortChannel> const & xAbortChannel,
+ Reference<XCommandEnvironment> const & xCmdEnv )
+ throw (deployment::DeploymentException,
+ CommandFailedException, CommandAbortedException, RuntimeException)
+{
+ try {
+ ::osl::ResettableMutexGuard guard( getMutex() );
+ return isRegistered_( guard,
+ AbortChannel::get(xAbortChannel),
+ xCmdEnv );
+ }
+ catch (RuntimeException &) {
+ throw;
+ }
+ catch (CommandFailedException &) {
+ throw;
+ }
+ catch (CommandAbortedException &) {
+ throw;
+ }
+ catch (deployment::DeploymentException &) {
+ throw;
+ }
+ catch (Exception &) {
+ Any exc( ::cppu::getCaughtException() );
+ throw deployment::DeploymentException(
+ OUSTR("unexpected exception occurred!"),
+ static_cast<OWeakObject *>(this), exc );
+ }
+}
+
+//______________________________________________________________________________
+void Package::processPackage_impl(
+ bool doRegisterPackage,
+ bool startup,
+ Reference<task::XAbortChannel> const & xAbortChannel,
+ Reference<XCommandEnvironment> const & xCmdEnv )
+{
+ check();
+ bool action = false;
+
+ try {
+ try {
+ ::osl::ResettableMutexGuard guard( getMutex() );
+ beans::Optional< beans::Ambiguous<sal_Bool> > option(
+ isRegistered_( guard, AbortChannel::get(xAbortChannel),
+ xCmdEnv ) );
+ action = (option.IsPresent &&
+ (option.Value.IsAmbiguous ||
+ (doRegisterPackage ? !option.Value.Value
+ : option.Value.Value)));
+ if (action) {
+
+ OUString displayName = isRemoved() ? getName() : getDisplayName();
+ ProgressLevel progress(
+ xCmdEnv,
+ (doRegisterPackage
+ ? PackageRegistryBackend::StrRegisteringPackage::get()
+ : PackageRegistryBackend::StrRevokingPackage::get())
+ + displayName );
+ processPackage_( guard,
+ doRegisterPackage,
+ startup,
+ AbortChannel::get(xAbortChannel),
+ xCmdEnv );
+ }
+ }
+ catch (RuntimeException &) {
+ OSL_FAIL( "### unexpected RuntimeException!" );
+ throw;
+ }
+ catch (CommandFailedException &) {
+ throw;
+ }
+ catch (CommandAbortedException &) {
+ throw;
+ }
+ catch (deployment::DeploymentException &) {
+ throw;
+ }
+ catch (Exception &) {
+ Any exc( ::cppu::getCaughtException() );
+ throw deployment::DeploymentException(
+ (doRegisterPackage
+ ? getResourceString(RID_STR_ERROR_WHILE_REGISTERING)
+ : getResourceString(RID_STR_ERROR_WHILE_REVOKING))
+ + getDisplayName(), static_cast<OWeakObject *>(this), exc );
+ }
+ }
+ catch (...) {
+ if (action)
+ fireModified();
+ throw;
+ }
+ if (action)
+ fireModified();
+}
+
+//______________________________________________________________________________
+void Package::registerPackage(
+ sal_Bool startup,
+ Reference<task::XAbortChannel> const & xAbortChannel,
+ Reference<XCommandEnvironment> const & xCmdEnv )
+ throw (deployment::DeploymentException,
+ deployment::ExtensionRemovedException,
+ CommandFailedException, CommandAbortedException,
+ lang::IllegalArgumentException, RuntimeException)
+{
+ if (m_bRemoved)
+ throw deployment::ExtensionRemovedException();
+ processPackage_impl( true /* register */, startup, xAbortChannel, xCmdEnv );
+}
+
+//______________________________________________________________________________
+void Package::revokePackage(
+ Reference<task::XAbortChannel> const & xAbortChannel,
+ Reference<XCommandEnvironment> const & xCmdEnv )
+ throw (deployment::DeploymentException,
+ CommandFailedException, CommandAbortedException,
+ lang::IllegalArgumentException, RuntimeException)
+{
+ processPackage_impl( false /* revoke */, false, xAbortChannel, xCmdEnv );
+
+}
+
+PackageRegistryBackend * Package::getMyBackend() const
+{
+ PackageRegistryBackend * pBackend = m_myBackend.get();
+ if (NULL == pBackend)
+ {
+ //May throw a DisposedException
+ check();
+ //We should never get here...
+ throw RuntimeException(
+ OUSTR("Failed to get the BackendImpl"),
+ static_cast<OWeakObject*>(const_cast<Package *>(this)));
+ }
+ return pBackend;
+}
+OUString Package::getRepositoryName()
+ throw (RuntimeException)
+{
+ PackageRegistryBackend * backEnd = getMyBackend();
+ return backEnd->getContext();
+}
+
+beans::Optional< OUString > Package::getRegistrationDataURL()
+ throw (deployment::ExtensionRemovedException,
+ css::uno::RuntimeException)
+{
+ if (m_bRemoved)
+ throw deployment::ExtensionRemovedException();
+ return beans::Optional<OUString>();
+}
+
+sal_Bool Package::isRemoved()
+ throw (RuntimeException)
+{
+ return m_bRemoved;
+}
+
+
+//______________________________________________________________________________
+Package::TypeInfo::~TypeInfo()
+{
+}
+
+// XPackageTypeInfo
+//______________________________________________________________________________
+OUString Package::TypeInfo::getMediaType() throw (RuntimeException)
+{
+ return m_mediaType;
+}
+
+//______________________________________________________________________________
+OUString Package::TypeInfo::getDescription()
+ throw (deployment::ExtensionRemovedException, RuntimeException)
+{
+ return getShortDescription();
+}
+
+//______________________________________________________________________________
+OUString Package::TypeInfo::getShortDescription()
+ throw (deployment::ExtensionRemovedException, RuntimeException)
+{
+ return m_shortDescr;
+}
+
+//______________________________________________________________________________
+OUString Package::TypeInfo::getFileFilter() throw (RuntimeException)
+{
+ return m_fileFilter;
+}
+
+//______________________________________________________________________________
+/**************************
+ * Get Icon
+ *
+ * @param highContrast NOTE: disabled the returning of high contrast icons.
+ * This bool is a noop now.
+ * @param smallIcon Return the small version of the icon
+ */
+Any Package::TypeInfo::getIcon( sal_Bool /*highContrast*/, sal_Bool smallIcon )
+ throw (RuntimeException)
+{
+ if (! smallIcon)
+ return Any();
+ const sal_uInt16 nIconId = m_smallIcon;
+ return Any( &nIconId, getCppuType( static_cast<sal_uInt16 const *>(0) ) );
+}
+
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/registry/dp_backenddb.cxx b/desktop/source/deployment/registry/dp_backenddb.cxx
new file mode 100644
index 000000000000..becfc14d254d
--- /dev/null
+++ b/desktop/source/deployment/registry/dp_backenddb.cxx
@@ -0,0 +1,716 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include "rtl/string.h"
+#include "rtl/strbuf.hxx"
+#include "rtl/bootstrap.hxx"
+#include "cppuhelper/exc_hlp.hxx"
+#include "osl/file.hxx"
+#include "com/sun/star/uno/XComponentContext.hpp"
+#include "com/sun/star/xml/dom/XDocumentBuilder.hpp"
+#include "com/sun/star/xml/xpath/XXPathAPI.hpp"
+#include "com/sun/star/io/XActiveDataSource.hpp"
+#include "com/sun/star/io/XActiveDataControl.hpp"
+#include "dp_ucb.h"
+#include "dp_misc.h"
+#include "ucbhelper/content.hxx"
+#include "xmlscript/xml_helper.hxx"
+#include "dp_backenddb.hxx"
+
+
+namespace css = ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using ::rtl::OUString;
+
+
+namespace dp_registry {
+namespace backend {
+
+BackendDb::BackendDb(
+ Reference<css::uno::XComponentContext> const & xContext,
+ ::rtl::OUString const & url):
+ m_xContext(xContext)
+{
+ m_urlDb = dp_misc::expandUnoRcUrl(url);
+}
+
+void BackendDb::save()
+{
+ const Reference<css::io::XActiveDataSource> xDataSource(m_doc,css::uno::UNO_QUERY_THROW);
+ ::rtl::ByteSequence bytes;
+ xDataSource->setOutputStream(::xmlscript::createOutputStream(&bytes));
+ const Reference<css::io::XActiveDataControl> xDataControl(m_doc,css::uno::UNO_QUERY_THROW);
+ xDataControl->start();
+
+ const Reference<css::io::XInputStream> xData(
+ ::xmlscript::createInputStream(bytes));
+ ::ucbhelper::Content ucbDb(m_urlDb, 0);
+ ucbDb.writeStream(xData, true /*replace existing*/);
+}
+
+css::uno::Reference<css::xml::dom::XDocument> BackendDb::getDocument()
+{
+ if (!m_doc.is())
+ {
+ const Reference<css::xml::dom::XDocumentBuilder> xDocBuilder(
+ m_xContext->getServiceManager()->createInstanceWithContext(
+ OUSTR("com.sun.star.xml.dom.DocumentBuilder"),
+ m_xContext ), css::uno::UNO_QUERY);
+ if (!xDocBuilder.is())
+ throw css::uno::RuntimeException(
+ OUSTR(" Could not create service com.sun.star.xml.dom.DocumentBuilder"), 0);
+
+ ::osl::DirectoryItem item;
+ ::osl::File::RC err = ::osl::DirectoryItem::get(m_urlDb, item);
+ if (err == ::osl::File::E_None)
+ {
+ ::ucbhelper::Content descContent(
+ m_urlDb, css::uno::Reference<css::ucb::XCommandEnvironment>());
+ Reference<css::io::XInputStream> xIn = descContent.openStream();
+ m_doc = xDocBuilder->parse(xIn);
+ }
+ else if (err == ::osl::File::E_NOENT)
+ {
+ //Create a new document and insert some basic stuff
+ m_doc = xDocBuilder->newDocument();
+ const Reference<css::xml::dom::XElement> rootNode =
+ m_doc->createElementNS(getDbNSName(), getNSPrefix() +
+ OUSTR(":") + getRootElementName());
+
+ m_doc->appendChild(Reference<css::xml::dom::XNode>(
+ rootNode, UNO_QUERY_THROW));
+ save();
+ }
+ else
+ throw css::uno::RuntimeException(
+ OUSTR("Extension manager could not access database file:" )
+ + m_urlDb, 0);
+
+ if (!m_doc.is())
+ throw css::uno::RuntimeException(
+ OUSTR("Extension manager could not get root node of data base file: ")
+ + m_urlDb, 0);
+ }
+
+ return m_doc;
+}
+
+Reference<css::xml::xpath::XXPathAPI> BackendDb::getXPathAPI()
+{
+ if (!m_xpathApi.is())
+ {
+ m_xpathApi = Reference< css::xml::xpath::XXPathAPI >(
+ m_xContext->getServiceManager()->createInstanceWithContext(
+ OUSTR("com.sun.star.xml.xpath.XPathAPI"),
+ m_xContext), css::uno::UNO_QUERY);
+
+ if (!m_xpathApi.is())
+ throw css::uno::RuntimeException(
+ OUSTR(" Could not create service com.sun.star.xml.xpath.XPathAPI"), 0);
+
+ m_xpathApi->registerNS(
+ getNSPrefix(), getDbNSName());
+ }
+
+ return m_xpathApi;
+}
+
+void BackendDb::removeElement(::rtl::OUString const & sXPathExpression)
+{
+ try
+ {
+ const Reference<css::xml::dom::XDocument> doc = getDocument();
+ const Reference<css::xml::dom::XNode> root = doc->getFirstChild();
+ const Reference<css::xml::xpath::XXPathAPI> xpathApi = getXPathAPI();
+ //find the extension element that is to be removed
+ const Reference<css::xml::dom::XNode> aNode =
+ xpathApi->selectSingleNode(root, sXPathExpression);
+
+ if (aNode.is())
+ {
+ root->removeChild(aNode);
+ save();
+ }
+
+#if OSL_DEBUG_LEVEL > 0
+ //There must not be any other entry with the same url
+ const Reference<css::xml::dom::XNode> nextNode =
+ xpathApi->selectSingleNode(root, sXPathExpression);
+ OSL_ASSERT(! nextNode.is());
+#endif
+ }
+ catch(css::uno::Exception &)
+ {
+ Any exc( ::cppu::getCaughtException() );
+ throw css::deployment::DeploymentException(
+ OUSTR("Extension Manager: failed to write data entry in backend db: ") +
+ m_urlDb, 0, exc);
+ }
+}
+
+void BackendDb::removeEntry(::rtl::OUString const & url)
+{
+ const OUString sKeyElement = getKeyElementName();
+ const OUString sPrefix = getNSPrefix();
+ ::rtl::OUStringBuffer sExpression(500);
+ sExpression.append(sPrefix);
+ sExpression.appendAscii(":");
+ sExpression.append(sKeyElement);
+ sExpression.append(OUSTR("[@url = \""));
+ sExpression.append(url);
+ sExpression.appendAscii("\"]");
+
+ removeElement(sExpression.makeStringAndClear());
+}
+
+void BackendDb::revokeEntry(::rtl::OUString const & url)
+{
+ try
+ {
+ Reference<css::xml::dom::XElement> entry = Reference<css::xml::dom::XElement>(getKeyElement(url), UNO_QUERY);
+ if (entry.is())
+ {
+ entry->setAttribute(OUSTR("revoked"), OUSTR("true"));
+ save();
+ }
+ }
+ catch(css::uno::Exception &)
+ {
+ Any exc( ::cppu::getCaughtException() );
+ throw css::deployment::DeploymentException(
+ OUSTR("Extension Manager: failed to revoke data entry in backend db: ") +
+ m_urlDb, 0, exc);
+ }
+}
+
+bool BackendDb::activateEntry(::rtl::OUString const & url)
+{
+ try
+ {
+ bool ret = false;
+ Reference<css::xml::dom::XElement> entry = Reference<css::xml::dom::XElement>(getKeyElement(url), UNO_QUERY);
+ if (entry.is())
+ {
+ //no attribute "active" means it is active, that is, registered.
+ entry->removeAttribute(OUSTR("revoked"));
+ save();
+ ret = true;
+ }
+ return ret;
+ }
+ catch(css::uno::Exception &)
+ {
+ Any exc( ::cppu::getCaughtException() );
+ throw css::deployment::DeploymentException(
+ OUSTR("Extension Manager: failed to revoke data entry in backend db: ") +
+ m_urlDb, 0, exc);
+ }
+}
+
+bool BackendDb::hasActiveEntry(::rtl::OUString const & url)
+{
+ try
+ {
+ bool ret = false;
+ Reference<css::xml::dom::XElement> entry = Reference<css::xml::dom::XElement>(getKeyElement(url), UNO_QUERY);
+ if (entry.is())
+ {
+ OUString sActive = entry->getAttribute(OUSTR("revoked"));
+ if (!sActive.equals(OUSTR("true")))
+ ret = true;
+ }
+ return ret;
+
+ }
+ catch(css::uno::Exception &)
+ {
+ Any exc( ::cppu::getCaughtException() );
+ throw css::deployment::DeploymentException(
+ OUSTR("Extension Manager: failed to determine an active entry in backend db: ") +
+ m_urlDb, 0, exc);
+ }
+}
+
+Reference<css::xml::dom::XNode> BackendDb::getKeyElement(
+ ::rtl::OUString const & url)
+{
+ try
+ {
+ const OUString sPrefix = getNSPrefix();
+ const OUString sKeyElement = getKeyElementName();
+ ::rtl::OUStringBuffer sExpression(500);
+ sExpression.append(sPrefix);
+ sExpression.appendAscii(":");
+ sExpression.append(sKeyElement);
+ sExpression.append(OUSTR("[@url = \""));
+ sExpression.append(url);
+ sExpression.appendAscii("\"]");
+
+ const Reference<css::xml::dom::XDocument> doc = getDocument();
+ const Reference<css::xml::dom::XNode> root = doc->getFirstChild();
+ const Reference<css::xml::xpath::XXPathAPI> xpathApi = getXPathAPI();
+ return xpathApi->selectSingleNode(root, sExpression.makeStringAndClear());
+ }
+ catch(css::uno::Exception &)
+ {
+ Any exc( ::cppu::getCaughtException() );
+ throw css::deployment::DeploymentException(
+ OUSTR("Extension Manager: failed to read key element in backend db: ") +
+ m_urlDb, 0, exc);
+ }
+}
+
+//Only writes the data if there is at least one entry
+void BackendDb::writeVectorOfPair(
+ ::std::vector< ::std::pair< ::rtl::OUString, ::rtl::OUString > > const & vecPairs,
+ OUString const & sVectorTagName,
+ OUString const & sPairTagName,
+ OUString const & sFirstTagName,
+ OUString const & sSecondTagName,
+ css::uno::Reference<css::xml::dom::XNode> const & xParent)
+{
+ try{
+ if (vecPairs.size() == 0)
+ return;
+ const OUString sNameSpace = getDbNSName();
+ OSL_ASSERT(sNameSpace.getLength());
+ const OUString sPrefix(getNSPrefix() + OUSTR(":"));
+ const Reference<css::xml::dom::XDocument> doc = getDocument();
+ const Reference<css::xml::dom::XNode> root = doc->getFirstChild();
+
+ const Reference<css::xml::dom::XElement> vectorNode(
+ doc->createElementNS(sNameSpace, sPrefix + sVectorTagName));
+
+ xParent->appendChild(
+ Reference<css::xml::dom::XNode>(
+ vectorNode, css::uno::UNO_QUERY_THROW));
+ typedef ::std::vector< ::std::pair< OUString, OUString > >::const_iterator CIT;
+ for (CIT i = vecPairs.begin(); i != vecPairs.end(); i++)
+ {
+ const Reference<css::xml::dom::XElement> pairNode(
+ doc->createElementNS(sNameSpace, sPrefix + sPairTagName));
+
+ vectorNode->appendChild(
+ Reference<css::xml::dom::XNode>(
+ pairNode, css::uno::UNO_QUERY_THROW));
+
+ const Reference<css::xml::dom::XElement> firstNode(
+ doc->createElementNS(sNameSpace, sPrefix + sFirstTagName));
+
+ pairNode->appendChild(
+ Reference<css::xml::dom::XNode>(
+ firstNode, css::uno::UNO_QUERY_THROW));
+
+ const Reference<css::xml::dom::XText> firstTextNode(
+ doc->createTextNode( i->first));
+
+ firstNode->appendChild(
+ Reference<css::xml::dom::XNode>(
+ firstTextNode, css::uno::UNO_QUERY_THROW));
+
+ const Reference<css::xml::dom::XElement> secondNode(
+ doc->createElementNS(sNameSpace, sPrefix + sSecondTagName));
+
+ pairNode->appendChild(
+ Reference<css::xml::dom::XNode>(
+ secondNode, css::uno::UNO_QUERY_THROW));
+
+ const Reference<css::xml::dom::XText> secondTextNode(
+ doc->createTextNode( i->second));
+
+ secondNode->appendChild(
+ Reference<css::xml::dom::XNode>(
+ secondTextNode, css::uno::UNO_QUERY_THROW));
+ }
+ }
+ catch(css::uno::Exception &)
+ {
+ Any exc( ::cppu::getCaughtException() );
+ throw css::deployment::DeploymentException(
+ OUSTR("Extension Manager: failed to write data entry in backend db: ") +
+ m_urlDb, 0, exc);
+ }
+}
+
+::std::vector< ::std::pair< OUString, OUString > >
+BackendDb::readVectorOfPair(
+ Reference<css::xml::dom::XNode> const & parent,
+ OUString const & sListTagName,
+ OUString const & sPairTagName,
+ OUString const & sFirstTagName,
+ OUString const & sSecondTagName)
+{
+ try
+ {
+ OSL_ASSERT(parent.is());
+ const OUString sPrefix(getNSPrefix() + OUSTR(":"));
+ const Reference<css::xml::xpath::XXPathAPI> xpathApi = getXPathAPI();
+ const OUString sExprPairs(
+ sPrefix + sListTagName + OUSTR("/") + sPrefix + sPairTagName);
+ const Reference<css::xml::dom::XNodeList> listPairs =
+ xpathApi->selectNodeList(parent, sExprPairs);
+
+ ::std::vector< ::std::pair< OUString, OUString > > retVector;
+ sal_Int32 length = listPairs->getLength();
+ for (sal_Int32 i = 0; i < length; i++)
+ {
+ const Reference<css::xml::dom::XNode> aPair = listPairs->item(i);
+ const OUString sExprFirst(sPrefix + sFirstTagName + OUSTR("/text()"));
+ const Reference<css::xml::dom::XNode> first =
+ xpathApi->selectSingleNode(aPair, sExprFirst);
+
+ const OUString sExprSecond(sPrefix + sSecondTagName + OUSTR("/text()"));
+ const Reference<css::xml::dom::XNode> second =
+ xpathApi->selectSingleNode(aPair, sExprSecond);
+ OSL_ASSERT(first.is() && second.is());
+
+ retVector.push_back(::std::make_pair(
+ first->getNodeValue(), second->getNodeValue()));
+ }
+ return retVector;
+ }
+ catch(css::uno::Exception &)
+ {
+ Any exc( ::cppu::getCaughtException() );
+ throw css::deployment::DeploymentException(
+ OUSTR("Extension Manager: failed to read data entry in backend db: ") +
+ m_urlDb, 0, exc);
+ }
+}
+
+//Only writes the data if there is at least one entry
+void BackendDb::writeSimpleList(
+ ::std::list< ::rtl::OUString> const & list,
+ OUString const & sListTagName,
+ OUString const & sMemberTagName,
+ Reference<css::xml::dom::XNode> const & xParent)
+{
+ try
+ {
+ if (list.size() == 0)
+ return;
+ const OUString sNameSpace = getDbNSName();
+ const OUString sPrefix(getNSPrefix() + OUSTR(":"));
+ const Reference<css::xml::dom::XDocument> doc = getDocument();
+
+ const Reference<css::xml::dom::XElement> listNode(
+ doc->createElementNS(sNameSpace, sPrefix + sListTagName));
+
+ xParent->appendChild(
+ Reference<css::xml::dom::XNode>(
+ listNode, css::uno::UNO_QUERY_THROW));
+
+ typedef ::std::list<OUString>::const_iterator ITC_ITEMS;
+ for (ITC_ITEMS i = list.begin(); i != list.end(); i++)
+ {
+ const Reference<css::xml::dom::XNode> memberNode(
+ doc->createElementNS(sNameSpace, sPrefix + sMemberTagName), css::uno::UNO_QUERY_THROW);
+
+ listNode->appendChild(memberNode);
+
+ const Reference<css::xml::dom::XNode> textNode(
+ doc->createTextNode( *i), css::uno::UNO_QUERY_THROW);
+
+ memberNode->appendChild(textNode);
+ }
+ }
+ catch(css::uno::Exception &)
+ {
+ Any exc( ::cppu::getCaughtException() );
+ throw css::deployment::DeploymentException(
+ OUSTR("Extension Manager: failed to write data entry in backend db: ") +
+ m_urlDb, 0, exc);
+ }
+}
+
+//Writes only the element if is has a value.
+//The prefix is automatically added to the element name
+void BackendDb::writeSimpleElement(
+ OUString const & sElementName, OUString const & value,
+ Reference<css::xml::dom::XNode> const & xParent)
+{
+ try
+ {
+ if (value.getLength() == 0)
+ return;
+ const OUString sPrefix = getNSPrefix();
+ const Reference<css::xml::dom::XDocument> doc = getDocument();
+ const OUString sNameSpace = getDbNSName();
+ const Reference<css::xml::dom::XNode> dataNode(
+ doc->createElementNS(sNameSpace, sPrefix + OUSTR(":") + sElementName),
+ UNO_QUERY_THROW);
+ xParent->appendChild(dataNode);
+
+ const Reference<css::xml::dom::XNode> dataValue(
+ doc->createTextNode(value), UNO_QUERY_THROW);
+ dataNode->appendChild(dataValue);
+ }
+ catch(css::uno::Exception &)
+ {
+ Any exc( ::cppu::getCaughtException() );
+ throw css::deployment::DeploymentException(
+ OUSTR("Extension Manager: failed to write data entry(writeSimpleElement) in backend db: ") +
+ m_urlDb, 0, exc);
+ }
+
+}
+
+/** The key elements have an url attribute and are always children of the root
+ element.
+*/
+Reference<css::xml::dom::XNode> BackendDb::writeKeyElement(
+ ::rtl::OUString const & url)
+{
+ try
+ {
+ const OUString sNameSpace = getDbNSName();
+ const OUString sPrefix = getNSPrefix();
+ const OUString sElementName = getKeyElementName();
+ const Reference<css::xml::dom::XDocument> doc = getDocument();
+ const Reference<css::xml::dom::XNode> root = doc->getFirstChild();
+
+ //Check if there are an entry with the same url. This can be the case if the
+ //the status of an XPackage is ambiguous. In this case a call to activateExtension
+ //(dp_extensionmanager.cxx), will register the package again. See also
+ //Package::processPackage_impl in dp_backend.cxx.
+ //A package can become
+ //invalid after its successful registration, for example if a second extension with
+ //the same service is installed.
+ const OUString sExpression(
+ sPrefix + OUSTR(":") + sElementName + OUSTR("[@url = \"") + url + OUSTR("\"]"));
+ const Reference<css::xml::dom::XNode> existingNode =
+ getXPathAPI()->selectSingleNode(root, sExpression);
+ if (existingNode.is())
+ {
+ OSL_ASSERT(0);
+ //replace the existing entry.
+ removeEntry(url);
+ }
+
+ const Reference<css::xml::dom::XElement> keyElement(
+ doc->createElementNS(sNameSpace, sPrefix + OUSTR(":") + sElementName));
+
+ keyElement->setAttribute(OUSTR("url"), url);
+
+ const Reference<css::xml::dom::XNode> keyNode(
+ keyElement, UNO_QUERY_THROW);
+ root->appendChild(keyNode);
+ return keyNode;
+ }
+ catch(css::uno::Exception &)
+ {
+ Any exc( ::cppu::getCaughtException() );
+ throw css::deployment::DeploymentException(
+ OUSTR("Extension Manager: failed to write key element in backend db: ") +
+ m_urlDb, 0, exc);
+ }
+}
+
+OUString BackendDb::readSimpleElement(
+ OUString const & sElementName, Reference<css::xml::dom::XNode> const & xParent)
+{
+ try
+ {
+ const OUString sPrefix = getNSPrefix();
+ const OUString sExpr(sPrefix + OUSTR(":") + sElementName + OUSTR("/text()"));
+ const Reference<css::xml::xpath::XXPathAPI> xpathApi = getXPathAPI();
+ const Reference<css::xml::dom::XNode> val =
+ xpathApi->selectSingleNode(xParent, sExpr);
+ if (val.is())
+ return val->getNodeValue();
+ return OUString();
+ }
+ catch(css::uno::Exception &)
+ {
+ Any exc( ::cppu::getCaughtException() );
+ throw css::deployment::DeploymentException(
+ OUSTR("Extension Manager: failed to read data (readSimpleElement) in backend db: ") +
+ m_urlDb, 0, exc);
+ }
+}
+
+
+::std::list< OUString> BackendDb::readList(
+ Reference<css::xml::dom::XNode> const & parent,
+ OUString const & sListTagName,
+ OUString const & sMemberTagName)
+{
+ try
+ {
+ OSL_ASSERT(parent.is());
+ const OUString sPrefix(getNSPrefix() + OUSTR(":"));
+ const Reference<css::xml::xpath::XXPathAPI> xpathApi = getXPathAPI();
+ const OUString sExprList(
+ sPrefix + sListTagName + OUSTR("/") + sPrefix + sMemberTagName + OUSTR("/text()"));
+ const Reference<css::xml::dom::XNodeList> list =
+ xpathApi->selectNodeList(parent, sExprList);
+
+ ::std::list<OUString > retList;
+ sal_Int32 length = list->getLength();
+ for (sal_Int32 i = 0; i < length; i++)
+ {
+ const Reference<css::xml::dom::XNode> member = list->item(i);
+ retList.push_back(member->getNodeValue());
+ }
+ return retList;
+ }
+ catch(css::uno::Exception &)
+ {
+ Any exc( ::cppu::getCaughtException() );
+ throw css::deployment::DeploymentException(
+ OUSTR("Extension Manager: failed to read data entry in backend db: ") +
+ m_urlDb, 0, exc);
+ }
+}
+
+::std::list<OUString> BackendDb::getOneChildFromAllEntries(
+ OUString const & name)
+{
+ try
+ {
+ ::std::list<OUString> listRet;
+ Reference<css::xml::dom::XDocument> doc = getDocument();
+ Reference<css::xml::dom::XNode> root = doc->getFirstChild();
+
+ Reference<css::xml::xpath::XXPathAPI> xpathApi = getXPathAPI();
+ const OUString sPrefix = getNSPrefix();
+ const OUString sKeyElement = getKeyElementName();
+ ::rtl::OUStringBuffer buf(512);
+ buf.append(sPrefix);
+ buf.appendAscii(":");
+ buf.append(sKeyElement);
+ buf.appendAscii("/");
+ buf.append(sPrefix);
+ buf.appendAscii(":");
+ buf.append(name);
+ buf.append(OUSTR("/text()"));
+
+ Reference<css::xml::dom::XNodeList> nodes =
+ xpathApi->selectNodeList(root, buf.makeStringAndClear());
+ if (nodes.is())
+ {
+ sal_Int32 length = nodes->getLength();
+ for (sal_Int32 i = 0; i < length; i++)
+ listRet.push_back(nodes->item(i)->getNodeValue());
+ }
+ return listRet;
+ }
+ catch (css::deployment::DeploymentException& )
+ {
+ throw;
+ }
+ catch(css::uno::Exception &)
+ {
+ Any exc( ::cppu::getCaughtException() );
+ throw css::deployment::DeploymentException(
+ OUSTR("Extension Manager: failed to read data entry in backend db: ") +
+ m_urlDb, 0, exc);
+ }
+}
+
+
+RegisteredDb::RegisteredDb(
+ Reference<XComponentContext> const & xContext,
+ ::rtl::OUString const & url):BackendDb(xContext, url)
+{
+}
+
+void RegisteredDb::addEntry(::rtl::OUString const & url)
+{
+ try{
+ if (!activateEntry(url))
+ {
+ const OUString sNameSpace = getDbNSName();
+ const OUString sPrefix = getNSPrefix();
+ const OUString sEntry = getKeyElementName();
+
+ Reference<css::xml::dom::XDocument> doc = getDocument();
+ Reference<css::xml::dom::XNode> root = doc->getFirstChild();
+
+#if OSL_DEBUG_LEVEL > 0
+ //There must not be yet an entry with the same url
+ OUString sExpression(
+ sPrefix + OUSTR(":") + sEntry + OUSTR("[@url = \"") + url + OUSTR("\"]"));
+ Reference<css::xml::dom::XNode> _extensionNode =
+ getXPathAPI()->selectSingleNode(root, sExpression);
+ OSL_ASSERT(! _extensionNode.is());
+#endif
+ Reference<css::xml::dom::XElement> helpElement(
+ doc->createElementNS(sNameSpace, sPrefix + OUSTR(":") + sEntry));
+
+ helpElement->setAttribute(OUSTR("url"), url);
+
+ Reference<css::xml::dom::XNode> helpNode(
+ helpElement, UNO_QUERY_THROW);
+ root->appendChild(helpNode);
+
+ save();
+ }
+ }
+ catch(css::uno::Exception &)
+ {
+ Any exc( ::cppu::getCaughtException() );
+ throw css::deployment::DeploymentException(
+ OUSTR("Extension Manager: failed to write data entry in backend db: ") +
+ m_urlDb, 0, exc);
+ }
+}
+
+bool RegisteredDb::getEntry(::rtl::OUString const & url)
+{
+ try
+ {
+ const OUString sPrefix = getNSPrefix();
+ const OUString sEntry = getKeyElementName();
+ const OUString sExpression(
+ sPrefix + OUSTR(":") + sEntry + OUSTR("[@url = \"") + url + OUSTR("\"]"));
+ Reference<css::xml::dom::XDocument> doc = getDocument();
+ Reference<css::xml::dom::XNode> root = doc->getFirstChild();
+
+ Reference<css::xml::xpath::XXPathAPI> xpathApi = getXPathAPI();
+ Reference<css::xml::dom::XNode> aNode =
+ xpathApi->selectSingleNode(root, sExpression);
+
+ return aNode.is();
+ }
+ catch(css::uno::Exception &)
+ {
+ Any exc( ::cppu::getCaughtException() );
+ throw css::deployment::DeploymentException(
+ OUSTR("Extension Manager: failed to read data entry in backend db: ") +
+ m_urlDb, 0, exc);
+ }
+}
+
+} // namespace backend
+} // namespace dp_registry
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/registry/dp_registry.cxx b/desktop/source/deployment/registry/dp_registry.cxx
new file mode 100644
index 000000000000..9e799dd2d559
--- /dev/null
+++ b/desktop/source/deployment/registry/dp_registry.cxx
@@ -0,0 +1,578 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include "dp_registry.hrc"
+#include "dp_misc.h"
+#include "dp_resource.h"
+#include "dp_interact.h"
+#include "dp_ucb.h"
+#include "osl/diagnose.h"
+#include "rtl/ustrbuf.hxx"
+#include "rtl/uri.hxx"
+#include "cppuhelper/compbase2.hxx"
+#include "cppuhelper/exc_hlp.hxx"
+#include "comphelper/sequence.hxx"
+#include "ucbhelper/content.hxx"
+#include "com/sun/star/uno/DeploymentException.hpp"
+#include "com/sun/star/lang/DisposedException.hpp"
+#include "com/sun/star/lang/WrappedTargetRuntimeException.hpp"
+#include "com/sun/star/lang/XServiceInfo.hpp"
+#include "com/sun/star/lang/XSingleComponentFactory.hpp"
+#include "com/sun/star/lang/XSingleServiceFactory.hpp"
+#include "com/sun/star/util/XUpdatable.hpp"
+#include "com/sun/star/container/XContentEnumerationAccess.hpp"
+#include "com/sun/star/deployment/PackageRegistryBackend.hpp"
+#include <boost/unordered_map.hpp>
+#include <set>
+#include <boost/unordered_set.hpp>
+#include <memory>
+
+using namespace ::dp_misc;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::ucb;
+using ::rtl::OUString;
+
+
+namespace dp_registry {
+
+namespace backend {
+namespace bundle {
+Reference<deployment::XPackageRegistry> create(
+ Reference<deployment::XPackageRegistry> const & xRootRegistry,
+ OUString const & context, OUString const & cachePath, bool readOnly,
+ Reference<XComponentContext> const & xComponentContext );
+}
+}
+
+namespace {
+
+typedef ::cppu::WeakComponentImplHelper2<
+ deployment::XPackageRegistry, util::XUpdatable > t_helper;
+
+//==============================================================================
+class PackageRegistryImpl : private MutexHolder, public t_helper
+{
+ struct ci_string_hash {
+ ::std::size_t operator () ( OUString const & str ) const {
+ return str.toAsciiLowerCase().hashCode();
+ }
+ };
+ struct ci_string_equals {
+ bool operator () ( OUString const & str1, OUString const & str2 ) const{
+ return str1.equalsIgnoreAsciiCase( str2 );
+ }
+ };
+ typedef ::boost::unordered_map<
+ OUString, Reference<deployment::XPackageRegistry>,
+ ci_string_hash, ci_string_equals > t_string2registry;
+ typedef ::boost::unordered_map<
+ OUString, OUString,
+ ci_string_hash, ci_string_equals > t_string2string;
+ typedef ::std::set<
+ Reference<deployment::XPackageRegistry> > t_registryset;
+
+ t_string2registry m_mediaType2backend;
+ t_string2string m_filter2mediaType;
+ t_registryset m_ambiguousBackends;
+ t_registryset m_allBackends;
+ ::std::vector< Reference<deployment::XPackageTypeInfo> > m_typesInfos;
+
+ void insertBackend(
+ Reference<deployment::XPackageRegistry> const & xBackend );
+
+protected:
+ inline void check();
+ virtual void SAL_CALL disposing();
+
+ virtual ~PackageRegistryImpl();
+ PackageRegistryImpl() : t_helper( getMutex() ) {}
+
+
+public:
+ static Reference<deployment::XPackageRegistry> create(
+ OUString const & context,
+ OUString const & cachePath, bool readOnly,
+ Reference<XComponentContext> const & xComponentContext );
+
+ // XUpdatable
+ virtual void SAL_CALL update() throw (RuntimeException);
+
+ // XPackageRegistry
+ virtual Reference<deployment::XPackage> SAL_CALL bindPackage(
+ OUString const & url, OUString const & mediaType, sal_Bool bRemoved,
+ OUString const & identifier, Reference<XCommandEnvironment> const & xCmdEnv )
+ throw (deployment::DeploymentException,
+ deployment::InvalidRemovedParameterException,
+ CommandFailedException,
+ lang::IllegalArgumentException, RuntimeException);
+ virtual Sequence< Reference<deployment::XPackageTypeInfo> > SAL_CALL
+ getSupportedPackageTypes() throw (RuntimeException);
+ virtual void SAL_CALL packageRemoved(OUString const & url, OUString const & mediaType)
+ throw (deployment::DeploymentException,
+ RuntimeException);
+
+};
+
+//______________________________________________________________________________
+inline void PackageRegistryImpl::check()
+{
+ ::osl::MutexGuard guard( getMutex() );
+ if (rBHelper.bInDispose || rBHelper.bDisposed) {
+ throw lang::DisposedException(
+ OUSTR("PackageRegistry instance has already been disposed!"),
+ static_cast<OWeakObject *>(this) );
+ }
+}
+
+//______________________________________________________________________________
+void PackageRegistryImpl::disposing()
+{
+ // dispose all backends:
+ t_registryset::const_iterator iPos( m_allBackends.begin() );
+ t_registryset::const_iterator const iEnd( m_allBackends.end() );
+ for ( ; iPos != iEnd; ++iPos ) {
+ try_dispose( *iPos );
+ }
+ m_mediaType2backend = t_string2registry();
+ m_ambiguousBackends = t_registryset();
+ m_allBackends = t_registryset();
+
+ t_helper::disposing();
+}
+
+//______________________________________________________________________________
+PackageRegistryImpl::~PackageRegistryImpl()
+{
+}
+
+//______________________________________________________________________________
+OUString normalizeMediaType( OUString const & mediaType )
+{
+ ::rtl::OUStringBuffer buf;
+ sal_Int32 index = 0;
+ for (;;) {
+ buf.append( mediaType.getToken( 0, '/', index ).trim() );
+ if (index < 0)
+ break;
+ buf.append( static_cast< sal_Unicode >('/') );
+ }
+ return buf.makeStringAndClear();
+}
+
+//______________________________________________________________________________
+
+void PackageRegistryImpl::packageRemoved(
+ ::rtl::OUString const & url, ::rtl::OUString const & mediaType)
+ throw (css::deployment::DeploymentException,
+ css::uno::RuntimeException)
+{
+ const t_string2registry::const_iterator i =
+ m_mediaType2backend.find(mediaType);
+
+ if (i != m_mediaType2backend.end())
+ {
+ i->second->packageRemoved(url, mediaType);
+ }
+}
+
+void PackageRegistryImpl::insertBackend(
+ Reference<deployment::XPackageRegistry> const & xBackend )
+{
+ m_allBackends.insert( xBackend );
+ typedef ::boost::unordered_set<OUString, ::rtl::OUStringHash> t_stringset;
+ t_stringset ambiguousFilters;
+
+ const Sequence< Reference<deployment::XPackageTypeInfo> > packageTypes(
+ xBackend->getSupportedPackageTypes() );
+ for ( sal_Int32 pos = 0; pos < packageTypes.getLength(); ++pos )
+ {
+ Reference<deployment::XPackageTypeInfo> const & xPackageType =
+ packageTypes[ pos ];
+ m_typesInfos.push_back( xPackageType );
+
+ const OUString mediaType( normalizeMediaType(
+ xPackageType->getMediaType() ) );
+ ::std::pair<t_string2registry::iterator, bool> mb_insertion(
+ m_mediaType2backend.insert( t_string2registry::value_type(
+ mediaType, xBackend ) ) );
+ if (mb_insertion.second)
+ {
+ // add parameterless media-type, too:
+ sal_Int32 semi = mediaType.indexOf( ';' );
+ if (semi >= 0) {
+ m_mediaType2backend.insert(
+ t_string2registry::value_type(
+ mediaType.copy( 0, semi ), xBackend ) );
+ }
+ const OUString fileFilter( xPackageType->getFileFilter() );
+ //The package backend shall also be called to determine the mediatype
+ //(XPackageRegistry.bindPackage) when the URL points to a directory.
+ const bool bExtension = mediaType.equals(OUSTR("application/vnd.sun.star.package-bundle"));
+ if (fileFilter.getLength() == 0 ||
+ fileFilter.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("*.*") ) ||
+ fileFilter.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("*") ) ||
+ bExtension)
+ {
+ m_ambiguousBackends.insert( xBackend );
+ }
+ else
+ {
+ sal_Int32 nIndex = 0;
+ do {
+ OUString token( fileFilter.getToken( 0, ';', nIndex ) );
+ if (token.matchAsciiL( RTL_CONSTASCII_STRINGPARAM("*.") ))
+ token = token.copy( 1 );
+ if (token.getLength() == 0)
+ continue;
+ // mark any further wildcards ambig:
+ bool ambig = (token.indexOf('*') >= 0 ||
+ token.indexOf('?') >= 0);
+ if (! ambig) {
+ ::std::pair<t_string2string::iterator, bool> ins(
+ m_filter2mediaType.insert(
+ t_string2string::value_type(
+ token, mediaType ) ) );
+ ambig = !ins.second;
+ if (ambig) {
+ // filter has already been in: add previously
+ // added backend to ambig set
+ const t_string2registry::const_iterator iFind(
+ m_mediaType2backend.find(
+ /* media-type of pr. added backend */
+ ins.first->second ) );
+ OSL_ASSERT(
+ iFind != m_mediaType2backend.end() );
+ if (iFind != m_mediaType2backend.end())
+ m_ambiguousBackends.insert( iFind->second );
+ }
+ }
+ if (ambig) {
+ m_ambiguousBackends.insert( xBackend );
+ // mark filter to be removed later from filters map:
+ ambiguousFilters.insert( token );
+ }
+ }
+ while (nIndex >= 0);
+ }
+ }
+#if OSL_DEBUG_LEVEL > 0
+ else {
+ ::rtl::OUStringBuffer buf;
+ buf.appendAscii(
+ RTL_CONSTASCII_STRINGPARAM(
+ "more than one PackageRegistryBackend for "
+ "media-type=\"") );
+ buf.append( mediaType );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\" => ") );
+ buf.append( Reference<lang::XServiceInfo>(
+ xBackend, UNO_QUERY_THROW )->
+ getImplementationName() );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\"!") );
+ OSL_FAIL( ::rtl::OUStringToOString(
+ buf.makeStringAndClear(),
+ RTL_TEXTENCODING_UTF8 ) );
+ }
+#endif
+ }
+
+ // cut out ambiguous filters:
+ t_stringset::const_iterator iPos( ambiguousFilters.begin() );
+ const t_stringset::const_iterator iEnd( ambiguousFilters.end() );
+ for ( ; iPos != iEnd; ++iPos ) {
+ m_filter2mediaType.erase( *iPos );
+ }
+}
+
+//______________________________________________________________________________
+Reference<deployment::XPackageRegistry> PackageRegistryImpl::create(
+ OUString const & context,
+ OUString const & cachePath, bool readOnly,
+ Reference<XComponentContext> const & xComponentContext )
+{
+ PackageRegistryImpl * that = new PackageRegistryImpl;
+ Reference<deployment::XPackageRegistry> xRet(that);
+
+ // auto-detect all registered package registries:
+ Reference<container::XEnumeration> xEnum(
+ Reference<container::XContentEnumerationAccess>(
+ xComponentContext->getServiceManager(),
+ UNO_QUERY_THROW )->createContentEnumeration(
+ OUSTR("com.sun.star.deployment.PackageRegistryBackend") ) );
+ if (xEnum.is())
+ {
+ while (xEnum->hasMoreElements())
+ {
+ Any element( xEnum->nextElement() );
+ Sequence<Any> registryArgs(
+ cachePath.getLength() == 0 ? 1 : 3 );
+ registryArgs[ 0 ] <<= context;
+ if (cachePath.getLength() > 0)
+ {
+ Reference<lang::XServiceInfo> xServiceInfo(
+ element, UNO_QUERY_THROW );
+ OUString registryCachePath(
+ makeURL( cachePath,
+ ::rtl::Uri::encode(
+ xServiceInfo->getImplementationName(),
+ rtl_UriCharClassPchar,
+ rtl_UriEncodeIgnoreEscapes,
+ RTL_TEXTENCODING_UTF8 ) ) );
+ registryArgs[ 1 ] <<= registryCachePath;
+ registryArgs[ 2 ] <<= readOnly;
+ if (! readOnly)
+ create_folder( 0, registryCachePath,
+ Reference<XCommandEnvironment>() );
+ }
+
+ Reference<deployment::XPackageRegistry> xBackend;
+ Reference<lang::XSingleComponentFactory> xFac( element, UNO_QUERY );
+ if (xFac.is()) {
+ xBackend.set(
+ xFac->createInstanceWithArgumentsAndContext(
+ registryArgs, xComponentContext ), UNO_QUERY );
+ }
+ else {
+ Reference<lang::XSingleServiceFactory> xSingleServiceFac(
+ element, UNO_QUERY_THROW );
+ xBackend.set(
+ xSingleServiceFac->createInstanceWithArguments(
+ registryArgs ), UNO_QUERY );
+ }
+ if (! xBackend.is()) {
+ throw DeploymentException(
+ OUSTR("cannot instantiate PackageRegistryBackend service: ")
+ + Reference<lang::XServiceInfo>(
+ element, UNO_QUERY_THROW )->getImplementationName(),
+ static_cast<OWeakObject *>(that) );
+ }
+
+ that->insertBackend( xBackend );
+ }
+ }
+
+ // Insert bundle back-end.
+ // Always register as last, because we want to add extensions also as folders
+ // and as a default we accept every folder, which was not recognized by the other
+ // backends.
+ Reference<deployment::XPackageRegistry> extensionBackend =
+ ::dp_registry::backend::bundle::create(
+ that, context, cachePath, readOnly, xComponentContext);
+ that->insertBackend(extensionBackend);
+
+ Reference<lang::XServiceInfo> xServiceInfo(
+ extensionBackend, UNO_QUERY_THROW );
+
+ OSL_ASSERT(xServiceInfo.is());
+ OUString registryCachePath(
+ makeURL( cachePath,
+ ::rtl::Uri::encode(
+ xServiceInfo->getImplementationName(),
+ rtl_UriCharClassPchar,
+ rtl_UriEncodeIgnoreEscapes,
+ RTL_TEXTENCODING_UTF8 ) ) );
+ create_folder( 0, registryCachePath, Reference<XCommandEnvironment>());
+
+
+#if OSL_DEBUG_LEVEL > 1
+ // dump tables:
+ {
+ t_registryset allBackends;
+ dp_misc::TRACE("> [dp_registry.cxx] media-type detection:\n\n" );
+ for ( t_string2string::const_iterator iPos(
+ that->m_filter2mediaType.begin() );
+ iPos != that->m_filter2mediaType.end(); ++iPos )
+ {
+ ::rtl::OUStringBuffer buf;
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("extension \"") );
+ buf.append( iPos->first );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
+ "\" maps to media-type \"") );
+ buf.append( iPos->second );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
+ "\" maps to backend ") );
+ const Reference<deployment::XPackageRegistry> xBackend(
+ that->m_mediaType2backend.find( iPos->second )->second );
+ allBackends.insert( xBackend );
+ buf.append( Reference<lang::XServiceInfo>(
+ xBackend, UNO_QUERY_THROW )
+ ->getImplementationName() );
+ dp_misc::writeConsole( buf.makeStringAndClear() + OUSTR("\n"));
+ }
+ dp_misc::TRACE( "> [dp_registry.cxx] ambiguous backends:\n\n" );
+ for ( t_registryset::const_iterator iPos(
+ that->m_ambiguousBackends.begin() );
+ iPos != that->m_ambiguousBackends.end(); ++iPos )
+ {
+ ::rtl::OUStringBuffer buf;
+ buf.append(
+ Reference<lang::XServiceInfo>(
+ *iPos, UNO_QUERY_THROW )->getImplementationName() );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(": ") );
+ const Sequence< Reference<deployment::XPackageTypeInfo> > types(
+ (*iPos)->getSupportedPackageTypes() );
+ for ( sal_Int32 pos = 0; pos < types.getLength(); ++pos ) {
+ Reference<deployment::XPackageTypeInfo> const & xInfo =
+ types[ pos ];
+ buf.append( xInfo->getMediaType() );
+ const OUString filter( xInfo->getFileFilter() );
+ if (filter.getLength() > 0) {
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" (") );
+ buf.append( filter );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(")") );
+ }
+ if (pos < (types.getLength() - 1))
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(", ") );
+ }
+ dp_misc::TRACE(buf.makeStringAndClear() + OUSTR("\n\n"));
+ }
+ allBackends.insert( that->m_ambiguousBackends.begin(),
+ that->m_ambiguousBackends.end() );
+ OSL_ASSERT( allBackends == that->m_allBackends );
+ }
+#endif
+
+ return xRet;
+}
+
+// XUpdatable: broadcast to backends
+//______________________________________________________________________________
+void PackageRegistryImpl::update() throw (RuntimeException)
+{
+ check();
+ t_registryset::const_iterator iPos( m_allBackends.begin() );
+ const t_registryset::const_iterator iEnd( m_allBackends.end() );
+ for ( ; iPos != iEnd; ++iPos ) {
+ const Reference<util::XUpdatable> xUpdatable( *iPos, UNO_QUERY );
+ if (xUpdatable.is())
+ xUpdatable->update();
+ }
+}
+
+// XPackageRegistry
+//______________________________________________________________________________
+Reference<deployment::XPackage> PackageRegistryImpl::bindPackage(
+ OUString const & url, OUString const & mediaType_, sal_Bool bRemoved,
+ OUString const & identifier, Reference<XCommandEnvironment> const & xCmdEnv )
+ throw (deployment::DeploymentException, deployment::InvalidRemovedParameterException,
+ CommandFailedException,
+ lang::IllegalArgumentException, RuntimeException)
+{
+ check();
+ OUString mediaType(mediaType_);
+ if (mediaType.getLength() == 0)
+ {
+ ::ucbhelper::Content ucbContent;
+ if (create_ucb_content(
+ &ucbContent, url, xCmdEnv, false /* no throw */ )
+ && !ucbContent.isFolder())
+ {
+ OUString title( ucbContent.getPropertyValue(
+ StrTitle::get() ).get<OUString>() );
+ for (;;)
+ {
+ const t_string2string::const_iterator iFind(
+ m_filter2mediaType.find(title) );
+ if (iFind != m_filter2mediaType.end()) {
+ mediaType = iFind->second;
+ break;
+ }
+ sal_Int32 point = title.indexOf( '.', 1 /* consume . */ );
+ if (point < 0)
+ break;
+ title = title.copy(point);
+ }
+ }
+ }
+ if (mediaType.getLength() == 0)
+ {
+ // try ambiguous backends:
+ t_registryset::const_iterator iPos( m_ambiguousBackends.begin() );
+ const t_registryset::const_iterator iEnd( m_ambiguousBackends.end() );
+ for ( ; iPos != iEnd; ++iPos )
+ {
+ try {
+ return (*iPos)->bindPackage( url, mediaType, bRemoved,
+ identifier, xCmdEnv );
+ }
+ catch (lang::IllegalArgumentException &) {
+ }
+ }
+ throw lang::IllegalArgumentException(
+ getResourceString(RID_STR_CANNOT_DETECT_MEDIA_TYPE) + url,
+ static_cast<OWeakObject *>(this), static_cast<sal_Int16>(-1) );
+ }
+ else
+ {
+ // get backend by media-type:
+ t_string2registry::const_iterator iFind(
+ m_mediaType2backend.find( normalizeMediaType(mediaType) ) );
+ if (iFind == m_mediaType2backend.end()) {
+ // xxx todo: more sophisticated media-type argument parsing...
+ sal_Int32 q = mediaType.indexOf( ';' );
+ if (q >= 0) {
+ iFind = m_mediaType2backend.find(
+ normalizeMediaType(
+ // cut parameters:
+ mediaType.copy( 0, q ) ) );
+ }
+ }
+ if (iFind == m_mediaType2backend.end()) {
+ throw lang::IllegalArgumentException(
+ getResourceString(RID_STR_UNSUPPORTED_MEDIA_TYPE) + mediaType,
+ static_cast<OWeakObject *>(this), static_cast<sal_Int16>(-1) );
+ }
+ return iFind->second->bindPackage( url, mediaType, bRemoved,
+ identifier, xCmdEnv );
+ }
+}
+
+//______________________________________________________________________________
+Sequence< Reference<deployment::XPackageTypeInfo> >
+PackageRegistryImpl::getSupportedPackageTypes() throw (RuntimeException)
+{
+ return comphelper::containerToSequence(m_typesInfos);
+}
+} // anon namespace
+
+//==============================================================================
+Reference<deployment::XPackageRegistry> SAL_CALL create(
+ OUString const & context,
+ OUString const & cachePath, bool readOnly,
+ Reference<XComponentContext> const & xComponentContext )
+{
+ return PackageRegistryImpl::create(
+ context, cachePath, readOnly, xComponentContext );
+}
+
+} // namespace dp_registry
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/registry/dp_registry.src b/desktop/source/deployment/registry/dp_registry.src
new file mode 100644
index 000000000000..68a52621741f
--- /dev/null
+++ b/desktop/source/deployment/registry/dp_registry.src
@@ -0,0 +1,59 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "dp_registry.hrc"
+
+String RID_STR_REGISTERING_PACKAGE
+{
+ Text [ en-US ] = "Enabling: ";
+};
+
+String RID_STR_REVOKING_PACKAGE
+{
+ Text [ en-US ] = "Disabling: ";
+};
+
+String RID_STR_CANNOT_DETECT_MEDIA_TYPE
+{
+ Text [ en-US ] = "Cannot detect media-type: ";
+};
+
+String RID_STR_UNSUPPORTED_MEDIA_TYPE
+{
+ Text [ en-US ] = "This media-type is not supported: ";
+};
+
+String RID_STR_ERROR_WHILE_REGISTERING
+{
+ Text [ en-US ] = "An error occurred while enabling: ";
+};
+
+String RID_STR_ERROR_WHILE_REVOKING
+{
+ Text [ en-US ] = "An error occurred while disabling: ";
+};
+
diff --git a/desktop/source/deployment/registry/executable/dp_executable.cxx b/desktop/source/deployment/registry/executable/dp_executable.cxx
new file mode 100644
index 000000000000..3579695ce81a
--- /dev/null
+++ b/desktop/source/deployment/registry/executable/dp_executable.cxx
@@ -0,0 +1,344 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include "dp_misc.h"
+#include "dp_backend.h"
+#include "dp_ucb.h"
+#include "dp_interact.h"
+#include "rtl/string.hxx"
+#include "osl/file.hxx"
+#include "ucbhelper/content.hxx"
+#include "comphelper/servicedecl.hxx"
+#include "svl/inettype.hxx"
+#include "cppuhelper/implbase1.hxx"
+#include "dp_executablebackenddb.hxx"
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::ucb;
+using namespace dp_misc;
+using ::rtl::OUString;
+
+namespace dp_registry {
+namespace backend {
+namespace executable {
+namespace {
+
+class BackendImpl : public ::dp_registry::backend::PackageRegistryBackend
+{
+ class ExecutablePackageImpl : public ::dp_registry::backend::Package
+ {
+ BackendImpl * getMyBackend() const;
+
+ // Package
+ virtual beans::Optional< beans::Ambiguous<sal_Bool> > isRegistered_(
+ ::osl::ResettableMutexGuard & guard,
+ ::rtl::Reference<dp_misc::AbortChannel> const & abortChannel,
+ Reference<XCommandEnvironment> const & xCmdEnv );
+ virtual void processPackage_(
+ ::osl::ResettableMutexGuard & guard,
+ bool registerPackage,
+ bool startup,
+ ::rtl::Reference<dp_misc::AbortChannel> const & abortChannel,
+ Reference<XCommandEnvironment> const & xCmdEnv );
+
+ bool getFileAttributes(sal_uInt64& out_Attributes);
+ bool isUrlTargetInExtension();
+
+ public:
+ inline ExecutablePackageImpl(
+ ::rtl::Reference<PackageRegistryBackend> const & myBackend,
+ OUString const & url, OUString const & name,
+ Reference<deployment::XPackageTypeInfo> const & xPackageType,
+ bool bRemoved, OUString const & identifier)
+ : Package( myBackend, url, name, name /* display-name */,
+ xPackageType, bRemoved, identifier)
+ {}
+ };
+ friend class ExecutablePackageImpl;
+
+ typedef ::boost::unordered_map< OUString, Reference<XInterface>,
+ ::rtl::OUStringHash > t_string2object;
+
+ // PackageRegistryBackend
+ virtual Reference<deployment::XPackage> bindPackage_(
+ OUString const & url, OUString const & mediaType, sal_Bool bRemoved,
+ OUString const & identifier, Reference<XCommandEnvironment> const & xCmdEnv );
+
+ void addDataToDb(OUString const & url);
+ bool hasActiveEntry(OUString const & url);
+ void revokeEntryFromDb(OUString const & url);
+
+ Reference<deployment::XPackageTypeInfo> m_xExecutableTypeInfo;
+ std::auto_ptr<ExecutableBackendDb> m_backendDb;
+public:
+ BackendImpl( Sequence<Any> const & args,
+ Reference<XComponentContext> const & xComponentContext );
+
+ // XPackageRegistry
+ virtual Sequence< Reference<deployment::XPackageTypeInfo> > SAL_CALL
+ getSupportedPackageTypes() throw (RuntimeException);
+ virtual void SAL_CALL packageRemoved(OUString const & url, OUString const & mediaType)
+ throw (deployment::DeploymentException,
+ uno::RuntimeException);
+
+ using PackageRegistryBackend::disposing;
+};
+
+
+BackendImpl::BackendImpl(
+ Sequence<Any> const & args,
+ Reference<XComponentContext> const & xComponentContext )
+ : PackageRegistryBackend( args, xComponentContext ),
+ m_xExecutableTypeInfo(new Package::TypeInfo(
+ OUSTR("application/vnd.sun.star.executable"),
+ OUSTR(""),
+ OUSTR("Executable"),
+ RID_IMG_COMPONENT ) )
+{
+ if (!transientMode())
+ {
+ OUString dbFile = makeURL(getCachePath(), OUSTR("backenddb.xml"));
+ m_backendDb.reset(
+ new ExecutableBackendDb(getComponentContext(), dbFile));
+ }
+}
+
+void BackendImpl::addDataToDb(OUString const & url)
+{
+ if (m_backendDb.get())
+ m_backendDb->addEntry(url);
+}
+
+void BackendImpl::revokeEntryFromDb(OUString const & url)
+{
+ if (m_backendDb.get())
+ m_backendDb->revokeEntry(url);
+}
+
+bool BackendImpl::hasActiveEntry(OUString const & url)
+{
+ if (m_backendDb.get())
+ return m_backendDb->hasActiveEntry(url);
+ return false;
+}
+
+
+// XPackageRegistry
+Sequence< Reference<deployment::XPackageTypeInfo> >
+BackendImpl::getSupportedPackageTypes() throw (RuntimeException)
+{
+ return Sequence<Reference<deployment::XPackageTypeInfo> >(
+ & m_xExecutableTypeInfo, 1);
+}
+
+void BackendImpl::packageRemoved(OUString const & url, OUString const & /*mediaType*/)
+ throw (deployment::DeploymentException,
+ uno::RuntimeException)
+{
+ if (m_backendDb.get())
+ m_backendDb->removeEntry(url);
+}
+
+// PackageRegistryBackend
+Reference<deployment::XPackage> BackendImpl::bindPackage_(
+ OUString const & url, OUString const & mediaType, sal_Bool bRemoved,
+ OUString const & identifier, Reference<XCommandEnvironment> const & xCmdEnv )
+{
+ if (mediaType.getLength() == 0)
+ {
+ throw lang::IllegalArgumentException(
+ StrCannotDetectMediaType::get() + url,
+ static_cast<OWeakObject *>(this), static_cast<sal_Int16>(-1) );
+ }
+
+ String type, subType;
+ INetContentTypeParameterList params;
+ if (INetContentTypes::parse( mediaType, type, subType, &params ))
+ {
+ if (type.EqualsIgnoreCaseAscii("application"))
+ {
+ OUString name;
+ if (!bRemoved)
+ {
+ ::ucbhelper::Content ucbContent( url, xCmdEnv );
+ name = ucbContent.getPropertyValue(
+ dp_misc::StrTitle::get() ).get<OUString>();
+ }
+ if (subType.EqualsIgnoreCaseAscii("vnd.sun.star.executable"))
+ {
+ return new BackendImpl::ExecutablePackageImpl(
+ this, url, name, m_xExecutableTypeInfo, bRemoved,
+ identifier);
+ }
+ }
+ }
+ return Reference<deployment::XPackage>();
+}
+
+
+
+// Package
+BackendImpl * BackendImpl::ExecutablePackageImpl::getMyBackend() const
+{
+ BackendImpl * pBackend = static_cast<BackendImpl *>(m_myBackend.get());
+ if (NULL == pBackend)
+ {
+ //May throw a DisposedException
+ check();
+ //We should never get here...
+ throw RuntimeException(
+ OUSTR("Failed to get the BackendImpl"),
+ static_cast<OWeakObject*>(const_cast<ExecutablePackageImpl *>(this)));
+ }
+ return pBackend;
+}
+
+beans::Optional< beans::Ambiguous<sal_Bool> >
+BackendImpl::ExecutablePackageImpl::isRegistered_(
+ ::osl::ResettableMutexGuard &,
+ ::rtl::Reference<dp_misc::AbortChannel> const &,
+ Reference<XCommandEnvironment> const & )
+{
+ bool registered = getMyBackend()->hasActiveEntry(getURL());
+ return beans::Optional< beans::Ambiguous<sal_Bool> >(
+ sal_True /* IsPresent */,
+ beans::Ambiguous<sal_Bool>(
+ registered, sal_False /* IsAmbiguous */ ) );
+}
+
+void BackendImpl::ExecutablePackageImpl::processPackage_(
+ ::osl::ResettableMutexGuard &,
+ bool doRegisterPackage,
+ bool /*startup*/,
+ ::rtl::Reference<dp_misc::AbortChannel> const & abortChannel,
+ Reference<XCommandEnvironment> const & /*xCmdEnv*/ )
+{
+ checkAborted(abortChannel);
+ if (doRegisterPackage)
+ {
+ if (!isUrlTargetInExtension())
+ {
+ OSL_ASSERT(0);
+ return;
+ }
+ sal_uInt64 attributes = 0;
+ //Setting the executable attribut does not affect executables on Windows
+ if (getFileAttributes(attributes))
+ {
+ if(getMyBackend()->m_context.equals(OUSTR("user")))
+ attributes |= osl_File_Attribute_OwnExe;
+ else if (getMyBackend()->m_context.equals(OUSTR("shared")))
+ attributes |= (osl_File_Attribute_OwnExe | osl_File_Attribute_GrpExe
+ | osl_File_Attribute_OthExe);
+ else if (!getMyBackend()->m_context.equals(OUSTR("bundled"))
+ && !getMyBackend()->m_context.equals(OUSTR("bundled_prereg")))
+ //Bundled extension are required to be in the properly
+ //installed. That is an executable must have the right flags
+ OSL_ASSERT(0);
+
+ //This won't have affect on Windows
+ osl::File::setAttributes(
+ dp_misc::expandUnoRcUrl(m_url), attributes);
+ }
+ getMyBackend()->addDataToDb(getURL());
+ }
+ else
+ {
+ getMyBackend()->revokeEntryFromDb(getURL());
+ }
+}
+
+//We currently cannot check if this XPackage represents a content of a particular extension
+//But we can check if we are within $UNO_USER_PACKAGES_CACHE etc.
+//Done for security reasons. For example an extension manifest could contain a path to
+//an executable outside the extension.
+bool BackendImpl::ExecutablePackageImpl::isUrlTargetInExtension()
+{
+ bool bSuccess = false;
+ OUString sExtensionDir;
+ if(getMyBackend()->m_context.equals(OUSTR("user")))
+ sExtensionDir = dp_misc::expandUnoRcTerm(OUSTR("$UNO_USER_PACKAGES_CACHE"));
+ else if (getMyBackend()->m_context.equals(OUSTR("shared")))
+ sExtensionDir = dp_misc::expandUnoRcTerm(OUSTR("$UNO_SHARED_PACKAGES_CACHE"));
+ else if (getMyBackend()->m_context.equals(OUSTR("bundled"))
+ || getMyBackend()->m_context.equals(OUSTR("bundled_prereg")))
+ sExtensionDir = dp_misc::expandUnoRcTerm(OUSTR("$BUNDLED_EXTENSIONS"));
+ else
+ OSL_ASSERT(0);
+ //remove file ellipses
+ if (osl::File::E_None == osl::File::getAbsoluteFileURL(OUString(), sExtensionDir, sExtensionDir))
+ {
+ OUString sFile;
+ if (osl::File::E_None == osl::File::getAbsoluteFileURL(
+ OUString(), dp_misc::expandUnoRcUrl(m_url), sFile))
+ {
+ if (sal_True == sFile.match(sExtensionDir, 0))
+ bSuccess = true;
+ }
+ }
+ return bSuccess;
+}
+
+bool BackendImpl::ExecutablePackageImpl::getFileAttributes(sal_uInt64& out_Attributes)
+{
+ bool bSuccess = false;
+ const OUString url(dp_misc::expandUnoRcUrl(m_url));
+ osl::DirectoryItem item;
+ if (osl::FileBase::E_None == osl::DirectoryItem::get(url, item))
+ {
+ osl::FileStatus aStatus(osl_FileStatus_Mask_Attributes);
+ if( osl::FileBase::E_None == item.getFileStatus(aStatus))
+ {
+ out_Attributes = aStatus.getAttributes();
+ bSuccess = true;
+ }
+ }
+ return bSuccess;
+}
+
+
+
+} // anon namespace
+
+namespace sdecl = comphelper::service_decl;
+sdecl::class_<BackendImpl, sdecl::with_args<true> > serviceBI;
+extern sdecl::ServiceDecl const serviceDecl(
+ serviceBI,
+ "com.sun.star.comp.deployment.executable.PackageRegistryBackend",
+ BACKEND_SERVICE_NAME );
+
+} // namespace component
+} // namespace backend
+} // namespace dp_registry
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/registry/executable/dp_executablebackenddb.cxx b/desktop/source/deployment/registry/executable/dp_executablebackenddb.cxx
new file mode 100644
index 000000000000..0c65a9bf4d2c
--- /dev/null
+++ b/desktop/source/deployment/registry/executable/dp_executablebackenddb.cxx
@@ -0,0 +1,83 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include "rtl/string.h"
+#include "com/sun/star/uno/XComponentContext.hpp"
+#include "dp_misc.h"
+#include "dp_executablebackenddb.hxx"
+
+
+namespace css = ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using ::rtl::OUString;
+
+#define EXTENSION_REG_NS "http://openoffice.org/extensionmanager/executable-registry/2010"
+#define NS_PREFIX "exe"
+#define ROOT_ELEMENT_NAME "executable-backend-db"
+#define ENTRY_NAME "executable"
+
+namespace dp_registry {
+namespace backend {
+namespace executable {
+
+ExecutableBackendDb::ExecutableBackendDb(
+ Reference<XComponentContext> const & xContext,
+ ::rtl::OUString const & url):RegisteredDb(xContext, url)
+{
+
+}
+
+OUString ExecutableBackendDb::getDbNSName()
+{
+ return OUSTR(EXTENSION_REG_NS);
+}
+
+OUString ExecutableBackendDb::getNSPrefix()
+{
+ return OUSTR(NS_PREFIX);
+}
+
+OUString ExecutableBackendDb::getRootElementName()
+{
+ return OUSTR(ROOT_ELEMENT_NAME);
+}
+
+OUString ExecutableBackendDb::getKeyElementName()
+{
+ return OUSTR(ENTRY_NAME);
+}
+
+
+} // namespace executable
+} // namespace backend
+} // namespace dp_registry
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/registry/executable/dp_executablebackenddb.hxx b/desktop/source/deployment/registry/executable/dp_executablebackenddb.hxx
new file mode 100644
index 000000000000..1a5828015260
--- /dev/null
+++ b/desktop/source/deployment/registry/executable/dp_executablebackenddb.hxx
@@ -0,0 +1,78 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#if ! defined INCLUDED_DP_EXECUTABLEBACKENDDB_HXX
+#define INCLUDED_DP_EXECUTABLEBACKENDDB_HXX
+
+#include "rtl/ustring.hxx"
+#include "dp_backenddb.hxx"
+
+namespace css = ::com::sun::star;
+
+namespace com { namespace sun { namespace star {
+ namespace uno {
+ class XComponentContext;
+ }
+}}}
+
+namespace dp_registry {
+namespace backend {
+namespace executable {
+
+/* The XML file stores the extensions which are currently registered.
+ They will be removed when they are revoked.
+ The format looks like this:
+
+<?xml version="1.0"?>
+ */
+class ExecutableBackendDb: public dp_registry::backend::RegisteredDb
+{
+protected:
+ virtual ::rtl::OUString getDbNSName();
+
+ virtual ::rtl::OUString getNSPrefix();
+
+ virtual ::rtl::OUString getRootElementName();
+
+ virtual ::rtl::OUString getKeyElementName();
+
+public:
+
+ ExecutableBackendDb( css::uno::Reference<css::uno::XComponentContext> const & xContext,
+ ::rtl::OUString const & url);
+
+};
+
+
+
+}
+}
+}
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/registry/executable/makefile.mk b/desktop/source/deployment/registry/executable/makefile.mk
new file mode 100755
index 000000000000..81b2baa44e5d
--- /dev/null
+++ b/desktop/source/deployment/registry/executable/makefile.mk
@@ -0,0 +1,44 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ = ..$/..$/..$/..
+
+PRJNAME = desktop
+TARGET = deployment_registry_executable
+ENABLE_EXCEPTIONS = TRUE
+
+.INCLUDE : settings.mk
+
+INCPRE += ..$/..$/inc
+
+SLOFILES = \
+ $(SLO)$/dp_executable.obj \
+ $(SLO)$/dp_executablebackenddb.obj
+
+.INCLUDE : ..$/..$/target.pmk
+.INCLUDE : target.mk
+
diff --git a/desktop/source/deployment/registry/help/dp_help.cxx b/desktop/source/deployment/registry/help/dp_help.cxx
new file mode 100644
index 000000000000..053e193729dc
--- /dev/null
+++ b/desktop/source/deployment/registry/help/dp_help.cxx
@@ -0,0 +1,676 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include "dp_help.hrc"
+#include "dp_backend.h"
+#include "dp_helpbackenddb.hxx"
+#include "dp_ucb.h"
+#include "rtl/uri.hxx"
+#include "osl/file.hxx"
+#include "rtl/bootstrap.hxx"
+#include "ucbhelper/content.hxx"
+#include "comphelper/servicedecl.hxx"
+#include "svl/inettype.hxx"
+#include "unotools/pathoptions.hxx"
+
+#include <l10ntools/compilehelp.hxx>
+#include <com/sun/star/ucb/XSimpleFileAccess.hpp>
+#include <com/sun/star/util/XMacroExpander.hpp>
+#include <com/sun/star/uri/XUriReferenceFactory.hpp>
+#include <com/sun/star/uri/XVndSunStarExpandUrl.hpp>
+#include <com/sun/star/script/XInvocation.hpp>
+#include "boost/optional.hpp"
+
+using namespace ::dp_misc;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::ucb;
+using ::rtl::OUString;
+
+namespace dp_registry {
+namespace backend {
+namespace help {
+namespace {
+
+//==============================================================================
+class BackendImpl : public ::dp_registry::backend::PackageRegistryBackend
+{
+ class PackageImpl : public ::dp_registry::backend::Package
+ {
+ BackendImpl * getMyBackend() const;
+
+ // Package
+ virtual beans::Optional< beans::Ambiguous<sal_Bool> > isRegistered_(
+ ::osl::ResettableMutexGuard & guard,
+ ::rtl::Reference<AbortChannel> const & abortChannel,
+ Reference<XCommandEnvironment> const & xCmdEnv );
+ virtual void processPackage_(
+ ::osl::ResettableMutexGuard & guard,
+ bool registerPackage,
+ bool startup,
+ ::rtl::Reference<AbortChannel> const & abortChannel,
+ Reference<XCommandEnvironment> const & xCmdEnv );
+
+
+ public:
+ PackageImpl(
+ ::rtl::Reference<PackageRegistryBackend> const & myBackend,
+ OUString const & url, OUString const & name,
+ Reference<deployment::XPackageTypeInfo> const & xPackageType,
+ bool bRemoved, OUString const & identifier);
+
+ bool extensionContainsCompiledHelp();
+
+ //XPackage
+ virtual css::beans::Optional< ::rtl::OUString > SAL_CALL getRegistrationDataURL()
+ throw (deployment::ExtensionRemovedException, css::uno::RuntimeException);
+ };
+ friend class PackageImpl;
+
+ // PackageRegistryBackend
+ virtual Reference<deployment::XPackage> bindPackage_(
+ OUString const & url, OUString const & mediaType,
+ sal_Bool bRemoved, OUString const & identifier,
+ Reference<XCommandEnvironment> const & xCmdEnv );
+
+ void implProcessHelp( PackageImpl * package, bool doRegisterPackage,
+ Reference<ucb::XCommandEnvironment> const & xCmdEnv);
+ void implCollectXhpFiles( const rtl::OUString& aDir,
+ std::vector< rtl::OUString >& o_rXhpFileVector );
+
+ void addDataToDb(OUString const & url, HelpBackendDb::Data const & data);
+ ::boost::optional<HelpBackendDb::Data> readDataFromDb(OUString const & url);
+ bool hasActiveEntry(OUString const & url);
+ void revokeEntryFromDb(OUString const & url);
+ bool activateEntry(OUString const & url);
+
+ Reference< ucb::XSimpleFileAccess > getFileAccess( void );
+ Reference< ucb::XSimpleFileAccess > m_xSFA;
+
+ const Reference<deployment::XPackageTypeInfo> m_xHelpTypeInfo;
+ Sequence< Reference<deployment::XPackageTypeInfo> > m_typeInfos;
+ std::auto_ptr<HelpBackendDb> m_backendDb;
+
+public:
+ BackendImpl( Sequence<Any> const & args,
+ Reference<XComponentContext> const & xComponentContext );
+
+ // XPackageRegistry
+ virtual Sequence< Reference<deployment::XPackageTypeInfo> > SAL_CALL
+ getSupportedPackageTypes() throw (RuntimeException);
+ virtual void SAL_CALL packageRemoved(OUString const & url, OUString const & mediaType)
+ throw (deployment::DeploymentException,
+ uno::RuntimeException);
+
+};
+
+//______________________________________________________________________________
+BackendImpl::BackendImpl(
+ Sequence<Any> const & args,
+ Reference<XComponentContext> const & xComponentContext )
+ : PackageRegistryBackend( args, xComponentContext ),
+ m_xHelpTypeInfo( new Package::TypeInfo(
+ OUSTR("application/vnd.sun.star.help"),
+ rtl::OUString(),
+ getResourceString(RID_STR_HELP),
+ RID_IMG_HELP ) ),
+ m_typeInfos( 1 )
+{
+ m_typeInfos[ 0 ] = m_xHelpTypeInfo;
+ if (!transientMode())
+ {
+ OUString dbFile = makeURL(getCachePath(), OUSTR("backenddb.xml"));
+ m_backendDb.reset(
+ new HelpBackendDb(getComponentContext(), dbFile));
+
+ //clean up data folders which are no longer used.
+ //This must not be done in the same process where the help files
+ //are still registers. Only after revoking and restarting OOo the folders
+ //can be removed. This works now, because the extension manager is a singleton
+ //and the backends are only create once per process.
+ ::std::list<OUString> folders = m_backendDb->getAllDataUrls();
+ deleteUnusedFolders(OUString(), folders);
+ }
+}
+
+// XPackageRegistry
+//______________________________________________________________________________
+Sequence< Reference<deployment::XPackageTypeInfo> >
+BackendImpl::getSupportedPackageTypes() throw (RuntimeException)
+{
+ return m_typeInfos;
+}
+
+void BackendImpl::packageRemoved(OUString const & url, OUString const & /*mediaType*/)
+ throw (deployment::DeploymentException,
+ uno::RuntimeException)
+{
+ if (m_backendDb.get())
+ m_backendDb->removeEntry(url);
+}
+
+// PackageRegistryBackend
+//______________________________________________________________________________
+Reference<deployment::XPackage> BackendImpl::bindPackage_(
+ OUString const & url, OUString const & mediaType_,
+ sal_Bool bRemoved, OUString const & identifier,
+ Reference<XCommandEnvironment> const & xCmdEnv )
+{
+ // we don't support auto detection:
+ if (mediaType_.getLength() == 0)
+ throw lang::IllegalArgumentException(
+ StrCannotDetectMediaType::get() + url,
+ static_cast<OWeakObject *>(this), static_cast<sal_Int16>(-1) );
+
+ String type, subType;
+ INetContentTypeParameterList params;
+ if (INetContentTypes::parse( mediaType_, type, subType, &params ))
+ {
+ if (type.EqualsIgnoreCaseAscii("application"))
+ {
+ OUString name;
+ if (!bRemoved)
+ {
+ ::ucbhelper::Content ucbContent( url, xCmdEnv );
+ name = ucbContent.getPropertyValue(
+ StrTitle::get() ).get<OUString>();
+ }
+
+ if (subType.EqualsIgnoreCaseAscii(
+ "vnd.sun.star.help"))
+ {
+ return new PackageImpl(
+ this, url, name, m_xHelpTypeInfo, bRemoved,
+ identifier);
+ }
+ }
+ }
+ throw lang::IllegalArgumentException(
+ StrUnsupportedMediaType::get() + mediaType_,
+ static_cast<OWeakObject *>(this),
+ static_cast<sal_Int16>(-1) );
+}
+
+void BackendImpl::addDataToDb(
+ OUString const & url, HelpBackendDb::Data const & data)
+{
+ if (m_backendDb.get())
+ m_backendDb->addEntry(url, data);
+}
+
+::boost::optional<HelpBackendDb::Data> BackendImpl::readDataFromDb(
+ OUString const & url)
+{
+ ::boost::optional<HelpBackendDb::Data> data;
+ if (m_backendDb.get())
+ data = m_backendDb->getEntry(url);
+ return data;
+}
+
+bool BackendImpl::hasActiveEntry(OUString const & url)
+{
+ if (m_backendDb.get())
+ return m_backendDb->hasActiveEntry(url);
+ return false;
+}
+
+void BackendImpl::revokeEntryFromDb(OUString const & url)
+{
+ if (m_backendDb.get())
+ m_backendDb->revokeEntry(url);
+}
+
+bool BackendImpl::activateEntry(OUString const & url)
+{
+ if (m_backendDb.get())
+ return m_backendDb->activateEntry(url);
+ return false;
+}
+
+
+BackendImpl::PackageImpl::PackageImpl(
+ ::rtl::Reference<PackageRegistryBackend> const & myBackend,
+ OUString const & url, OUString const & name,
+ Reference<deployment::XPackageTypeInfo> const & xPackageType,
+ bool bRemoved, OUString const & identifier)
+ : Package( myBackend, url, name, name, xPackageType, bRemoved,
+ identifier)
+{
+}
+
+// Package
+BackendImpl * BackendImpl::PackageImpl::getMyBackend() const
+{
+ BackendImpl * pBackend = static_cast<BackendImpl *>(m_myBackend.get());
+ if (NULL == pBackend)
+ {
+ //May throw a DisposedException
+ check();
+ //We should never get here...
+ throw RuntimeException(
+ OUSTR("Failed to get the BackendImpl"),
+ static_cast<OWeakObject*>(const_cast<PackageImpl *>(this)));
+ }
+ return pBackend;
+}
+
+bool BackendImpl::PackageImpl::extensionContainsCompiledHelp()
+{
+ bool bCompiled = true;
+ rtl::OUString aExpandedHelpURL = dp_misc::expandUnoRcUrl(getURL());
+
+ ::osl::Directory helpFolder(aExpandedHelpURL);
+ if ( helpFolder.open() == ::osl::File::E_None)
+ {
+ //iterate over the contents of the help folder
+ //We assume that all folders withing the help folder contain language specific
+ //help files. If just one of them does not contain compiled help then this
+ //function returns false.
+ ::osl::DirectoryItem item;
+ ::osl::File::RC errorNext = ::osl::File::E_None;
+ while ((errorNext = helpFolder.getNextItem(item)) == ::osl::File::E_None)
+ {
+ //No find the language folders
+ ::osl::FileStatus stat(FileStatusMask_Type | FileStatusMask_FileName |FileStatusMask_FileURL);
+ if (item.getFileStatus(stat) == ::osl::File::E_None)
+ {
+ if (stat.getFileType() != ::osl::FileStatus::Directory)
+ continue;
+
+ //look if there is the folder help.idxl in the language folder
+ OUString compUrl(stat.getFileURL() + OUSTR("/help.idxl"));
+ ::osl::Directory compiledFolder(compUrl);
+ if (compiledFolder.open() != ::osl::File::E_None)
+ {
+ bCompiled = false;
+ break;
+ }
+ }
+ else
+ {
+ //Error
+ OSL_ASSERT(0);
+ bCompiled = false;
+ break;
+ }
+ }
+ if (errorNext != ::osl::File::E_NOENT
+ && errorNext != ::osl::File::E_None)
+ {
+ //Error
+ OSL_ASSERT(0);
+ bCompiled = false;
+ }
+ }
+ return bCompiled;
+}
+
+//______________________________________________________________________________
+beans::Optional< beans::Ambiguous<sal_Bool> >
+BackendImpl::PackageImpl::isRegistered_(
+ ::osl::ResettableMutexGuard &,
+ ::rtl::Reference<AbortChannel> const &,
+ Reference<XCommandEnvironment> const & )
+{
+ BackendImpl * that = getMyBackend();
+
+ bool bReg = false;
+ if (that->hasActiveEntry(getURL()))
+ bReg = true;
+
+ return beans::Optional< beans::Ambiguous<sal_Bool> >( true, beans::Ambiguous<sal_Bool>( bReg, false ) );
+}
+
+//______________________________________________________________________________
+void BackendImpl::PackageImpl::processPackage_(
+ ::osl::ResettableMutexGuard &,
+ bool doRegisterPackage,
+ bool /* startup */,
+ ::rtl::Reference<AbortChannel> const & abortChannel,
+ Reference<XCommandEnvironment> const & xCmdEnv )
+{
+ (void)doRegisterPackage;
+ (void)abortChannel;
+ (void)xCmdEnv;
+
+ BackendImpl* that = getMyBackend();
+ that->implProcessHelp( this, doRegisterPackage, xCmdEnv);
+}
+
+beans::Optional< OUString > BackendImpl::PackageImpl::getRegistrationDataURL()
+ throw (deployment::ExtensionRemovedException,
+ css::uno::RuntimeException)
+{
+ if (m_bRemoved)
+ throw deployment::ExtensionRemovedException();
+
+ ::boost::optional<HelpBackendDb::Data> data =
+ getMyBackend()->readDataFromDb(getURL());
+
+ if (data && getMyBackend()->hasActiveEntry(getURL()))
+ return beans::Optional<OUString>(true, data->dataUrl);
+
+ return beans::Optional<OUString>(true, OUString());
+}
+
+static rtl::OUString aSlash(RTL_CONSTASCII_USTRINGPARAM("/"));
+static rtl::OUString aHelpStr(RTL_CONSTASCII_USTRINGPARAM("help"));
+
+void BackendImpl::implProcessHelp(
+ PackageImpl * package, bool doRegisterPackage,
+ Reference<ucb::XCommandEnvironment> const & xCmdEnv)
+{
+ Reference< deployment::XPackage > xPackage(package);
+ OSL_ASSERT(xPackage.is());
+ if (doRegisterPackage)
+ {
+ //revive already processed help if possible
+ if ( !activateEntry(xPackage->getURL()))
+ {
+ HelpBackendDb::Data data;
+ data.dataUrl = xPackage->getURL();
+ if (!package->extensionContainsCompiledHelp())
+ {
+ const OUString sHelpFolder = createFolder(OUString(), xCmdEnv);
+ data.dataUrl = sHelpFolder;
+
+ Reference< ucb::XSimpleFileAccess > xSFA = getFileAccess();
+ rtl::OUString aHelpURL = xPackage->getURL();
+ rtl::OUString aExpandedHelpURL = dp_misc::expandUnoRcUrl( aHelpURL );
+ rtl::OUString aName = xPackage->getName();
+ if( !xSFA->isFolder( aExpandedHelpURL ) )
+ {
+ rtl::OUString aErrStr = getResourceString( RID_STR_HELPPROCESSING_GENERAL_ERROR );
+ aErrStr += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "No help folder" ));
+ OWeakObject* oWeakThis = static_cast<OWeakObject *>(this);
+ throw deployment::DeploymentException( rtl::OUString(), oWeakThis,
+ makeAny( uno::Exception( aErrStr, oWeakThis ) ) );
+ }
+
+ Reference<XComponentContext> const & xContext = getComponentContext();
+ Reference< script::XInvocation > xInvocation;
+ if( xContext.is() )
+ {
+ try
+ {
+ xInvocation = Reference< script::XInvocation >(
+ xContext->getServiceManager()->createInstanceWithContext(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM("com.sun.star.help.HelpIndexer" )), xContext ) , UNO_QUERY );
+ }
+ catch (Exception &)
+ {
+ // i98680: Survive missing lucene
+ }
+ }
+
+ // Scan languages
+ Sequence< rtl::OUString > aLanguageFolderSeq = xSFA->getFolderContents( aExpandedHelpURL, true );
+ sal_Int32 nLangCount = aLanguageFolderSeq.getLength();
+ const rtl::OUString* pSeq = aLanguageFolderSeq.getConstArray();
+ for( sal_Int32 iLang = 0 ; iLang < nLangCount ; ++iLang )
+ {
+ rtl::OUString aLangURL = pSeq[iLang];
+ if( xSFA->isFolder( aLangURL ) )
+ {
+ std::vector< rtl::OUString > aXhpFileVector;
+
+ // calculate jar file URL
+ sal_Int32 indexStartSegment = aLangURL.lastIndexOf('/');
+ // for example "/en"
+ OUString langFolderURLSegment(
+ aLangURL.copy(
+ indexStartSegment + 1, aLangURL.getLength() - indexStartSegment - 1));
+
+ //create the folder in the "temporary folder"
+ ::ucbhelper::Content langFolderContent;
+ const OUString langFolderDest = makeURL(sHelpFolder, langFolderURLSegment);
+ const OUString langFolderDestExpanded = ::dp_misc::expandUnoRcUrl(langFolderDest);
+ ::dp_misc::create_folder(
+ &langFolderContent,
+ langFolderDest, xCmdEnv);
+
+ rtl::OUString aJarFile(
+ makeURL(sHelpFolder, langFolderURLSegment + aSlash + aHelpStr +
+ OUSTR(".jar")));
+ aJarFile = ::dp_misc::expandUnoRcUrl(aJarFile);
+
+ rtl::OUString aEncodedJarFilePath = rtl::Uri::encode(
+ aJarFile, rtl_UriCharClassPchar,
+ rtl_UriEncodeIgnoreEscapes,
+ RTL_TEXTENCODING_UTF8 );
+ rtl::OUString aDestBasePath = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "vnd.sun.star.zip://" ));
+ aDestBasePath += aEncodedJarFilePath;
+ aDestBasePath += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "/" ));
+
+ sal_Int32 nLenLangFolderURL = aLangURL.getLength() + 1;
+
+ Sequence< rtl::OUString > aSubLangSeq = xSFA->getFolderContents( aLangURL, true );
+ sal_Int32 nSubLangCount = aSubLangSeq.getLength();
+ const rtl::OUString* pSubLangSeq = aSubLangSeq.getConstArray();
+ for( sal_Int32 iSubLang = 0 ; iSubLang < nSubLangCount ; ++iSubLang )
+ {
+ rtl::OUString aSubFolderURL = pSubLangSeq[iSubLang];
+ if( !xSFA->isFolder( aSubFolderURL ) )
+ continue;
+
+ implCollectXhpFiles( aSubFolderURL, aXhpFileVector );
+
+ // Copy to package (later: move?)
+ rtl::OUString aDestPath = aDestBasePath;
+ rtl::OUString aPureFolderName = aSubFolderURL.copy( nLenLangFolderURL );
+ aDestPath += aPureFolderName;
+ xSFA->copy( aSubFolderURL, aDestPath );
+ }
+
+ // Call compiler
+ sal_Int32 nXhpFileCount = aXhpFileVector.size();
+ rtl::OUString* pXhpFiles = new rtl::OUString[nXhpFileCount];
+ for( sal_Int32 iXhp = 0 ; iXhp < nXhpFileCount ; ++iXhp )
+ {
+ rtl::OUString aXhpFile = aXhpFileVector[iXhp];
+ rtl::OUString aXhpRelFile = aXhpFile.copy( nLenLangFolderURL );
+ pXhpFiles[iXhp] = aXhpRelFile;
+ }
+
+ rtl::OUString aOfficeHelpPath( SvtPathOptions().GetHelpPath() );
+ rtl::OUString aOfficeHelpPathFileURL;
+ ::osl::File::getFileURLFromSystemPath( aOfficeHelpPath, aOfficeHelpPathFileURL );
+
+ HelpProcessingErrorInfo aErrorInfo;
+ bool bSuccess = compileExtensionHelp(
+ aOfficeHelpPathFileURL, aHelpStr, aLangURL,
+ nXhpFileCount, pXhpFiles,
+ langFolderDestExpanded, aErrorInfo );
+
+ if( bSuccess && xInvocation.is() )
+ {
+ Sequence<uno::Any> aParamsSeq( 6 );
+
+ aParamsSeq[0] = uno::makeAny( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "-lang" ) ));
+
+ rtl::OUString aLang;
+ sal_Int32 nLastSlash = aLangURL.lastIndexOf( '/' );
+ if( nLastSlash != -1 )
+ aLang = aLangURL.copy( nLastSlash + 1 );
+ else
+ aLang = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "en" ));
+ aParamsSeq[1] = uno::makeAny( aLang );
+
+ aParamsSeq[2] = uno::makeAny( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "-mod" ) ));
+ aParamsSeq[3] = uno::makeAny( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "help" ) ));
+
+ aParamsSeq[4] = uno::makeAny( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "-zipdir" ) ));
+ rtl::OUString aSystemPath;
+ osl::FileBase::getSystemPathFromFileURL(
+ langFolderDestExpanded, aSystemPath );
+ aParamsSeq[5] = uno::makeAny( aSystemPath );
+
+ Sequence< sal_Int16 > aOutParamIndex;
+ Sequence< uno::Any > aOutParam;
+ uno::Any aRet = xInvocation->invoke( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "createIndex" )),
+ aParamsSeq, aOutParamIndex, aOutParam );
+ }
+
+ if( !bSuccess )
+ {
+ sal_uInt16 nErrStrId = 0;
+ switch( aErrorInfo.m_eErrorClass )
+ {
+ case HELPPROCESSING_GENERAL_ERROR:
+ case HELPPROCESSING_INTERNAL_ERROR: nErrStrId = RID_STR_HELPPROCESSING_GENERAL_ERROR; break;
+ case HELPPROCESSING_XMLPARSING_ERROR: nErrStrId = RID_STR_HELPPROCESSING_XMLPARSING_ERROR; break;
+ default: ;
+ };
+
+ rtl::OUString aErrStr;
+ if( nErrStrId != 0 )
+ {
+ aErrStr = getResourceString( nErrStrId );
+
+ // Remoce CR/LF
+ rtl::OUString aErrMsg( aErrorInfo.m_aErrorMsg );
+ sal_Unicode nCR = 13, nLF = 10;
+ sal_Int32 nSearchCR = aErrMsg.indexOf( nCR );
+ sal_Int32 nSearchLF = aErrMsg.indexOf( nLF );
+ sal_Int32 nCopy;
+ if( nSearchCR != -1 || nSearchLF != -1 )
+ {
+ if( nSearchCR == -1 )
+ nCopy = nSearchLF;
+ else if( nSearchLF == -1 )
+ nCopy = nSearchCR;
+ else
+ nCopy = ( nSearchCR < nSearchLF ) ? nSearchCR : nSearchLF;
+
+ aErrMsg = aErrMsg.copy( 0, nCopy );
+ }
+ aErrStr += aErrMsg;
+ if( nErrStrId == RID_STR_HELPPROCESSING_XMLPARSING_ERROR && aErrorInfo.m_aXMLParsingFile.getLength() )
+ {
+ aErrStr += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( " in " ));
+
+ rtl::OUString aDecodedFile = rtl::Uri::decode( aErrorInfo.m_aXMLParsingFile,
+ rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8 );
+ aErrStr += aDecodedFile;
+ if( aErrorInfo.m_nXMLParsingLine != -1 )
+ {
+ aErrStr += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( ", line " ));
+ aErrStr += ::rtl::OUString::valueOf( aErrorInfo.m_nXMLParsingLine );
+ }
+ }
+ }
+
+ OWeakObject* oWeakThis = static_cast<OWeakObject *>(this);
+ throw deployment::DeploymentException( rtl::OUString(), oWeakThis,
+ makeAny( uno::Exception( aErrStr, oWeakThis ) ) );
+ }
+ }
+ }
+ }
+ //Writing the data entry replaces writing the flag file. If we got to this
+ //point the registration was successful.
+ addDataToDb(xPackage->getURL(), data);
+ }
+ } //if (doRegisterPackage)
+ else
+ {
+ revokeEntryFromDb(xPackage->getURL());
+ }
+}
+
+void BackendImpl::implCollectXhpFiles( const rtl::OUString& aDir,
+ std::vector< rtl::OUString >& o_rXhpFileVector )
+{
+ Reference< ucb::XSimpleFileAccess > xSFA = getFileAccess();
+
+ // Scan xhp files recursively
+ Sequence< rtl::OUString > aSeq = xSFA->getFolderContents( aDir, true );
+ sal_Int32 nCount = aSeq.getLength();
+ const rtl::OUString* pSeq = aSeq.getConstArray();
+ for( sal_Int32 i = 0 ; i < nCount ; ++i )
+ {
+ rtl::OUString aURL = pSeq[i];
+ if( xSFA->isFolder( aURL ) )
+ {
+ implCollectXhpFiles( aURL, o_rXhpFileVector );
+ }
+ else
+ {
+ sal_Int32 nLastDot = aURL.lastIndexOf( '.' );
+ if( nLastDot != -1 )
+ {
+ rtl::OUString aExt = aURL.copy( nLastDot + 1 );
+ if( aExt.equalsIgnoreAsciiCase( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "xhp" )) ) )
+ o_rXhpFileVector.push_back( aURL );
+ }
+ }
+ }
+}
+
+Reference< ucb::XSimpleFileAccess > BackendImpl::getFileAccess( void )
+{
+ if( !m_xSFA.is() )
+ {
+ Reference<XComponentContext> const & xContext = getComponentContext();
+ if( xContext.is() )
+ {
+ m_xSFA = Reference< ucb::XSimpleFileAccess >(
+ xContext->getServiceManager()->createInstanceWithContext(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.ucb.SimpleFileAccess" )),
+ xContext ), UNO_QUERY );
+ }
+ if( !m_xSFA.is() )
+ {
+ throw RuntimeException(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "dp_registry::backend::help::BackendImpl::getFileAccess(), "
+ "could not instatiate SimpleFileAccess." )),
+ Reference< XInterface >() );
+ }
+ }
+ return m_xSFA;
+}
+
+} // anon namespace
+
+namespace sdecl = comphelper::service_decl;
+sdecl::class_<BackendImpl, sdecl::with_args<true> > serviceBI;
+extern sdecl::ServiceDecl const serviceDecl(
+ serviceBI,
+ "com.sun.star.comp.deployment.help.PackageRegistryBackend",
+ BACKEND_SERVICE_NAME );
+
+} // namespace help
+} // namespace backend
+} // namespace dp_registry
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/registry/help/dp_help.hrc b/desktop/source/deployment/registry/help/dp_help.hrc
new file mode 100755
index 000000000000..c1e10547ccdd
--- /dev/null
+++ b/desktop/source/deployment/registry/help/dp_help.hrc
@@ -0,0 +1,39 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#if ! defined INCLUDED_DP_HELP_HRC
+#define INCLUDED_DP_HELP_HRC
+
+#include "deployment.hrc"
+
+#define RID_STR_HELP (RID_DEPLOYMENT_HELP_START+2)
+
+#define RID_STR_HELPPROCESSING_GENERAL_ERROR (RID_DEPLOYMENT_HELP_START+3)
+#define RID_STR_HELPPROCESSING_XMLPARSING_ERROR (RID_DEPLOYMENT_HELP_START+4)
+
+
+#endif
diff --git a/desktop/source/deployment/registry/help/dp_help.src b/desktop/source/deployment/registry/help/dp_help.src
new file mode 100644
index 000000000000..6b6a3f9a6508
--- /dev/null
+++ b/desktop/source/deployment/registry/help/dp_help.src
@@ -0,0 +1,44 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "dp_help.hrc"
+
+String RID_STR_HELP
+{
+ Text [ en-US ] = "Help";
+};
+
+String RID_STR_HELPPROCESSING_GENERAL_ERROR
+{
+ Text [ en-US ] = "The extension cannot be installed because:\n";
+};
+
+String RID_STR_HELPPROCESSING_XMLPARSING_ERROR
+{
+ Text [ en-US ] = "The extension will not be installed because an error occurred in the Help files:\n";
+};
+
diff --git a/desktop/source/deployment/registry/help/dp_helpbackenddb.cxx b/desktop/source/deployment/registry/help/dp_helpbackenddb.cxx
new file mode 100644
index 000000000000..491f6d6c1db9
--- /dev/null
+++ b/desktop/source/deployment/registry/help/dp_helpbackenddb.cxx
@@ -0,0 +1,149 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include "rtl/string.h"
+#include "rtl/bootstrap.hxx"
+#include "cppuhelper/exc_hlp.hxx"
+#include "com/sun/star/uno/XComponentContext.hpp"
+#include "com/sun/star/xml/dom/XDocumentBuilder.hpp"
+#include "com/sun/star/xml/xpath/XXPathAPI.hpp"
+#include "dp_misc.h"
+
+#include "dp_helpbackenddb.hxx"
+
+
+namespace css = ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using ::rtl::OUString;
+
+#define EXTENSION_REG_NS "http://openoffice.org/extensionmanager/help-registry/2010"
+#define NS_PREFIX "help"
+#define ROOT_ELEMENT_NAME "help-backend-db"
+#define KEY_ELEMENT_NAME "help"
+
+namespace dp_registry {
+namespace backend {
+namespace help {
+
+HelpBackendDb::HelpBackendDb(
+ Reference<XComponentContext> const & xContext,
+ ::rtl::OUString const & url):BackendDb(xContext, url)
+{
+
+}
+
+OUString HelpBackendDb::getDbNSName()
+{
+ return OUSTR(EXTENSION_REG_NS);
+}
+
+OUString HelpBackendDb::getNSPrefix()
+{
+ return OUSTR(NS_PREFIX);
+}
+
+OUString HelpBackendDb::getRootElementName()
+{
+ return OUSTR(ROOT_ELEMENT_NAME);
+}
+
+OUString HelpBackendDb::getKeyElementName()
+{
+ return OUSTR(KEY_ELEMENT_NAME);
+}
+
+
+void HelpBackendDb::addEntry(::rtl::OUString const & url, Data const & data)
+{
+ try{
+ if (!activateEntry(url))
+ {
+ Reference<css::xml::dom::XNode> helpNode
+ = writeKeyElement(url);
+
+ writeSimpleElement(OUSTR("data-url"), data.dataUrl, helpNode);
+ save();
+ }
+ }
+ catch (css::deployment::DeploymentException& )
+ {
+ throw;
+ }
+ catch(css::uno::Exception &)
+ {
+ Any exc( ::cppu::getCaughtException() );
+ throw css::deployment::DeploymentException(
+ OUSTR("Extension Manager: failed to write data entry in help backend db: ") +
+ m_urlDb, 0, exc);
+ }
+}
+
+
+::boost::optional<HelpBackendDb::Data>
+HelpBackendDb::getEntry(::rtl::OUString const & url)
+{
+ try
+ {
+ HelpBackendDb::Data retData;
+ Reference<css::xml::dom::XNode> aNode = getKeyElement(url);
+ if (aNode.is())
+ {
+ retData.dataUrl = readSimpleElement(OUSTR("data-url"), aNode);
+ }
+ else
+ {
+ return ::boost::optional<Data>();
+ }
+ return ::boost::optional<Data>(retData);
+ }
+ catch (css::deployment::DeploymentException& )
+ {
+ throw;
+ }
+ catch(css::uno::Exception &)
+ {
+ Any exc( ::cppu::getCaughtException() );
+ throw css::deployment::DeploymentException(
+ OUSTR("Extension Manager: failed to read data entry in help backend db: ") +
+ m_urlDb, 0, exc);
+ }
+}
+
+::std::list<OUString> HelpBackendDb::getAllDataUrls()
+{
+ return getOneChildFromAllEntries(OUString(RTL_CONSTASCII_USTRINGPARAM("data-url")));
+}
+
+} // namespace help
+} // namespace backend
+} // namespace dp_registry
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/registry/help/dp_helpbackenddb.hxx b/desktop/source/deployment/registry/help/dp_helpbackenddb.hxx
new file mode 100644
index 000000000000..34e732d4118d
--- /dev/null
+++ b/desktop/source/deployment/registry/help/dp_helpbackenddb.hxx
@@ -0,0 +1,93 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#if ! defined INCLUDED_DP_HELPBACKENDDB_HXX
+#define INCLUDED_DP_HELPBACKENDDB_HXX
+
+#include "rtl/ustring.hxx"
+#include <list>
+#include "boost/optional.hpp"
+#include "dp_backenddb.hxx"
+
+namespace css = ::com::sun::star;
+
+namespace com { namespace sun { namespace star {
+ namespace uno {
+ class XComponentContext;
+ }
+}}}
+
+namespace dp_registry {
+namespace backend {
+namespace help {
+
+/* The XML file stores the extensions which are currently registered.
+ They will be removed when they are revoked.
+ */
+class HelpBackendDb: public dp_registry::backend::BackendDb
+{
+protected:
+ virtual ::rtl::OUString getDbNSName();
+
+ virtual ::rtl::OUString getNSPrefix();
+
+ virtual ::rtl::OUString getRootElementName();
+
+ virtual ::rtl::OUString getKeyElementName();
+
+public:
+ struct Data
+ {
+ /* the URL to the folder containing the compiled help files, etc.
+ */
+ ::rtl::OUString dataUrl;
+
+ };
+
+public:
+
+ HelpBackendDb( css::uno::Reference<css::uno::XComponentContext> const & xContext,
+ ::rtl::OUString const & url);
+
+ void addEntry(::rtl::OUString const & url, Data const & data);
+
+ ::boost::optional<Data> getEntry(::rtl::OUString const & url);
+ //must also return the data urls for entries with @activ="false". That is,
+ //those are currently revoked.
+ ::std::list< ::rtl::OUString> getAllDataUrls();
+
+};
+
+
+
+}
+}
+}
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/registry/help/makefile.mk b/desktop/source/deployment/registry/help/makefile.mk
new file mode 100755
index 000000000000..d4934f71a46f
--- /dev/null
+++ b/desktop/source/deployment/registry/help/makefile.mk
@@ -0,0 +1,52 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ = ..$/..$/..$/..
+
+PRJNAME = desktop
+TARGET = deployment_registry_help
+ENABLE_EXCEPTIONS = TRUE
+
+INCPRE += ..$/..$/inc
+
+.INCLUDE : settings.mk
+
+.IF "$(SYSTEM_DB)" == "YES"
+CFLAGS+=-DSYSTEM_DB -I$(DB_INCLUDES)
+.ENDIF
+
+SRS1NAME = $(TARGET)
+SRC1FILES = \
+ dp_help.src
+
+SLOFILES = \
+ $(SLO)$/dp_help.obj \
+ $(SLO)$/dp_helpbackenddb.obj
+
+.INCLUDE : ..$/..$/target.pmk
+.INCLUDE : target.mk
+
diff --git a/desktop/source/deployment/registry/inc/dp_backend.h b/desktop/source/deployment/registry/inc/dp_backend.h
new file mode 100755
index 000000000000..847eb43d5cb2
--- /dev/null
+++ b/desktop/source/deployment/registry/inc/dp_backend.h
@@ -0,0 +1,401 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#if ! defined INCLUDED_DP_REGISTRY_H
+#define INCLUDED_DP_REGISTRY_H
+
+#include "dp_misc.h"
+#include "dp_resource.h"
+#include "dp_interact.h"
+#include "rtl/ref.hxx"
+#include "cppuhelper/weakref.hxx"
+#include "cppuhelper/implbase1.hxx"
+#include "cppuhelper/compbase1.hxx"
+#include "cppuhelper/compbase2.hxx"
+#include "tools/inetmime.hxx"
+#include "com/sun/star/lang/XEventListener.hpp"
+#include "com/sun/star/deployment/XPackageRegistry.hpp"
+#include "com/sun/star/deployment/XPackageManager.hpp"
+#include "com/sun/star/deployment/InvalidRemovedParameterException.hpp"
+#include <memory>
+#include <boost/unordered_map.hpp>
+#include <list>
+#include "dp_registry.hrc"
+
+namespace dp_registry
+{
+namespace backend
+{
+
+namespace css = ::com::sun::star;
+
+class PackageRegistryBackend;
+
+#define BACKEND_SERVICE_NAME "com.sun.star.deployment.PackageRegistryBackend"
+
+typedef ::cppu::WeakComponentImplHelper1<
+ css::deployment::XPackage > t_PackageBase;
+
+//==============================================================================
+class Package : protected ::dp_misc::MutexHolder, public t_PackageBase
+{
+ PackageRegistryBackend * getMyBackend() const;
+ void processPackage_impl(
+ bool registerPackage,
+ bool startup,
+ css::uno::Reference<css::task::XAbortChannel> const & xAbortChannel,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv );
+
+protected:
+ ::rtl::Reference<PackageRegistryBackend> m_myBackend;
+ const ::rtl::OUString m_url;
+ ::rtl::OUString m_name;
+ ::rtl::OUString m_displayName;
+ const css::uno::Reference<css::deployment::XPackageTypeInfo> m_xPackageType;
+ const bool m_bRemoved;
+ //Only set if m_bRemoved = true;
+ const ::rtl::OUString m_identifier;
+
+ void check() const;
+ void fireModified();
+ virtual void SAL_CALL disposing();
+
+ void checkAborted(
+ ::rtl::Reference< ::dp_misc::AbortChannel > const & abortChannel );
+
+ // @@@ to be implemented by specific backend:
+ virtual css::beans::Optional< css::beans::Ambiguous<sal_Bool> >
+ isRegistered_(
+ ::osl::ResettableMutexGuard & guard,
+ ::rtl::Reference< ::dp_misc::AbortChannel > const & abortChannel,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv )
+ = 0;
+ virtual void processPackage_(
+ ::osl::ResettableMutexGuard & guard,
+ bool registerPackage,
+ bool startup,
+ ::rtl::Reference< ::dp_misc::AbortChannel > const & abortChannel,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv )
+ = 0;
+
+ virtual ~Package();
+ Package( ::rtl::Reference<PackageRegistryBackend> const & myBackend,
+ ::rtl::OUString const & url,
+ ::rtl::OUString const & name,
+ ::rtl::OUString const & displayName,
+ css::uno::Reference<css::deployment::XPackageTypeInfo> const &
+ xPackageType,
+ bool bRemoved,
+ ::rtl::OUString const & identifier);
+
+public:
+
+ class TypeInfo :
+ public ::cppu::WeakImplHelper1<css::deployment::XPackageTypeInfo>
+ {
+ const ::rtl::OUString m_mediaType;
+ const ::rtl::OUString m_fileFilter;
+ const ::rtl::OUString m_shortDescr;
+ const sal_uInt16 m_smallIcon;
+ public:
+ virtual ~TypeInfo();
+ TypeInfo( ::rtl::OUString const & mediaType,
+ ::rtl::OUString const & fileFilter,
+ ::rtl::OUString const & shortDescr,
+ sal_uInt16 smallIcon)
+ : m_mediaType(mediaType), m_fileFilter(fileFilter),
+ m_shortDescr(shortDescr),
+ m_smallIcon(smallIcon)
+ {}
+ // XPackageTypeInfo
+ virtual ::rtl::OUString SAL_CALL getMediaType()
+ throw (css::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getDescription()
+ throw (css::deployment::ExtensionRemovedException,
+ css::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getShortDescription()
+ throw (css::deployment::ExtensionRemovedException,
+ css::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getFileFilter()
+ throw (css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL getIcon( sal_Bool highContrast,
+ sal_Bool smallIcon )
+ throw (css::uno::RuntimeException);
+ };
+
+ // XComponent
+ virtual void SAL_CALL dispose() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL addEventListener(
+ css::uno::Reference<css::lang::XEventListener> const & xListener )
+ throw (css::uno::RuntimeException);
+ virtual void SAL_CALL removeEventListener(
+ css::uno::Reference<css::lang::XEventListener> const & xListener )
+ throw (css::uno::RuntimeException);
+
+ // XModifyBroadcaster
+ virtual void SAL_CALL addModifyListener(
+ css::uno::Reference<css::util::XModifyListener> const & xListener )
+ throw (css::uno::RuntimeException);
+ virtual void SAL_CALL removeModifyListener(
+ css::uno::Reference<css::util::XModifyListener> const & xListener )
+ throw (css::uno::RuntimeException);
+
+ // XPackage
+ virtual css::uno::Reference<css::task::XAbortChannel> SAL_CALL
+ createAbortChannel() throw (css::uno::RuntimeException);
+ virtual css::beans::Optional< css::beans::Ambiguous<sal_Bool> >
+ SAL_CALL isRegistered(
+ css::uno::Reference<css::task::XAbortChannel> const & xAbortChannel,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv )
+ throw (css::deployment::DeploymentException,
+ css::ucb::CommandFailedException,
+ css::ucb::CommandAbortedException,
+ css::uno::RuntimeException);
+
+ virtual ::sal_Int32 SAL_CALL checkPrerequisites(
+ const css::uno::Reference< css::task::XAbortChannel >& xAbortChannel,
+ const css::uno::Reference< css::ucb::XCommandEnvironment >& xCmdEnv,
+ sal_Bool noLicenseChecking)
+ throw (css::deployment::DeploymentException,
+ css::deployment::ExtensionRemovedException,
+ css::ucb::CommandFailedException,
+ css::ucb::CommandAbortedException,
+ css::uno::RuntimeException);
+
+ virtual ::sal_Bool SAL_CALL checkDependencies(
+ const css::uno::Reference< css::ucb::XCommandEnvironment >& xCmdEnv )
+ throw (css::deployment::DeploymentException,
+ css::deployment::ExtensionRemovedException,
+ css::ucb::CommandFailedException,
+ css::uno::RuntimeException);
+
+ virtual void SAL_CALL registerPackage(
+ sal_Bool startup,
+ css::uno::Reference<css::task::XAbortChannel> const & xAbortChannel,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv )
+ throw (css::deployment::DeploymentException,
+ css::deployment::ExtensionRemovedException,
+ css::ucb::CommandFailedException,
+ css::ucb::CommandAbortedException,
+ css::lang::IllegalArgumentException, css::uno::RuntimeException);
+ virtual void SAL_CALL revokePackage(
+ css::uno::Reference<css::task::XAbortChannel> const & xAbortChannel,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv )
+ throw (css::deployment::DeploymentException,
+ css::ucb::CommandFailedException,
+ css::ucb::CommandAbortedException,
+ css::lang::IllegalArgumentException,
+ css::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL isBundle()
+ throw (css::uno::RuntimeException);
+ virtual css::uno::Sequence< css::uno::Reference<css::deployment::XPackage> >
+ SAL_CALL getBundle(
+ css::uno::Reference<css::task::XAbortChannel> const & xAbortChannel,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv )
+ throw (css::deployment::DeploymentException,
+ css::ucb::CommandFailedException,
+ css::ucb::CommandAbortedException,
+ css::lang::IllegalArgumentException,
+ css::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getName()
+ throw (css::uno::RuntimeException);
+ virtual css::beans::Optional< ::rtl::OUString > SAL_CALL getIdentifier()
+ throw (css::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getVersion()
+ throw (css::deployment::ExtensionRemovedException,
+ css::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getURL()
+ throw (css::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getDisplayName()
+ throw (css::deployment::ExtensionRemovedException,
+ css::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getDescription()
+ throw (css::deployment::ExtensionRemovedException,
+ css::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getLicenseText()
+ throw (css::deployment::ExtensionRemovedException,
+ css::uno::RuntimeException);
+ virtual css::uno::Sequence< ::rtl::OUString > SAL_CALL
+ getUpdateInformationURLs()
+ throw (css::deployment::ExtensionRemovedException,
+ css::uno::RuntimeException);
+ virtual css::beans::StringPair SAL_CALL getPublisherInfo()
+ throw (css::deployment::ExtensionRemovedException,
+ css::uno::RuntimeException);
+ virtual css::uno::Reference< css::graphic::XGraphic > SAL_CALL
+ getIcon( sal_Bool bHighContrast )
+ throw (css::deployment::ExtensionRemovedException,
+ css::uno::RuntimeException);
+ virtual css::uno::Reference<css::deployment::XPackageTypeInfo> SAL_CALL
+ getPackageType() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL exportTo(
+ ::rtl::OUString const & destFolderURL,
+ ::rtl::OUString const & newTitle,
+ sal_Int32 nameClashAction,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv )
+ throw (css::deployment::ExtensionRemovedException,
+ css::ucb::CommandFailedException,
+ css::ucb::CommandAbortedException, css::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getRepositoryName()
+ throw (css::uno::RuntimeException);
+ virtual css::beans::Optional< ::rtl::OUString > SAL_CALL getRegistrationDataURL()
+ throw (css::deployment::ExtensionRemovedException,
+ css::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL isRemoved()
+ throw (css::uno::RuntimeException);
+
+};
+
+typedef ::cppu::WeakComponentImplHelper2<
+ css::lang::XEventListener,
+ css::deployment::XPackageRegistry > t_BackendBase;
+
+//==============================================================================
+class PackageRegistryBackend
+ : protected ::dp_misc::MutexHolder, public t_BackendBase
+{
+ //The map held originally WeakReferences. The map entries are removed in the disposing
+ //function, which is called when the XPackages are destructed or they are
+ //explicitely disposed. The latter happens, for example, when a extension is
+ //removed (see dp_manager.cxx). However, because of how the help systems work, now
+ // XPackageManager::getDeployedPackages is called often. This results in a lot
+ //of bindPackage calls which are costly. Therefore we keep hard references in
+ //the map now.
+ typedef ::boost::unordered_map<
+ ::rtl::OUString, css::uno::Reference<css::deployment::XPackage>,
+ ::rtl::OUStringHash > t_string2ref;
+ t_string2ref m_bound;
+
+protected:
+ ::rtl::OUString m_cachePath;
+ css::uno::Reference<css::uno::XComponentContext> m_xComponentContext;
+
+ ::rtl::OUString m_context;
+ // currently only for library containers:
+ enum {
+ CONTEXT_UNKNOWN,
+ CONTEXT_USER, CONTEXT_SHARED,CONTEXT_BUNDLED, CONTEXT_TMP, CONTEXT_BUNDLED_PREREG,
+ CONTEXT_DOCUMENT
+ } m_eContext;
+ bool m_readOnly;
+
+ struct StrCannotDetectMediaType : public ::dp_misc::StaticResourceString<
+ StrCannotDetectMediaType, RID_STR_CANNOT_DETECT_MEDIA_TYPE> {};
+ struct StrUnsupportedMediaType : public ::dp_misc::StaticResourceString<
+ StrUnsupportedMediaType, RID_STR_UNSUPPORTED_MEDIA_TYPE> {};
+
+ // @@@ to be implemented by specific backend:
+ virtual css::uno::Reference<css::deployment::XPackage> bindPackage_(
+ ::rtl::OUString const & url, ::rtl::OUString const & mediaType,
+ sal_Bool bRemoved, ::rtl::OUString const & identifier,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv )
+ = 0;
+
+ void check();
+ virtual void SAL_CALL disposing();
+
+ virtual ~PackageRegistryBackend();
+ PackageRegistryBackend(
+ css::uno::Sequence<css::uno::Any> const & args,
+ css::uno::Reference<css::uno::XComponentContext> const & xContext );
+
+ /* creates a folder with a unique name.
+ If url is empty then it is created in the the backend folder, otherwise
+ at a location relative to that folder specified by url.
+ */
+ ::rtl::OUString createFolder(
+ ::rtl::OUString const & relUrl,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv);
+ /* deletes folders and files.
+
+ All folder all files which end with ".tmp" or ".tmp_" and which are
+ not used are deleted.
+ */
+ void deleteUnusedFolders(
+ ::rtl::OUString const & relUrl,
+ ::std::list< ::rtl::OUString> const & usedFolders);
+ /* deletes one folder with a "temporary" name and the corresponding
+ tmp file, which was used to derive the folder name.
+ */
+ static void deleteTempFolder(
+ ::rtl::OUString const & folderUrl);
+
+ ::rtl::OUString getSharedRegistrationDataURL(
+ css::uno::Reference<css::deployment::XPackage> const & extension,
+ css::uno::Reference<css::deployment::XPackage> const & item);
+
+ /* The backends must implement this function, which is called
+ from XPackageRegistry::packageRemoved (also implemented here).
+ This ensure that the backends clean up their registration data
+ when an extension was removed.
+ */
+// virtual void deleteDbEntry( ::rtl::OUString const & url) = 0;
+
+
+
+public:
+ struct StrRegisteringPackage : public ::dp_misc::StaticResourceString<
+ StrRegisteringPackage, RID_STR_REGISTERING_PACKAGE> {};
+ struct StrRevokingPackage : public ::dp_misc::StaticResourceString<
+ StrRevokingPackage, RID_STR_REVOKING_PACKAGE> {};
+
+ inline css::uno::Reference<css::uno::XComponentContext> const &
+ getComponentContext() const { return m_xComponentContext; }
+
+ inline ::rtl::OUString const & getCachePath() const { return m_cachePath; }
+ inline bool transientMode() const { return m_cachePath.getLength() == 0; }
+
+ inline ::rtl::OUString getContext() const {return m_context; }
+
+ // XEventListener
+ virtual void SAL_CALL disposing( css::lang::EventObject const & evt )
+ throw (css::uno::RuntimeException);
+
+ // XPackageRegistry
+ virtual css::uno::Reference<css::deployment::XPackage> SAL_CALL bindPackage(
+ ::rtl::OUString const & url, ::rtl::OUString const & mediaType,
+ sal_Bool bRemoved, ::rtl::OUString const & identifier,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv )
+ throw (css::deployment::DeploymentException,
+ css::deployment::InvalidRemovedParameterException,
+ css::ucb::CommandFailedException,
+ css::lang::IllegalArgumentException, css::uno::RuntimeException);
+
+// virtual void SAL_CALL packageRemoved(
+// ::rtl::OUString const & url, ::rtl::OUString const & mediaType)
+// throw (css::deployment::DeploymentException,
+// css::uno::RuntimeException);
+
+};
+
+}
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/registry/inc/dp_backenddb.hxx b/desktop/source/deployment/registry/inc/dp_backenddb.hxx
new file mode 100644
index 000000000000..063da7bae1c4
--- /dev/null
+++ b/desktop/source/deployment/registry/inc/dp_backenddb.hxx
@@ -0,0 +1,181 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#if ! defined INCLUDED_DP_BACKENDDB_HXX
+#define INCLUDED_DP_BACKENDDB_HXX
+
+#include "rtl/ustring.hxx"
+#include <list>
+#include <vector>
+
+namespace css = ::com::sun::star;
+
+namespace com { namespace sun { namespace star {
+ namespace uno {
+ class XComponentContext;
+ }
+ namespace xml { namespace dom {
+ class XDocument;
+ class XNode;
+ }}
+ namespace xml { namespace xpath {
+ class XXPathAPI;
+ }}
+}}}
+
+namespace dp_registry {
+namespace backend {
+
+class BackendDb
+{
+private:
+
+ css::uno::Reference<css::xml::dom::XDocument> m_doc;
+ css::uno::Reference<css::xml::xpath::XXPathAPI> m_xpathApi;
+
+ BackendDb(BackendDb const &);
+ BackendDb & operator = (BackendDb const &);
+
+protected:
+ const css::uno::Reference<css::uno::XComponentContext> m_xContext;
+ ::rtl::OUString m_urlDb;
+
+protected:
+
+ /* caller must make sure that only one thread accesses the function
+ */
+ css::uno::Reference<css::xml::dom::XDocument> getDocument();
+
+ /* the namespace prefix is "reg" (without quotes)
+ */
+ css::uno::Reference<css::xml::xpath::XXPathAPI> getXPathAPI();
+ void save();
+ void removeElement(::rtl::OUString const & sXPathExpression);
+
+ css::uno::Reference<css::xml::dom::XNode> getKeyElement(
+ ::rtl::OUString const & url);
+
+ void writeSimpleList(
+ ::std::list< ::rtl::OUString> const & list,
+ ::rtl::OUString const & sListTagName,
+ ::rtl::OUString const & sMemberTagName,
+ css::uno::Reference<css::xml::dom::XNode> const & xParent);
+
+ void writeVectorOfPair(
+ ::std::vector< ::std::pair< ::rtl::OUString, ::rtl::OUString > > const & vecPairs,
+ ::rtl::OUString const & sVectorTagName,
+ ::rtl::OUString const & sPairTagName,
+ ::rtl::OUString const & sFirstTagName,
+ ::rtl::OUString const & sSecondTagName,
+ css::uno::Reference<css::xml::dom::XNode> const & xParent);
+
+ void writeSimpleElement(
+ ::rtl::OUString const & sElementName, ::rtl::OUString const & value,
+ css::uno::Reference<css::xml::dom::XNode> const & xParent);
+
+ css::uno::Reference<css::xml::dom::XNode> writeKeyElement(
+ ::rtl::OUString const & url);
+
+ ::rtl::OUString readSimpleElement(
+ ::rtl::OUString const & sElementName,
+ css::uno::Reference<css::xml::dom::XNode> const & xParent);
+
+ ::std::vector< ::std::pair< ::rtl::OUString, ::rtl::OUString > >
+ readVectorOfPair(
+ css::uno::Reference<css::xml::dom::XNode> const & parent,
+ ::rtl::OUString const & sListTagName,
+ ::rtl::OUString const & sPairTagName,
+ ::rtl::OUString const & sFirstTagName,
+ ::rtl::OUString const & sSecondTagName);
+
+ ::std::list< ::rtl::OUString> readList(
+ css::uno::Reference<css::xml::dom::XNode> const & parent,
+ ::rtl::OUString const & sListTagName,
+ ::rtl::OUString const & sMemberTagName);
+
+ /* returns the values of one particulary child element of all key elements.
+ */
+ ::std::list< ::rtl::OUString> getOneChildFromAllEntries(
+ ::rtl::OUString const & sElementName);
+
+
+ /* returns the namespace which is to be written as xmlns attribute
+ into the root element.
+ */
+ virtual ::rtl::OUString getDbNSName()=0;
+ /* return the namespace prefix which is to be registered with the XPath API.
+
+ The prefix can then be used in XPath expressions.
+ */
+ virtual ::rtl::OUString getNSPrefix()=0;
+ /* returns the name of the root element without any namespace prefix.
+ */
+ virtual ::rtl::OUString getRootElementName()=0;
+ /* returns the name of xml element for each entry
+ */
+ virtual ::rtl::OUString getKeyElementName()=0;
+
+public:
+ BackendDb(css::uno::Reference<css::uno::XComponentContext> const & xContext,
+ ::rtl::OUString const & url);
+ virtual ~BackendDb() {};
+
+ void removeEntry(::rtl::OUString const & url);
+
+ /* This is called to write the "revoked" attribute to the entry.
+ This is done when XPackage::revokePackage is called.
+ */
+ void revokeEntry(::rtl::OUString const & url);
+
+ /* returns false if the entry does not exist yet.
+ */
+ bool activateEntry(::rtl::OUString const & url);
+
+ bool hasActiveEntry(::rtl::OUString const & url);
+
+};
+
+class RegisteredDb: public BackendDb
+{
+
+public:
+ RegisteredDb( css::uno::Reference<css::uno::XComponentContext> const & xContext,
+ ::rtl::OUString const & url);
+ virtual ~RegisteredDb() {};
+
+
+ virtual void addEntry(::rtl::OUString const & url);
+ virtual bool getEntry(::rtl::OUString const & url);
+
+};
+
+}
+}
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/registry/inc/dp_registry.hrc b/desktop/source/deployment/registry/inc/dp_registry.hrc
new file mode 100755
index 000000000000..4a3b1d0b1a4a
--- /dev/null
+++ b/desktop/source/deployment/registry/inc/dp_registry.hrc
@@ -0,0 +1,40 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#if ! defined INCLUDED_DP_REGISTRY_HRC
+#define INCLUDED_DP_REGISTRY_HRC
+
+#include "deployment.hrc"
+
+#define RID_STR_CANNOT_DETECT_MEDIA_TYPE (RID_DEPLOYMENT_REGISTRY_START+0)
+#define RID_STR_UNSUPPORTED_MEDIA_TYPE (RID_DEPLOYMENT_REGISTRY_START+1)
+#define RID_STR_ERROR_WHILE_REGISTERING (RID_DEPLOYMENT_REGISTRY_START+2)
+#define RID_STR_ERROR_WHILE_REVOKING (RID_DEPLOYMENT_REGISTRY_START+3)
+#define RID_STR_REGISTERING_PACKAGE (RID_DEPLOYMENT_REGISTRY_START+4)
+#define RID_STR_REVOKING_PACKAGE (RID_DEPLOYMENT_REGISTRY_START+5)
+
+#endif
diff --git a/desktop/source/deployment/registry/makefile.mk b/desktop/source/deployment/registry/makefile.mk
new file mode 100755
index 000000000000..e45cec272ca7
--- /dev/null
+++ b/desktop/source/deployment/registry/makefile.mk
@@ -0,0 +1,49 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ = ..$/..$/..
+
+PRJNAME = desktop
+TARGET = deployment_registry
+ENABLE_EXCEPTIONS = TRUE
+
+.INCLUDE : settings.mk
+
+SRS1NAME = $(TARGET)
+SRC1FILES = \
+ dp_registry.src
+
+INCPRE += inc
+
+SLOFILES = \
+ $(SLO)$/dp_backend.obj \
+ $(SLO)$/dp_registry.obj \
+ $(SLO)$/dp_backenddb.obj
+
+.INCLUDE : ..$/target.pmk
+.INCLUDE : target.mk
+
diff --git a/desktop/source/deployment/registry/package/dp_extbackenddb.cxx b/desktop/source/deployment/registry/package/dp_extbackenddb.cxx
new file mode 100644
index 000000000000..5331f612c383
--- /dev/null
+++ b/desktop/source/deployment/registry/package/dp_extbackenddb.cxx
@@ -0,0 +1,140 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include "rtl/bootstrap.hxx"
+#include "cppuhelper/exc_hlp.hxx"
+#include "com/sun/star/uno/XComponentContext.hpp"
+#include "com/sun/star/xml/dom/XDocumentBuilder.hpp"
+#include "com/sun/star/xml/xpath/XXPathAPI.hpp"
+#include "dp_misc.h"
+
+#include "dp_extbackenddb.hxx"
+
+
+namespace css = ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using ::rtl::OUString;
+
+#define EXTENSION_REG_NS "http://openoffice.org/extensionmanager/extension-registry/2010"
+#define NS_PREFIX "ext"
+#define ROOT_ELEMENT_NAME "extension-backend-db"
+#define KEY_ELEMENT_NAME "extension"
+
+namespace dp_registry {
+namespace backend {
+namespace bundle {
+
+ExtensionBackendDb::ExtensionBackendDb(
+ Reference<XComponentContext> const & xContext,
+ ::rtl::OUString const & url):BackendDb(xContext, url)
+{
+
+}
+
+OUString ExtensionBackendDb::getDbNSName()
+{
+ return OUSTR(EXTENSION_REG_NS);
+}
+
+OUString ExtensionBackendDb::getNSPrefix()
+{
+ return OUSTR(NS_PREFIX);
+}
+
+OUString ExtensionBackendDb::getRootElementName()
+{
+ return OUSTR(ROOT_ELEMENT_NAME);
+}
+
+OUString ExtensionBackendDb::getKeyElementName()
+{
+ return OUSTR(KEY_ELEMENT_NAME);
+}
+
+void ExtensionBackendDb::addEntry(::rtl::OUString const & url, Data const & data)
+{
+ try{
+ //reactive revoked entry if possible.
+ if (!activateEntry(url))
+ {
+ Reference<css::xml::dom::XNode> extensionNodeNode = writeKeyElement(url);
+ writeVectorOfPair(
+ data.items,
+ OUSTR("extension-items"),
+ OUSTR("item"),
+ OUSTR("url"),
+ OUSTR("media-type"),
+ extensionNodeNode);
+ save();
+ }
+ }
+ catch(css::uno::Exception &)
+ {
+ Any exc( ::cppu::getCaughtException() );
+ throw css::deployment::DeploymentException(
+ OUSTR("Extension Manager: failed to write data entry in backend db: ") +
+ m_urlDb, 0, exc);
+ }
+}
+
+ExtensionBackendDb::Data ExtensionBackendDb::getEntry(::rtl::OUString const & url)
+{
+ try
+ {
+ ExtensionBackendDb::Data retData;
+ Reference<css::xml::dom::XNode> aNode = getKeyElement(url);
+
+ if (aNode.is())
+ {
+ retData.items =
+ readVectorOfPair(
+ aNode,
+ OUSTR("extension-items"),
+ OUSTR("item"),
+ OUSTR("url"),
+ OUSTR("media-type"));
+ }
+ return retData;
+ }
+ catch(css::uno::Exception &)
+ {
+ Any exc( ::cppu::getCaughtException() );
+ throw css::deployment::DeploymentException(
+ OUSTR("Extension Manager: failed to read data entry in backend db: ") +
+ m_urlDb, 0, exc);
+ }
+}
+
+} // namespace bundle
+} // namespace backend
+} // namespace dp_registry
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/registry/package/dp_extbackenddb.hxx b/desktop/source/deployment/registry/package/dp_extbackenddb.hxx
new file mode 100644
index 000000000000..e94c846887c3
--- /dev/null
+++ b/desktop/source/deployment/registry/package/dp_extbackenddb.hxx
@@ -0,0 +1,95 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#if ! defined INCLUDED_DP_EXTBACKENDDB_HXX
+#define INCLUDED_DP_EXTBACKENDDB_HXX
+
+#include <utility>
+#include <vector>
+
+#include "rtl/ustring.hxx"
+
+#include "dp_backenddb.hxx"
+
+namespace css = ::com::sun::star;
+
+namespace com { namespace sun { namespace star {
+ namespace uno {
+ class XComponentContext;
+ }
+ namespace xml { namespace dom {
+ class XDocument;
+ class XNode;
+ }}
+ namespace xml { namespace xpath {
+ class XXPathAPI;
+ }}
+}}}
+
+namespace dp_registry {
+namespace backend {
+namespace bundle {
+
+/* The XML file stores the extensions which are currently registered.
+ They will be removed when they are revoked.
+ */
+class ExtensionBackendDb: public dp_registry::backend::BackendDb
+{
+protected:
+ virtual ::rtl::OUString getDbNSName();
+ virtual ::rtl::OUString getNSPrefix();
+ virtual ::rtl::OUString getRootElementName();
+ virtual ::rtl::OUString getKeyElementName();
+
+public:
+ struct Data
+ {
+ /* every element consists of a pair of the url to the item (jar,rdb, etc)
+ and the media type
+ */
+ ::std::vector< ::std::pair< ::rtl::OUString, ::rtl::OUString> > items;
+ typedef ::std::vector<
+ ::std::pair< ::rtl::OUString, ::rtl::OUString> >::const_iterator ITC_ITEMS;
+ };
+
+public:
+ ExtensionBackendDb( css::uno::Reference<css::uno::XComponentContext> const & xContext,
+ ::rtl::OUString const & url);
+
+ void addEntry(::rtl::OUString const & url, Data const & data);
+
+ Data getEntry(::rtl::OUString const & url);
+
+};
+
+}
+}
+}
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/registry/package/dp_package.cxx b/desktop/source/deployment/registry/package/dp_package.cxx
new file mode 100644
index 000000000000..f28269411703
--- /dev/null
+++ b/desktop/source/deployment/registry/package/dp_package.cxx
@@ -0,0 +1,1691 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include "dp_package.hrc"
+#include "dp_backend.h"
+#include "dp_ucb.h"
+#include "dp_interact.h"
+#include "dp_dependencies.hxx"
+#include "dp_platform.hxx"
+#include "dp_descriptioninfoset.hxx"
+#include "dp_identifier.hxx"
+#include "rtl/uri.hxx"
+#include "cppuhelper/exc_hlp.hxx"
+#include "cppuhelper/implbase1.hxx"
+#include "ucbhelper/content.hxx"
+#include "svl/inettype.hxx"
+#include "comphelper/anytostring.hxx"
+#include "comphelper/makesequence.hxx"
+#include "comphelper/sequence.hxx"
+#include "com/sun/star/lang/WrappedTargetException.hpp"
+#include "com/sun/star/lang/XServiceInfo.hpp"
+#include "com/sun/star/beans/UnknownPropertyException.hpp"
+#include "com/sun/star/graphic/XGraphic.hpp"
+#include "com/sun/star/graphic/XGraphicProvider.hpp"
+#include "com/sun/star/io/XOutputStream.hpp"
+#include "com/sun/star/io/XInputStream.hpp"
+#include "com/sun/star/task/InteractionClassification.hpp"
+#include "com/sun/star/task/XInteractionApprove.hpp"
+#include "com/sun/star/ucb/XInteractionReplaceExistingData.hpp"
+#include "com/sun/star/ucb/NameClashResolveRequest.hpp"
+#include "com/sun/star/ucb/XContentAccess.hpp"
+#include "com/sun/star/ucb/NameClash.hpp"
+#include "com/sun/star/ucb/UnsupportedCommandException.hpp"
+#include "com/sun/star/sdbc/XResultSet.hpp"
+#include "com/sun/star/sdbc/XRow.hpp"
+#include "com/sun/star/packages/manifest/XManifestReader.hpp"
+#include "com/sun/star/packages/manifest/XManifestWriter.hpp"
+#include "com/sun/star/deployment/DependencyException.hpp"
+#include "com/sun/star/deployment/LicenseException.hpp"
+#include "com/sun/star/deployment/PlatformException.hpp"
+#include "com/sun/star/deployment/Prerequisites.hpp"
+#include "com/sun/star/xml/dom/XDocumentBuilder.hpp"
+#include "com/sun/star/xml/xpath/XXPathAPI.hpp"
+#include "com/sun/star/deployment/XPackageManager.hpp"
+#include "boost/optional.hpp"
+#include <vector>
+#include <stdio.h>
+
+#include "dp_extbackenddb.hxx"
+using namespace ::dp_misc;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+
+namespace css = ::com::sun::star;
+
+using ::rtl::OUString;
+
+namespace dp_registry {
+namespace backend {
+namespace bundle {
+namespace {
+
+typedef cppu::ImplInheritanceHelper1<PackageRegistryBackend,
+ lang::XServiceInfo> ImplBaseT;
+
+//==============================================================================
+class BackendImpl : public ImplBaseT
+{
+ class PackageImpl : public ::dp_registry::backend::Package
+ {
+ BackendImpl * getMyBackend() const;
+ /** constains the old tooltip description for the Extension Manager GUI in OOo v.2.x
+ We keep it for backward compatibility.
+ */
+ OUString m_oldDescription;
+ OUString m_url_expanded;
+ const bool m_legacyBundle;
+ Sequence< Reference<deployment::XPackage> > m_bundle;
+ Sequence< Reference<deployment::XPackage> > * m_pBundle;
+
+ ExtensionBackendDb::Data m_dbData;
+
+ Reference<deployment::XPackage> bindBundleItem(
+ OUString const & url, OUString const & mediaType,
+ sal_Bool bRemoved, //that is, useing data base information
+ OUString const & identifier,
+ Reference<ucb::XCommandEnvironment> const & xCmdEnv,
+ bool notifyDetectionError = true );
+
+ typedef ::std::vector< Reference<deployment::XPackage> > t_packagevec;
+ void scanBundle(
+ t_packagevec & bundle,
+ ::rtl::Reference<AbortChannel> const & abortChannel,
+ Reference<ucb::XCommandEnvironment> const & xCmdEnv );
+ void scanLegacyBundle(
+ t_packagevec & bundle,
+ OUString const & url,
+ ::rtl::Reference<AbortChannel> const & abortChannel,
+ Reference<ucb::XCommandEnvironment> const & xCmdEnv,
+ bool skip_registration = false );
+ ::std::vector<Reference<deployment::XPackage> > getPackagesFromDb(
+ Reference<ucb::XCommandEnvironment> const & xCmdEnv);
+ bool checkPlatform(
+ Reference<ucb::XCommandEnvironment > const & environment);
+
+ bool checkDependencies(
+ Reference<ucb::XCommandEnvironment > const &
+ environment,
+ DescriptionInfoset const & description);
+ // throws css::uno::RuntimeException,
+ // css::deployment::DeploymentException
+
+ ::sal_Bool checkLicense(
+ Reference< ucb::XCommandEnvironment > const & xCmdEnv,
+ DescriptionInfoset const & description, bool bNoLicenseChecking)
+ throw (deployment::DeploymentException,
+ ucb::CommandFailedException,
+ ucb::CommandAbortedException,
+ RuntimeException);
+ // @throws DeploymentException
+ OUString getTextFromURL(
+ const Reference< ucb::XCommandEnvironment >& xCmdEnv,
+ const OUString& licenseUrl);
+
+ DescriptionInfoset getDescriptionInfoset();
+
+ // Package
+ virtual beans::Optional< beans::Ambiguous<sal_Bool> > isRegistered_(
+ ::osl::ResettableMutexGuard & guard,
+ ::rtl::Reference<AbortChannel> const & abortChannel,
+ Reference<ucb::XCommandEnvironment> const & xCmdEnv );
+ virtual void processPackage_(
+ ::osl::ResettableMutexGuard & guard,
+ bool registerPackage,
+ bool startup,
+ ::rtl::Reference<AbortChannel> const & abortChannel,
+ Reference<ucb::XCommandEnvironment> const & xCmdEnv );
+
+ virtual void SAL_CALL disposing();
+
+
+
+ public:
+ PackageImpl(
+ ::rtl::Reference<PackageRegistryBackend> const & myBackend,
+ OUString const & url,
+ OUString const & name,
+ Reference<deployment::XPackageTypeInfo> const & xPackageType,
+ bool legacyBundle,
+ bool bRemoved,
+ OUString const & identifier);
+
+ // XPackage
+ virtual sal_Bool SAL_CALL isBundle() throw (RuntimeException);
+
+ virtual Sequence< Reference<deployment::XPackage> > SAL_CALL getBundle(
+ Reference<task::XAbortChannel> const & xAbortChannel,
+ Reference<ucb::XCommandEnvironment> const & xCmdEnv )
+ throw (deployment::DeploymentException,
+ ucb::CommandFailedException,
+ ucb::CommandAbortedException,
+ lang::IllegalArgumentException, RuntimeException);
+ virtual OUString SAL_CALL getDescription()
+ throw (deployment::ExtensionRemovedException, RuntimeException);
+
+ virtual OUString SAL_CALL getLicenseText()
+ throw (deployment::ExtensionRemovedException, RuntimeException);
+
+ virtual void SAL_CALL exportTo(
+ OUString const & destFolderURL, OUString const & newTitle,
+ sal_Int32 nameClashAction,
+ Reference<ucb::XCommandEnvironment> const & xCmdEnv )
+ throw (deployment::ExtensionRemovedException,
+ ucb::CommandFailedException,
+ ucb::CommandAbortedException,
+ RuntimeException);
+
+ virtual ::sal_Int32 SAL_CALL checkPrerequisites(
+ const Reference< task::XAbortChannel >& xAbortChannel,
+ const Reference< ucb::XCommandEnvironment >& xCmdEnv,
+ ::sal_Bool noLicenseChecking)
+ throw (deployment::ExtensionRemovedException,
+ deployment::DeploymentException,
+ ucb::CommandFailedException,
+ ucb::CommandAbortedException,
+ RuntimeException);
+
+ virtual ::sal_Bool SAL_CALL checkDependencies(
+ const Reference< ucb::XCommandEnvironment >& xCmdEnv )
+ throw (deployment::DeploymentException,
+ deployment::ExtensionRemovedException,
+ ucb::CommandFailedException,
+ RuntimeException);
+
+ virtual beans::Optional<OUString> SAL_CALL getIdentifier()
+ throw (RuntimeException);
+
+ virtual OUString SAL_CALL getVersion()
+ throw (deployment::ExtensionRemovedException, RuntimeException);
+
+ virtual Sequence<OUString> SAL_CALL getUpdateInformationURLs()
+ throw (deployment::ExtensionRemovedException, RuntimeException);
+
+ virtual beans::StringPair SAL_CALL getPublisherInfo()
+ throw (deployment::ExtensionRemovedException, RuntimeException);
+
+ virtual OUString SAL_CALL getDisplayName()
+ throw (deployment::ExtensionRemovedException, RuntimeException);
+
+ virtual Reference< graphic::XGraphic > SAL_CALL
+ getIcon( ::sal_Bool bHighContrast )
+ throw (deployment::ExtensionRemovedException,
+ RuntimeException);
+ };
+ friend class PackageImpl;
+
+ Reference<deployment::XPackageRegistry> m_xRootRegistry;
+ const Reference<deployment::XPackageTypeInfo> m_xBundleTypeInfo;
+ const Reference<deployment::XPackageTypeInfo> m_xLegacyBundleTypeInfo;
+ Sequence< Reference<deployment::XPackageTypeInfo> > m_typeInfos;
+
+ std::auto_ptr<ExtensionBackendDb> m_backendDb;
+
+ void addDataToDb(OUString const & url, ExtensionBackendDb::Data const & data);
+ ExtensionBackendDb::Data readDataFromDb(OUString const & url);
+ void revokeEntryFromDb(OUString const & url);
+
+ // PackageRegistryBackend
+ virtual Reference<deployment::XPackage> bindPackage_(
+ OUString const & url, OUString const & mediaType,
+ sal_Bool bRemoved, OUString const & identifier,
+ Reference<ucb::XCommandEnvironment> const & xCmdEnv );
+
+ virtual void SAL_CALL disposing();
+
+public:
+ BackendImpl(
+ Sequence<Any> const & args,
+ Reference<XComponentContext> const & xComponentContext,
+ Reference<deployment::XPackageRegistry> const & xRootRegistry );
+
+ // XServiceInfo
+ virtual OUString SAL_CALL getImplementationName() throw (RuntimeException);
+ virtual sal_Bool SAL_CALL supportsService( OUString const& name )
+ throw (RuntimeException);
+ virtual Sequence<OUString> SAL_CALL getSupportedServiceNames()
+ throw (RuntimeException);
+
+ // XPackageRegistry
+ virtual Sequence< Reference<deployment::XPackageTypeInfo> > SAL_CALL
+ getSupportedPackageTypes() throw (RuntimeException);
+ virtual void SAL_CALL packageRemoved(OUString const & url, OUString const & mediaType)
+ throw (deployment::DeploymentException,
+ uno::RuntimeException);
+
+ using ImplBaseT::disposing;
+};
+
+//Used to find a XPackage with a particular URL
+class XPackage_eq : public std::unary_function<Reference<deployment::XPackage>, bool>
+{
+ OUString m_URL;
+public:
+ explicit XPackage_eq(const OUString & s) : m_URL(s) {}
+ bool operator() (const Reference<deployment::XPackage> & p) const
+ {
+ return m_URL.equals(p->getURL());
+ }
+};
+
+//______________________________________________________________________________
+BackendImpl::BackendImpl(
+ Sequence<Any> const & args,
+ Reference<XComponentContext> const & xComponentContext,
+ Reference<deployment::XPackageRegistry> const & xRootRegistry )
+ : ImplBaseT( args, xComponentContext ),
+ m_xRootRegistry( xRootRegistry ),
+ m_xBundleTypeInfo( new Package::TypeInfo(
+ OUSTR("application/vnd.sun.star.package-bundle"),
+ OUSTR("*.oxt;*.uno.pkg"),
+ getResourceString(RID_STR_PACKAGE_BUNDLE),
+ RID_IMG_DEF_PACKAGE_BUNDLE ) ),
+ m_xLegacyBundleTypeInfo( new Package::TypeInfo(
+ OUSTR("application/"
+ "vnd.sun.star.legacy-package-bundle"),
+ OUSTR("*.zip"),
+ m_xBundleTypeInfo->getShortDescription(),
+ RID_IMG_DEF_PACKAGE_BUNDLE ) ),
+ m_typeInfos(2)
+{
+ m_typeInfos[ 0 ] = m_xBundleTypeInfo;
+ m_typeInfos[ 1 ] = m_xLegacyBundleTypeInfo;
+
+ if (!transientMode())
+ {
+ OUString dbFile = makeURL(getCachePath(), getImplementationName());
+ dbFile = makeURL(dbFile, OUSTR("backenddb.xml"));
+ m_backendDb.reset(
+ new ExtensionBackendDb(getComponentContext(), dbFile));
+ }
+}
+
+//______________________________________________________________________________
+void BackendImpl::disposing()
+{
+ m_xRootRegistry.clear();
+ PackageRegistryBackend::disposing();
+}
+
+// XServiceInfo
+OUString BackendImpl::getImplementationName() throw (RuntimeException)
+{
+ return OUSTR("com.sun.star.comp.deployment.bundle.PackageRegistryBackend");
+}
+
+sal_Bool BackendImpl::supportsService( OUString const& name )
+ throw (RuntimeException)
+{
+ return getSupportedServiceNames()[0].equals(name);
+}
+
+Sequence<OUString> BackendImpl::getSupportedServiceNames()
+ throw (RuntimeException)
+{
+ return comphelper::makeSequence(
+ OUString(RTL_CONSTASCII_USTRINGPARAM(BACKEND_SERVICE_NAME)) );
+}
+
+// XPackageRegistry
+//______________________________________________________________________________
+Sequence< Reference<deployment::XPackageTypeInfo> >
+BackendImpl::getSupportedPackageTypes() throw (RuntimeException)
+{
+ return m_typeInfos;
+}
+
+void BackendImpl::packageRemoved(OUString const & url, OUString const & /*mediaType*/)
+ throw (deployment::DeploymentException,
+ uno::RuntimeException)
+{
+ //Notify the backend responsible for processing the different media
+ //types that this extension was removed.
+ ExtensionBackendDb::Data data = readDataFromDb(url);
+ for (ExtensionBackendDb::Data::ITC_ITEMS i = data.items.begin(); i != data.items.end(); i++)
+ {
+ m_xRootRegistry->packageRemoved(i->first, i->second);
+ }
+
+ if (m_backendDb.get())
+ m_backendDb->removeEntry(url);
+}
+
+
+// PackageRegistryBackend
+//______________________________________________________________________________
+Reference<deployment::XPackage> BackendImpl::bindPackage_(
+ OUString const & url, OUString const & mediaType_,
+ sal_Bool bRemoved, OUString const & identifier,
+ Reference<ucb::XCommandEnvironment> const & xCmdEnv )
+{
+ OUString mediaType( mediaType_ );
+ if (mediaType.getLength() == 0)
+ {
+ // detect media-type:
+ ::ucbhelper::Content ucbContent;
+ if (create_ucb_content( &ucbContent, url, xCmdEnv ))
+ {
+ if (ucbContent.isFolder())
+ {
+ //Every .oxt, uno.pkg file must contain a META-INF folder
+ ::ucbhelper::Content metaInfContent;
+ if (create_ucb_content(
+ &metaInfContent, makeURL( url, OUSTR("META-INF") ),
+ xCmdEnv, false /* no throw */ ))
+ {
+ mediaType = OUSTR("application/vnd.sun.star.package-bundle");
+ }
+ //No support of legacy bundles, because every folder could be one.
+ }
+ else
+ {
+ const OUString title( ucbContent.getPropertyValue(
+ StrTitle::get() ).get<OUString>() );
+ if (title.endsWithIgnoreAsciiCaseAsciiL(
+ RTL_CONSTASCII_STRINGPARAM(".oxt") ) ||
+ title.endsWithIgnoreAsciiCaseAsciiL(
+ RTL_CONSTASCII_STRINGPARAM(".uno.pkg") ))
+ mediaType = OUSTR("application/vnd.sun.star.package-bundle");
+ else if (title.endsWithIgnoreAsciiCaseAsciiL(
+ RTL_CONSTASCII_STRINGPARAM(".zip") ))
+ mediaType =
+ OUSTR("application/vnd.sun.star.legacy-package-bundle");
+ }
+ }
+ if (mediaType.getLength() == 0)
+ throw lang::IllegalArgumentException(
+ StrCannotDetectMediaType::get() + url,
+ static_cast<OWeakObject *>(this), static_cast<sal_Int16>(-1) );
+ }
+
+ String type, subType;
+ INetContentTypeParameterList params;
+ if (INetContentTypes::parse( mediaType, type, subType, &params ))
+ {
+ if (type.EqualsIgnoreCaseAscii("application"))
+ {
+
+ //In case a XPackage is created for a removed extension, we cannot
+ //obtain the name
+ OUString name;
+ if (!bRemoved)
+ {
+ ::ucbhelper::Content ucbContent( url, xCmdEnv );
+ name = ucbContent.getPropertyValue(
+ StrTitle::get() ).get<OUString>();
+ }
+ if (subType.EqualsIgnoreCaseAscii("vnd.sun.star.package-bundle")) {
+ return new PackageImpl(
+ this, url, name, m_xBundleTypeInfo, false, bRemoved,
+ identifier);
+ }
+ else if (subType.EqualsIgnoreCaseAscii(
+ "vnd.sun.star.legacy-package-bundle")) {
+ return new PackageImpl(
+ this, url, name, m_xLegacyBundleTypeInfo, true, bRemoved,
+ identifier);
+ }
+ }
+ }
+ throw lang::IllegalArgumentException(
+ StrUnsupportedMediaType::get() + mediaType,
+ static_cast<OWeakObject *>(this),
+ static_cast<sal_Int16>(-1) );
+}
+
+void BackendImpl::addDataToDb(
+ OUString const & url, ExtensionBackendDb::Data const & data)
+{
+ if (m_backendDb.get())
+ m_backendDb->addEntry(url, data);
+}
+
+ExtensionBackendDb::Data BackendImpl::readDataFromDb(
+ OUString const & url)
+{
+ ExtensionBackendDb::Data data;
+ if (m_backendDb.get())
+ data = m_backendDb->getEntry(url);
+ return data;
+}
+
+void BackendImpl::revokeEntryFromDb(OUString const & url)
+{
+ if (m_backendDb.get())
+ m_backendDb->revokeEntry(url);
+}
+
+
+
+BackendImpl::PackageImpl::PackageImpl(
+ ::rtl::Reference<PackageRegistryBackend> const & myBackend,
+ OUString const & url,
+ OUString const & name,
+ Reference<deployment::XPackageTypeInfo> const & xPackageType,
+ bool legacyBundle, bool bRemoved, OUString const & identifier)
+ : Package( myBackend, url, name, name /* display-name */,
+ xPackageType, bRemoved, identifier),
+ m_url_expanded( expandUnoRcUrl( url ) ),
+ m_legacyBundle( legacyBundle ),
+ m_pBundle( 0 )
+{
+ if (bRemoved)
+ m_dbData = getMyBackend()->readDataFromDb(url);
+}
+
+BackendImpl * BackendImpl::PackageImpl::getMyBackend() const
+{
+ BackendImpl * pBackend = static_cast<BackendImpl *>(m_myBackend.get());
+ if (NULL == pBackend)
+ {
+ //May throw a DisposedException
+ check();
+ //We should never get here...
+ throw RuntimeException(
+ OUSTR("Failed to get the BackendImpl"),
+ static_cast<OWeakObject*>(const_cast<PackageImpl *>(this)));
+ }
+ return pBackend;
+}
+//______________________________________________________________________________
+void BackendImpl::PackageImpl::disposing()
+{
+ sal_Int32 len = m_bundle.getLength();
+ Reference<deployment::XPackage> const * p = m_bundle.getConstArray();
+ for ( sal_Int32 pos = 0; pos < len; ++pos )
+ try_dispose( p[ pos ] );
+ m_bundle.realloc( 0 );
+
+ Package::disposing();
+}
+
+// Package
+//______________________________________________________________________________
+beans::Optional< beans::Ambiguous<sal_Bool> >
+BackendImpl::PackageImpl::isRegistered_(
+ ::osl::ResettableMutexGuard &,
+ ::rtl::Reference<AbortChannel> const & abortChannel,
+ Reference<ucb::XCommandEnvironment> const & xCmdEnv )
+{
+ //In case the object was created for a removed extension (m_bRemoved = true)
+ //but the extension is not registered, then bundle will be empty. Then
+ //the return value will be Optional<...>.IsPresent= false. Althoug this is
+ //not true, this does not matter. Then registerPackage or revokePackage
+ //would never be called for the items. But since the extension is removed
+ //and not registered anyway, this does not matter.
+ const Sequence< Reference<deployment::XPackage> > bundle(
+ getBundle( abortChannel.get(), xCmdEnv ) );
+
+ bool reg = false;
+ bool present = false;
+ bool ambig = false;
+ for ( sal_Int32 pos = bundle.getLength(); pos--; )
+ {
+ Reference<deployment::XPackage> const & xPackage = bundle[ pos ];
+ Reference<task::XAbortChannel> xSubAbortChannel(
+ xPackage->createAbortChannel() );
+ AbortChannel::Chain chain( abortChannel, xSubAbortChannel );
+ beans::Optional< beans::Ambiguous<sal_Bool> > option(
+ xPackage->isRegistered( xSubAbortChannel, xCmdEnv ) );
+
+ //present = true if at least one bundle item has this value.
+ //reg = true if all bundle items have an option value (option.IsPresent == 1)
+ //and all have value of true (option.Value.Value == true)
+ //If not, then the bundle has the status of not registered and ambiguous.
+ if (option.IsPresent)
+ {
+ beans::Ambiguous<sal_Bool> const & status = option.Value;
+ if (present)
+ {
+ //we never come here in the first iteration
+ if (reg != (status.Value != sal_False)) {
+
+ ambig = true;
+ reg = false;
+ break;
+ }
+ }
+ else
+ {
+ //we always come here in the first iteration
+ reg = status.Value;
+ present = true;
+ }
+ }
+ }
+ return beans::Optional< beans::Ambiguous<sal_Bool> >(
+ present, beans::Ambiguous<sal_Bool>(reg, ambig) );
+}
+
+OUString BackendImpl::PackageImpl::getTextFromURL(
+ const css::uno::Reference< css::ucb::XCommandEnvironment >& xCmdEnv,
+ const OUString& licenseUrl)
+{
+ try
+ {
+ ::ucbhelper::Content descContent(licenseUrl, xCmdEnv);
+ ::rtl::ByteSequence seq = dp_misc::readFile(descContent);
+ return OUString( reinterpret_cast<sal_Char const *>(
+ seq.getConstArray()), seq.getLength(), RTL_TEXTENCODING_UTF8);
+ }
+ catch (css::uno::Exception&)
+ {
+ Any exc( ::cppu::getCaughtException() );
+ throw css::deployment::DeploymentException(
+ OUSTR("Could not read file ") + licenseUrl, 0, exc);
+ }
+
+}
+
+DescriptionInfoset BackendImpl::PackageImpl::getDescriptionInfoset()
+{
+ return dp_misc::getDescriptionInfoset(m_url_expanded);
+}
+
+bool BackendImpl::PackageImpl::checkPlatform(
+ css::uno::Reference< css::ucb::XCommandEnvironment > const & environment)
+{
+ bool ret = false;
+ DescriptionInfoset info(getDescriptionInfoset());
+ Sequence<OUString> platforms(info.getSupportedPlaforms());
+ if (hasValidPlatform(platforms))
+ {
+ ret = true;
+ }
+ else
+ {
+ ret = false;
+ rtl::OUString msg(
+ RTL_CONSTASCII_USTRINGPARAM("unsupported platform"));
+ Any e(
+ css::deployment::PlatformException(
+ msg, static_cast<OWeakObject *>(this), this));
+ if (!interactContinuation(
+ e, cppu::UnoType< css::task::XInteractionApprove >::get(),
+ environment, NULL, NULL))
+ {
+ throw css::deployment::DeploymentException(
+ msg, static_cast<OWeakObject *>(this), e);
+ }
+ }
+ return ret;
+}
+
+
+bool BackendImpl::PackageImpl::checkDependencies(
+ css::uno::Reference< css::ucb::XCommandEnvironment > const & environment,
+ DescriptionInfoset const & description)
+{
+ css::uno::Sequence< css::uno::Reference< css::xml::dom::XElement > >
+ unsatisfied(dp_misc::Dependencies::check(description));
+
+ if (unsatisfied.getLength() == 0) {
+ return true;
+ } else {
+ rtl::OUString msg(
+ RTL_CONSTASCII_USTRINGPARAM("unsatisfied dependencies"));
+ Any e(
+ css::deployment::DependencyException(
+ msg, static_cast<OWeakObject *>(this), unsatisfied));
+ if (!interactContinuation(
+ e, cppu::UnoType< css::task::XInteractionApprove >::get(),
+ environment, NULL, NULL))
+ {
+ throw css::deployment::DeploymentException(
+ msg, static_cast<OWeakObject *>(this), e);
+ }
+ return false;
+ }
+}
+
+::sal_Bool BackendImpl::PackageImpl::checkLicense(
+ css::uno::Reference< css::ucb::XCommandEnvironment > const & xCmdEnv,
+ DescriptionInfoset const & info, bool alreadyInstalled)
+ throw (css::deployment::DeploymentException,
+ css::ucb::CommandFailedException,
+ css::ucb::CommandAbortedException,
+ css::uno::RuntimeException)
+{
+ try
+ {
+ ::boost::optional<SimpleLicenseAttributes> simplLicAttr
+ = info.getSimpleLicenseAttributes();
+ if (! simplLicAttr)
+ return true;
+ OUString sLic = info.getLocalizedLicenseURL();
+ //If we do not get a localized licence then there is an error in the description.xml
+ //This should be handled by using a validating parser. Therefore we assume that no
+ //license is available.
+ if (sLic.getLength() == 0)
+ throw css::deployment::DeploymentException(
+ OUSTR("Could not obtain path to license. Possible error in description.xml"), 0, Any());
+ OUString sHref = m_url_expanded + OUSTR("/") + sLic;
+ OUString sLicense = getTextFromURL(xCmdEnv, sHref);
+ ////determine who has to agree to the license
+ //check correct value for attribute
+ if ( ! (simplLicAttr->acceptBy.equals(OUSTR("user")) || simplLicAttr->acceptBy.equals(OUSTR("admin"))))
+ throw css::deployment::DeploymentException(
+ OUSTR("Could not obtain attribute simple-lincense@accept-by or it has no valid value"), 0, Any());
+
+
+ //Only use interaction if there is no version of this extension already installed
+ //and the suppress-on-update flag is not set for the new extension
+ // alreadyInstalled | bSuppressOnUpdate | show license
+ //----------------------------------------
+ // 0 | 0 | 1
+ // 0 | 1 | 1
+ // 1 | 0 | 1
+ // 1 | 1 | 0
+
+ if ( !(alreadyInstalled && simplLicAttr->suppressOnUpdate))
+ {
+ css::deployment::LicenseException licExc(
+ OUString(), 0, getDisplayName(), sLicense,
+ simplLicAttr->acceptBy);
+ bool approve = false;
+ bool abort = false;
+ if (! interactContinuation(
+ Any(licExc), task::XInteractionApprove::static_type(), xCmdEnv, &approve, &abort ))
+ throw css::deployment::DeploymentException(
+ OUSTR("Could not interact with user."), 0, Any());
+
+ if (approve == true)
+ return true;
+ else
+ return false;
+ }
+ return true;
+ } catch (css::ucb::CommandFailedException&) {
+ throw;
+ } catch (css::ucb::CommandAbortedException&) {
+ throw;
+ } catch (css::deployment::DeploymentException&) {
+ throw;
+ } catch (css::uno::RuntimeException&) {
+ throw;
+ } catch (css::uno::Exception&) {
+ Any anyExc = cppu::getCaughtException();
+ throw css::deployment::DeploymentException(OUSTR("Unexpected exception"), 0, anyExc);
+ }
+}
+
+::sal_Int32 BackendImpl::PackageImpl::checkPrerequisites(
+ const css::uno::Reference< css::task::XAbortChannel >&,
+ const css::uno::Reference< css::ucb::XCommandEnvironment >& xCmdEnv,
+ sal_Bool alreadyInstalled)
+ throw (css::deployment::DeploymentException,
+ css::deployment::ExtensionRemovedException,
+ css::ucb::CommandFailedException,
+ css::ucb::CommandAbortedException,
+ css::uno::RuntimeException)
+{
+ if (m_bRemoved)
+ throw deployment::ExtensionRemovedException();
+ DescriptionInfoset info = getDescriptionInfoset();
+ if (!info.hasDescription())
+ return 0;
+
+ //always return LICENSE as long as the user did not accept the license
+ //so that XExtensonManager::checkPrerequisitesAndEnable will again
+ //check the license
+ if (!checkPlatform(xCmdEnv))
+ return deployment::Prerequisites::PLATFORM |
+ deployment::Prerequisites::LICENSE;
+ else if(!checkDependencies(xCmdEnv, info))
+ return deployment::Prerequisites::DEPENDENCIES |
+ deployment::Prerequisites::LICENSE;
+ else if(!checkLicense(xCmdEnv, info, alreadyInstalled))
+ return deployment::Prerequisites::LICENSE;
+ else
+ return 0;
+}
+
+::sal_Bool BackendImpl::PackageImpl::checkDependencies(
+ const css::uno::Reference< css::ucb::XCommandEnvironment >& xCmdEnv )
+ throw (deployment::DeploymentException,
+ deployment::ExtensionRemovedException,
+ ucb::CommandFailedException,
+ RuntimeException)
+{
+ if (m_bRemoved)
+ throw deployment::ExtensionRemovedException();
+ DescriptionInfoset info = getDescriptionInfoset();
+ if (!info.hasDescription())
+ return sal_True;
+
+ return checkDependencies(xCmdEnv, info);
+}
+
+beans::Optional<OUString> BackendImpl::PackageImpl::getIdentifier()
+ throw (RuntimeException)
+{
+ OUString identifier;
+ if (m_bRemoved)
+ identifier = m_identifier;
+ else
+ identifier = dp_misc::generateIdentifier(
+ getDescriptionInfoset().getIdentifier(), m_name);
+
+ return beans::Optional<OUString>(
+ true, identifier);
+}
+
+OUString BackendImpl::PackageImpl::getVersion()
+ throw (deployment::ExtensionRemovedException, RuntimeException)
+{
+ if (m_bRemoved)
+ throw deployment::ExtensionRemovedException();
+ return getDescriptionInfoset().getVersion();
+}
+
+Sequence<OUString> BackendImpl::PackageImpl::getUpdateInformationURLs()
+ throw (deployment::ExtensionRemovedException, RuntimeException)
+{
+ if (m_bRemoved)
+ throw deployment::ExtensionRemovedException();
+ return getDescriptionInfoset().getUpdateInformationUrls();
+}
+
+beans::StringPair BackendImpl::PackageImpl::getPublisherInfo()
+ throw (deployment::ExtensionRemovedException, RuntimeException)
+{
+ if (m_bRemoved)
+ throw deployment::ExtensionRemovedException();
+ ::std::pair< OUString, OUString > aInfo = getDescriptionInfoset().getLocalizedPublisherNameAndURL();
+ beans::StringPair aStrPair( aInfo.first, aInfo.second );
+ return aStrPair;
+}
+
+//______________________________________________________________________________
+uno::Reference< graphic::XGraphic > BackendImpl::PackageImpl::getIcon( sal_Bool bHighContrast )
+ throw (deployment::ExtensionRemovedException, RuntimeException )
+{
+ if (m_bRemoved)
+ throw deployment::ExtensionRemovedException();
+
+ uno::Reference< graphic::XGraphic > xGraphic;
+
+ OUString aIconURL = getDescriptionInfoset().getIconURL( bHighContrast );
+ if ( aIconURL.getLength() )
+ {
+ OUString aFullIconURL = m_url_expanded + OUSTR("/") + aIconURL;
+
+ uno::Reference< XComponentContext > xContext( getMyBackend()->getComponentContext() );
+ uno::Reference< graphic::XGraphicProvider > xGraphProvider(
+ xContext->getServiceManager()->createInstanceWithContext( OUSTR( "com.sun.star.graphic.GraphicProvider" ), xContext ),
+ uno::UNO_QUERY );
+
+ if ( xGraphProvider.is() )
+ {
+ uno::Sequence< beans::PropertyValue > aMediaProps( 1 );
+ aMediaProps[0].Name = OUSTR( "URL" );
+ aMediaProps[0].Value <<= aFullIconURL;
+
+ xGraphic = xGraphProvider->queryGraphic( aMediaProps );
+ }
+ }
+
+ return xGraphic;
+}
+
+//______________________________________________________________________________
+void BackendImpl::PackageImpl::processPackage_(
+ ::osl::ResettableMutexGuard &,
+ bool doRegisterPackage,
+ bool startup,
+ ::rtl::Reference<AbortChannel> const & abortChannel,
+ Reference<ucb::XCommandEnvironment> const & xCmdEnv )
+{
+ const Sequence< Reference<deployment::XPackage> > bundle(
+ getBundle( abortChannel.get(), xCmdEnv ) );
+
+ if (doRegisterPackage)
+ {
+ ExtensionBackendDb::Data data;
+ const sal_Int32 len = bundle.getLength();
+ for ( sal_Int32 pos = 0; pos < len; ++pos )
+ {
+ checkAborted(abortChannel);
+ Reference<deployment::XPackage> const & xPackage = bundle[ pos ];
+ Reference<task::XAbortChannel> xSubAbortChannel(
+ xPackage->createAbortChannel() );
+ AbortChannel::Chain chain( abortChannel, xSubAbortChannel );
+ try {
+ xPackage->registerPackage( startup, xSubAbortChannel, xCmdEnv );
+ }
+ catch (Exception &)
+ {
+ //We even try a rollback if the user cancelled the action (CommandAbortedException)
+ //in order to prevent invalid database entries.
+ Any exc( ::cppu::getCaughtException() );
+ // try to handle exception, notify:
+ bool approve = false, abort = false;
+ if (! interactContinuation(
+ Any( lang::WrappedTargetException(
+ OUSTR("bundle item registration error!"),
+ static_cast<OWeakObject *>(this), exc ) ),
+ task::XInteractionApprove::static_type(), xCmdEnv,
+ &approve, &abort )) {
+ OSL_ASSERT( !approve && !abort );
+ if (m_legacyBundle) // default for legacy packages: ignore
+ continue;
+ // no selection at all, so rethrow;
+ // no C++ rethrow after getCaughtException(),
+ // see cppuhelper/exc_hlp.hxx:
+ ::cppu::throwException(exc);
+ }
+ if (approve && !abort) // ignore error, just continue
+ continue;
+
+ {
+ ProgressLevel progress(
+ xCmdEnv, OUSTR("rollback...") );
+ // try rollback
+ for ( ; pos--; )
+ {
+ try {
+ bundle[ pos ]->revokePackage(
+ xSubAbortChannel, xCmdEnv );
+ }
+ catch (Exception &)
+ {
+ OSL_FAIL( ::rtl::OUStringToOString(
+ ::comphelper::anyToString(
+ ::cppu::getCaughtException() ),
+ RTL_TEXTENCODING_UTF8 ).getStr() );
+ // ignore any errors of rollback
+ }
+ }
+ progress.update( OUSTR("rollback finished.") );
+ }
+
+ deployment::DeploymentException dpExc;
+ if (exc >>= dpExc) {
+ throw ucb::CommandFailedException(
+ dpExc.Message, dpExc.Context, dpExc.Cause );
+ }
+ else {
+ // rethrow CommandFailedException
+ ::cppu::throwException(exc);
+ }
+ }
+ data.items.push_back(
+ ::std::make_pair(xPackage->getURL(),
+ xPackage->getPackageType()->getMediaType()));
+ }
+ getMyBackend()->addDataToDb(getURL(), data);
+ }
+ else
+ {
+ // revoke in reverse order:
+ for ( sal_Int32 pos = bundle.getLength(); pos--; )
+ {
+ checkAborted(abortChannel);
+ Reference<deployment::XPackage> const & xPackage = bundle[ pos ];
+ Reference<task::XAbortChannel> xSubAbortChannel(
+ xPackage->createAbortChannel() );
+ AbortChannel::Chain chain( abortChannel, xSubAbortChannel );
+ try {
+ bundle[ pos ]->revokePackage( xSubAbortChannel, xCmdEnv );
+ }
+ catch (RuntimeException &) {
+ throw;
+ }
+ catch (ucb::CommandAbortedException &) {
+ throw;
+ }
+ catch (Exception &) {
+ // CommandFailedException, DeploymentException:
+ Any exc( ::cppu::getCaughtException() );
+ // try to handle exception, notify:
+ bool approve = false, abort = false;
+ if (! interactContinuation(
+ Any( lang::WrappedTargetException(
+ OUSTR("bundle item revocation error!"),
+ static_cast<OWeakObject *>(this), exc ) ),
+ task::XInteractionApprove::static_type(), xCmdEnv,
+ &approve, &abort )) {
+ OSL_ASSERT( !approve && !abort );
+ if (m_legacyBundle) // default for legacy packages: ignore
+ continue;
+ // no selection at all, so rethrow
+ // no C++ rethrow after getCaughtException(),
+ // see cppuhelper/exc_hlp.hxx:
+ ::cppu::throwException(exc);
+ }
+ // ignore errors when revoking, although abort may have been
+ // selected
+ }
+ }
+ getMyBackend()->revokeEntryFromDb(getURL());
+ }
+}
+
+//______________________________________________________________________________
+OUString BackendImpl::PackageImpl::getDescription()
+ throw (deployment::ExtensionRemovedException, RuntimeException)
+{
+ if (m_bRemoved)
+ throw deployment::ExtensionRemovedException();
+
+ const OUString sRelativeURL(getDescriptionInfoset().getLocalizedDescriptionURL());
+ OUString sDescription;
+ if (sRelativeURL.getLength())
+ {
+ OUString sURL = m_url_expanded + OUSTR("/") + sRelativeURL;
+
+ try
+ {
+ sDescription = getTextFromURL( css::uno::Reference< css::ucb::XCommandEnvironment >(), sURL );
+ }
+ catch ( css::deployment::DeploymentException& )
+ {
+ OSL_FAIL( ::rtl::OUStringToOString( ::comphelper::anyToString( ::cppu::getCaughtException() ), RTL_TEXTENCODING_UTF8 ).getStr() );
+ }
+ }
+
+ if (sDescription.getLength())
+ return sDescription;
+ return m_oldDescription;
+}
+
+//______________________________________________________________________________
+OUString BackendImpl::PackageImpl::getLicenseText()
+ throw (deployment::ExtensionRemovedException, RuntimeException)
+{
+ if (m_bRemoved)
+ throw deployment::ExtensionRemovedException();
+
+ OUString sLicense;
+ DescriptionInfoset aInfo = getDescriptionInfoset();
+
+ ::boost::optional< SimpleLicenseAttributes > aSimplLicAttr = aInfo.getSimpleLicenseAttributes();
+ if ( aSimplLicAttr )
+ {
+ OUString aLicenseURL = aInfo.getLocalizedLicenseURL();
+
+ if ( aLicenseURL.getLength() )
+ {
+ OUString aFullURL = m_url_expanded + OUSTR("/") + aLicenseURL;
+ sLicense = getTextFromURL( Reference< ucb::XCommandEnvironment >(), aFullURL);
+ }
+ }
+
+ return sLicense;
+}
+
+//______________________________________________________________________________
+void BackendImpl::PackageImpl::exportTo(
+ OUString const & destFolderURL, OUString const & newTitle,
+ sal_Int32 nameClashAction, Reference<ucb::XCommandEnvironment> const & xCmdEnv )
+ throw (ucb::CommandFailedException,
+ deployment::ExtensionRemovedException,
+ ucb::CommandAbortedException, RuntimeException)
+{
+ if (m_bRemoved)
+ throw deployment::ExtensionRemovedException();
+
+ ::ucbhelper::Content sourceContent( m_url_expanded, xCmdEnv );
+ OUString title(newTitle);
+ if (title.getLength() == 0)
+ sourceContent.getPropertyValue( StrTitle::get() ) >>= title;
+ OUString destURL( makeURL( destFolderURL, ::rtl::Uri::encode(
+ title, rtl_UriCharClassPchar,
+ rtl_UriEncodeIgnoreEscapes,
+ RTL_TEXTENCODING_UTF8 ) ) );
+
+ if (nameClashAction == ucb::NameClash::ASK)
+ {
+ if (create_ucb_content(
+ 0, destURL, xCmdEnv, false /* no throw */ )) {
+ bool replace = false, abort = false;
+ if (! interactContinuation(
+ Any( ucb::NameClashResolveRequest(
+ OUSTR("file already exists: ") + title,
+ static_cast<OWeakObject *>(this),
+ task::InteractionClassification_QUERY,
+ destFolderURL, title, OUString() ) ),
+ ucb::XInteractionReplaceExistingData::static_type(), xCmdEnv,
+ &replace, &abort ) || !replace) {
+ return;
+ }
+ }
+ }
+ else if (nameClashAction != ucb::NameClash::OVERWRITE) {
+ throw ucb::CommandFailedException(
+ OUSTR("unsupported nameClashAction!"),
+ static_cast<OWeakObject *>(this), Any() );
+ }
+ erase_path( destURL, xCmdEnv );
+
+ ::rtl::OUStringBuffer buf;
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("vnd.sun.star.zip://") );
+ buf.append( ::rtl::Uri::encode( destURL,
+ rtl_UriCharClassRegName,
+ rtl_UriEncodeIgnoreEscapes,
+ RTL_TEXTENCODING_UTF8 ) );
+ buf.append( static_cast<sal_Unicode>('/') );
+ OUString destFolder( buf.makeStringAndClear() );
+
+ ::ucbhelper::Content destFolderContent( destFolder, xCmdEnv );
+ {
+ // transfer every item of folder into zip:
+ Reference<sdbc::XResultSet> xResultSet(
+ sourceContent.createCursor(
+ Sequence<OUString>(),
+ ::ucbhelper::INCLUDE_FOLDERS_AND_DOCUMENTS ) );
+ ProgressLevel progress( xCmdEnv, OUString() );
+ while (xResultSet->next())
+ {
+ ::ucbhelper::Content subContent(
+ Reference<ucb::XContentAccess>(
+ xResultSet, UNO_QUERY_THROW )->queryContent(), xCmdEnv );
+ if (! destFolderContent.transferContent(
+ subContent, ::ucbhelper::InsertOperation_COPY,
+ OUString(), ucb::NameClash::OVERWRITE ))
+ throw RuntimeException( OUSTR("UCB transferContent() failed!"),
+ static_cast<OWeakObject *>(this) );
+ progress.update( Any() ); // animating progress bar
+ }
+ }
+
+ // assure META-INF folder:
+ ::ucbhelper::Content metainfFolderContent;
+ create_folder( &metainfFolderContent,
+ makeURL( destFolderContent.getURL(), OUSTR("META-INF") ),
+ xCmdEnv );
+
+ if (m_legacyBundle)
+ {
+ // easy to migrate legacy bundles to new format:
+ // just export them once using a .oxt name!
+ // set detected media-types of any bundle item:
+
+ // collect all manifest entries:
+ Sequence< Reference<deployment::XPackage> > bundle;
+ try {
+ bundle = getBundle( Reference<task::XAbortChannel>(), xCmdEnv );
+ }
+ // xxx todo: think about exception specs:
+ catch (deployment::DeploymentException &) {
+ OSL_FAIL( ::rtl::OUStringToOString(
+ ::comphelper::anyToString(
+ ::cppu::getCaughtException() ),
+ RTL_TEXTENCODING_UTF8 ).getStr() );
+ }
+ catch (lang::IllegalArgumentException & exc) {
+ (void) exc;
+ OSL_FAIL( ::rtl::OUStringToOString(
+ exc.Message, RTL_TEXTENCODING_UTF8 ).getStr() );
+ }
+
+ ::std::vector< Sequence<beans::PropertyValue> > manifest;
+ manifest.reserve( bundle.getLength() );
+ sal_Int32 baseURLlen = m_url_expanded.getLength();
+ Reference<deployment::XPackage> const *pbundle = bundle.getConstArray();
+ const OUString strMediaType = OUSTR("MediaType");
+ const OUString strFullPath = OUSTR("FullPath");
+ const OUString strIsFolder = OUSTR("IsFolder");
+ for ( sal_Int32 pos = bundle.getLength(); pos--; )
+ {
+ Reference<deployment::XPackage> const & xPackage = pbundle[ pos ];
+ OUString url_( expandUnoRcUrl( xPackage->getURL() ) );
+ OSL_ASSERT( url_.getLength() >= baseURLlen );
+ OUString fullPath;
+ if (url_.getLength() > baseURLlen)
+ fullPath = url_.copy( baseURLlen + 1 );
+ ::ucbhelper::Content ucbContent( url_, xCmdEnv );
+ if (ucbContent.getPropertyValue(strIsFolder).get<bool>())
+ fullPath += OUSTR("/");
+ Sequence<beans::PropertyValue> attribs( 2 );
+ beans::PropertyValue * pattribs = attribs.getArray();
+ pattribs[ 0 ].Name = strFullPath;
+ pattribs[ 0 ].Value <<= fullPath;
+ pattribs[ 1 ].Name = strMediaType;
+ const Reference<deployment::XPackageTypeInfo> xPackageType(
+ xPackage->getPackageType() );
+ OUString mediaType;
+ OSL_ASSERT( xPackageType.is() );
+ if (xPackageType.is())
+ mediaType = xPackageType->getMediaType();
+ else
+ mediaType = OUSTR("unknown");
+ pattribs[ 1 ].Value <<= mediaType;
+ manifest.push_back( attribs );
+ }
+
+ // write into pipe:
+ Reference<XComponentContext> xContext(
+ getMyBackend()->getComponentContext() );
+ Reference<packages::manifest::XManifestWriter> xManifestWriter(
+ xContext->getServiceManager()->createInstanceWithContext(
+ OUSTR("com.sun.star.packages.manifest.ManifestWriter"),
+ xContext ), UNO_QUERY_THROW );
+ Reference<io::XOutputStream> xPipe(
+ xContext->getServiceManager()->createInstanceWithContext(
+ OUSTR("com.sun.star.io.Pipe"), xContext ), UNO_QUERY_THROW );
+ xManifestWriter->writeManifestSequence(
+ xPipe, comphelper::containerToSequence(manifest) );
+
+ // write buffered pipe data to content:
+ ::ucbhelper::Content manifestContent(
+ makeURL( metainfFolderContent.getURL(), OUSTR("manifest.xml") ),
+ xCmdEnv );
+ manifestContent.writeStream(
+ Reference<io::XInputStream>( xPipe, UNO_QUERY_THROW ),
+ true /* replace existing */ );
+ }
+ else
+ {
+ // overwrite manifest.xml:
+ ::ucbhelper::Content manifestContent;
+ if ( ! create_ucb_content(
+ &manifestContent,
+ makeURL( m_url_expanded, OUSTR("META-INF/manifest.xml") ),
+ xCmdEnv, false ) )
+ {
+ OSL_FAIL( "### missing META-INF/manifest.xml file!" );
+ return;
+ }
+
+ if (! metainfFolderContent.transferContent(
+ manifestContent, ::ucbhelper::InsertOperation_COPY,
+ OUString(), ucb::NameClash::OVERWRITE ))
+ throw RuntimeException( OUSTR("UCB transferContent() failed!"),
+ static_cast<OWeakObject *>(this) );
+ }
+
+ // xxx todo: maybe obsolete in the future
+ try {
+ destFolderContent.executeCommand( OUSTR("flush"), Any() );
+ }
+ catch (ucb::UnsupportedCommandException &) {
+ }
+}
+
+//______________________________________________________________________________
+sal_Bool BackendImpl::PackageImpl::isBundle() throw (RuntimeException)
+{
+ return true;
+}
+
+//______________________________________________________________________________
+Sequence< Reference<deployment::XPackage> > BackendImpl::PackageImpl::getBundle(
+ Reference<task::XAbortChannel> const & xAbortChannel,
+ Reference<ucb::XCommandEnvironment> const & xCmdEnv )
+ throw (deployment::DeploymentException,
+ ucb::CommandFailedException, ucb::CommandAbortedException,
+ lang::IllegalArgumentException, RuntimeException)
+{
+ Sequence< Reference<deployment::XPackage> > * pBundle = m_pBundle;
+ if (pBundle == 0)
+ {
+ t_packagevec bundle;
+ if (m_bRemoved)
+ {
+ bundle = getPackagesFromDb(xCmdEnv);
+ }
+ else
+ {
+ try {
+ if (m_legacyBundle)
+ {
+ // .zip legacy packages allow script.xlb, dialog.xlb in bundle
+ // root folder:
+ OUString mediaType;
+ // probe for script.xlb:
+ if (create_ucb_content(
+ 0, makeURL( m_url_expanded, OUSTR("script.xlb") ),
+ xCmdEnv, false /* no throw */ )) {
+ mediaType = OUSTR("application/vnd.sun.star.basic-library");
+ }
+ // probe for dialog.xlb:
+ else if (create_ucb_content(
+ 0, makeURL( m_url_expanded, OUSTR("dialog.xlb") ),
+ xCmdEnv, false /* no throw */ ))
+ mediaType = OUSTR("application/vnd.sun.star."
+ "dialog-library");
+
+ if (mediaType.getLength() > 0) {
+ const Reference<deployment::XPackage> xPackage(
+ bindBundleItem( getURL(), mediaType, false, OUString(),
+ xCmdEnv ) );
+ if (xPackage.is())
+ bundle.push_back( xPackage );
+ // continue scanning:
+ }
+ scanLegacyBundle( bundle, getURL(),
+ AbortChannel::get(xAbortChannel), xCmdEnv );
+ }
+ else
+ {
+ // .oxt:
+ scanBundle( bundle, AbortChannel::get(xAbortChannel), xCmdEnv );
+ }
+
+ }
+ catch (RuntimeException &) {
+ throw;
+ }
+ catch (ucb::CommandFailedException &) {
+ throw;
+ }
+ catch (ucb::CommandAbortedException &) {
+ throw;
+ }
+ catch (deployment::DeploymentException &) {
+ throw;
+ }
+ catch (Exception &) {
+ Any exc( ::cppu::getCaughtException() );
+ throw deployment::DeploymentException(
+ OUSTR("error scanning bundle: ") + getURL(),
+ static_cast<OWeakObject *>(this), exc );
+ }
+ }
+
+ // sort: schema before config data, typelibs before components:
+ Sequence< Reference<deployment::XPackage> > ret( bundle.size() );
+ Reference<deployment::XPackage> * pret = ret.getArray();
+ sal_Int32 lower_end = 0;
+ sal_Int32 upper_end = ret.getLength();
+ t_packagevec::const_iterator iPos( bundle.begin() );
+ t_packagevec::const_iterator const iEnd( bundle.end() );
+ for ( ; iPos != iEnd; ++iPos )
+ {
+ const Reference<deployment::XPackageTypeInfo> xPackageType(
+ (*iPos)->getPackageType() );
+ OSL_ASSERT( xPackageType.is() );
+ if (xPackageType.is()) {
+ const OUString mediaType( xPackageType->getMediaType() );
+ String type, subType;
+ INetContentTypeParameterList params;
+ if (INetContentTypes::parse(
+ mediaType, type, subType, &params ) &&
+ type.EqualsIgnoreCaseAscii("application") &&
+ (subType.EqualsIgnoreCaseAscii(
+ "vnd.sun.star.uno-component") ||
+ subType.EqualsIgnoreCaseAscii(
+ "vnd.sun.star.configuration-data")))
+ {
+ --upper_end;
+ pret[ upper_end ] = *iPos;
+ continue;
+ }
+ }
+ pret[ lower_end ] = *iPos;
+ ++lower_end;
+ }
+ OSL_ASSERT( lower_end == upper_end );
+
+ const ::osl::MutexGuard guard( getMutex() );
+ pBundle = m_pBundle;
+ if (pBundle == 0) {
+ m_bundle = ret;
+ pBundle = &m_bundle;
+ OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
+ m_pBundle = pBundle;
+ }
+ }
+ else {
+ OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
+ }
+ return *pBundle;
+}
+
+inline bool isBundle_( OUString const & mediaType )
+{
+ // xxx todo: additional parsing?
+ return mediaType.getLength() > 0 &&
+ (mediaType.matchIgnoreAsciiCaseAsciiL(
+ RTL_CONSTASCII_STRINGPARAM(
+ "application/vnd.sun.star.package-bundle") ) ||
+ mediaType.matchIgnoreAsciiCaseAsciiL(
+ RTL_CONSTASCII_STRINGPARAM(
+ "application/vnd.sun.star.legacy-package-bundle") ));
+}
+
+//______________________________________________________________________________
+Reference<deployment::XPackage> BackendImpl::PackageImpl::bindBundleItem(
+ OUString const & url, OUString const & mediaType,
+ sal_Bool bRemoved, OUString const & identifier,
+ Reference<ucb::XCommandEnvironment> const & xCmdEnv,
+ bool notifyDetectionError )
+{
+ // ignore any nested bundles:
+ if (isBundle_(mediaType))
+ return Reference<deployment::XPackage>();
+
+ Reference<deployment::XPackage>xPackage;
+ try {
+ xPackage.set( getMyBackend()->m_xRootRegistry->bindPackage(
+ url, mediaType, bRemoved, identifier, xCmdEnv ) );
+ OSL_ASSERT( xPackage.is() );
+ }
+ catch (RuntimeException &) {
+ throw;
+ }
+ catch (ucb::CommandFailedException &) {
+ // ignore already handled error
+ }
+ catch (Exception &) {
+ const Any exc( ::cppu::getCaughtException() );
+ if (notifyDetectionError ||
+ !exc.isExtractableTo(
+ ::getCppuType( reinterpret_cast<
+ lang::IllegalArgumentException const *>(0) ) ))
+ {
+ interactContinuation(
+ Any( lang::WrappedTargetException(
+ OUSTR("bundle item error!"),
+ static_cast<OWeakObject *>(this), exc ) ),
+ task::XInteractionApprove::static_type(), xCmdEnv, 0, 0 );
+ }
+ }
+
+ if (xPackage.is()) {
+ const Reference<deployment::XPackageTypeInfo> xPackageType(
+ xPackage->getPackageType() );
+ OSL_ASSERT( xPackageType.is() );
+ // ignore any nested bundles:
+ if (xPackageType.is() && isBundle_( xPackageType->getMediaType() ))
+ xPackage.clear();
+ }
+ return xPackage;
+}
+
+//______________________________________________________________________________
+void BackendImpl::PackageImpl::scanBundle(
+ t_packagevec & bundle,
+ ::rtl::Reference<AbortChannel> const & abortChannel,
+ Reference<ucb::XCommandEnvironment> const & xCmdEnv )
+{
+ OSL_ASSERT( !m_legacyBundle );
+
+ ::ucbhelper::Content manifestContent;
+ if (! create_ucb_content(
+ &manifestContent,
+ makeURL( m_url_expanded, OUSTR("META-INF/manifest.xml") ),
+ xCmdEnv, false /* no throw */ ))
+ {
+ OSL_FAIL( "### missing META-INF/manifest.xml file!" );
+ return;
+ }
+
+
+ const lang::Locale officeLocale = getOfficeLocale();
+ OUString descrFile;
+ lang::Locale descrFileLocale;
+
+ const Reference<XComponentContext> xContext(
+ getMyBackend()->getComponentContext() );
+ Reference<packages::manifest::XManifestReader> xManifestReader(
+ xContext->getServiceManager()->createInstanceWithContext(
+ OUSTR("com.sun.star.packages.manifest.ManifestReader"),
+ xContext ), UNO_QUERY_THROW );
+ const Sequence< Sequence<beans::PropertyValue> > manifestSeq(
+ xManifestReader->readManifestSequence( manifestContent.openStream() ) );
+ const OUString packageRootURL( getURL() );
+ for ( sal_Int32 pos = manifestSeq.getLength(); pos--; )
+ {
+ OUString fullPath, mediaType;
+ Sequence<beans::PropertyValue> const & attribs = manifestSeq[ pos ];
+ for ( sal_Int32 i = attribs.getLength(); i--; )
+ {
+ if (fullPath.getLength() > 0 && mediaType.getLength() > 0)
+ break;
+ if (attribs[i].Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM("FullPath") ))
+ attribs[i].Value >>= fullPath;
+ else if (attribs[i].Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM("MediaType") ))
+ attribs[i].Value >>= mediaType;
+ }
+
+ if (fullPath.getLength() == 0 || mediaType.getLength() == 0 ||
+ mediaType.equalsAsciiL( // opt: exclude common text/xml
+ RTL_CONSTASCII_STRINGPARAM("text/xml") ))
+ continue;
+
+ String type, subType;
+ INetContentTypeParameterList params;
+ if (! INetContentTypes::parse( mediaType, type, subType, &params ))
+ continue;
+
+ INetContentTypeParameter const * param = params.find(
+ ByteString("platform") );
+ if (param != 0 && !platform_fits( param->m_sValue ))
+ continue;
+ const OUString url( makeURL( packageRootURL, fullPath ) );
+
+ // check for bundle description:
+ if (type.EqualsIgnoreCaseAscii("application") &&
+ subType.EqualsIgnoreCaseAscii(
+ "vnd.sun.star.package-bundle-description"))
+ {
+ // check locale:
+ param = params.find( ByteString("locale") );
+ if (param == 0) {
+ if (descrFile.getLength() == 0)
+ descrFile = url;
+ }
+ else {
+ // match best locale:
+ lang::Locale locale( toLocale(param->m_sValue) );
+ if (locale.Language == officeLocale.Language)
+ {
+ if (descrFileLocale.Country == officeLocale.Country
+ && locale.Country != officeLocale.Country)
+ continue;
+ if (descrFileLocale.Variant == officeLocale.Variant
+ && locale.Variant != officeLocale.Variant)
+ continue;
+ descrFile = url;
+ descrFileLocale = locale;
+ }
+ }
+ continue;
+ }
+
+ checkAborted( abortChannel );
+
+ //We make sure that we only create one XPackage for a particular URL.
+ //Sometime programmers insert the same URL several times in the manifest
+ //which may lead to DisposedExceptions.
+ if (bundle.end() == std::find_if(bundle.begin(), bundle.end(), XPackage_eq(url)))
+ {
+ const Reference<deployment::XPackage> xPackage(
+ bindBundleItem( url, mediaType, false, OUString(), xCmdEnv ) );
+ if (xPackage.is())
+ bundle.push_back( xPackage );
+ }
+ else
+ {
+ fprintf(stderr, "manifest.xml contains a duplicate entry!\n");
+ }
+ }
+
+ if (descrFile.getLength() > 0)
+ {
+ ::ucbhelper::Content descrFileContent;
+ if (create_ucb_content( &descrFileContent, descrFile,
+ xCmdEnv, false /* no throw */ ))
+ {
+ // patch description:
+ ::rtl::ByteSequence bytes( readFile( descrFileContent ) );
+ ::rtl::OUStringBuffer buf;
+ if ( bytes.getLength() )
+ {
+ buf.append( OUString( reinterpret_cast<sal_Char const *>(
+ bytes.getConstArray() ),
+ bytes.getLength(), RTL_TEXTENCODING_UTF8 ) );
+ }
+ else
+ {
+ buf.append( Package::getDescription() );
+ }
+ m_oldDescription = buf.makeStringAndClear();
+ }
+ }
+}
+
+//______________________________________________________________________________
+void BackendImpl::PackageImpl::scanLegacyBundle(
+ t_packagevec & bundle,
+ OUString const & url,
+ ::rtl::Reference<AbortChannel> const & abortChannel,
+ Reference<ucb::XCommandEnvironment> const & xCmdEnv,
+ bool skip_registration )
+{
+ ::ucbhelper::Content ucbContent( url, xCmdEnv );
+
+ // check for platform pathes:
+ const OUString title( ucbContent.getPropertyValue(
+ StrTitle::get() ).get<OUString>() );
+ if (title.endsWithIgnoreAsciiCaseAsciiL(
+ RTL_CONSTASCII_STRINGPARAM(".plt") ) &&
+ !platform_fits( title.copy( 0, title.getLength() - 4 ) )) {
+ return;
+ }
+ if (title.endsWithIgnoreAsciiCaseAsciiL(
+ RTL_CONSTASCII_STRINGPARAM("skip_registration") ))
+ skip_registration = true;
+
+ OUString ar [] = { StrTitle::get(), OUSTR("IsFolder") };
+ Reference<sdbc::XResultSet> xResultSet(
+ ucbContent.createCursor(
+ Sequence<OUString>( ar, ARLEN(ar) ),
+ ::ucbhelper::INCLUDE_FOLDERS_AND_DOCUMENTS ) );
+ while (xResultSet->next())
+ {
+ checkAborted( abortChannel );
+
+ const Reference<sdbc::XRow> xRow( xResultSet, UNO_QUERY_THROW );
+ const OUString title_enc( ::rtl::Uri::encode(
+ xRow->getString( 1 /* Title */ ),
+ rtl_UriCharClassPchar,
+ rtl_UriEncodeIgnoreEscapes,
+ RTL_TEXTENCODING_UTF8 ) );
+ const OUString path( makeURL( url, title_enc ) );
+
+ OUString mediaType;
+ const Reference<deployment::XPackage> xPackage(
+ bindBundleItem( path, OUString() /* detect */, false, OUString(),
+ xCmdEnv, false /* ignore detection errors */ ) );
+ if (xPackage.is()) {
+ const Reference<deployment::XPackageTypeInfo> xPackageType(
+ xPackage->getPackageType() );
+ OSL_ASSERT( xPackageType.is() );
+ if (xPackageType.is())
+ mediaType = xPackageType->getMediaType();
+
+ if (skip_registration &&
+ // xxx todo: additional parsing?
+ mediaType.matchIgnoreAsciiCaseAsciiL(
+ RTL_CONSTASCII_STRINGPARAM(
+ "application/vnd.sun.star.uno-component") ))
+ continue;
+
+ bundle.push_back( xPackage );
+ }
+
+ if (mediaType.getLength() == 0 ||
+ // script.xlb, dialog.xlb can be met everywhere:
+ mediaType.matchIgnoreAsciiCaseAsciiL(
+ RTL_CONSTASCII_STRINGPARAM(
+ "application/vnd.sun.star.basic-library") ) ||
+ mediaType.matchIgnoreAsciiCaseAsciiL(
+ RTL_CONSTASCII_STRINGPARAM(
+ "application/vnd.sun.star.dialog-library") ))
+ {
+ if (xRow->getBoolean( 2 /* IsFolder */ )) { // recurse into folder:
+ scanLegacyBundle(
+ bundle, path, abortChannel, xCmdEnv, skip_registration );
+ }
+ }
+ }
+}
+
+OUString BackendImpl::PackageImpl::getDisplayName()
+ throw (deployment::ExtensionRemovedException, RuntimeException)
+{
+ if (m_bRemoved)
+ throw deployment::ExtensionRemovedException();
+
+ OUString sName = getDescriptionInfoset().getLocalizedDisplayName();
+ if (sName.getLength() == 0)
+ return m_displayName;
+ else
+ return sName;
+}
+
+::std::vector<Reference<deployment::XPackage> >
+BackendImpl::PackageImpl::getPackagesFromDb(
+ Reference<ucb::XCommandEnvironment> const & xCmdEnv)
+{
+ ::std::vector<Reference<deployment::XPackage> > retVector;
+
+ typedef ::std::vector< ::std::pair<OUString, OUString> >::const_iterator ITC;
+ for (ITC i = m_dbData.items.begin(); i != m_dbData.items.end(); i++)
+ {
+ Reference<deployment::XPackage> xExtension =
+ bindBundleItem(i->first, i->second, true, m_identifier, xCmdEnv);
+ OSL_ASSERT(xExtension.is());
+ if (xExtension.is())
+ retVector.push_back(xExtension);
+ }
+
+ return retVector;
+}
+
+} // anon namespace
+
+//==============================================================================
+Reference<deployment::XPackageRegistry> create(
+ Reference<deployment::XPackageRegistry> const & xRootRegistry,
+ OUString const & context, OUString const & cachePath, bool readOnly,
+ Reference<XComponentContext> const & xComponentContext )
+{
+ Sequence<Any> args(
+ cachePath.getLength() == 0 ? 1 : 3 );
+ args[ 0 ] <<= context;
+ if (cachePath.getLength() > 0) {
+ args[ 1 ] <<= cachePath;
+ args[ 2 ] <<= readOnly;
+ }
+ return new BackendImpl( args, xComponentContext, xRootRegistry );
+}
+
+} // namespace bundle
+} // namespace backend
+} // namespace dp_registry
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/registry/package/dp_package.hrc b/desktop/source/deployment/registry/package/dp_package.hrc
new file mode 100755
index 000000000000..3a840b64f0b6
--- /dev/null
+++ b/desktop/source/deployment/registry/package/dp_package.hrc
@@ -0,0 +1,35 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#if ! defined INCLUDED_DP_PACKAGE_HRC
+#define INCLUDED_DP_PACKAGE_HRC
+
+#include "deployment.hrc"
+
+#define RID_STR_PACKAGE_BUNDLE (RID_DEPLOYMENT_BUNDLE_START+10)
+
+#endif
diff --git a/desktop/source/deployment/registry/package/dp_package.src b/desktop/source/deployment/registry/package/dp_package.src
new file mode 100644
index 000000000000..57307040bba4
--- /dev/null
+++ b/desktop/source/deployment/registry/package/dp_package.src
@@ -0,0 +1,34 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "dp_package.hrc"
+
+String RID_STR_PACKAGE_BUNDLE
+{
+ Text [ en-US ] = "Extension";
+};
+
diff --git a/desktop/source/deployment/registry/package/makefile.mk b/desktop/source/deployment/registry/package/makefile.mk
new file mode 100755
index 000000000000..203ce176d289
--- /dev/null
+++ b/desktop/source/deployment/registry/package/makefile.mk
@@ -0,0 +1,48 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ = ..$/..$/..$/..
+
+PRJNAME = desktop
+TARGET = deployment_registry_package
+ENABLE_EXCEPTIONS = TRUE
+
+.INCLUDE : settings.mk
+
+SRS1NAME = $(TARGET)
+SRC1FILES = \
+ dp_package.src
+
+INCPRE += ..$/..$/inc
+
+SLOFILES = \
+ $(SLO)$/dp_package.obj \
+ $(SLO)$/dp_extbackenddb.obj
+
+.INCLUDE : ..$/..$/target.pmk
+.INCLUDE : target.mk
+
diff --git a/desktop/source/deployment/registry/script/dp_lib_container.cxx b/desktop/source/deployment/registry/script/dp_lib_container.cxx
new file mode 100644
index 000000000000..2bc2c07130a0
--- /dev/null
+++ b/desktop/source/deployment/registry/script/dp_lib_container.cxx
@@ -0,0 +1,81 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include "com/sun/star/uno/XComponentContext.hpp"
+#include "com/sun/star/ucb/XCommandEnvironment.hpp"
+
+#include "dp_script.hrc"
+#include "dp_resource.h"
+#include "dp_xml.h"
+#include "dp_lib_container.h"
+
+#include "rtl/ustring.hxx"
+#include "ucbhelper/content.hxx"
+#include "xmlscript/xmllib_imexp.hxx"
+
+
+using namespace ::dp_misc;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::ucb;
+using ::rtl::OUString;
+
+namespace dp_registry {
+namespace backend {
+namespace script {
+
+namespace {
+struct StrCannotDetermineLibName : public StaticResourceString<
+ StrCannotDetermineLibName, RID_STR_CANNOT_DETERMINE_LIBNAME> {};
+}
+
+//______________________________________________________________________________
+OUString LibraryContainer::get_libname(
+ OUString const & url,
+ Reference<XCommandEnvironment> const & xCmdEnv,
+ Reference<XComponentContext> const & xContext )
+{
+ ::xmlscript::LibDescriptor import;
+ ::ucbhelper::Content ucb_content( url, xCmdEnv );
+ xml_parse( ::xmlscript::importLibrary( import ), ucb_content, xContext );
+
+ if (import.aName.getLength() == 0) {
+ throw Exception( StrCannotDetermineLibName::get(),
+ Reference<XInterface>() );
+ }
+ return import.aName;
+}
+
+}
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/registry/script/dp_lib_container.h b/desktop/source/deployment/registry/script/dp_lib_container.h
new file mode 100755
index 000000000000..0cd5cb2cba90
--- /dev/null
+++ b/desktop/source/deployment/registry/script/dp_lib_container.h
@@ -0,0 +1,69 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#if ! defined INCLUDED_DP_LIB_CONTAINER_H
+#define INCLUDED_DP_LIB_CONTAINER_H
+
+#include <com/sun/star/uno/Reference.hxx>
+
+namespace com { namespace sun { namespace star {
+ namespace uno {
+ class XComponentContext;
+ }
+ namespace ucb {
+ class XCommandEnvironment;
+ }
+}}}
+
+namespace rtl {
+ class OUString;
+}
+
+namespace css = ::com::sun::star;
+
+namespace dp_registry {
+namespace backend {
+namespace script {
+
+//==============================================================================
+class LibraryContainer
+{
+public:
+ static ::rtl::OUString get_libname(
+ ::rtl::OUString const & url,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv,
+ css::uno::Reference<css::uno::XComponentContext> const & xContext );
+};
+
+}
+}
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/registry/script/dp_script.cxx b/desktop/source/deployment/registry/script/dp_script.cxx
new file mode 100644
index 000000000000..c9d3b19a5309
--- /dev/null
+++ b/desktop/source/deployment/registry/script/dp_script.cxx
@@ -0,0 +1,483 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include "dp_script.hrc"
+#include "dp_lib_container.h"
+#include "dp_backend.h"
+#include "dp_ucb.h"
+#include "rtl/uri.hxx"
+#include "ucbhelper/content.hxx"
+#include "cppuhelper/exc_hlp.hxx"
+#include "cppuhelper/implbase1.hxx"
+#include "comphelper/servicedecl.hxx"
+#include "svl/inettype.hxx"
+#include "com/sun/star/util/XUpdatable.hpp"
+#include "com/sun/star/script/XLibraryContainer3.hpp"
+#include <com/sun/star/util/XMacroExpander.hpp>
+#include <com/sun/star/uri/XUriReferenceFactory.hpp>
+#include <memory>
+#include "dp_scriptbackenddb.hxx"
+
+using namespace ::dp_misc;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::ucb;
+using ::rtl::OUString;
+namespace css = ::com::sun::star;
+
+namespace dp_registry {
+namespace backend {
+namespace script {
+namespace {
+
+typedef ::cppu::ImplInheritanceHelper1<
+ ::dp_registry::backend::PackageRegistryBackend, util::XUpdatable > t_helper;
+
+class BackendImpl : public t_helper
+{
+ class PackageImpl : public ::dp_registry::backend::Package
+ {
+ BackendImpl * getMyBackend() const;
+
+ const OUString m_scriptURL;
+ const OUString m_dialogURL;
+ OUString m_dialogName;
+
+ // Package
+ virtual beans::Optional< beans::Ambiguous<sal_Bool> > isRegistered_(
+ ::osl::ResettableMutexGuard & guard,
+ ::rtl::Reference<AbortChannel> const & abortChannel,
+ Reference<XCommandEnvironment> const & xCmdEnv );
+ virtual void processPackage_(
+ ::osl::ResettableMutexGuard & guard,
+ bool registerPackage,
+ bool startup,
+ ::rtl::Reference<AbortChannel> const & abortChannel,
+ Reference<XCommandEnvironment> const & xCmdEnv );
+
+ public:
+ PackageImpl(
+ ::rtl::Reference<BackendImpl> const & myBackend,
+ OUString const & url,
+ Reference<XCommandEnvironment> const &xCmdEnv,
+ OUString const & scriptURL, OUString const & dialogURL,
+ bool bRemoved, OUString const & identifier);
+ };
+ friend class PackageImpl;
+
+ // PackageRegistryBackend
+ virtual Reference<deployment::XPackage> bindPackage_(
+ OUString const & url, OUString const & mediaType,
+ sal_Bool bRemoved, OUString const & identifier,
+ Reference<XCommandEnvironment> const & xCmdEnv );
+
+ void addDataToDb(OUString const & url);
+ bool hasActiveEntry(OUString const & url);
+ void revokeEntryFromDb(OUString const & url);
+
+ const Reference<deployment::XPackageTypeInfo> m_xBasicLibTypeInfo;
+ const Reference<deployment::XPackageTypeInfo> m_xDialogLibTypeInfo;
+ Sequence< Reference<deployment::XPackageTypeInfo> > m_typeInfos;
+ std::auto_ptr<ScriptBackendDb> m_backendDb;
+public:
+ BackendImpl( Sequence<Any> const & args,
+ Reference<XComponentContext> const & xComponentContext );
+
+ // XUpdatable
+ virtual void SAL_CALL update() throw (RuntimeException);
+
+ // XPackageRegistry
+ virtual Sequence< Reference<deployment::XPackageTypeInfo> > SAL_CALL
+ getSupportedPackageTypes() throw (RuntimeException);
+ virtual void SAL_CALL packageRemoved(OUString const & url, OUString const & mediaType)
+ throw (deployment::DeploymentException,
+ uno::RuntimeException);
+
+};
+
+//______________________________________________________________________________
+BackendImpl::PackageImpl::PackageImpl(
+ ::rtl::Reference<BackendImpl> const & myBackend,
+ OUString const & url,
+ Reference<XCommandEnvironment> const &xCmdEnv,
+ OUString const & scriptURL, OUString const & dialogURL, bool bRemoved,
+ OUString const & identifier)
+ : Package( myBackend.get(), url,
+ OUString(), OUString(), // will be late-initialized
+ scriptURL.getLength() > 0 ? myBackend->m_xBasicLibTypeInfo
+ : myBackend->m_xDialogLibTypeInfo, bRemoved, identifier),
+ m_scriptURL( scriptURL ),
+ m_dialogURL( dialogURL )
+{
+ // name, displayName:
+ if (dialogURL.getLength() > 0) {
+ m_dialogName = LibraryContainer::get_libname(
+ dialogURL, xCmdEnv, myBackend->getComponentContext() );
+ }
+ if (scriptURL.getLength() > 0) {
+ m_name = LibraryContainer::get_libname(
+ scriptURL, xCmdEnv, myBackend->getComponentContext() );
+ }
+ else
+ m_name = m_dialogName;
+ m_displayName = m_name;
+}
+
+//______________________________________________________________________________
+BackendImpl::BackendImpl(
+ Sequence<Any> const & args,
+ Reference<XComponentContext> const & xComponentContext )
+ : t_helper( args, xComponentContext ),
+ m_xBasicLibTypeInfo( new Package::TypeInfo(
+ OUSTR("application/"
+ "vnd.sun.star.basic-library"),
+ OUString() /* no file filter */,
+ getResourceString(RID_STR_BASIC_LIB),
+ RID_IMG_SCRIPTLIB) ),
+ m_xDialogLibTypeInfo( new Package::TypeInfo(
+ OUSTR("application/"
+ "vnd.sun.star.dialog-library"),
+ OUString() /* no file filter */,
+ getResourceString(RID_STR_DIALOG_LIB),
+ RID_IMG_DIALOGLIB) ),
+ m_typeInfos( 2 )
+{
+ m_typeInfos[ 0 ] = m_xBasicLibTypeInfo;
+ m_typeInfos[ 1 ] = m_xDialogLibTypeInfo;
+
+ OSL_ASSERT( ! transientMode() );
+
+ if (!transientMode())
+ {
+ OUString dbFile = makeURL(getCachePath(), OUSTR("backenddb.xml"));
+ m_backendDb.reset(
+ new ScriptBackendDb(getComponentContext(), dbFile));
+ }
+
+}
+void BackendImpl::addDataToDb(OUString const & url)
+{
+ if (m_backendDb.get())
+ m_backendDb->addEntry(url);
+}
+
+bool BackendImpl::hasActiveEntry(OUString const & url)
+{
+ if (m_backendDb.get())
+ return m_backendDb->hasActiveEntry(url);
+ return false;
+}
+
+// XUpdatable
+//______________________________________________________________________________
+void BackendImpl::update() throw (RuntimeException)
+{
+ // Nothing to do here after fixing i70283!?
+}
+
+// XPackageRegistry
+//______________________________________________________________________________
+Sequence< Reference<deployment::XPackageTypeInfo> >
+BackendImpl::getSupportedPackageTypes() throw (RuntimeException)
+{
+ return m_typeInfos;
+}
+void BackendImpl::revokeEntryFromDb(OUString const & url)
+{
+ if (m_backendDb.get())
+ m_backendDb->revokeEntry(url);
+}
+
+void BackendImpl::packageRemoved(OUString const & url, OUString const & /*mediaType*/)
+ throw (deployment::DeploymentException,
+ uno::RuntimeException)
+{
+ if (m_backendDb.get())
+ m_backendDb->removeEntry(url);
+}
+
+// PackageRegistryBackend
+//______________________________________________________________________________
+Reference<deployment::XPackage> BackendImpl::bindPackage_(
+ OUString const & url, OUString const & mediaType_,
+ sal_Bool bRemoved, OUString const & identifier,
+ Reference<XCommandEnvironment> const & xCmdEnv )
+{
+ OUString mediaType( mediaType_ );
+ if (mediaType.getLength() == 0)
+ {
+ // detect media-type:
+ ::ucbhelper::Content ucbContent;
+ if (create_ucb_content( &ucbContent, url, xCmdEnv ) &&
+ ucbContent.isFolder())
+ {
+ // probe for script.xlb:
+ if (create_ucb_content(
+ 0, makeURL( url, OUSTR("script.xlb") ),
+ xCmdEnv, false /* no throw */ ))
+ mediaType = OUSTR("application/vnd.sun.star.basic-library");
+ // probe for dialog.xlb:
+ else if (create_ucb_content(
+ 0, makeURL( url, OUSTR("dialog.xlb") ),
+ xCmdEnv, false /* no throw */ ))
+ mediaType = OUSTR("application/vnd.sun.star.dialog-library");
+ }
+ if (mediaType.getLength() == 0)
+ throw lang::IllegalArgumentException(
+ StrCannotDetectMediaType::get() + url,
+ static_cast<OWeakObject *>(this), static_cast<sal_Int16>(-1) );
+ }
+
+ String type, subType;
+ INetContentTypeParameterList params;
+ if (INetContentTypes::parse( mediaType, type, subType, &params ))
+ {
+ if (type.EqualsIgnoreCaseAscii("application"))
+ {
+ OUString dialogURL( makeURL( url, OUSTR("dialog.xlb") ) );
+ if (! create_ucb_content(
+ 0, dialogURL, xCmdEnv, false /* no throw */ )) {
+ dialogURL = OUString();
+ }
+
+ if (subType.EqualsIgnoreCaseAscii("vnd.sun.star.basic-library"))
+ {
+ OUString scriptURL( makeURL( url, OUSTR("script.xlb")));
+ if (! create_ucb_content(
+ 0, scriptURL, xCmdEnv, false /* no throw */ )) {
+ scriptURL = OUString();
+ }
+
+ return new PackageImpl(
+ this, url, xCmdEnv, scriptURL,
+ dialogURL, bRemoved, identifier);
+ }
+ else if (subType.EqualsIgnoreCaseAscii(
+ "vnd.sun.star.dialog-library")) {
+ return new PackageImpl(
+ this, url, xCmdEnv,
+ OUString() /* no script lib */,
+ dialogURL,
+ bRemoved, identifier);
+ }
+ }
+ }
+ throw lang::IllegalArgumentException(
+ StrUnsupportedMediaType::get() + mediaType,
+ static_cast<OWeakObject *>(this),
+ static_cast<sal_Int16>(-1) );
+}
+
+
+// Package
+BackendImpl * BackendImpl::PackageImpl::getMyBackend() const
+{
+ BackendImpl * pBackend = static_cast<BackendImpl *>(m_myBackend.get());
+ if (NULL == pBackend)
+ {
+ //May throw a DisposedException
+ check();
+ //We should never get here...
+ throw RuntimeException(
+ OUSTR("Failed to get the BackendImpl"),
+ static_cast<OWeakObject*>(const_cast<PackageImpl *>(this)));
+ }
+ return pBackend;
+}
+
+beans::Optional< beans::Ambiguous<sal_Bool> >
+BackendImpl::PackageImpl::isRegistered_(
+ ::osl::ResettableMutexGuard & /* guard */,
+ ::rtl::Reference<AbortChannel> const & /* abortChannel */,
+ Reference<XCommandEnvironment> const & /* xCmdEnv */ )
+{
+ BackendImpl * that = getMyBackend();
+ Reference< deployment::XPackage > xThisPackage( this );
+
+ bool registered = that->hasActiveEntry(getURL());
+ return beans::Optional< beans::Ambiguous<sal_Bool> >(
+ true /* IsPresent */,
+ beans::Ambiguous<sal_Bool>( registered, false /* IsAmbiguous */ ) );
+}
+
+void
+lcl_maybeRemoveScript(
+ bool const bExists,
+ OUString const& rName,
+ OUString const& rScriptURL,
+ Reference<css::script::XLibraryContainer3> const& xScriptLibs)
+{
+ if (bExists && xScriptLibs.is() && xScriptLibs->hasByName(rName))
+ {
+ const OUString sScriptUrl = xScriptLibs->getOriginalLibraryLinkURL(rName);
+ if (sScriptUrl.equals(rScriptURL))
+ xScriptLibs->removeLibrary(rName);
+ }
+}
+
+bool
+lcl_maybeAddScript(
+ bool const bExists,
+ OUString const& rName,
+ OUString const& rScriptURL,
+ Reference<css::script::XLibraryContainer3> const& xScriptLibs)
+{
+ if (bExists && xScriptLibs.is())
+ {
+ bool bCanAdd = true;
+ if (xScriptLibs->hasByName(rName))
+ {
+ const OUString sOriginalUrl = xScriptLibs->getOriginalLibraryLinkURL(rName);
+ //We assume here that library names in extensions are unique, which may not be the case
+ //ToDo: If the script exist in another extension, then both extensions must have the
+ //same id
+ if (sOriginalUrl.match(OUSTR("vnd.sun.star.expand:$UNO_USER_PACKAGES_CACHE"))
+ || sOriginalUrl.match(OUSTR("vnd.sun.star.expand:$UNO_SHARED_PACKAGES_CACHE"))
+ || sOriginalUrl.match(OUSTR("vnd.sun.star.expand:$BUNDLED_EXTENSIONS")))
+ {
+ xScriptLibs->removeLibrary(rName);
+ bCanAdd = true;
+ }
+ else
+ {
+ bCanAdd = false;
+ }
+ }
+
+ if (bCanAdd)
+ {
+ xScriptLibs->createLibraryLink(rName, rScriptURL, false);
+ return xScriptLibs->hasByName(rName);
+ }
+ }
+
+ return false;
+}
+
+void BackendImpl::PackageImpl::processPackage_(
+ ::osl::ResettableMutexGuard & /* guard */,
+ bool doRegisterPackage,
+ bool startup,
+ ::rtl::Reference<AbortChannel> const & /* abortChannel */,
+ Reference<XCommandEnvironment> const & /* xCmdEnv */ )
+{
+ BackendImpl * that = getMyBackend();
+
+ Reference< deployment::XPackage > xThisPackage( this );
+ Reference<XComponentContext> const & xComponentContext = that->getComponentContext();
+
+ bool bScript = (m_scriptURL.getLength() > 0);
+ Reference<css::script::XLibraryContainer3> xScriptLibs;
+
+ bool bDialog = (m_dialogURL.getLength() > 0);
+ Reference<css::script::XLibraryContainer3> xDialogLibs;
+
+ bool bRunning = office_is_running();
+ if( bRunning )
+ {
+ if( bScript )
+ {
+ xScriptLibs.set(
+ xComponentContext->getServiceManager()->createInstanceWithContext(
+ OUSTR("com.sun.star.script.ApplicationScriptLibraryContainer"),
+ xComponentContext ), UNO_QUERY_THROW );
+ }
+
+ if( bDialog )
+ {
+ xDialogLibs.set(
+ xComponentContext->getServiceManager()->createInstanceWithContext(
+ OUSTR("com.sun.star.script.ApplicationDialogLibraryContainer"),
+ xComponentContext ), UNO_QUERY_THROW );
+ }
+ }
+ bool bRegistered = getMyBackend()->hasActiveEntry(getURL());
+ if( !doRegisterPackage )
+ {
+ //We cannot just call removeLibrary(name) because this could remove a
+ //script which was added by an extension in a different repository. For
+ //example, extension foo is contained in the bundled repository and then
+ //the user adds it it to the user repository. The extension manager will
+ //then register the new script and revoke the script from the bundled
+ //extension. removeLibrary(name) would now remove the script from the
+ //user repository. That is, the script of the newly added user extension does
+ //not work anymore. Therefore we must check if the currently active
+ //script comes in fact from the currently processed extension.
+
+ if (bRegistered)
+ {
+ //we also prevent and live deployment at startup
+ if (!isRemoved() && !startup)
+ {
+ lcl_maybeRemoveScript(bScript, m_name, m_scriptURL, xScriptLibs);
+ lcl_maybeRemoveScript(bDialog, m_dialogName, m_dialogURL, xDialogLibs);
+ }
+ getMyBackend()->revokeEntryFromDb(getURL());
+ return;
+ }
+ }
+ if (bRegistered)
+ return; // Already registered
+
+ // Update LibraryContainer
+ bool bScriptSuccess = false;
+ bool bDialogSuccess = false;
+ if (!startup)
+ {
+ //If there is a bundled extension, and the user installes the same extension
+ //then the script from the bundled extension must be removed. If this does not work
+ //then live deployment does not work for scripts.
+ bScriptSuccess = lcl_maybeAddScript(bScript, m_name, m_scriptURL, xScriptLibs);
+ bDialogSuccess = lcl_maybeAddScript(bDialog, m_dialogName, m_dialogURL, xDialogLibs);
+ }
+ bool bSuccess = bScript || bDialog; // Something must have happened
+ if( bRunning && !startup)
+ if( (bScript && !bScriptSuccess) || (bDialog && !bDialogSuccess) )
+ bSuccess = false;
+
+ if (bSuccess)
+ getMyBackend()->addDataToDb(getURL());
+}
+
+} // anon namespace
+
+namespace sdecl = comphelper::service_decl;
+sdecl::class_<BackendImpl, sdecl::with_args<true> > serviceBI;
+extern sdecl::ServiceDecl const serviceDecl(
+ serviceBI,
+ "com.sun.star.comp.deployment.script.PackageRegistryBackend",
+ BACKEND_SERVICE_NAME );
+
+} // namespace script
+} // namespace backend
+} // namespace dp_registry
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/registry/script/dp_script.hrc b/desktop/source/deployment/registry/script/dp_script.hrc
new file mode 100755
index 000000000000..8ddfa6f51ffc
--- /dev/null
+++ b/desktop/source/deployment/registry/script/dp_script.hrc
@@ -0,0 +1,39 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#if ! defined INCLUDED_DP_SCRIPT_HRC
+#define INCLUDED_DP_SCRIPT_HRC
+
+#include "deployment.hrc"
+
+#define RID_STR_BASIC_LIB (RID_DEPLOYMENT_SCRIPT_START+10)
+#define RID_STR_DIALOG_LIB (RID_DEPLOYMENT_SCRIPT_START+11)
+
+#define RID_STR_LIBNAME_ALREADY_EXISTS (RID_DEPLOYMENT_SCRIPT_START+15)
+#define RID_STR_CANNOT_DETERMINE_LIBNAME (RID_DEPLOYMENT_SCRIPT_START+16)
+
+#endif
diff --git a/desktop/source/deployment/registry/script/dp_script.src b/desktop/source/deployment/registry/script/dp_script.src
new file mode 100644
index 000000000000..117f4eac945a
--- /dev/null
+++ b/desktop/source/deployment/registry/script/dp_script.src
@@ -0,0 +1,49 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "dp_script.hrc"
+
+String RID_STR_BASIC_LIB
+{
+ Text [ en-US ] = "%PRODUCTNAME Basic Library";
+};
+
+String RID_STR_DIALOG_LIB
+{
+ Text [ en-US ] = "Dialog Library";
+};
+
+String RID_STR_CANNOT_DETERMINE_LIBNAME
+{
+ Text [ en-US ] = "The library name could not be determined.";
+};
+
+String RID_STR_LIBNAME_ALREADY_EXISTS
+{
+ Text [ en-US ] = "This library name already exists. Please choose a different name.";
+};
+
diff --git a/desktop/source/deployment/registry/script/dp_scriptbackenddb.cxx b/desktop/source/deployment/registry/script/dp_scriptbackenddb.cxx
new file mode 100644
index 000000000000..8c6a4924212e
--- /dev/null
+++ b/desktop/source/deployment/registry/script/dp_scriptbackenddb.cxx
@@ -0,0 +1,87 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include "rtl/string.h"
+#include "cppuhelper/exc_hlp.hxx"
+#include "com/sun/star/uno/XComponentContext.hpp"
+#include "com/sun/star/xml/dom/XDocument.hpp"
+#include "com/sun/star/xml/xpath/XXPathAPI.hpp"
+#include "dp_misc.h"
+#include "dp_scriptbackenddb.hxx"
+
+
+namespace css = ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using ::rtl::OUString;
+
+#define EXTENSION_REG_NS "http://openoffice.org/extensionmanager/script-registry/2010"
+#define NS_PREFIX "script"
+#define ROOT_ELEMENT_NAME "script-backend-db"
+#define KEY_ELEMENT_NAME "script"
+
+namespace dp_registry {
+namespace backend {
+namespace script {
+
+ScriptBackendDb::ScriptBackendDb(
+ Reference<XComponentContext> const & xContext,
+ ::rtl::OUString const & url):RegisteredDb(xContext, url)
+{
+
+}
+
+OUString ScriptBackendDb::getDbNSName()
+{
+ return OUSTR(EXTENSION_REG_NS);
+}
+
+OUString ScriptBackendDb::getNSPrefix()
+{
+ return OUSTR(NS_PREFIX);
+}
+
+OUString ScriptBackendDb::getRootElementName()
+{
+ return OUSTR(ROOT_ELEMENT_NAME);
+}
+
+OUString ScriptBackendDb::getKeyElementName()
+{
+ return OUSTR(KEY_ELEMENT_NAME);
+}
+
+
+
+} // namespace executable
+} // namespace backend
+} // namespace dp_registry
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/registry/script/dp_scriptbackenddb.hxx b/desktop/source/deployment/registry/script/dp_scriptbackenddb.hxx
new file mode 100644
index 000000000000..58a749480113
--- /dev/null
+++ b/desktop/source/deployment/registry/script/dp_scriptbackenddb.hxx
@@ -0,0 +1,75 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#if ! defined INCLUDED_DP_SCRIPTBACKENDDB_HXX
+#define INCLUDED_DP_SCRIPTBACKENDDB_HXX
+
+#include "rtl/ustring.hxx"
+#include "dp_backenddb.hxx"
+#include "boost/optional.hpp"
+namespace css = ::com::sun::star;
+
+namespace com { namespace sun { namespace star {
+ namespace uno {
+ class XComponentContext;
+ }
+}}}
+
+namespace dp_registry {
+namespace backend {
+namespace script {
+
+/* The XML file stores the extensions which are currently registered.
+ They will be removed when they are revoked.
+ */
+class ScriptBackendDb: public dp_registry::backend::RegisteredDb
+{
+protected:
+ virtual ::rtl::OUString getDbNSName();
+
+ virtual ::rtl::OUString getNSPrefix();
+
+ virtual ::rtl::OUString getRootElementName();
+
+ virtual ::rtl::OUString getKeyElementName();
+
+
+public:
+
+ ScriptBackendDb( css::uno::Reference<css::uno::XComponentContext> const & xContext,
+ ::rtl::OUString const & url);
+};
+
+
+
+}
+}
+}
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/registry/script/makefile.mk b/desktop/source/deployment/registry/script/makefile.mk
new file mode 100755
index 000000000000..708def358021
--- /dev/null
+++ b/desktop/source/deployment/registry/script/makefile.mk
@@ -0,0 +1,49 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ = ..$/..$/..$/..
+
+PRJNAME = desktop
+TARGET = deployment_registry_script
+ENABLE_EXCEPTIONS = TRUE
+
+.INCLUDE : settings.mk
+
+SRS1NAME = $(TARGET)
+SRC1FILES = \
+ dp_script.src
+
+INCPRE += ..$/..$/inc
+
+SLOFILES = \
+ $(SLO)$/dp_script.obj \
+ $(SLO)$/dp_lib_container.obj \
+ $(SLO)$/dp_scriptbackenddb.obj
+
+.INCLUDE : ..$/..$/target.pmk
+.INCLUDE : target.mk
+
diff --git a/desktop/source/deployment/registry/sfwk/dp_parceldesc.cxx b/desktop/source/deployment/registry/sfwk/dp_parceldesc.cxx
new file mode 100644
index 000000000000..11835ddfa957
--- /dev/null
+++ b/desktop/source/deployment/registry/sfwk/dp_parceldesc.cxx
@@ -0,0 +1,132 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+#include "dp_misc.h"
+#include "dp_parceldesc.hxx"
+
+
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+
+using ::rtl::OUString;
+
+namespace css = ::com::sun::star;
+namespace dp_registry
+{
+namespace backend
+{
+namespace sfwk
+{
+
+
+// XDocumentHandler
+void SAL_CALL
+ParcelDescDocHandler::startDocument()
+throw ( xml::sax::SAXException, RuntimeException )
+{
+ m_bIsParsed = false;
+}
+
+void SAL_CALL
+ParcelDescDocHandler::endDocument()
+throw ( xml::sax::SAXException, RuntimeException )
+{
+ m_bIsParsed = true;
+}
+
+void SAL_CALL
+ParcelDescDocHandler::characters( const OUString & )
+ throw ( xml::sax::SAXException, RuntimeException )
+{
+}
+
+void SAL_CALL
+ParcelDescDocHandler::ignorableWhitespace( const OUString & )
+ throw ( xml::sax::SAXException, RuntimeException )
+{
+}
+
+void SAL_CALL
+ParcelDescDocHandler::processingInstruction(
+ const OUString &, const OUString & )
+ throw ( xml::sax::SAXException, RuntimeException )
+{
+}
+
+void SAL_CALL
+ParcelDescDocHandler::setDocumentLocator(
+ const Reference< xml::sax::XLocator >& )
+ throw ( xml::sax::SAXException, RuntimeException )
+{
+}
+
+void SAL_CALL
+ParcelDescDocHandler::startElement( const OUString& aName,
+ const Reference< xml::sax::XAttributeList > & xAttribs )
+ throw ( xml::sax::SAXException,
+ RuntimeException )
+{
+
+ dp_misc::TRACE(OUSTR("ParcelDescDocHandler::startElement() for ") +
+ aName + OUSTR("\n"));
+ if ( !skipIndex )
+ {
+ if ( aName.equals( OUString(RTL_CONSTASCII_USTRINGPARAM( "parcel" )) ) )
+ {
+ m_sLang = xAttribs->getValueByName( OUString(RTL_CONSTASCII_USTRINGPARAM( "language" )) );
+ }
+ ++skipIndex;
+ }
+ else
+ {
+ dp_misc::TRACE(OUSTR("ParcelDescDocHandler::startElement() skipping for ")
+ + aName + OUSTR("\n"));
+ }
+
+}
+
+void SAL_CALL ParcelDescDocHandler::endElement( const OUString & aName )
+ throw ( xml::sax::SAXException, RuntimeException )
+{
+ if ( skipIndex )
+ {
+ --skipIndex;
+ dp_misc::TRACE(OUSTR("ParcelDescDocHandler::endElement() skipping for ")
+ + aName + OUSTR("\n"));
+ }
+}
+
+
+}
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/registry/sfwk/dp_parceldesc.hxx b/desktop/source/deployment/registry/sfwk/dp_parceldesc.hxx
new file mode 100644
index 000000000000..83ffddda1aff
--- /dev/null
+++ b/desktop/source/deployment/registry/sfwk/dp_parceldesc.hxx
@@ -0,0 +1,92 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <cppuhelper/implbase1.hxx>
+
+#include <com/sun/star/xml/sax/XAttributeList.hpp>
+#include <com/sun/star/xml/sax/SAXException.hpp>
+#include <com/sun/star/xml/sax/XDocumentHandler.hpp>
+#include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp>
+#include <com/sun/star/xml/sax/XParser.hpp>
+
+#include <com/sun/star/lang/NoSupportException.hpp>
+#include <com/sun/star/lang/XMultiComponentFactory.hpp>
+namespace css = ::com::sun::star;
+namespace dp_registry
+{
+namespace backend
+{
+namespace sfwk
+{
+
+typedef ::cppu::WeakImplHelper1< css::xml::sax::XDocumentHandler > t_DocHandlerImpl;
+
+class ParcelDescDocHandler : public t_DocHandlerImpl
+{
+private:
+ bool m_bIsParsed;
+ ::rtl::OUString m_sLang;
+ sal_Int32 skipIndex;
+public:
+ ParcelDescDocHandler():m_bIsParsed( false ), skipIndex( 0 ){}
+ ::rtl::OUString getParcelLanguage() { return m_sLang; }
+ bool isParsed() { return m_bIsParsed; }
+ // XDocumentHandler
+ virtual void SAL_CALL startDocument()
+ throw ( css::xml::sax::SAXException, css::uno::RuntimeException );
+
+ virtual void SAL_CALL endDocument()
+ throw ( css::xml::sax::SAXException, css::uno::RuntimeException );
+
+ virtual void SAL_CALL startElement( const ::rtl::OUString& aName,
+ const css::uno::Reference< css::xml::sax::XAttributeList > & xAttribs )
+ throw ( css::xml::sax::SAXException,
+ css::uno::RuntimeException );
+
+ virtual void SAL_CALL endElement( const ::rtl::OUString & aName )
+ throw ( css::xml::sax::SAXException, css::uno::RuntimeException );
+
+ virtual void SAL_CALL characters( const ::rtl::OUString & aChars )
+ throw ( css::xml::sax::SAXException, css::uno::RuntimeException );
+
+ virtual void SAL_CALL ignorableWhitespace( const ::rtl::OUString & aWhitespaces )
+ throw ( css::xml::sax::SAXException, css::uno::RuntimeException );
+
+ virtual void SAL_CALL processingInstruction(
+ const ::rtl::OUString & aTarget, const ::rtl::OUString & aData )
+ throw ( css::xml::sax::SAXException, css::uno::RuntimeException );
+
+ virtual void SAL_CALL setDocumentLocator(
+ const css::uno::Reference< css::xml::sax::XLocator >& xLocator )
+ throw ( css::xml::sax::SAXException, css::uno::RuntimeException );
+};
+}
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/registry/sfwk/dp_sfwk.cxx b/desktop/source/deployment/registry/sfwk/dp_sfwk.cxx
new file mode 100644
index 000000000000..a93069465435
--- /dev/null
+++ b/desktop/source/deployment/registry/sfwk/dp_sfwk.cxx
@@ -0,0 +1,396 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+#include "dp_sfwk.hrc"
+#include "dp_backend.h"
+#include "dp_ucb.h"
+#include "dp_parceldesc.hxx"
+#include "rtl/uri.hxx"
+#include "ucbhelper/content.hxx"
+#include "cppuhelper/exc_hlp.hxx"
+#include "comphelper/servicedecl.hxx"
+#include "svl/inettype.hxx"
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/script/provider/XScriptProviderFactory.hpp>
+#include <memory>
+
+
+using namespace ::dp_misc;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::ucb;
+using namespace ::com::sun::star::script;
+
+using ::rtl::OUString;
+namespace css = ::com::sun::star;
+
+namespace dp_registry
+{
+namespace backend
+{
+namespace sfwk
+{
+
+//==============================================================================
+class BackendImpl : public ::dp_registry::backend::PackageRegistryBackend
+{
+ class PackageImpl : public ::dp_registry::backend::Package
+ {
+ BackendImpl * getMyBackend() const;
+
+ Reference< container::XNameContainer > m_xNameCntrPkgHandler;
+ OUString m_descr;
+
+ void initPackageHandler();
+
+ // Package
+ virtual beans::Optional< beans::Ambiguous<sal_Bool> > isRegistered_(
+ ::osl::ResettableMutexGuard & guard,
+ ::rtl::Reference<AbortChannel> const & abortChannel,
+ Reference<XCommandEnvironment> const & xCmdEnv );
+ virtual void processPackage_(
+ ::osl::ResettableMutexGuard & guard,
+ bool registerPackage,
+ bool startup,
+ ::rtl::Reference<AbortChannel> const & abortChannel,
+ Reference<XCommandEnvironment> const & xCmdEnv );
+
+ public:
+ PackageImpl(
+ ::rtl::Reference<BackendImpl> const & myBackend,
+ OUString const & url, OUString const & libType, bool bRemoved,
+ OUString const & identifier);
+ // XPackage
+ virtual OUString SAL_CALL getDescription() throw (RuntimeException);
+ virtual OUString SAL_CALL getLicenseText() throw (RuntimeException);
+ };
+ friend class PackageImpl;
+
+ // PackageRegistryBackend
+ virtual Reference<deployment::XPackage> bindPackage_(
+ OUString const & url, OUString const & mediaType,
+ sal_Bool bRemoved, OUString const & identifier,
+ Reference<XCommandEnvironment> const & xCmdEnv );
+
+ const Reference<deployment::XPackageTypeInfo> m_xTypeInfo;
+
+
+public:
+ BackendImpl(
+ Sequence<Any> const & args,
+ Reference<XComponentContext> const & xComponentContext );
+
+ // XPackageRegistry
+ virtual Sequence< Reference<deployment::XPackageTypeInfo> > SAL_CALL
+ getSupportedPackageTypes() throw (RuntimeException);
+ virtual void SAL_CALL packageRemoved(OUString const & url, OUString const & mediaType)
+ throw (deployment::DeploymentException,
+ uno::RuntimeException);
+};
+
+BackendImpl * BackendImpl::PackageImpl::getMyBackend() const
+{
+ BackendImpl * pBackend = static_cast<BackendImpl *>(m_myBackend.get());
+ if (NULL == pBackend)
+ {
+ //May throw a DisposedException
+ check();
+ //We should never get here...
+ throw RuntimeException(
+ OUSTR("Failed to get the BackendImpl"),
+ static_cast<OWeakObject*>(const_cast<PackageImpl *>(this)));
+ }
+ return pBackend;
+}
+//______________________________________________________________________________
+OUString BackendImpl::PackageImpl::getDescription() throw (RuntimeException)
+{
+ if (m_descr.getLength() == 0)
+ return Package::getDescription();
+ else
+ return m_descr;
+}
+
+//______________________________________________________________________________
+OUString BackendImpl::PackageImpl::getLicenseText() throw (RuntimeException)
+{
+ return Package::getDescription();
+}
+
+//______________________________________________________________________________
+BackendImpl::PackageImpl::PackageImpl(
+ ::rtl::Reference<BackendImpl> const & myBackend,
+ OUString const & url, OUString const & libType, bool bRemoved,
+ OUString const & identifier)
+ : Package( myBackend.get(), url, OUString(), OUString(),
+ myBackend->m_xTypeInfo, bRemoved, identifier),
+ m_descr(libType)
+{
+ initPackageHandler();
+
+ sal_Int32 segmEnd = url.getLength();
+ if (url.getLength() > 0 && url[ url.getLength() - 1 ] == '/')
+ --segmEnd;
+ sal_Int32 segmStart = (url.lastIndexOf( '/', segmEnd ) + 1);
+ if (segmStart < 0)
+ segmStart = 0;
+ // name and display name default the same:
+ m_displayName = ::rtl::Uri::decode(
+ url.copy( segmStart, segmEnd - segmStart ),
+ rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8 );
+ m_name = m_displayName;
+
+ dp_misc::TRACE(OUSTR("PakageImpl displayName is ") + m_displayName);
+}
+
+//______________________________________________________________________________
+BackendImpl::BackendImpl(
+ Sequence<Any> const & args,
+ Reference<XComponentContext> const & xComponentContext )
+ : PackageRegistryBackend( args, xComponentContext ),
+ m_xTypeInfo( new Package::TypeInfo(
+ OUSTR("application/vnd.sun.star.framework-script"),
+ OUString() /* no file filter */,
+ OUSTR("Scripting Framework Script Library"),
+ RID_IMG_SCRIPTLIB ) )
+{
+ if (! transientMode())
+ {
+ }
+}
+
+
+
+// XPackageRegistry
+//______________________________________________________________________________
+Sequence< Reference<deployment::XPackageTypeInfo> >
+BackendImpl::getSupportedPackageTypes() throw (RuntimeException)
+{
+ return Sequence< Reference<deployment::XPackageTypeInfo> >(&m_xTypeInfo, 1);
+}
+
+void BackendImpl::packageRemoved(OUString const & /*url*/, OUString const & /*mediaType*/)
+ throw (deployment::DeploymentException,
+ uno::RuntimeException)
+{
+}
+
+// PackageRegistryBackend
+//______________________________________________________________________________
+Reference<deployment::XPackage> BackendImpl::bindPackage_(
+ OUString const & url, OUString const & mediaType_, sal_Bool bRemoved,
+ OUString const & identifier, Reference<XCommandEnvironment> const & xCmdEnv )
+{
+ OUString mediaType( mediaType_ );
+ if (mediaType.getLength() == 0)
+ {
+ // detect media-type:
+ ::ucbhelper::Content ucbContent;
+ if (create_ucb_content( &ucbContent, url, xCmdEnv ) &&
+ ucbContent.isFolder())
+ {
+ // probe for parcel-descriptor.xml:
+ if (create_ucb_content(
+ 0, makeURL( url, OUSTR("parcel-descriptor.xml") ),
+ xCmdEnv, false /* no throw */ ))
+ {
+ mediaType = OUSTR("application/vnd.sun.star.framework-script");
+ }
+ }
+ if (mediaType.getLength() == 0)
+ throw lang::IllegalArgumentException(
+ StrCannotDetectMediaType::get() + url,
+ static_cast<OWeakObject *>(this), static_cast<sal_Int16>(-1) );
+ }
+
+ String type, subType;
+ INetContentTypeParameterList params;
+ if (INetContentTypes::parse( mediaType, type, subType, &params ))
+ {
+ if (type.EqualsIgnoreCaseAscii("application"))
+ {
+ if (subType.EqualsIgnoreCaseAscii("vnd.sun.star.framework-script"))
+ {
+ OUString lang = OUString(RTL_CONSTASCII_USTRINGPARAM("Script"));
+ OUString sParcelDescURL = makeURL(
+ url, OUSTR("parcel-descriptor.xml") );
+
+ ::ucbhelper::Content ucb_content;
+
+ if (create_ucb_content( &ucb_content, sParcelDescURL,
+ xCmdEnv, false /* no throw */ ))
+ {
+ ParcelDescDocHandler* pHandler =
+ new ParcelDescDocHandler();
+ Reference< xml::sax::XDocumentHandler >
+ xDocHandler = pHandler;
+
+ Reference<XComponentContext>
+ xContext( getComponentContext() );
+
+ Reference< xml::sax::XParser > xParser(
+ xContext->getServiceManager()->createInstanceWithContext(
+ OUSTR("com.sun.star.xml.sax.Parser"), xContext ),
+ UNO_QUERY_THROW );
+
+ xParser->setDocumentHandler( xDocHandler );
+ xml::sax::InputSource source;
+ source.aInputStream = ucb_content.openStream();
+ source.sSystemId = ucb_content.getURL();
+ xParser->parseStream( source );
+
+ if ( pHandler->isParsed() )
+ {
+ lang = pHandler->getParcelLanguage();
+ }
+ }
+
+ OUString sfwkLibType = getResourceString( RID_STR_SFWK_LIB );
+ // replace %MACRONAME placeholder with language name
+ OUString MACRONAME( OUSTR("%MACROLANG" ) );
+ sal_Int32 startOfReplace = sfwkLibType.indexOf( MACRONAME );
+ sal_Int32 charsToReplace = MACRONAME.getLength();
+ sfwkLibType = sfwkLibType.replaceAt( startOfReplace, charsToReplace, lang );
+ dp_misc::TRACE("******************************\n");
+ dp_misc::TRACE(OUSTR(" BackEnd detected lang = ") + lang + OUSTR("\n"));
+ dp_misc::TRACE(OUSTR(" for url ") + sParcelDescURL + OUSTR("\n") );
+ dp_misc::TRACE("******************************\n");
+ return new PackageImpl( this, url, sfwkLibType, bRemoved, identifier);
+ }
+ }
+ }
+ throw lang::IllegalArgumentException(
+ StrUnsupportedMediaType::get() + mediaType,
+ static_cast<OWeakObject *>(this),
+ static_cast<sal_Int16>(-1) );
+}
+
+
+void BackendImpl::PackageImpl:: initPackageHandler()
+{
+ if (m_xNameCntrPkgHandler.is())
+ return;
+
+ BackendImpl * that = getMyBackend();
+ Any aContext;
+
+ if ( that->m_eContext == CONTEXT_USER )
+ {
+ aContext <<= OUSTR("user");
+ }
+ else if ( that->m_eContext == CONTEXT_SHARED )
+ {
+ aContext <<= OUSTR("share");
+ }
+ else if ( that->m_eContext == CONTEXT_BUNDLED )
+ {
+ aContext <<= OUSTR("bundled");
+ }
+ else if ( that->m_eContext == CONTEXT_BUNDLED_PREREG )
+ {
+ aContext <<= OUSTR("bundled_prereg");
+ }
+
+ else
+ {
+ OSL_ASSERT( 0 );
+ // NOT supported at the momemtn // TODO
+ }
+
+ Reference< provider::XScriptProviderFactory > xFac(
+ that->getComponentContext()->getValueByName(
+ OUSTR( "/singletons/com.sun.star.script.provider.theMasterScriptProviderFactory") ), UNO_QUERY );
+
+ if ( xFac.is() )
+ {
+ Reference< container::XNameContainer > xName( xFac->createScriptProvider( aContext ), UNO_QUERY );
+ if ( xName.is() )
+ {
+ m_xNameCntrPkgHandler.set( xName );
+ }
+ }
+ // TODO what happens if above fails??
+}
+
+// Package
+//______________________________________________________________________________
+beans::Optional< beans::Ambiguous<sal_Bool> >
+BackendImpl::PackageImpl::isRegistered_(
+ ::osl::ResettableMutexGuard &,
+ ::rtl::Reference<AbortChannel> const &,
+ Reference<XCommandEnvironment> const & )
+{
+ return beans::Optional< beans::Ambiguous<sal_Bool> >(
+ true /* IsPresent */,
+ beans::Ambiguous<sal_Bool>(
+ m_xNameCntrPkgHandler.is() && m_xNameCntrPkgHandler->hasByName(
+ m_url ),
+ false /* IsAmbiguous */ ) );
+}
+
+//______________________________________________________________________________
+void BackendImpl::PackageImpl::processPackage_(
+ ::osl::ResettableMutexGuard &,
+ bool doRegisterPackage,
+ bool /* startup */,
+ ::rtl::Reference<AbortChannel> const &,
+ Reference<XCommandEnvironment> const & )
+{
+ if ( !m_xNameCntrPkgHandler.is() )
+ {
+ dp_misc::TRACE("no package handler!!!!\n");
+ throw RuntimeException( OUSTR("No package Handler " ),
+ Reference< XInterface >() );
+ }
+
+ if (doRegisterPackage)
+ {
+ // will throw if it fails
+ m_xNameCntrPkgHandler->insertByName( m_url, makeAny( Reference< XPackage >(this) ) );
+
+ }
+ else // revokePackage()
+ {
+ m_xNameCntrPkgHandler->removeByName( m_url );
+ }
+}
+
+namespace sdecl = comphelper::service_decl;
+sdecl::class_<BackendImpl, sdecl::with_args<true> > serviceBI;
+extern sdecl::ServiceDecl const serviceDecl(
+ serviceBI,
+ "com.sun.star.comp.deployment.sfwk.PackageRegistryBackend",
+ BACKEND_SERVICE_NAME );
+
+} // namespace sfwk
+} // namespace backend
+} // namespace dp_registry
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/registry/sfwk/dp_sfwk.hrc b/desktop/source/deployment/registry/sfwk/dp_sfwk.hrc
new file mode 100755
index 000000000000..0eb619e839e3
--- /dev/null
+++ b/desktop/source/deployment/registry/sfwk/dp_sfwk.hrc
@@ -0,0 +1,35 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#if ! defined INCLUDED_DP_SFWK_HRC
+#define INCLUDED_DP_SFWK_HRC
+
+#include "deployment.hrc"
+
+#define RID_STR_SFWK_LIB (RID_DEPLOYMENT_SCRIPT_START+20)
+
+#endif
diff --git a/desktop/source/deployment/registry/sfwk/dp_sfwk.src b/desktop/source/deployment/registry/sfwk/dp_sfwk.src
new file mode 100644
index 000000000000..c8d37ce067ac
--- /dev/null
+++ b/desktop/source/deployment/registry/sfwk/dp_sfwk.src
@@ -0,0 +1,35 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "dp_sfwk.hrc"
+
+String RID_STR_SFWK_LIB
+{
+ Text [ en-US ] = "%MACROLANG Library";
+};
+
+
diff --git a/desktop/source/deployment/registry/sfwk/makefile.mk b/desktop/source/deployment/registry/sfwk/makefile.mk
new file mode 100755
index 000000000000..a052296d5c21
--- /dev/null
+++ b/desktop/source/deployment/registry/sfwk/makefile.mk
@@ -0,0 +1,48 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ = ..$/..$/..$/..
+
+PRJNAME = desktop
+TARGET = deployment_registry_sfwk
+ENABLE_EXCEPTIONS = TRUE
+
+.INCLUDE : settings.mk
+SRS1NAME = $(TARGET)
+
+SRC1FILES = \
+ dp_sfwk.src
+
+INCPRE += ..$/..$/inc
+
+SLOFILES = \
+ $(SLO)$/dp_parceldesc.obj \
+ $(SLO)$/dp_sfwk.obj
+
+.INCLUDE : ..$/..$/target.pmk
+.INCLUDE : target.mk
+
diff --git a/desktop/source/deployment/target.pmk b/desktop/source/deployment/target.pmk
new file mode 100755
index 000000000000..82b41766b253
--- /dev/null
+++ b/desktop/source/deployment/target.pmk
@@ -0,0 +1,36 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+.IF "$(debug)" != ""
+
+# MSVC: no inlining
+.IF "$(COM)" == "MSC"
+CFLAGS += /Ob0
+.ENDIF
+
+.ENDIF
+
diff --git a/desktop/source/deployment/unopkg/makefile.mk b/desktop/source/deployment/unopkg/makefile.mk
new file mode 100755
index 000000000000..06b39cd2d04e
--- /dev/null
+++ b/desktop/source/deployment/unopkg/makefile.mk
@@ -0,0 +1,48 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ = ..$/..$/..
+
+PRJNAME = desktop
+TARGET = deployment_unopkg
+ENABLE_EXCEPTIONS = TRUE
+
+.INCLUDE : settings.mk
+
+.IF "$(SYSTEM_DB)" == "YES"
+CFLAGS+=-DSYSTEM_DB -I$(DB_INCLUDES)
+.ENDIF
+
+SRS1NAME = $(TARGET)
+SRC1FILES = \
+ unopkg.src
+
+SLOFILES =
+
+.INCLUDE : ..$/target.pmk
+.INCLUDE : target.mk
+
diff --git a/desktop/source/deployment/unopkg/unopkg.src b/desktop/source/deployment/unopkg/unopkg.src
new file mode 100644
index 000000000000..dc204e265ec6
--- /dev/null
+++ b/desktop/source/deployment/unopkg/unopkg.src
@@ -0,0 +1,84 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "deployment.hrc"
+
+
+String RID_STR_UNOPKG_ACCEPT_LIC_1
+{
+ Text [ en-US ] = "Extension Software License Agreement of $NAME:";
+};
+
+String RID_STR_UNOPKG_ACCEPT_LIC_2
+{
+ Text [ en-US ] = "Read the complete License Agreement displayed above. "
+ "Accept the License Agreement by typing \"yes\" on the console "
+ "then press the Return key. Type \"no\" to decline and to abort the "
+ "extension setup.";
+};
+
+String RID_STR_UNOPKG_ACCEPT_LIC_3
+{
+ Text [ en-US ] = "[Enter \"yes\" or \"no\"]:";
+};
+
+String RID_STR_UNOPKG_ACCEPT_LIC_4
+{
+ Text [ en-US ] = "Your input was not correct. Please enter \"yes\" or \"no\":";
+};
+
+String RID_STR_UNOPKG_ACCEPT_LIC_YES
+{
+ Text [ en-US ] = "YES";
+};
+
+String RID_STR_UNOPKG_ACCEPT_LIC_Y
+{
+ Text [ en-US ] = "Y";
+};
+
+String RID_STR_UNOPKG_ACCEPT_LIC_NO
+{
+ Text [ en-US ] = "NO";
+};
+
+String RID_STR_UNOPKG_ACCEPT_LIC_N
+{
+ Text [ en-US ] = "N";
+};
+
+String RID_STR_CONCURRENTINSTANCE
+{
+ Text [ en-US ] = "unopkg cannot be started. The lock file indicates it as already running. "
+ "If this does not apply, delete the lock file at:";
+};
+
+String RID_STR_UNOPKG_ERROR
+{
+ Text [ en-US ] = "ERROR: ";
+};
+
diff --git a/desktop/source/inc/exithelper.hxx b/desktop/source/inc/exithelper.hxx
new file mode 100644
index 000000000000..25cdc3e1b722
--- /dev/null
+++ b/desktop/source/inc/exithelper.hxx
@@ -0,0 +1,71 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _DESKTOP_EXITHELPER_HXX_
+#define _DESKTOP_EXITHELPER_HXX_
+
+namespace desktop
+{
+
+//=============================================================================
+/** @short provide helper functions to handle a abnormal exit
+ and contain a list of all "well known" exit codes.
+ */
+class ExitHelper
+{
+ //-------------------------------------------------------------------------
+ // const
+ public:
+
+ //---------------------------------------------------------------------
+ /** @short list of all well known exit codes.
+
+ @descr Its not allowed to use exit codes hard coded
+ inside office. All places must use these list to
+ be synchron.
+ */
+ enum EExitCodes
+ {
+ /// e.g. used to force showing of the command line help
+ E_NO_ERROR = 0,
+ /// pipe was detected - second office must terminate itself
+ E_SECOND_OFFICE = 1,
+ /// an uno exception was catched during startup
+ E_FATAL_ERROR = 333, // Only the low 8 bits are significant 333 % 256 = 77
+ /// user force automatic restart after crash
+ E_CRASH_WITH_RESTART = 79,
+ /// the office restarts itself
+ E_NORMAL_RESTART = 81
+ };
+};
+
+} // namespace desktop
+
+#endif // #ifndef _DESKTOP_EXITHELPER_HXX_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/inc/helpid.hrc b/desktop/source/inc/helpid.hrc
new file mode 100755
index 000000000000..d96b12196342
--- /dev/null
+++ b/desktop/source/inc/helpid.hrc
@@ -0,0 +1,67 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#if ! defined INCLUDED_DESKTOP_HELPID_HRC
+#define INCLUDED_DESKTOP_HELPID_HRC
+
+#define HID_PACKAGE_MANAGER "DESKTOP_HID_PACKAGE_MANAGER"
+#define HID_PACKAGE_MANAGER_TREELISTBOX "DESKTOP_HID_PACKAGE_MANAGER_TREELISTBOX"
+#define HID_PACKAGE_MANAGER_PROGRESS "DESKTOP_HID_PACKAGE_MANAGER_PROGRESS"
+#define HID_PACKAGE_MANAGER_PROGRESS_CANCEL "DESKTOP_HID_PACKAGE_MANAGER_PROGRESS_CANCEL"
+#define HID_PACKAGE_MANAGER_MENU_ITEM "DESKTOP_HID_PACKAGE_MANAGER_MENU_ITEM"
+
+#define HID_FIRSTSTART_DIALOG "DESKTOP_HID_FIRSTSTART_DIALOG"
+#define HID_FIRSTSTART_WELCOME "DESKTOP_HID_FIRSTSTART_WELCOME"
+#define HID_FIRSTSTART_LICENSE "DESKTOP_HID_FIRSTSTART_LICENSE"
+#define HID_FIRSTSTART_MIGRATION "DESKTOP_HID_FIRSTSTART_MIGRATION"
+#define HID_FIRSTSTART_REGISTRATION "DESKTOP_HID_FIRSTSTART_REGISTRATION"
+#define HID_FIRSTSTART_USER "DESKTOP_HID_FIRSTSTART_USER"
+#define HID_FIRSTSTART_PREV "DESKTOP_HID_FIRSTSTART_PREV"
+#define HID_FIRSTSTART_NEXT "DESKTOP_HID_FIRSTSTART_NEXT"
+#define HID_FIRSTSTART_CANCEL "DESKTOP_HID_FIRSTSTART_CANCEL"
+#define HID_FIRSTSTART_FINISH "DESKTOP_HID_FIRSTSTART_FINISH"
+#define UID_FIRSTSTART_HELP "DESKTOP_UID_FIRSTSTART_HELP"
+#define UID_BTN_LICENSE_ACCEPT "DESKTOP_UID_BTN_LICENSE_ACCEPT"
+#define HID_FIRSTSTART_UPDATE_CHECK "DESKTOP_HID_FIRSTSTART_UPDATE_CHECK"
+#define HID_DEPLOYMENT_GUI_UPDATE "DESKTOP_HID_DEPLOYMENT_GUI_UPDATE"
+#define HID_DEPLOYMENT_GUI_UPDATEINSTALL "DESKTOP_HID_DEPLOYMENT_GUI_UPDATEINSTALL"
+#define HID_DEPLOYMENT_GUI_UPDATE_PUBLISHER "DESKTOP_HID_DEPLOYMENT_GUI_UPDATE_PUBLISHER"
+#define HID_DEPLOYMENT_GUI_UPDATE_RELEASENOTES "DESKTOP_HID_DEPLOYMENT_GUI_UPDATE_RELEASENOTES"
+#define HID_DEPLOYMENT_GUI_UPDATE_AVAILABLE_UPDATES "DESKTOP_HID_DEPLOYMENT_GUI_UPDATE_AVAILABLE_UPDATES"
+
+#define HID_EXTENSION_MANAGER_LISTBOX "DESKTOP_HID_EXTENSION_MANAGER_LISTBOX"
+#define HID_EXTENSION_MANAGER_LISTBOX_OPTIONS "DESKTOP_HID_EXTENSION_MANAGER_LISTBOX_OPTIONS"
+#define HID_EXTENSION_MANAGER_LISTBOX_ENABLE "DESKTOP_HID_EXTENSION_MANAGER_LISTBOX_ENABLE"
+#define HID_EXTENSION_MANAGER_LISTBOX_DISABLE "DESKTOP_HID_EXTENSION_MANAGER_LISTBOX_DISABLE"
+#define HID_EXTENSION_MANAGER_LISTBOX_REMOVE "DESKTOP_HID_EXTENSION_MANAGER_LISTBOX_REMOVE"
+
+#define HID_EXTENSION_DEPENDENCIES "DESKTOP_HID_EXTENSION_DEPENDENCIES"
+
+#define HID_PACKAGE_MANAGER_UPD_REQ "DESKTOP_HID_PACKAGE_MANAGER_UPD_REQ"
+
+#endif
+
diff --git a/desktop/source/migration/makefile.mk b/desktop/source/migration/makefile.mk
new file mode 100755
index 000000000000..b20b4c57974f
--- /dev/null
+++ b/desktop/source/migration/makefile.mk
@@ -0,0 +1,52 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+PRJNAME=desktop
+TARGET=mig
+AUTOSEG=true
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+RSCEXTINC=..$/app
+
+# hacky - is no define
+CDEFS+=-I..$/app
+CDEFS+=-I$(PRJ)/inc
+
+SLOFILES = \
+ $(SLO)$/migration.obj
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/desktop/source/migration/migration.cxx b/desktop/source/migration/migration.cxx
new file mode 100644
index 000000000000..1ed91e906886
--- /dev/null
+++ b/desktop/source/migration/migration.cxx
@@ -0,0 +1,1356 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include <map>
+#include <new>
+#include <set>
+
+#include "migration.hxx"
+#include "migration_impl.hxx"
+
+#include <unotools/textsearch.hxx>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/sequence.hxx>
+#include <unotools/bootstrap.hxx>
+#include <rtl/bootstrap.hxx>
+#include <rtl/uri.hxx>
+#include <tools/config.hxx>
+#include <i18npool/lang.h>
+#include <tools/urlobj.hxx>
+#include <osl/file.hxx>
+#include <osl/mutex.hxx>
+#include <ucbhelper/content.hxx>
+#include <osl/security.hxx>
+#include <unotools/configmgr.hxx>
+
+#include <com/sun/star/configuration/Update.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/task/XJob.hpp>
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/util/XRefreshable.hpp>
+#include <com/sun/star/util/XChangesBatch.hpp>
+#include <com/sun/star/util/XStringSubstitution.hpp>
+#include <com/sun/star/embed/ElementModes.hpp>
+#include <com/sun/star/embed/XStorage.hpp>
+#include <com/sun/star/ui/XUIConfiguration.hpp>
+#include <com/sun/star/ui/XUIConfigurationStorage.hpp>
+#include <com/sun/star/ui/XUIConfigurationPersistence.hpp>
+
+using namespace osl;
+using namespace std;
+using namespace com::sun::star::task;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::util;
+using namespace com::sun::star::container;
+using com::sun::star::uno::Exception;
+using namespace com::sun::star;
+
+using ::rtl::OUString;
+using ::rtl::OString;
+
+namespace desktop {
+
+static const ::rtl::OUString ITEM_DESCRIPTOR_COMMANDURL(RTL_CONSTASCII_USTRINGPARAM("CommandURL"));
+static const ::rtl::OUString ITEM_DESCRIPTOR_CONTAINER(RTL_CONSTASCII_USTRINGPARAM("ItemDescriptorContainer"));
+static const ::rtl::OUString ITEM_DESCRIPTOR_LABEL(RTL_CONSTASCII_USTRINGPARAM("Label"));
+
+static const ::rtl::OUString MENU_SEPERATOR(RTL_CONSTASCII_USTRINGPARAM(" | "));
+static const ::rtl::OUString MENU_SUBMENU(RTL_CONSTASCII_USTRINGPARAM("..."));
+static const ::rtl::OUString MIGRATION_STAMP_NAME(RTL_CONSTASCII_USTRINGPARAM("/MIGRATED"));
+
+::rtl::OUString retrieveLabelFromCommand(const ::rtl::OUString& sCommand, const ::rtl::OUString& sModuleIdentifier)
+{
+ ::rtl::OUString sLabel;
+
+ uno::Reference< container::XNameAccess > xUICommands;
+ uno::Reference< container::XNameAccess > xNameAccess( ::comphelper::getProcessServiceFactory()->createInstance( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.UICommandDescription")) ), uno::UNO_QUERY );
+ if ( xNameAccess.is() )
+ {
+ uno::Any a = xNameAccess->getByName( sModuleIdentifier );
+ a >>= xUICommands;
+ }
+ if (xUICommands.is())
+ {
+ if ( sCommand.getLength() > 0 )
+ {
+ rtl::OUString aStr;
+ ::uno::Sequence< beans::PropertyValue > aPropSeq;
+ try
+ {
+ uno::Any a( xUICommands->getByName( sCommand ));
+ if ( a >>= aPropSeq )
+ {
+ for ( sal_Int32 i = 0; i < aPropSeq.getLength(); i++ )
+ {
+ if ( aPropSeq[i].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Label" ) ))
+ {
+ aPropSeq[i].Value >>= aStr;
+ break;
+ }
+ }
+ }
+
+ sLabel = aStr;
+ }
+
+ catch(container::NoSuchElementException&)
+ {
+ sLabel = sCommand;
+ sal_Int32 nIndex = sLabel.indexOf(':');
+ if (nIndex>=0 && nIndex <= sLabel.getLength()-1)
+ sLabel = sLabel.copy(nIndex+1);
+ }
+
+ }
+ }
+
+ return sLabel;
+}
+
+::rtl::OUString mapModuleShortNameToIdentifier(const ::rtl::OUString& sShortName)
+{
+ ::rtl::OUString sIdentifier;
+
+ if (sShortName.equals(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("StartModule"))))
+ sIdentifier = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.StartModule"));
+
+ else if (sShortName.equals(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("swriter"))))
+ sIdentifier = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.text.TextDocument"));
+
+ else if (sShortName.equals(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("scalc"))))
+ sIdentifier = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sheet.SpreadsheetDocument"));
+
+ else if (sShortName.equals(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("sdraw"))))
+ sIdentifier = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.drawing.DrawingDocument"));
+
+ else if (sShortName.equals(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("simpress"))))
+ sIdentifier = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.presentation.PresentationDocument"));
+
+ else if (sShortName.equals(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("smath"))))
+ sIdentifier = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.formula.FormulaProperties"));
+
+ else if (sShortName.equals(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("schart"))))
+ sIdentifier = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.chart2.ChartDocument"));
+
+ else if (sShortName.equals(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("BasicIDE"))))
+ sIdentifier = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.script.BasicIDE"));
+
+ else if (sShortName.equals(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("dbapp"))))
+ sIdentifier = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sdb.OfficeDatabaseDocument"));
+
+ else if (sShortName.equals(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("sglobal"))))
+ sIdentifier = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.text.GlobalDocument"));
+
+ else if (sShortName.equals(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("sweb"))))
+ sIdentifier = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.text.WebDocument"));
+
+ else if (sShortName.equals(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("swxform"))))
+ sIdentifier = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.xforms.XMLFormDocument"));
+
+ else if (sShortName.equals(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("sbibliography"))))
+ sIdentifier = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.Bibliography"));
+
+ return sIdentifier;
+}
+
+bool MigrationImpl::alreadyMigrated()
+{
+ rtl::OUString aStr = m_aInfo.userdata + MIGRATION_STAMP_NAME;
+ File aFile(aStr);
+ // create migration stamp, and/or check its existence
+ bool bRet = aFile.open (osl_File_OpenFlag_Write | osl_File_OpenFlag_Create | osl_File_OpenFlag_NoLock) == FileBase::E_EXIST;
+ OSL_TRACE( "File '%s' exists? %d\n",
+ rtl::OUStringToOString(aStr, RTL_TEXTENCODING_ASCII_US).getStr(),
+ bRet );
+ return bRet;
+}
+
+bool MigrationImpl::initializeMigration()
+{
+ bool bRet = false;
+
+ if (!checkMigrationCompleted()) {
+ readAvailableMigrations(m_vMigrationsAvailable);
+ sal_Int32 nIndex = findPreferedMigrationProcess(m_vMigrationsAvailable);
+ // m_aInfo is now set to the preferred migration source
+ if ( nIndex >= 0 ) {
+ if (alreadyMigrated())
+ return false;
+ m_vrMigrations = readMigrationSteps(m_vMigrationsAvailable[nIndex].name);
+ }
+
+ bRet = m_aInfo.userdata.getLength() > 0;
+ }
+
+ OSL_TRACE( "Migration %s\n", bRet ? "needed" : "not required" );
+
+ return bRet;
+}
+
+void Migration::migrateSettingsIfNecessary()
+{
+ MigrationImpl aImpl( comphelper::getProcessServiceFactory() );
+
+ if (! aImpl.initializeMigration() )
+ return;
+
+ sal_Bool bResult = sal_False;
+ try {
+ bResult = aImpl.doMigration();
+ } catch (Exception& e)
+ {
+ OString aMsg("doMigration() exception: ");
+ aMsg += OUStringToOString(e.Message, RTL_TEXTENCODING_ASCII_US);
+ OSL_FAIL(aMsg.getStr());
+ }
+ OSL_ENSURE(bResult, "Migration has not been successfull");
+ (void)bResult;
+}
+
+MigrationImpl::MigrationImpl(const uno::Reference< XMultiServiceFactory >& xFactory)
+ : m_vrVersions(new strings_v)
+ , m_xFactory(xFactory)
+{
+}
+
+MigrationImpl::~MigrationImpl()
+{
+}
+
+// The main entry point for migrating settings
+sal_Bool MigrationImpl::doMigration()
+{
+ // compile file list for migration
+ m_vrFileList = compileFileList();
+
+ sal_Bool result = sal_False;
+ try
+ {
+ NewVersionUIInfo aNewVersionUIInfo;
+ ::std::vector< MigrationModuleInfo > vModulesInfo = dectectUIChangesForAllModules();
+ aNewVersionUIInfo.init(vModulesInfo);
+
+ copyFiles();
+
+ const ::rtl::OUString sMenubarResourceURL(RTL_CONSTASCII_USTRINGPARAM("private:resource/menubar/menubar"));
+ const ::rtl::OUString sToolbarResourcePre(RTL_CONSTASCII_USTRINGPARAM("private:resource/toolbar/"));
+ for (sal_uInt32 i=0; i<vModulesInfo.size(); ++i)
+ {
+ ::rtl::OUString sModuleIdentifier = mapModuleShortNameToIdentifier(vModulesInfo[i].sModuleShortName);
+ if (sModuleIdentifier.getLength()==0)
+ continue;
+
+ uno::Sequence< uno::Any > lArgs(2);
+ ::rtl::OUString aOldCfgDataPath = m_aInfo.userdata + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/user/config/soffice.cfg/modules/"));
+ lArgs[0] <<= aOldCfgDataPath + vModulesInfo[i].sModuleShortName;
+ lArgs[1] <<= embed::ElementModes::READ;
+
+ uno::Reference< lang::XSingleServiceFactory > xStorageFactory(m_xFactory->createInstance(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.embed.FileSystemStorageFactory"))), uno::UNO_QUERY);
+ uno::Reference< embed::XStorage > xModules;
+
+ xModules = uno::Reference< embed::XStorage >(xStorageFactory->createInstanceWithArguments(lArgs), uno::UNO_QUERY);
+ uno::Reference< ui::XUIConfigurationManager > xOldCfgManager( m_xFactory->createInstance( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.ui.UIConfigurationManager"))), uno::UNO_QUERY );
+ uno::Reference< ui::XUIConfigurationStorage > xOldCfgStorage( xOldCfgManager, uno::UNO_QUERY );
+ uno::Reference< ui::XUIConfigurationPersistence > xOldCfgPersistence( xOldCfgManager, uno::UNO_QUERY );
+
+ if ( xOldCfgStorage.is() && xOldCfgPersistence.is() && xModules.is() )
+ {
+ xOldCfgStorage->setStorage( xModules );
+ xOldCfgPersistence->reload();
+ }
+
+ uno::Reference< ui::XUIConfigurationManager > xCfgManager = aNewVersionUIInfo.getConfigManager(vModulesInfo[i].sModuleShortName);
+
+ if (vModulesInfo[i].bHasMenubar)
+ {
+ uno::Reference< container::XIndexContainer > xOldVersionMenuSettings = uno::Reference< container::XIndexContainer >(xOldCfgManager->getSettings(sMenubarResourceURL, sal_True), uno::UNO_QUERY);
+ uno::Reference< container::XIndexContainer > xNewVersionMenuSettings = aNewVersionUIInfo.getNewMenubarSettings(vModulesInfo[i].sModuleShortName);
+ ::rtl::OUString sParent;
+ compareOldAndNewConfig(sParent, xOldVersionMenuSettings, xNewVersionMenuSettings, sMenubarResourceURL);
+ mergeOldToNewVersion(xCfgManager, xNewVersionMenuSettings, sModuleIdentifier, sMenubarResourceURL);
+ }
+
+ sal_Int32 nToolbars = vModulesInfo[i].m_vToolbars.size();
+ if (nToolbars >0)
+ {
+ for (sal_Int32 j=0; j<nToolbars; ++j)
+ {
+ ::rtl::OUString sToolbarName = vModulesInfo[i].m_vToolbars[j];
+ ::rtl::OUString sToolbarResourceURL = sToolbarResourcePre + sToolbarName;
+
+ uno::Reference< container::XIndexContainer > xOldVersionToolbarSettings = uno::Reference< container::XIndexContainer >(xOldCfgManager->getSettings(sToolbarResourceURL, sal_True), uno::UNO_QUERY);
+ uno::Reference< container::XIndexContainer > xNewVersionToolbarSettings = aNewVersionUIInfo.getNewToolbarSettings(vModulesInfo[i].sModuleShortName, sToolbarName);
+ ::rtl::OUString sParent;
+ compareOldAndNewConfig(sParent, xOldVersionToolbarSettings, xNewVersionToolbarSettings, sToolbarResourceURL);
+ mergeOldToNewVersion(xCfgManager, xNewVersionToolbarSettings, sModuleIdentifier, sToolbarResourceURL);
+ }
+ }
+
+ m_aOldVersionItemsHashMap.clear();
+ m_aNewVersionItemsHashMap.clear();
+ }
+
+ // execute the migration items from Setup.xcu
+ copyConfig();
+
+ // execute custom migration services from Setup.xcu
+ // and refresh the cache
+ runServices();
+ refresh();
+
+ result = sal_True;
+ } catch (...)
+ {
+ OString aMsg("An unexpected exception was thrown during migration");
+ aMsg += "\nOldVersion: " + OUStringToOString(m_aInfo.productname, RTL_TEXTENCODING_ASCII_US);
+ aMsg += "\nDataPath : " + OUStringToOString(m_aInfo.userdata, RTL_TEXTENCODING_ASCII_US);
+ OSL_FAIL(aMsg.getStr());
+ }
+
+ // prevent running the migration multiple times
+ setMigrationCompleted();
+ return result;
+}
+
+void MigrationImpl::refresh()
+{
+ uno::Reference< XRefreshable > xRefresh(m_xFactory->createInstance(
+ OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.configuration.ConfigurationProvider"))), uno::UNO_QUERY);
+ if (xRefresh.is())
+ xRefresh->refresh();
+ else
+ OSL_FAIL("could not get XRefresh interface from default config provider. No refresh done.");
+
+}
+
+void MigrationImpl::setMigrationCompleted()
+{
+ try {
+ uno::Reference< XPropertySet > aPropertySet(getConfigAccess("org.openoffice.Setup/Office", true), uno::UNO_QUERY_THROW);
+ aPropertySet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("MigrationCompleted")), uno::makeAny(sal_True));
+ uno::Reference< XChangesBatch >(aPropertySet, uno::UNO_QUERY_THROW)->commitChanges();
+ } catch (...) {
+ // fail silently
+ }
+}
+
+bool MigrationImpl::checkMigrationCompleted()
+{
+ sal_Bool bMigrationCompleted = sal_False;
+ try {
+ uno::Reference< XPropertySet > aPropertySet(
+ getConfigAccess("org.openoffice.Setup/Office"), uno::UNO_QUERY_THROW);
+ aPropertySet->getPropertyValue(
+ OUString(RTL_CONSTASCII_USTRINGPARAM("MigrationCompleted"))) >>= bMigrationCompleted;
+
+ if( !bMigrationCompleted && getenv("SAL_DISABLE_USERMIGRATION" ) )
+ {
+ // migration prevented - fake it's success
+ setMigrationCompleted();
+ bMigrationCompleted = sal_True;
+ }
+ } catch (Exception&) {
+ // just return false...
+ }
+ OSL_TRACE( "Migration %s", bMigrationCompleted ? "already completed" : "not done" );
+
+ return bMigrationCompleted;
+}
+
+static void insertSorted(migrations_available& rAvailableMigrations, supported_migration& aSupportedMigration)
+{
+ bool bInserted( false );
+ migrations_available::iterator pIter = rAvailableMigrations.begin();
+ while ( !bInserted && pIter != rAvailableMigrations.end())
+ {
+ if ( pIter->nPriority < aSupportedMigration.nPriority )
+ {
+ rAvailableMigrations.insert(pIter, aSupportedMigration );
+ bInserted = true;
+ break; // i111193: insert invalidates iterator!
+ }
+ ++pIter;
+ }
+ if ( !bInserted )
+ rAvailableMigrations.push_back( aSupportedMigration );
+}
+
+bool MigrationImpl::readAvailableMigrations(migrations_available& rAvailableMigrations)
+{
+ // get supported version names
+ uno::Reference< XNameAccess > aMigrationAccess(getConfigAccess("org.openoffice.Setup/Migration/SupportedVersions"), uno::UNO_QUERY_THROW);
+ uno::Sequence< OUString > seqSupportedVersions = aMigrationAccess->getElementNames();
+
+ const OUString aVersionIdentifiers( RTL_CONSTASCII_USTRINGPARAM( "VersionIdentifiers" ));
+ const OUString aPriorityIdentifier( RTL_CONSTASCII_USTRINGPARAM( "Priority" ));
+
+ for (sal_Int32 i=0; i<seqSupportedVersions.getLength(); i++)
+ {
+ sal_Int32 nPriority( 0 );
+ uno::Sequence< OUString > seqVersions;
+ uno::Reference< XNameAccess > xMigrationData( aMigrationAccess->getByName(seqSupportedVersions[i]), uno::UNO_QUERY_THROW );
+ xMigrationData->getByName( aVersionIdentifiers ) >>= seqVersions;
+ xMigrationData->getByName( aPriorityIdentifier ) >>= nPriority;
+
+ supported_migration aSupportedMigration;
+ aSupportedMigration.name = seqSupportedVersions[i];
+ aSupportedMigration.nPriority = nPriority;
+ for (sal_Int32 j=0; j<seqVersions.getLength(); j++)
+ aSupportedMigration.supported_versions.push_back(seqVersions[j].trim());
+ insertSorted( rAvailableMigrations, aSupportedMigration );
+ OSL_TRACE( " available migration '%s'\n",
+ rtl::OUStringToOString( aSupportedMigration.name, RTL_TEXTENCODING_ASCII_US ).getStr() );
+ }
+
+ return true;
+}
+
+migrations_vr MigrationImpl::readMigrationSteps(const ::rtl::OUString& rMigrationName)
+{
+ // get migration access
+ uno::Reference< XNameAccess > aMigrationAccess(getConfigAccess("org.openoffice.Setup/Migration/SupportedVersions"), uno::UNO_QUERY_THROW);
+ uno::Reference< XNameAccess > xMigrationData( aMigrationAccess->getByName(rMigrationName), uno::UNO_QUERY_THROW );
+
+ // get migration description from from org.openoffice.Setup/Migration
+ // and build vector of migration steps
+ OUString aMigrationSteps( RTL_CONSTASCII_USTRINGPARAM( "MigrationSteps" ));
+ uno::Reference< XNameAccess > theNameAccess(xMigrationData->getByName(aMigrationSteps), uno::UNO_QUERY_THROW);
+ uno::Sequence< OUString > seqMigrations = theNameAccess->getElementNames();
+ uno::Reference< XNameAccess > tmpAccess;
+ uno::Reference< XNameAccess > tmpAccess2;
+ uno::Sequence< OUString > tmpSeq;
+ migrations_vr vrMigrations(new migrations_v);
+ for (sal_Int32 i = 0; i < seqMigrations.getLength(); i++)
+ {
+ // get current migration step
+ theNameAccess->getByName(seqMigrations[i]) >>= tmpAccess;
+ migration_step tmpStep;
+ tmpStep.name = seqMigrations[i];
+
+ // read included files from current step description
+ ::rtl::OUString aSeqEntry;
+ if (tmpAccess->getByName(OUString(RTL_CONSTASCII_USTRINGPARAM("IncludedFiles"))) >>= tmpSeq)
+ {
+ for (sal_Int32 j=0; j<tmpSeq.getLength(); j++)
+ {
+ aSeqEntry = tmpSeq[j];
+ tmpStep.includeFiles.push_back(aSeqEntry);
+ }
+ }
+
+ // exluded files...
+ if (tmpAccess->getByName(OUString(RTL_CONSTASCII_USTRINGPARAM("ExcludedFiles"))) >>= tmpSeq)
+ {
+ for (sal_Int32 j=0; j<tmpSeq.getLength(); j++)
+ tmpStep.excludeFiles.push_back(tmpSeq[j]);
+ }
+
+ // included nodes...
+ if (tmpAccess->getByName(OUString(RTL_CONSTASCII_USTRINGPARAM("IncludedNodes"))) >>= tmpSeq)
+ {
+ for (sal_Int32 j=0; j<tmpSeq.getLength(); j++)
+ tmpStep.includeConfig.push_back(tmpSeq[j]);
+ }
+
+ // excluded nodes...
+ if (tmpAccess->getByName(OUString(RTL_CONSTASCII_USTRINGPARAM("ExcludedNodes"))) >>= tmpSeq)
+ {
+ for (sal_Int32 j=0; j<tmpSeq.getLength(); j++)
+ tmpStep.excludeConfig.push_back(tmpSeq[j]);
+ }
+
+ // included extensions...
+ if (tmpAccess->getByName(OUString(RTL_CONSTASCII_USTRINGPARAM("IncludedExtensions"))) >>= tmpSeq)
+ {
+ for (sal_Int32 j=0; j<tmpSeq.getLength(); j++)
+ tmpStep.includeExtensions.push_back(tmpSeq[j]);
+ }
+
+ // excluded extensions...
+ if (tmpAccess->getByName(OUString(RTL_CONSTASCII_USTRINGPARAM("ExcludedExtensions"))) >>= tmpSeq)
+ {
+ for (sal_Int32 j=0; j<tmpSeq.getLength(); j++)
+ {
+ aSeqEntry = tmpSeq[j];
+ tmpStep.excludeExtensions.push_back(aSeqEntry);
+ }
+ }
+
+ // generic service
+ tmpAccess->getByName(OUString(RTL_CONSTASCII_USTRINGPARAM("MigrationService"))) >>= tmpStep.service;
+
+ vrMigrations->push_back(tmpStep);
+ }
+ return vrMigrations;
+}
+
+static FileBase::RC _checkAndCreateDirectory(INetURLObject& dirURL)
+{
+ FileBase::RC result = Directory::create(dirURL.GetMainURL(INetURLObject::DECODE_TO_IURI));
+ if (result == FileBase::E_NOENT)
+ {
+ INetURLObject baseURL(dirURL);
+ baseURL.removeSegment();
+ _checkAndCreateDirectory(baseURL);
+ return Directory::create(dirURL.GetMainURL(INetURLObject::DECODE_TO_IURI));
+ } else
+ return result;
+}
+
+install_info MigrationImpl::findInstallation(const strings_v& rVersions)
+{
+ rtl::OUString aProductName;
+ uno::Any aRet = ::utl::ConfigManager::GetDirectConfigProperty( ::utl::ConfigManager::PRODUCTNAME );
+ aRet >>= aProductName;
+ aProductName = aProductName.toAsciiLowerCase();
+
+ install_info aInfo;
+ strings_v::const_iterator i_ver = rVersions.begin();
+ uno::Reference < util::XStringSubstitution > xSubst( ::comphelper::getProcessServiceFactory()->createInstance(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.util.PathSubstitution"))), uno::UNO_QUERY );
+ while (i_ver != rVersions.end())
+ {
+ ::rtl::OUString aVersion, aProfileName;
+ sal_Int32 nSeparatorIndex = (*i_ver).indexOf('=');
+ if ( nSeparatorIndex != -1 )
+ {
+ aVersion = (*i_ver).copy( 0, nSeparatorIndex );
+ aProfileName = (*i_ver).copy( nSeparatorIndex+1 );
+ }
+
+ if ( aVersion.getLength() && aProfileName.getLength() &&
+ ( !aInfo.userdata.getLength() || !aProfileName.toAsciiLowerCase().compareTo( aProductName, aProductName.getLength() ) )
+ )
+ {
+ ::rtl::OUString aUserInst;
+ osl::Security().getConfigDir( aUserInst );
+ if ( aUserInst.getLength() && aUserInst[ aUserInst.getLength()-1 ] != '/' )
+ aUserInst += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/"));
+#if defined UNX && ! defined MACOSX
+ // tribute to whoever had the "great" idea to use different names on Windows and Unix
+ aUserInst += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("."));
+#endif
+ aUserInst += aProfileName;
+ try
+ {
+ INetURLObject aObj(aUserInst);
+ ::ucbhelper::Content aCnt( aObj.GetMainURL( INetURLObject::NO_DECODE ), uno::Reference< ucb::XCommandEnvironment > () );
+ aCnt.isDocument();
+ aInfo.userdata = aObj.GetMainURL( INetURLObject::NO_DECODE );
+ aInfo.productname = aVersion;
+ }
+ catch( uno::Exception& ){}
+ }
+ ++i_ver;
+ }
+
+ return aInfo;
+}
+
+sal_Int32 MigrationImpl::findPreferedMigrationProcess(const migrations_available& rAvailableMigrations)
+{
+ sal_Int32 nIndex( -1 );
+ sal_Int32 i( 0 );
+
+ migrations_available::const_iterator rIter = rAvailableMigrations.begin();
+ while ( rIter != rAvailableMigrations.end() )
+ {
+ install_info aInstallInfo = findInstallation(rIter->supported_versions);
+ if (aInstallInfo.productname.getLength() > 0 )
+ {
+ m_aInfo = aInstallInfo;
+ nIndex = i;
+ break;
+ }
+ ++i;
+ ++rIter;
+ }
+
+ OSL_TRACE( " preferred migration is from product '%s'\n",
+ rtl::OUStringToOString( m_aInfo.productname, RTL_TEXTENCODING_ASCII_US ).getStr() );
+ OSL_TRACE( " and settings directory '%s'\n",
+ rtl::OUStringToOString( m_aInfo.userdata, RTL_TEXTENCODING_ASCII_US ).getStr() );
+
+ return nIndex;
+}
+
+strings_vr MigrationImpl::applyPatterns(const strings_v& vSet, const strings_v& vPatterns) const
+{
+ using namespace utl;
+ strings_vr vrResult(new strings_v);
+ strings_v::const_iterator i_set;
+ strings_v::const_iterator i_pat = vPatterns.begin();
+ while (i_pat != vPatterns.end())
+ {
+ // find matches for this pattern in input set
+ // and copy them to the result
+ SearchParam param(*i_pat, SearchParam::SRCH_REGEXP);
+ TextSearch ts(param, LANGUAGE_DONTKNOW);
+ i_set = vSet.begin();
+ xub_StrLen start = 0;
+ xub_StrLen end = 0;
+ while (i_set != vSet.end())
+ {
+ end = (xub_StrLen)(i_set->getLength());
+ if (ts.SearchFrwrd(*i_set, &start, &end))
+ vrResult->push_back(*i_set);
+ ++i_set;
+ }
+ ++i_pat;
+ }
+ return vrResult;
+}
+
+strings_vr MigrationImpl::getAllFiles(const OUString& baseURL) const
+{
+ using namespace osl;
+ strings_vr vrResult(new strings_v);
+
+ // get sub dirs
+ Directory dir(baseURL);
+ if (dir.open() == FileBase::E_None)
+ {
+ strings_v vSubDirs;
+ strings_vr vrSubResult;
+
+ // work through directory contents...
+ DirectoryItem item;
+ FileStatus fs(FileStatusMask_Type | FileStatusMask_FileURL);
+ while (dir.getNextItem(item) == FileBase::E_None)
+ {
+ if (item.getFileStatus(fs) == FileBase::E_None)
+ {
+ if (fs.getFileType() == FileStatus::Directory)
+ vSubDirs.push_back(fs.getFileURL());
+ else
+ vrResult->push_back(fs.getFileURL());
+ }
+ }
+
+ // recurse subfolders
+ strings_v::const_iterator i = vSubDirs.begin();
+ while (i != vSubDirs.end())
+ {
+ vrSubResult = getAllFiles(*i);
+ vrResult->insert(vrResult->end(), vrSubResult->begin(), vrSubResult->end());
+ ++i;
+ }
+ }
+ return vrResult;
+}
+
+strings_vr MigrationImpl::compileFileList()
+{
+
+ strings_vr vrResult(new strings_v);
+ strings_vr vrInclude;
+ strings_vr vrExclude;
+ strings_vr vrTemp;
+
+#ifdef SAL_OS2
+ if (m_aInfo.userdata.getLength() == 0)
+ return vrResult;
+#endif
+
+ // get a list of all files:
+ strings_vr vrFiles = getAllFiles(m_aInfo.userdata);
+
+ // get a file list result for each migration step
+ migrations_v::const_iterator i_migr = m_vrMigrations->begin();
+ while (i_migr != m_vrMigrations->end())
+ {
+ vrInclude = applyPatterns(*vrFiles, i_migr->includeFiles);
+ vrExclude = applyPatterns(*vrFiles, i_migr->excludeFiles);
+ subtract(*vrInclude, *vrExclude);
+ vrResult->insert(vrResult->end(), vrInclude->begin(), vrInclude->end());
+ ++i_migr;
+ }
+ return vrResult;
+}
+
+namespace {
+
+struct componentParts {
+ std::set< rtl::OUString > includedPaths;
+ std::set< rtl::OUString > excludedPaths;
+};
+
+typedef std::map< rtl::OUString, componentParts > Components;
+
+bool getComponent(rtl::OUString const & path, rtl::OUString * component) {
+ OSL_ASSERT(component != 0);
+ if (path.getLength() == 0 || path[0] != '/') {
+ OSL_TRACE(
+ ("configuration migration in/exclude path %s ignored (does not"
+ " start with slash)"),
+ rtl::OUStringToOString(path, RTL_TEXTENCODING_UTF8).getStr());
+ return false;
+ }
+ sal_Int32 i = path.indexOf('/', 1);
+ *component = i < 0 ? path.copy(1) : path.copy(1, i - 1);
+ return true;
+}
+
+uno::Sequence< rtl::OUString > setToSeq(std::set< rtl::OUString > const & set) {
+ std::set< rtl::OUString >::size_type n = set.size();
+ if (n > SAL_MAX_INT32) {
+ throw std::bad_alloc();
+ }
+ uno::Sequence< rtl::OUString > seq(static_cast< sal_Int32 >(n));
+ sal_Int32 i = 0;
+ for (std::set< rtl::OUString >::const_iterator j(set.begin());
+ j != set.end(); ++j)
+ {
+ seq[i++] = *j;
+ }
+ return seq;
+}
+
+}
+
+void MigrationImpl::copyConfig() {
+ Components comps;
+ for (migrations_v::const_iterator i(m_vrMigrations->begin());
+ i != m_vrMigrations->end(); ++i)
+ {
+ for (strings_v::const_iterator j(i->includeConfig.begin());
+ j != i->includeConfig.end(); ++j)
+ {
+ rtl::OUString comp;
+ if (getComponent(*j, &comp)) {
+ comps[comp].includedPaths.insert(*j);
+ }
+ }
+ for (strings_v::const_iterator j(i->excludeConfig.begin());
+ j != i->excludeConfig.end(); ++j)
+ {
+ rtl::OUString comp;
+ if (getComponent(*j, &comp)) {
+ comps[comp].excludedPaths.insert(*j);
+ }
+ }
+ }
+ for (Components::const_iterator i(comps.begin()); i != comps.end(); ++i) {
+ if (!i->second.includedPaths.empty()) {
+ rtl::OUStringBuffer buf(m_aInfo.userdata);
+ buf.appendAscii(RTL_CONSTASCII_STRINGPARAM("/user/registry/data"));
+ sal_Int32 n = 0;
+ do {
+ rtl::OUString seg(i->first.getToken(0, '.', n));
+ rtl::OUString enc(
+ rtl::Uri::encode(
+ seg, rtl_UriCharClassPchar, rtl_UriEncodeStrict,
+ RTL_TEXTENCODING_UTF8));
+ if (enc.getLength() == 0 && seg.getLength() != 0) {
+ OSL_TRACE(
+ ("configuration migration component %s ignored (cannot"
+ " be encoded as file path)"),
+ rtl::OUStringToOString(
+ i->first, RTL_TEXTENCODING_UTF8).getStr());
+ goto next;
+ }
+ buf.append(sal_Unicode('/'));
+ buf.append(enc);
+ } while (n >= 0);
+ buf.appendAscii(RTL_CONSTASCII_STRINGPARAM(".xcu"));
+ configuration::Update::get(
+ comphelper::getProcessComponentContext())->
+ insertModificationXcuFile(
+ buf.makeStringAndClear(), setToSeq(i->second.includedPaths),
+ setToSeq(i->second.excludedPaths));
+ } else {
+ OSL_TRACE(
+ ("configuration migration component %s ignored (only excludes,"
+ " no includes)"),
+ rtl::OUStringToOString(
+ i->first, RTL_TEXTENCODING_UTF8).getStr());
+ }
+ next:;
+ }
+}
+
+// removes elements of vector 2 in vector 1
+void MigrationImpl::subtract(strings_v& va, const strings_v& vb_c) const
+{
+ strings_v vb(vb_c);
+ // ensure uniqueness of entries
+ sort(va.begin(), va.end());
+ sort(vb.begin(), vb.end());
+ unique(va.begin(), va.end());
+ unique(vb.begin(), vb.end());
+
+ strings_v::const_iterator i_ex = vb.begin();
+ strings_v::iterator i_in;
+ strings_v::iterator i_next;
+ while (i_ex != vb.end())
+ {
+ i_in = va.begin();
+ while (i_in != va.end())
+ {
+ if ( *i_in == *i_ex)
+ {
+ i_next = i_in+1;
+ va.erase(i_in);
+ i_in = i_next;
+ // we can only find one match since we
+ // ensured uniquness of the entries. ergo:
+ break;
+ }
+ else
+ ++i_in;
+ }
+ ++i_ex;
+ }
+}
+
+uno::Reference< XNameAccess > MigrationImpl::getConfigAccess(const sal_Char* pPath, sal_Bool bUpdate)
+{
+ uno::Reference< XNameAccess > xNameAccess;
+ try{
+ OUString sConfigSrvc(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.configuration.ConfigurationProvider"));
+ OUString sAccessSrvc;
+ if (bUpdate)
+ sAccessSrvc = OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.configuration.ConfigurationUpdateAccess"));
+ else
+ sAccessSrvc = OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.configuration.ConfigurationAccess"));
+
+ OUString sConfigURL = OUString::createFromAscii(pPath);
+
+ // get configuration provider
+ uno::Reference< XMultiServiceFactory > theMSF = comphelper::getProcessServiceFactory();
+ uno::Reference< XMultiServiceFactory > theConfigProvider = uno::Reference< XMultiServiceFactory > (
+ theMSF->createInstance( sConfigSrvc ),uno::UNO_QUERY_THROW );
+
+ // access the provider
+ uno::Sequence< uno::Any > theArgs(1);
+ theArgs[ 0 ] <<= sConfigURL;
+ xNameAccess = uno::Reference< XNameAccess > (
+ theConfigProvider->createInstanceWithArguments(
+ sAccessSrvc, theArgs ), uno::UNO_QUERY_THROW );
+ } catch (com::sun::star::uno::Exception& e)
+ {
+ OString aMsg = OUStringToOString(e.Message, RTL_TEXTENCODING_ASCII_US);
+ OSL_FAIL(aMsg.getStr());
+ }
+ return xNameAccess;
+}
+
+void MigrationImpl::copyFiles()
+{
+ strings_v::const_iterator i_file = m_vrFileList->begin();
+ OUString localName;
+ OUString destName;
+ OUString userInstall;
+ utl::Bootstrap::PathStatus aStatus;
+ aStatus = utl::Bootstrap::locateUserInstallation(userInstall);
+ if (aStatus == utl::Bootstrap::PATH_EXISTS)
+ {
+ while (i_file != m_vrFileList->end())
+ {
+ // remove installation prefix from file
+ localName = i_file->copy(m_aInfo.userdata.getLength());
+ destName = userInstall + localName;
+ INetURLObject aURL(destName);
+ // check whether destination directory exists
+ aURL.removeSegment();
+ _checkAndCreateDirectory(aURL);
+ FileBase::RC copyResult = File::copy(*i_file, destName);
+ if (copyResult != FileBase::E_None)
+ {
+ OString msg("Cannot copy ");
+ msg += OUStringToOString(*i_file, RTL_TEXTENCODING_UTF8) + " to "
+ + OUStringToOString(destName, RTL_TEXTENCODING_UTF8);
+ OSL_FAIL(msg.getStr());
+ }
+ ++i_file;
+ }
+ }
+ else
+ {
+ OSL_FAIL("copyFiles: UserInstall does not exist");
+ }
+}
+
+void MigrationImpl::runServices()
+{
+ // Build argument array
+ uno::Sequence< uno::Any > seqArguments(3);
+ seqArguments[0] = uno::makeAny(NamedValue(
+ OUString(RTL_CONSTASCII_USTRINGPARAM("Productname")),
+ uno::makeAny(m_aInfo.productname)));
+ seqArguments[1] = uno::makeAny(NamedValue(
+ OUString(RTL_CONSTASCII_USTRINGPARAM("UserData")),
+ uno::makeAny(m_aInfo.userdata)));
+
+
+ // create an instance of every migration service
+ // and execute the migration job
+ uno::Reference< XJob > xMigrationJob;
+
+ migrations_v::const_iterator i_mig = m_vrMigrations->begin();
+ while (i_mig != m_vrMigrations->end())
+ {
+ if( i_mig->service.getLength() > 0)
+ {
+
+ try
+ {
+ // set black list for extension migration
+ uno::Sequence< rtl::OUString > seqExtBlackList;
+ sal_uInt32 nSize = i_mig->excludeExtensions.size();
+ if ( nSize > 0 )
+ seqExtBlackList = comphelper::arrayToSequence< ::rtl::OUString >(
+ &i_mig->excludeExtensions[0], nSize );
+ seqArguments[2] = uno::makeAny(NamedValue(
+ OUString(RTL_CONSTASCII_USTRINGPARAM("ExtensionBlackList")),
+ uno::makeAny( seqExtBlackList )));
+
+ xMigrationJob = uno::Reference< XJob >(m_xFactory->createInstanceWithArguments(
+ i_mig->service, seqArguments), uno::UNO_QUERY_THROW);
+
+ xMigrationJob->execute(uno::Sequence< NamedValue >());
+
+
+ } catch (Exception& e)
+ {
+ OString aMsg("Execution of migration service failed (Exception caught).\nService: ");
+ aMsg += OUStringToOString(i_mig->service, RTL_TEXTENCODING_ASCII_US) + "\nMessage: ";
+ aMsg += OUStringToOString(e.Message, RTL_TEXTENCODING_ASCII_US);
+ OSL_FAIL(aMsg.getStr());
+ } catch (...)
+ {
+ OString aMsg("Execution of migration service failed (Exception caught).\nService: ");
+ aMsg += OUStringToOString(i_mig->service, RTL_TEXTENCODING_ASCII_US) +
+ "\nNo message available";
+ OSL_FAIL(aMsg.getStr());
+ }
+
+ }
+ ++i_mig;
+ }
+}
+
+::std::vector< MigrationModuleInfo > MigrationImpl::dectectUIChangesForAllModules() const
+{
+ ::std::vector< MigrationModuleInfo > vModulesInfo;
+ const ::rtl::OUString MENUBAR(RTL_CONSTASCII_USTRINGPARAM("menubar"));
+ const ::rtl::OUString TOOLBAR(RTL_CONSTASCII_USTRINGPARAM("toolbar"));
+
+ uno::Sequence< uno::Any > lArgs(2);
+ lArgs[0] <<= m_aInfo.userdata + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/user/config/soffice.cfg/modules"));
+ lArgs[1] <<= embed::ElementModes::READ;
+
+ uno::Reference< lang::XSingleServiceFactory > xStorageFactory(m_xFactory->createInstance(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.embed.FileSystemStorageFactory"))), uno::UNO_QUERY);
+ uno::Reference< embed::XStorage > xModules;
+
+ xModules = uno::Reference< embed::XStorage >(xStorageFactory->createInstanceWithArguments(lArgs), uno::UNO_QUERY);
+ if (!xModules.is())
+ return vModulesInfo;
+
+ uno::Reference< container::XNameAccess > xAccess = uno::Reference< container::XNameAccess >(xModules, uno::UNO_QUERY);
+ uno::Sequence< ::rtl::OUString > lNames = xAccess->getElementNames();
+ sal_Int32 nLength = lNames.getLength();
+ for (sal_Int32 i=0; i<nLength; ++i)
+ {
+ ::rtl::OUString sModuleShortName = lNames[i];
+ uno::Reference< embed::XStorage > xModule = xModules->openStorageElement(sModuleShortName, embed::ElementModes::READ);
+ if (xModule.is())
+ {
+ MigrationModuleInfo aModuleInfo;
+
+ uno::Reference< embed::XStorage > xMenubar = xModule->openStorageElement(MENUBAR, embed::ElementModes::READ);
+ if (xMenubar.is())
+ {
+ uno::Reference< container::XNameAccess > xNameAccess = uno::Reference< container::XNameAccess >(xMenubar, uno::UNO_QUERY);
+ if (xNameAccess->getElementNames().getLength() > 0)
+ {
+ aModuleInfo.sModuleShortName = sModuleShortName;
+ aModuleInfo.bHasMenubar = sal_True;
+ }
+ }
+
+ uno::Reference< embed::XStorage > xToolbar = xModule->openStorageElement(TOOLBAR, embed::ElementModes::READ);
+ if (xToolbar.is())
+ {
+ const ::rtl::OUString RESOURCEURL_CUSTOM_ELEMENT(RTL_CONSTASCII_USTRINGPARAM("custom_"));
+ sal_Int32 nCustomLen = 7;
+
+ uno::Reference< container::XNameAccess > xNameAccess = uno::Reference< container::XNameAccess >(xToolbar, uno::UNO_QUERY);
+ ::uno::Sequence< ::rtl::OUString > lToolbars = xNameAccess->getElementNames();
+ for (sal_Int32 j=0; j<lToolbars.getLength(); ++j)
+ {
+ ::rtl::OUString sToolbarName = lToolbars[j];
+ if (sToolbarName.getLength()>=nCustomLen &&
+ sToolbarName.copy(0, nCustomLen).equals(RESOURCEURL_CUSTOM_ELEMENT))
+ continue;
+
+ aModuleInfo.sModuleShortName = sModuleShortName;
+ sal_Int32 nIndex = sToolbarName.lastIndexOf('.');
+ if (nIndex > 0)
+ {
+ ::rtl::OUString sExtension(sToolbarName.copy(nIndex));
+ ::rtl::OUString sToolbarResourceName(sToolbarName.copy(0, nIndex));
+ if (sToolbarResourceName.getLength()>0 && sExtension.equalsAsciiL(".xml", 4))
+ aModuleInfo.m_vToolbars.push_back(sToolbarResourceName);
+ }
+ }
+ }
+
+ if (aModuleInfo.sModuleShortName.getLength()>0)
+ vModulesInfo.push_back(aModuleInfo);
+ }
+ }
+
+ return vModulesInfo;
+}
+
+void MigrationImpl::compareOldAndNewConfig(const ::rtl::OUString& sParent,
+ const uno::Reference< container::XIndexContainer >& xIndexOld,
+ const uno::Reference< container::XIndexContainer >& xIndexNew,
+ const ::rtl::OUString& sResourceURL)
+{
+ ::std::vector< MigrationItem > vOldItems;
+ ::std::vector< MigrationItem > vNewItems;
+ uno::Sequence< beans::PropertyValue > aProp;
+ sal_Int32 nOldCount = xIndexOld->getCount();
+ sal_Int32 nNewCount = xIndexNew->getCount();
+
+ for (int n=0; n<nOldCount; ++n)
+ {
+ MigrationItem aMigrationItem;
+ if (xIndexOld->getByIndex(n) >>= aProp)
+ {
+ for(int i=0; i<aProp.getLength(); ++i)
+ {
+ if (aProp[i].Name.equals(ITEM_DESCRIPTOR_COMMANDURL))
+ aProp[i].Value >>= aMigrationItem.m_sCommandURL;
+ else if (aProp[i].Name.equals(ITEM_DESCRIPTOR_CONTAINER))
+ aProp[i].Value >>= aMigrationItem.m_xPopupMenu;
+ }
+
+ if (aMigrationItem.m_sCommandURL.getLength())
+ vOldItems.push_back(aMigrationItem);
+ }
+ }
+
+ for (int n=0; n<nNewCount; ++n)
+ {
+ MigrationItem aMigrationItem;
+ if (xIndexNew->getByIndex(n) >>= aProp)
+ {
+ for(int i=0; i<aProp.getLength(); ++i)
+ {
+ if (aProp[i].Name.equals(ITEM_DESCRIPTOR_COMMANDURL))
+ aProp[i].Value >>= aMigrationItem.m_sCommandURL;
+ else if (aProp[i].Name.equals(ITEM_DESCRIPTOR_CONTAINER))
+ aProp[i].Value >>= aMigrationItem.m_xPopupMenu;
+ }
+
+ if (aMigrationItem.m_sCommandURL.getLength())
+ vNewItems.push_back(aMigrationItem);
+ }
+ }
+
+ ::std::vector< MigrationItem >::iterator it;
+
+ ::rtl::OUString sSibling;
+ for (it = vOldItems.begin(); it!=vOldItems.end(); ++it)
+ {
+ ::std::vector< MigrationItem >::iterator pFound = ::std::find(vNewItems.begin(), vNewItems.end(), *it);
+ if (pFound != vNewItems.end() && it->m_xPopupMenu.is())
+ {
+ ::rtl::OUString sName;
+ if (sParent.getLength()>0)
+ sName = sParent + MENU_SEPERATOR + it->m_sCommandURL;
+ else
+ sName = it->m_sCommandURL;
+ compareOldAndNewConfig(sName, it->m_xPopupMenu, pFound->m_xPopupMenu, sResourceURL);
+ }
+ else if (pFound == vNewItems.end())
+ {
+ MigrationItem aMigrationItem(sParent, sSibling, it->m_sCommandURL, it->m_xPopupMenu);
+ if (m_aOldVersionItemsHashMap.find(sResourceURL)==m_aOldVersionItemsHashMap.end())
+ {
+ ::std::vector< MigrationItem > vMigrationItems;
+ m_aOldVersionItemsHashMap.insert(MigrationHashMap::value_type(sResourceURL, vMigrationItems));
+ m_aOldVersionItemsHashMap[sResourceURL].push_back(aMigrationItem);
+ }
+ else
+ {
+ if (::std::find(m_aOldVersionItemsHashMap[sResourceURL].begin(), m_aOldVersionItemsHashMap[sResourceURL].end(), aMigrationItem)==m_aOldVersionItemsHashMap[sResourceURL].end())
+ m_aOldVersionItemsHashMap[sResourceURL].push_back(aMigrationItem);
+ }
+ }
+
+ sSibling = it->m_sCommandURL;
+ }
+
+ ::rtl::OUString sNewSibling;
+ uno::Reference< container::XIndexContainer > xPopup;
+ for (it = vNewItems.begin(); it!=vNewItems.end(); ++it)
+ {
+ ::std::vector< MigrationItem >::iterator pFound = ::std::find(vOldItems.begin(), vOldItems.end(), *it);
+ if (pFound != vOldItems.end() && it->m_xPopupMenu.is())
+ {
+ ::rtl::OUString sName;
+ if (sParent.getLength()>0)
+ sName = sParent + MENU_SEPERATOR + it->m_sCommandURL;
+ else
+ sName = it->m_sCommandURL;
+ compareOldAndNewConfig(sName, pFound->m_xPopupMenu, it->m_xPopupMenu, sResourceURL);
+ }
+ else if (::std::find(vOldItems.begin(), vOldItems.end(), *it) == vOldItems.end())
+ {
+ MigrationItem aMigrationItem(sParent, sSibling, it->m_sCommandURL, it->m_xPopupMenu);
+ if (m_aNewVersionItemsHashMap.find(sResourceURL)==m_aNewVersionItemsHashMap.end())
+ {
+ ::std::vector< MigrationItem > vMigrationItems;
+ m_aNewVersionItemsHashMap.insert(MigrationHashMap::value_type(sResourceURL, vMigrationItems));
+ m_aNewVersionItemsHashMap[sResourceURL].push_back(aMigrationItem);
+ }
+ else
+ {
+ if (::std::find(m_aNewVersionItemsHashMap[sResourceURL].begin(), m_aNewVersionItemsHashMap[sResourceURL].end(), aMigrationItem)==m_aNewVersionItemsHashMap[sResourceURL].end())
+ m_aNewVersionItemsHashMap[sResourceURL].push_back(aMigrationItem);
+ }
+ }
+ }
+}
+
+void MigrationImpl::mergeOldToNewVersion(const uno::Reference< ui::XUIConfigurationManager >& xCfgManager,
+ const uno::Reference< container::XIndexContainer>& xIndexContainer,
+ const ::rtl::OUString& sModuleIdentifier,
+ const ::rtl::OUString& sResourceURL)
+{
+ MigrationHashMap::iterator pFound = m_aOldVersionItemsHashMap.find(sResourceURL);
+ if (pFound==m_aOldVersionItemsHashMap.end())
+ return;
+
+ ::std::vector< MigrationItem >::iterator it;
+ for (it=pFound->second.begin(); it!=pFound->second.end(); ++it)
+ {
+ uno::Reference< container::XIndexContainer > xTemp = xIndexContainer;
+
+ ::rtl::OUString sParentNodeName = it->m_sParentNodeName;
+ sal_Int32 nIndex = 0;
+ do
+ {
+ ::rtl::OUString sToken = sParentNodeName.getToken(0, '|', nIndex).trim();
+ if (sToken.getLength()<=0)
+ break;
+
+ sal_Int32 nCount = xTemp->getCount();
+ for (sal_Int32 i=0; i<nCount; ++i)
+ {
+ ::rtl::OUString sCommandURL;
+ ::rtl::OUString sLabel;
+ uno::Reference< container::XIndexContainer > xChild;
+
+ uno::Sequence< beans::PropertyValue > aPropSeq;
+ xTemp->getByIndex(i) >>= aPropSeq;
+ for (sal_Int32 j=0; j<aPropSeq.getLength(); ++j)
+ {
+ ::rtl::OUString sPropName = aPropSeq[j].Name;
+ if (sPropName.equals(ITEM_DESCRIPTOR_COMMANDURL))
+ aPropSeq[j].Value >>= sCommandURL;
+ else if (sPropName.equals(ITEM_DESCRIPTOR_LABEL))
+ aPropSeq[j].Value >>= sLabel;
+ else if (sPropName.equals(ITEM_DESCRIPTOR_CONTAINER))
+ aPropSeq[j].Value >>= xChild;
+ }
+
+ if (sCommandURL == sToken)
+ {
+ xTemp = xChild;
+ break;
+ }
+ }
+
+ } while (nIndex>=0);
+
+ if (nIndex == -1)
+ {
+ uno::Sequence< beans::PropertyValue > aPropSeq(3);
+
+ aPropSeq[0].Name = ITEM_DESCRIPTOR_COMMANDURL;
+ aPropSeq[0].Value <<= it->m_sCommandURL;
+ aPropSeq[1].Name = ITEM_DESCRIPTOR_LABEL;
+ aPropSeq[1].Value <<= retrieveLabelFromCommand(it->m_sCommandURL, sModuleIdentifier);
+ aPropSeq[2].Name = ITEM_DESCRIPTOR_CONTAINER;
+ aPropSeq[2].Value <<= it->m_xPopupMenu;
+
+ if (it->m_sPrevSibling.getLength() == 0)
+ xTemp->insertByIndex(0, uno::makeAny(aPropSeq));
+ else if (it->m_sPrevSibling.getLength() > 0)
+ {
+ sal_Int32 nCount = xTemp->getCount();
+ sal_Int32 i = 0;
+ for (; i<nCount; ++i)
+ {
+ ::rtl::OUString sCmd;
+ uno::Sequence< beans::PropertyValue > aTempPropSeq;
+ xTemp->getByIndex(i) >>= aTempPropSeq;
+ for (sal_Int32 j=0; j<aTempPropSeq.getLength(); ++j)
+ {
+ if (aTempPropSeq[j].Name.equals(ITEM_DESCRIPTOR_COMMANDURL))
+ {
+ aTempPropSeq[j].Value >>= sCmd;
+ break;
+ }
+ }
+
+ if (sCmd.equals(it->m_sPrevSibling))
+ break;
+ }
+
+ xTemp->insertByIndex(i+1, uno::makeAny(aPropSeq));
+ }
+ }
+ }
+
+ uno::Reference< container::XIndexAccess > xIndexAccess(xIndexContainer, uno::UNO_QUERY);
+ if (xIndexAccess.is())
+ xCfgManager->replaceSettings(sResourceURL, xIndexAccess);
+
+ uno::Reference< ui::XUIConfigurationPersistence > xUIConfigurationPersistence(xCfgManager, uno::UNO_QUERY);
+ if (xUIConfigurationPersistence.is())
+ xUIConfigurationPersistence->store();
+}
+
+uno::Reference< ui::XUIConfigurationManager > NewVersionUIInfo::getConfigManager(const ::rtl::OUString& sModuleShortName) const
+{
+ uno::Reference< ui::XUIConfigurationManager > xCfgManager;
+
+ for (sal_Int32 i=0; i<m_lCfgManagerSeq.getLength(); ++i)
+ {
+ if (m_lCfgManagerSeq[i].Name.equals(sModuleShortName))
+ {
+ m_lCfgManagerSeq[i].Value >>= xCfgManager;
+ break;
+ }
+ }
+
+ return xCfgManager;
+}
+
+uno::Reference< container::XIndexContainer > NewVersionUIInfo::getNewMenubarSettings(const ::rtl::OUString& sModuleShortName) const
+{
+ uno::Reference< container::XIndexContainer > xNewMenuSettings;
+
+ for (sal_Int32 i=0; i<m_lNewVersionMenubarSettingsSeq.getLength(); ++i)
+ {
+ if (m_lNewVersionMenubarSettingsSeq[i].Name.equals(sModuleShortName))
+ {
+ m_lNewVersionMenubarSettingsSeq[i].Value >>= xNewMenuSettings;
+ break;
+ }
+ }
+
+ return xNewMenuSettings;
+}
+
+uno::Reference< container::XIndexContainer > NewVersionUIInfo::getNewToolbarSettings(const ::rtl::OUString& sModuleShortName, const ::rtl::OUString& sToolbarName) const
+{
+ uno::Reference< container::XIndexContainer > xNewToolbarSettings;
+
+ for (sal_Int32 i=0; i<m_lNewVersionToolbarSettingsSeq.getLength(); ++i)
+ {
+ if (m_lNewVersionToolbarSettingsSeq[i].Name.equals(sModuleShortName))
+ {
+ uno::Sequence< beans::PropertyValue > lToolbarSettingsSeq;
+ m_lNewVersionToolbarSettingsSeq[i].Value >>= lToolbarSettingsSeq;
+ for (sal_Int32 j=0; j<lToolbarSettingsSeq.getLength(); ++j)
+ {
+ if (lToolbarSettingsSeq[j].Name.equals(sToolbarName))
+ {
+ lToolbarSettingsSeq[j].Value >>= xNewToolbarSettings;
+ break;
+ }
+ }
+
+ break;
+ }
+ }
+
+ return xNewToolbarSettings;
+}
+
+void NewVersionUIInfo::init(const ::std::vector< MigrationModuleInfo >& vModulesInfo)
+{
+ m_lCfgManagerSeq.realloc(vModulesInfo.size());
+ m_lNewVersionMenubarSettingsSeq.realloc(vModulesInfo.size());
+ m_lNewVersionToolbarSettingsSeq.realloc(vModulesInfo.size());
+
+ const ::rtl::OUString sModuleCfgSupplier(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.ui.ModuleUIConfigurationManagerSupplier"));
+ const ::rtl::OUString sMenubarResourceURL(RTL_CONSTASCII_USTRINGPARAM("private:resource/menubar/menubar"));
+ const ::rtl::OUString sToolbarResourcePre(RTL_CONSTASCII_USTRINGPARAM("private:resource/toolbar/"));
+
+ uno::Reference< ui::XModuleUIConfigurationManagerSupplier > xModuleCfgSupplier = uno::Reference< ui::XModuleUIConfigurationManagerSupplier >(::comphelper::getProcessServiceFactory()->createInstance(sModuleCfgSupplier), uno::UNO_QUERY);
+
+ for (sal_uInt32 i=0; i<vModulesInfo.size(); ++i)
+ {
+ ::rtl::OUString sModuleIdentifier = mapModuleShortNameToIdentifier(vModulesInfo[i].sModuleShortName);
+ if (sModuleIdentifier.getLength() > 0)
+ {
+ uno::Reference< ui::XUIConfigurationManager > xCfgManager = xModuleCfgSupplier->getUIConfigurationManager(sModuleIdentifier);
+ m_lCfgManagerSeq[i].Name = vModulesInfo[i].sModuleShortName;
+ m_lCfgManagerSeq[i].Value <<= xCfgManager;
+
+ if (vModulesInfo[i].bHasMenubar)
+ {
+ m_lNewVersionMenubarSettingsSeq[i].Name = vModulesInfo[i].sModuleShortName;
+ m_lNewVersionMenubarSettingsSeq[i].Value <<= xCfgManager->getSettings(sMenubarResourceURL, sal_True);
+ }
+
+ sal_Int32 nToolbars = vModulesInfo[i].m_vToolbars.size();
+ if (nToolbars > 0)
+ {
+ uno::Sequence< beans::PropertyValue > lPropSeq(nToolbars);
+ for (sal_Int32 j=0; j<nToolbars; ++j)
+ {
+ ::rtl::OUString sToolbarName = vModulesInfo[i].m_vToolbars[j];
+ ::rtl::OUString sToolbarResourceURL = sToolbarResourcePre + sToolbarName;
+
+ lPropSeq[j].Name = sToolbarName;
+ lPropSeq[j].Value <<= xCfgManager->getSettings(sToolbarResourceURL, sal_True);
+ }
+
+ m_lNewVersionToolbarSettingsSeq[i].Name = vModulesInfo[i].sModuleShortName;
+ m_lNewVersionToolbarSettingsSeq[i].Value <<= lPropSeq;
+ }
+ }
+ }
+}
+
+} // namespace desktop
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/migration/migration_impl.hxx b/desktop/source/migration/migration_impl.hxx
new file mode 100644
index 000000000000..2d079aeb99a5
--- /dev/null
+++ b/desktop/source/migration/migration_impl.hxx
@@ -0,0 +1,254 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _DESKTOP_MIGRATION_IMPL_HXX_
+#define _DESKTOP_MIGRATION_IMPL_HXX_
+
+#include <vector>
+#include <algorithm>
+#include <memory>
+#include <boost/unordered_map.hpp>
+
+#include "migration.hxx"
+
+#include <sal/types.h>
+#include <rtl/string.hxx>
+#include <rtl/ustring.hxx>
+
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/container/XIndexAccess.hpp>
+#include <com/sun/star/container/XIndexContainer.hpp>
+#include <com/sun/star/lang/XSingleComponentFactory.hpp>
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#include <com/sun/star/ui/XModuleUIConfigurationManagerSupplier.hpp>
+#include <com/sun/star/ui/XUIConfigurationManager.hpp>
+#include <com/sun/star/ui/XUIConfigurationPersistence.hpp>
+
+#define NS_CSS com::sun::star
+#define NS_UNO com::sun::star::uno
+
+namespace desktop
+{
+
+struct install_info
+{
+ rtl::OUString productname; // human readeable product name
+ rtl::OUString userdata; // file: url for user installation
+};
+
+typedef std::vector< rtl::OUString > strings_v;
+typedef std::auto_ptr< strings_v > strings_vr;
+
+struct migration_step
+{
+ rtl::OUString name;
+ strings_v includeFiles;
+ strings_v excludeFiles;
+ strings_v includeConfig;
+ strings_v excludeConfig;
+ strings_v includeExtensions;
+ strings_v excludeExtensions;
+ rtl::OUString service;
+};
+
+struct supported_migration
+{
+ rtl::OUString name;
+ sal_Int32 nPriority;
+ strings_v supported_versions;
+};
+
+typedef std::vector< migration_step > migrations_v;
+typedef std::auto_ptr< migrations_v > migrations_vr;
+typedef std::vector< supported_migration > migrations_available;
+
+//__________________________________________
+/**
+ define the item, e.g.:menuitem, toolbaritem, to be migrated. we keep the information
+ of the command URL, the previous sibling node and the parent node of a item
+*/
+struct MigrationItem
+{
+ ::rtl::OUString m_sParentNodeName;
+ ::rtl::OUString m_sPrevSibling;
+ ::rtl::OUString m_sCommandURL;
+ NS_UNO::Reference< NS_CSS::container::XIndexContainer > m_xPopupMenu;
+
+ MigrationItem()
+ :m_xPopupMenu(0)
+ {
+ }
+
+ MigrationItem(const ::rtl::OUString& sParentNodeName,
+ const ::rtl::OUString& sPrevSibling,
+ const ::rtl::OUString& sCommandURL,
+ const NS_UNO::Reference< NS_CSS::container::XIndexContainer > xPopupMenu)
+ {
+ m_sParentNodeName = sParentNodeName;
+ m_sPrevSibling = sPrevSibling;
+ m_sCommandURL = sCommandURL;
+ m_xPopupMenu = xPopupMenu;
+ }
+
+ MigrationItem& operator=(const MigrationItem& aMigrationItem)
+ {
+ m_sParentNodeName = aMigrationItem.m_sParentNodeName;
+ m_sPrevSibling = aMigrationItem.m_sPrevSibling;
+ m_sCommandURL = aMigrationItem.m_sCommandURL;
+ m_xPopupMenu = aMigrationItem.m_xPopupMenu;
+
+ return *this;
+ }
+
+ sal_Bool operator==(const MigrationItem& aMigrationItem)
+ {
+ return ( aMigrationItem.m_sParentNodeName == m_sParentNodeName &&
+ aMigrationItem.m_sPrevSibling == m_sPrevSibling &&
+ aMigrationItem.m_sCommandURL == m_sCommandURL &&
+ aMigrationItem.m_xPopupMenu.is() == m_xPopupMenu.is() );
+ }
+
+ ::rtl::OUString GetPrevSibling() const { return m_sPrevSibling; }
+};
+
+typedef ::boost::unordered_map< ::rtl::OUString,
+ ::std::vector< MigrationItem >,
+ ::rtl::OUStringHash,
+ ::std::equal_to< ::rtl::OUString > > MigrationHashMap;
+
+struct MigrationItemInfo
+{
+ ::rtl::OUString m_sResourceURL;
+ MigrationItem m_aMigrationItem;
+
+ MigrationItemInfo(){}
+
+ MigrationItemInfo(const ::rtl::OUString& sResourceURL, const MigrationItem& aMigratiionItem)
+ {
+ m_sResourceURL = sResourceURL;
+ m_aMigrationItem = aMigratiionItem;
+ }
+};
+
+//__________________________________________
+/**
+ information for the UI elements to be migrated for one module
+*/
+struct MigrationModuleInfo
+{
+ ::rtl::OUString sModuleShortName;
+ sal_Bool bHasMenubar;
+ ::std::vector< ::rtl::OUString > m_vToolbars;
+
+ MigrationModuleInfo():bHasMenubar(sal_False){};
+};
+
+//__________________________________________
+/**
+ get the information before copying the ui configuration files of old version to new version
+*/
+class NewVersionUIInfo
+{
+public:
+
+ NS_UNO::Reference< NS_CSS::ui::XUIConfigurationManager > getConfigManager(const ::rtl::OUString& sModuleShortName) const;
+ NS_UNO::Reference< NS_CSS::container::XIndexContainer > getNewMenubarSettings(const ::rtl::OUString& sModuleShortName) const;
+ NS_UNO::Reference< NS_CSS::container::XIndexContainer > getNewToolbarSettings(const ::rtl::OUString& sModuleShortName, const ::rtl::OUString& sToolbarName) const;
+ void init(const ::std::vector< MigrationModuleInfo >& vModulesInfo);
+
+private:
+
+ NS_UNO::Sequence< NS_CSS::beans::PropertyValue > m_lCfgManagerSeq;
+ NS_UNO::Sequence< NS_CSS::beans::PropertyValue > m_lNewVersionMenubarSettingsSeq;
+ NS_UNO::Sequence< NS_CSS::beans::PropertyValue > m_lNewVersionToolbarSettingsSeq;
+};
+
+class MigrationImpl
+{
+
+private:
+ strings_vr m_vrVersions;
+ NS_UNO::Reference< NS_CSS::lang::XMultiServiceFactory > m_xFactory;
+
+ migrations_available m_vMigrationsAvailable; // list of all available migrations
+ migrations_vr m_vrMigrations; // list of all migration specs from config
+ install_info m_aInfo; // info about the version being migrated
+ strings_vr m_vrFileList; // final list of files to be copied
+ MigrationHashMap m_aOldVersionItemsHashMap;
+ MigrationHashMap m_aNewVersionItemsHashMap;
+ ::rtl::OUString m_sModuleIdentifier;
+
+ // functions to control the migration process
+ bool readAvailableMigrations(migrations_available&);
+ bool alreadyMigrated();
+ migrations_vr readMigrationSteps(const ::rtl::OUString& rMigrationName);
+ sal_Int32 findPreferedMigrationProcess(const migrations_available&);
+ install_info findInstallation(const strings_v& rVersions);
+ strings_vr compileFileList();
+
+ // helpers
+ void subtract(strings_v& va, const strings_v& vb_c) const;
+ strings_vr getAllFiles(const rtl::OUString& baseURL) const;
+ strings_vr applyPatterns(const strings_v& vSet, const strings_v& vPatterns) const;
+ NS_UNO::Reference< NS_CSS::container::XNameAccess > getConfigAccess(const sal_Char* path, sal_Bool rw=sal_False);
+
+ ::std::vector< MigrationModuleInfo > dectectUIChangesForAllModules() const;
+ void compareOldAndNewConfig(const ::rtl::OUString& sParentNodeName,
+ const NS_UNO::Reference< NS_CSS::container::XIndexContainer >& xOldIndexContainer,
+ const NS_UNO::Reference< NS_CSS::container::XIndexContainer >& xNewIndexContainer,
+ const ::rtl::OUString& sToolbarName);
+ void mergeOldToNewVersion(const NS_UNO::Reference< NS_CSS::ui::XUIConfigurationManager >& xCfgManager,
+ const NS_UNO::Reference< NS_CSS::container::XIndexContainer>& xIndexContainer,
+ const ::rtl::OUString& sModuleIdentifier,
+ const ::rtl::OUString& sResourceURL);
+
+ // actual processing function that perform the migration steps
+ void copyFiles();
+ void copyConfig();
+ void runServices();
+ void refresh();
+
+ void setMigrationCompleted();
+ bool checkMigrationCompleted();
+
+public:
+ MigrationImpl(const NS_UNO::Reference< NS_CSS::lang::XMultiServiceFactory >&);
+ ~MigrationImpl();
+ bool initializeMigration();
+ sal_Bool doMigration();
+ rtl::OUString getOldVersionName();
+};
+}
+#undef NS_CSS
+#undef NS_UNO
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/migration/pages.cxx b/desktop/source/migration/pages.cxx
new file mode 100644
index 000000000000..eefb529d0ca7
--- /dev/null
+++ b/desktop/source/migration/pages.cxx
@@ -0,0 +1,671 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include "pages.hxx"
+#include "wizard.hrc"
+#include "wizard.hxx"
+#include "migration.hxx"
+#include <vcl/msgbox.hxx>
+#include <vcl/mnemonic.hxx>
+#include <vos/security.hxx>
+#include <app.hxx>
+#include <rtl/ustring.hxx>
+#include <osl/file.hxx>
+#include <unotools/bootstrap.hxx>
+#include <unotools/configmgr.hxx>
+#include <unotools/regoptions.hxx>
+#include <unotools/useroptions.hxx>
+#include <sfx2/basedlgs.hxx>
+#include <comphelper/processfactory.hxx>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/frame/XDesktop.hpp>
+#include <com/sun/star/beans/XMaterialHolder.hpp>
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <com/sun/star/container/XNameReplace.hpp>
+#include <com/sun/star/task/XJobExecutor.hpp>
+#include <comphelper/configurationhelper.hxx>
+#include <rtl/bootstrap.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <osl/file.hxx>
+#include <osl/thread.hxx>
+#include <unotools/bootstrap.hxx>
+#include <tools/config.hxx>
+
+using namespace rtl;
+using namespace osl;
+using namespace utl;
+using namespace svt;
+using namespace com::sun::star;
+using namespace com::sun::star::frame;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::util;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::container;
+
+#define UNISTRING(s) rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(s))
+
+namespace desktop {
+
+static void _setBold(FixedText& ft)
+{
+ Font f = ft.GetControlFont();
+ f.SetWeight(WEIGHT_BOLD);
+ ft.SetControlFont(f);
+}
+
+WelcomePage::WelcomePage( svt::OWizardMachine* parent, const ResId& resid, sal_Bool bLicenseNeedsAcceptance )
+ : OWizardPage(parent, resid)
+ , m_ftHead(this, WizardResId(FT_WELCOME_HEADER))
+ , m_ftBody(this, WizardResId(FT_WELCOME_BODY))
+ , m_pParent(parent)
+ , m_bLicenseNeedsAcceptance( bLicenseNeedsAcceptance )
+ , bIsEvalVersion(false)
+ , bNoEvalText(false)
+{
+ FreeResource();
+
+ _setBold(m_ftHead);
+
+ checkEval();
+
+ // check for migration
+ if (Migration::checkMigration())
+ {
+ String aText(WizardResId(STR_WELCOME_MIGRATION));
+ // replace %OLDPRODUCT with found version name
+ aText.SearchAndReplaceAll( UniString::CreateFromAscii("%OLD_VERSION"), Migration::getOldVersionName());
+ m_ftBody.SetText( aText );
+ }
+ else if ( ! m_bLicenseNeedsAcceptance )
+ {
+ String aText(WizardResId(STR_WELCOME_WITHOUT_LICENSE));
+ m_ftBody.SetText( aText );
+ }
+}
+
+
+void WelcomePage::checkEval()
+{
+ Reference< XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory();
+ Reference< XMaterialHolder > xHolder(xFactory->createInstance(
+ OUString::createFromAscii("com.sun.star.tab.tabreg")), UNO_QUERY);
+ if (xHolder.is()) {
+ Any aData = xHolder->getMaterial();
+ Sequence < NamedValue > aSeq;
+ if (aData >>= aSeq) {
+ bIsEvalVersion = true;
+ for (int i=0; i< aSeq.getLength(); i++) {
+ if (aSeq[i].Name.equalsAscii("NoEvalText")) {
+ aSeq[i].Value >>= bNoEvalText;
+ }
+ }
+ }
+ }
+}
+
+
+void WelcomePage::ActivatePage()
+{
+ OWizardPage::ActivatePage();
+ // this page has no controls, so forwarding to default
+ // button (next) won't work if we grap focus
+ // GrabFocus();
+}
+
+LicensePage::LicensePage( svt::OWizardMachine* parent, const ResId& resid, const rtl::OUString &rLicensePath )
+ : OWizardPage(parent, resid)
+ , m_pParent(parent)
+ , m_ftHead(this, WizardResId(FT_LICENSE_HEADER))
+ , m_ftBody1(this, WizardResId(FT_LICENSE_BODY_1))
+ , m_ftBody1Txt(this, WizardResId(FT_LICENSE_BODY_1_TXT))
+ , m_ftBody2(this, WizardResId(FT_LICENSE_BODY_2))
+ , m_ftBody2Txt(this, WizardResId(FT_LICENSE_BODY_2_TXT))
+ , m_mlLicense(this, WizardResId(ML_LICENSE))
+ , m_pbDown(this, WizardResId(PB_LICENSE_DOWN))
+ , m_bLicenseRead(sal_False)
+{
+ FreeResource();
+
+ _setBold(m_ftHead);
+
+ m_mlLicense.SetEndReachedHdl( LINK(this, LicensePage, EndReachedHdl) );
+ m_mlLicense.SetScrolledHdl( LINK(this, LicensePage, ScrolledHdl) );
+ m_pbDown.SetClickHdl( LINK(this, LicensePage, PageDownHdl) );
+
+ // We want a automatic repeating page down button
+ WinBits aStyle = m_pbDown.GetStyle();
+ aStyle |= WB_REPEAT;
+ m_pbDown.SetStyle( aStyle );
+
+ // replace %PAGEDOWN in text2 with button text
+ String aText = m_ftBody1Txt.GetText();
+ aText.SearchAndReplaceAll( UniString::CreateFromAscii("%PAGEDOWN"),
+ MnemonicGenerator::EraseAllMnemonicChars(m_pbDown.GetText()));
+
+ m_ftBody1Txt.SetText( aText );
+
+ // load license text
+ File aLicenseFile(rLicensePath);
+ if ( aLicenseFile.open(OpenFlag_Read) == FileBase::E_None)
+ {
+ DirectoryItem d;
+ DirectoryItem::get(rLicensePath, d);
+ FileStatus fs(FileStatusMask_FileSize);
+ d.getFileStatus(fs);
+ sal_uInt64 nBytesRead = 0;
+ sal_uInt64 nPosition = 0;
+ sal_uInt32 nBytes = (sal_uInt32)fs.getFileSize();
+ sal_Char *pBuffer = new sal_Char[nBytes];
+ // FileBase RC r = FileBase::E_None;
+ while (aLicenseFile.read(pBuffer+nPosition, nBytes-nPosition, nBytesRead) == FileBase::E_None
+ && nPosition + nBytesRead < nBytes)
+ {
+ nPosition += nBytesRead;
+ }
+ OUString aLicenseString(pBuffer, nBytes, RTL_TEXTENCODING_UTF8,
+ OSTRING_TO_OUSTRING_CVTFLAGS | RTL_TEXTTOUNICODE_FLAGS_GLOBAL_SIGNATURE);
+ delete[] pBuffer;
+ m_mlLicense.SetText(aLicenseString);
+
+ }
+}
+
+void LicensePage::ActivatePage()
+{
+ OWizardPage::ActivatePage();
+ m_bLicenseRead = m_mlLicense.IsEndReached();
+ m_pbDown.GrabFocus();
+ updateDialogTravelUI();
+}
+
+bool LicensePage::canAdvance() const
+{
+ if (m_mlLicense.IsEndReached())
+ const_cast< LicensePage* >( this )->m_pbDown.Disable();
+ else
+ const_cast< LicensePage* >( this )->m_pbDown.Enable();
+
+ return m_bLicenseRead;
+}
+
+IMPL_LINK( LicensePage, PageDownHdl, PushButton *, EMPTYARG )
+{
+ m_mlLicense.ScrollDown( SCROLL_PAGEDOWN );
+ return 0;
+}
+
+IMPL_LINK( LicensePage, EndReachedHdl, LicenseView *, EMPTYARG )
+{
+ m_bLicenseRead = sal_True;
+ updateDialogTravelUI();
+ return 0;
+}
+
+IMPL_LINK( LicensePage, ScrolledHdl, LicenseView *, EMPTYARG )
+{
+ updateDialogTravelUI();
+ return 0;
+}
+
+
+LicenseView::LicenseView( Window* pParent, const ResId& rResId )
+ : MultiLineEdit( pParent, rResId )
+{
+ SetLeftMargin( 5 );
+ mbEndReached = IsEndReached();
+ StartListening( *GetTextEngine() );
+}
+
+LicenseView::~LicenseView()
+{
+ maEndReachedHdl = Link();
+ maScrolledHdl = Link();
+ EndListeningAll();
+}
+
+void LicenseView::ScrollDown( ScrollType eScroll )
+{
+ ScrollBar* pScroll = GetVScrollBar();
+ if ( pScroll )
+ pScroll->DoScrollAction( eScroll );
+}
+
+sal_Bool LicenseView::IsEndReached() const
+{
+ sal_Bool bEndReached;
+
+ ExtTextView* pView = GetTextView();
+ ExtTextEngine* pEdit = GetTextEngine();
+ sal_uLong nHeight = pEdit->GetTextHeight();
+ Size aOutSize = pView->GetWindow()->GetOutputSizePixel();
+ Point aBottom( 0, aOutSize.Height() );
+
+ if ( (sal_uLong) pView->GetDocPos( aBottom ).Y() >= nHeight - 1 )
+ bEndReached = sal_True;
+ else
+ bEndReached = sal_False;
+
+ return bEndReached;
+}
+
+void LicenseView::Notify( SfxBroadcaster&, const SfxHint& rHint )
+{
+ if ( rHint.IsA( TYPE(TextHint) ) )
+ {
+ sal_Bool bLastVal = EndReached();
+ sal_uLong nId = ((const TextHint&)rHint).GetId();
+
+ if ( nId == TEXT_HINT_PARAINSERTED )
+ {
+ if ( bLastVal )
+ mbEndReached = IsEndReached();
+ }
+ else if ( nId == TEXT_HINT_VIEWSCROLLED )
+ {
+ if ( ! mbEndReached )
+ mbEndReached = IsEndReached();
+ maScrolledHdl.Call( this );
+ }
+
+ if ( EndReached() && !bLastVal )
+ {
+ maEndReachedHdl.Call( this );
+ }
+ }
+}
+
+
+
+// -------------------------------------------------------------------
+
+class MigrationThread : public ::osl::Thread
+{
+ public:
+ MigrationThread();
+
+ virtual void SAL_CALL run();
+ virtual void SAL_CALL onTerminated();
+};
+
+MigrationThread::MigrationThread()
+{
+}
+
+void MigrationThread::run()
+{
+ try
+ {
+ Migration::doMigration();
+ }
+ catch ( uno::Exception& )
+ {
+ }
+}
+
+void MigrationThread::onTerminated()
+{
+}
+
+// -------------------------------------------------------------------
+
+MigrationPage::MigrationPage(
+ svt::OWizardMachine* parent,
+ const ResId& resid, Throbber& i_throbber )
+ : OWizardPage(parent, resid)
+ , m_ftHead(this, WizardResId(FT_MIGRATION_HEADER))
+ , m_ftBody(this, WizardResId(FT_MIGRATION_BODY))
+ , m_cbMigration(this, WizardResId(CB_MIGRATION))
+ , m_rThrobber(i_throbber)
+ , m_bMigrationDone(sal_False)
+{
+ FreeResource();
+ _setBold(m_ftHead);
+
+ // replace %OLDPRODUCT with found version name
+ String aText = m_ftBody.GetText();
+ aText.SearchAndReplaceAll( UniString::CreateFromAscii("%OLDPRODUCT"), Migration::getOldVersionName());
+ m_ftBody.SetText( aText );
+}
+
+sal_Bool MigrationPage::commitPage( svt::WizardTypes::CommitPageReason _eReason )
+{
+ if (_eReason == svt::WizardTypes::eTravelForward && m_cbMigration.IsChecked() && !m_bMigrationDone)
+ {
+ GetParent()->EnterWait();
+ FirstStartWizard* pWizard = dynamic_cast< FirstStartWizard* >( GetParent() );
+ if ( pWizard )
+ pWizard->DisableButtonsWhileMigration();
+
+ m_rThrobber.Show();
+ m_rThrobber.start();
+ MigrationThread* pMigThread = new MigrationThread();
+ pMigThread->create();
+
+ while ( pMigThread->isRunning() )
+ {
+ Application::Reschedule();
+ }
+
+ m_rThrobber.stop();
+ GetParent()->LeaveWait();
+ // Next state will enable buttons - so no EnableButtons necessary!
+ m_rThrobber.Hide();
+ pMigThread->join();
+ delete pMigThread;
+ m_bMigrationDone = sal_True;
+ }
+ else
+ Migration::cancelMigration();
+ return sal_True;
+}
+
+void MigrationPage::ActivatePage()
+{
+ OWizardPage::ActivatePage();
+ GrabFocus();
+}
+
+UserPage::UserPage( svt::OWizardMachine* parent, const ResId& resid)
+ : OWizardPage(parent, resid)
+ , m_ftHead(this, WizardResId(FT_USER_HEADER))
+ , m_ftBody(this, WizardResId(FT_USER_BODY))
+ , m_ftFirst(this, WizardResId(FT_USER_FIRST))
+ , m_edFirst(this, WizardResId(ED_USER_FIRST))
+ , m_ftLast(this, WizardResId(FT_USER_LAST))
+ , m_edLast(this, WizardResId(ED_USER_LAST))
+ , m_ftInitials(this, WizardResId(FT_USER_INITIALS))
+ , m_edInitials(this, WizardResId(ED_USER_INITIALS))
+ , m_ftFather(this, WizardResId(FT_USER_FATHER))
+ , m_edFather(this, WizardResId(ED_USER_FATHER))
+ , m_lang(Application::GetSettings().GetUILanguage())
+{
+ FreeResource();
+ _setBold(m_ftHead);
+
+ // check whether this is a russian version. otherwise
+ // we'll hide the 'Fathers name' field
+ SvtUserOptions aUserOpt;
+ m_edFirst.SetText(aUserOpt.GetFirstName());
+ m_edLast.SetText(aUserOpt.GetLastName());
+#if 0
+ rtl::OUString aUserName;
+ vos::OSecurity().getUserName( aUserName );
+ aUserOpt.SetID( aUserName );
+#endif
+
+ m_edInitials.SetText(aUserOpt.GetID());
+ if (m_lang == LANGUAGE_RUSSIAN)
+ {
+ m_ftFather.Show();
+ m_edFather.Show();
+ m_edFather.SetText(aUserOpt.GetFathersName());
+ }
+}
+
+sal_Bool UserPage::commitPage( svt::WizardTypes::CommitPageReason )
+{
+ SvtUserOptions aUserOpt;
+ aUserOpt.SetFirstName(m_edFirst.GetText());
+ aUserOpt.SetLastName(m_edLast.GetText());
+ aUserOpt.SetID( m_edInitials.GetText());
+
+ if (m_lang == LANGUAGE_RUSSIAN)
+ aUserOpt.SetFathersName(m_edFather.GetText());
+
+ return sal_True;
+}
+
+void UserPage::ActivatePage()
+{
+ OWizardPage::ActivatePage();
+ GrabFocus();
+}
+
+// -------------------------------------------------------------------
+UpdateCheckPage::UpdateCheckPage( svt::OWizardMachine* parent, const ResId& resid)
+ : OWizardPage(parent, resid)
+ , m_ftHead(this, WizardResId(FT_UPDATE_CHECK_HEADER))
+ , m_ftBody(this, WizardResId(FT_UPDATE_CHECK_BODY))
+ , m_cbUpdateCheck(this, WizardResId(CB_UPDATE_CHECK))
+{
+ FreeResource();
+ _setBold(m_ftHead);
+}
+
+sal_Bool UpdateCheckPage::commitPage( svt::WizardTypes::CommitPageReason _eReason )
+{
+ if ( _eReason == svt::WizardTypes::eTravelForward )
+ {
+ try {
+ Reference < XNameReplace > xUpdateAccess;
+ Reference < XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory() );
+
+ xUpdateAccess = Reference < XNameReplace >(
+ xFactory->createInstance( UNISTRING( "com.sun.star.setup.UpdateCheckConfig" ) ), UNO_QUERY_THROW );
+
+ if ( !xUpdateAccess.is() )
+ return sal_False;
+
+ sal_Bool bAutoUpdChk = m_cbUpdateCheck.IsChecked();
+ xUpdateAccess->replaceByName( UNISTRING("AutoCheckEnabled"), makeAny( bAutoUpdChk ) );
+
+ Reference< XChangesBatch > xChangesBatch( xUpdateAccess, UNO_QUERY);
+ if( xChangesBatch.is() && xChangesBatch->hasPendingChanges() )
+ xChangesBatch->commitChanges();
+ } catch (RuntimeException)
+ {
+ }
+ }
+
+ return sal_True;
+}
+
+void UpdateCheckPage::ActivatePage()
+{
+ OWizardPage::ActivatePage();
+ GrabFocus();
+}
+
+// -------------------------------------------------------------------
+RegistrationPage::RegistrationPage( Window* pParent, const ResId& rResid )
+ : OWizardPage( pParent, rResid )
+ , m_ftHeader(this, WizardResId(FT_REGISTRATION_HEADER))
+ , m_ftBody(this, WizardResId(FT_REGISTRATION_BODY))
+ , m_rbNow(this, WizardResId(RB_REGISTRATION_NOW))
+ , m_rbLater(this, WizardResId(RB_REGISTRATION_LATER))
+ , m_rbNever(this, WizardResId(RB_REGISTRATION_NEVER))
+ , m_flSeparator(this, WizardResId(FL_REGISTRATION))
+ , m_ftEnd(this, WizardResId(FT_REGISTRATION_END))
+ , m_bNeverVisible( sal_True )
+{
+ FreeResource();
+
+ // another text for OOo
+ sal_Int32 nOpenSourceContext = 0;
+ try
+ {
+ ::utl::ConfigManager::GetDirectConfigProperty(
+ ::utl::ConfigManager::OPENSOURCECONTEXT ) >>= nOpenSourceContext;
+ }
+ catch( Exception& )
+ {
+ DBG_ERRORFILE( "RegistrationPage::RegistrationPage(): error while getting open source context" );
+ }
+
+ if ( nOpenSourceContext > 0 )
+ {
+ String sBodyText( WizardResId( STR_REGISTRATION_OOO ) );
+ m_ftBody.SetText( sBodyText );
+ }
+
+ // calculate height of body text and rearrange the buttons
+ Size aSize = m_ftBody.GetSizePixel();
+ Size aMinSize = m_ftBody.CalcMinimumSize( aSize.Width() );
+ long nTxtH = aMinSize.Height();
+ long nCtrlH = aSize.Height();
+ long nDelta = ( nCtrlH - nTxtH );
+ aSize.Height() -= nDelta;
+ m_ftBody.SetSizePixel( aSize );
+ Window* pWins[] = { &m_rbNow, &m_rbLater, &m_rbNever };
+ Window** pCurrent = pWins;
+ for ( sal_uInt32 i = 0; i < sizeof( pWins ) / sizeof( pWins[ 0 ] ); ++i, ++pCurrent )
+ {
+ Point aNewPos = (*pCurrent)->GetPosPixel();
+ aNewPos.Y() -= nDelta;
+ (*pCurrent)->SetPosPixel( aNewPos );
+ }
+
+ _setBold(m_ftHeader);
+ impl_retrieveConfigurationData();
+ updateButtonStates();
+}
+
+bool RegistrationPage::canAdvance() const
+{
+ return false;
+}
+
+void RegistrationPage::ActivatePage()
+{
+ OWizardPage::ActivatePage();
+ GrabFocus();
+}
+
+void RegistrationPage::impl_retrieveConfigurationData()
+{
+ static ::rtl::OUString PACKAGE = ::rtl::OUString::createFromAscii("org.openoffice.FirstStartWizard");
+ static ::rtl::OUString PATH = ::rtl::OUString::createFromAscii("TabPages/Registration/RegistrationOptions/NeverButton");
+ static ::rtl::OUString KEY = ::rtl::OUString::createFromAscii("Visible");
+
+ ::com::sun::star::uno::Any aValue;
+ try
+ {
+ aValue = ::comphelper::ConfigurationHelper::readDirectKey(
+ ::comphelper::getProcessServiceFactory(),
+ PACKAGE,
+ PATH,
+ KEY,
+ ::comphelper::ConfigurationHelper::E_READONLY);
+ }
+ catch(const ::com::sun::star::uno::Exception&)
+ { aValue.clear(); }
+
+ aValue >>= m_bNeverVisible;
+}
+
+void RegistrationPage::updateButtonStates()
+{
+ m_rbNever.Show( m_bNeverVisible );
+}
+
+sal_Bool RegistrationPage::commitPage( svt::WizardTypes::CommitPageReason _eReason )
+{
+ if ( _eReason == svt::WizardTypes::eFinish )
+ {
+ ::utl::RegOptions aOptions;
+ rtl::OUString aEvent;
+
+ if ( m_rbNow.IsChecked())
+ {
+ aEvent = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "RegistrationRequired" ) );
+ }
+ else if (m_rbLater.IsChecked())
+ {
+ aOptions.activateReminder(7);
+ // avtivate a reminder job...
+ }
+ // aOptions.markSessionDone();
+
+ try
+ {
+ // create the Desktop component which can load components
+ Reference < XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory();
+ if( xFactory.is() )
+ {
+ Reference< com::sun::star::task::XJobExecutor > xProductRegistration(
+ xFactory->createInstance( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.setup.ProductRegistration" ) ) ),
+ UNO_QUERY_THROW );
+
+ // tell it that the user wants to register
+ xProductRegistration->trigger( aEvent );
+ }
+ }
+ catch( const Exception& )
+ {
+ }
+ }
+ return sal_True;
+}
+
+RegistrationPage::RegistrationMode RegistrationPage::getRegistrationMode() const
+{
+ RegistrationPage::RegistrationMode eMode = rmNow;
+ if ( m_rbLater.IsChecked() )
+ eMode = rmLater;
+ else if ( m_rbNever.IsChecked() )
+ eMode = rmNever;
+ return eMode;
+}
+
+void RegistrationPage::prepareSingleMode()
+{
+ // remove wizard text (hide and cut)
+ m_flSeparator.Hide();
+ m_ftEnd.Hide();
+ Size aNewSize = GetSizePixel();
+ aNewSize.Height() -= ( aNewSize.Height() - m_flSeparator.GetPosPixel().Y() );
+ SetSizePixel( aNewSize );
+}
+
+bool RegistrationPage::hasReminderDateCome()
+{
+ return ::utl::RegOptions().hasReminderDateCome();
+}
+
+void RegistrationPage::executeSingleMode()
+{
+ // opens the page in a single tabdialog
+ SfxSingleTabDialog aSingleDlg( NULL, TP_REGISTRATION );
+ RegistrationPage* pPage = new RegistrationPage( &aSingleDlg, WizardResId( TP_REGISTRATION ) );
+ pPage->prepareSingleMode();
+ aSingleDlg.SetPage( pPage );
+ aSingleDlg.SetText( pPage->getSingleModeTitle() );
+ aSingleDlg.Execute();
+ // the registration modes "Now" and "Later" are handled by the page
+ RegistrationPage::RegistrationMode eMode = pPage->getRegistrationMode();
+ if ( eMode == RegistrationPage::rmNow || eMode == RegistrationPage::rmLater )
+ pPage->commitPage( WizardTypes::eFinish );
+ if ( eMode != RegistrationPage::rmLater )
+ ::utl::RegOptions().removeReminder();
+}
+
+} // namespace desktop
diff --git a/desktop/source/migration/pages.hxx b/desktop/source/migration/pages.hxx
new file mode 100644
index 000000000000..47eae23ff58c
--- /dev/null
+++ b/desktop/source/migration/pages.hxx
@@ -0,0 +1,212 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _PAGES_HXX_
+#define _PAGES_HXX_
+
+#include <vcl/tabpage.hxx>
+#include <vcl/button.hxx>
+#include <vcl/dialog.hxx>
+#include <vcl/scrbar.hxx>
+#include <vcl/throbber.hxx>
+#include <svtools/wizardmachine.hxx>
+#include <svtools/svmedit.hxx>
+#include <svl/lstner.hxx>
+#include <svtools/xtextedt.hxx>
+
+namespace desktop
+{
+class WelcomePage : public svt::OWizardPage
+{
+private:
+ FixedText m_ftHead;
+ FixedText m_ftBody;
+ svt::OWizardMachine *m_pParent;
+ sal_Bool m_bLicenseNeedsAcceptance;
+ enum OEMType
+ {
+ OEM_NONE, OEM_NORMAL, OEM_EXTENDED
+ };
+ bool bIsEvalVersion;
+ bool bNoEvalText;
+ void checkEval();
+
+
+public:
+ WelcomePage( svt::OWizardMachine* parent, const ResId& resid, sal_Bool bLicenseNeedsAcceptance );
+protected:
+ virtual void ActivatePage();
+};
+
+class LicenseView : public MultiLineEdit, public SfxListener
+{
+ sal_Bool mbEndReached;
+ Link maEndReachedHdl;
+ Link maScrolledHdl;
+
+public:
+ LicenseView( Window* pParent, const ResId& rResId );
+ ~LicenseView();
+
+ void ScrollDown( ScrollType eScroll );
+
+ sal_Bool IsEndReached() const;
+ sal_Bool EndReached() const { return mbEndReached; }
+ void SetEndReached( sal_Bool bEnd ) { mbEndReached = bEnd; }
+
+ void SetEndReachedHdl( const Link& rHdl ) { maEndReachedHdl = rHdl; }
+ const Link& GetAutocompleteHdl() const { return maEndReachedHdl; }
+
+ void SetScrolledHdl( const Link& rHdl ) { maScrolledHdl = rHdl; }
+ const Link& GetScrolledHdl() const { return maScrolledHdl; }
+
+ virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint );
+
+protected:
+ using MultiLineEdit::Notify;
+};
+
+class LicensePage : public svt::OWizardPage
+{
+private:
+ svt::OWizardMachine *m_pParent;
+ FixedText m_ftHead;
+ FixedText m_ftBody1;
+ FixedText m_ftBody1Txt;
+ FixedText m_ftBody2;
+ FixedText m_ftBody2Txt;
+ LicenseView m_mlLicense;
+ PushButton m_pbDown;
+ sal_Bool m_bLicenseRead;
+public:
+ LicensePage( svt::OWizardMachine* parent, const ResId& resid, const rtl::OUString &rLicensePath );
+private:
+ DECL_LINK(PageDownHdl, PushButton*);
+ DECL_LINK(EndReachedHdl, LicenseView*);
+ DECL_LINK(ScrolledHdl, LicenseView*);
+protected:
+ virtual bool canAdvance() const;
+ virtual void ActivatePage();
+};
+
+class MigrationPage : public svt::OWizardPage
+{
+private:
+ FixedText m_ftHead;
+ FixedText m_ftBody;
+ CheckBox m_cbMigration;
+ Throbber& m_rThrobber;
+ sal_Bool m_bMigrationDone;
+public:
+ MigrationPage( svt::OWizardMachine* parent, const ResId& resid, Throbber& i_throbber );
+ virtual sal_Bool commitPage( svt::WizardTypes::CommitPageReason _eReason );
+
+protected:
+ virtual void ActivatePage();
+};
+
+class UserPage : public svt::OWizardPage
+{
+private:
+ FixedText m_ftHead;
+ FixedText m_ftBody;
+ FixedText m_ftFirst;
+ Edit m_edFirst;
+ FixedText m_ftLast;
+ Edit m_edLast;
+ FixedText m_ftInitials;
+ Edit m_edInitials;
+ FixedText m_ftFather;
+ Edit m_edFather;
+ LanguageType m_lang;
+
+public:
+ UserPage( svt::OWizardMachine* parent, const ResId& resid);
+ virtual sal_Bool commitPage( svt::WizardTypes::CommitPageReason _eReason );
+protected:
+ virtual void ActivatePage();
+};
+
+class UpdateCheckPage : public svt::OWizardPage
+{
+private:
+ FixedText m_ftHead;
+ FixedText m_ftBody;
+ CheckBox m_cbUpdateCheck;
+public:
+ UpdateCheckPage( svt::OWizardMachine* parent, const ResId& resid);
+ virtual sal_Bool commitPage( svt::WizardTypes::CommitPageReason _eReason );
+
+protected:
+ virtual void ActivatePage();
+};
+
+
+class RegistrationPage : public svt::OWizardPage
+{
+private:
+ FixedText m_ftHeader;
+ FixedText m_ftBody;
+ RadioButton m_rbNow;
+ RadioButton m_rbLater;
+ RadioButton m_rbNever;
+ FixedLine m_flSeparator;
+ FixedText m_ftEnd;
+
+ sal_Bool m_bNeverVisible;
+
+ void updateButtonStates();
+ void impl_retrieveConfigurationData();
+
+protected:
+ virtual bool canAdvance() const;
+ virtual void ActivatePage();
+
+ virtual sal_Bool commitPage( svt::WizardTypes::CommitPageReason _eReason );
+
+public:
+ RegistrationPage( Window* parent, const ResId& resid);
+
+ enum RegistrationMode
+ {
+ rmNow, // register now
+ rmLater, // register later
+ rmNever // register never
+ };
+
+ RegistrationMode getRegistrationMode() const;
+ void prepareSingleMode();
+ inline String getSingleModeTitle() const { return m_ftHeader.GetText(); }
+
+ static bool hasReminderDateCome();
+ static void executeSingleMode();
+};
+
+} // namespace desktop
+
+#endif // #ifndef _PAGES_HXX_
+
diff --git a/desktop/source/migration/services/autocorrmigration.cxx b/desktop/source/migration/services/autocorrmigration.cxx
new file mode 100644
index 000000000000..6e2f26c771ec
--- /dev/null
+++ b/desktop/source/migration/services/autocorrmigration.cxx
@@ -0,0 +1,288 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+#include "autocorrmigration.hxx"
+#include <i18npool/mslangid.hxx>
+#include <tools/urlobj.hxx>
+#include <unotools/bootstrap.hxx>
+
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+
+
+//.........................................................................
+namespace migration
+{
+//.........................................................................
+
+
+ static ::rtl::OUString sSourceSubDir = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/user/autocorr" ) );
+ static ::rtl::OUString sTargetSubDir = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/user/autocorr" ) );
+ static ::rtl::OUString sBaseName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/acor" ) );
+ static ::rtl::OUString sSuffix = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".dat" ) );
+
+
+ // =============================================================================
+ // component operations
+ // =============================================================================
+
+ ::rtl::OUString AutocorrectionMigration_getImplementationName()
+ {
+ static ::rtl::OUString* pImplName = 0;
+ if ( !pImplName )
+ {
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ if ( !pImplName )
+ {
+ static ::rtl::OUString aImplName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.desktop.migration.Autocorrection" ) );
+ pImplName = &aImplName;
+ }
+ }
+ return *pImplName;
+ }
+
+ // -----------------------------------------------------------------------------
+
+ Sequence< ::rtl::OUString > AutocorrectionMigration_getSupportedServiceNames()
+ {
+ static Sequence< ::rtl::OUString >* pNames = 0;
+ if ( !pNames )
+ {
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ if ( !pNames )
+ {
+ static Sequence< ::rtl::OUString > aNames(1);
+ aNames.getArray()[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.migration.Autocorrection" ) );
+ pNames = &aNames;
+ }
+ }
+ return *pNames;
+ }
+
+ // =============================================================================
+ // AutocorrectionMigration
+ // =============================================================================
+
+ AutocorrectionMigration::AutocorrectionMigration()
+ {
+ }
+
+ // -----------------------------------------------------------------------------
+
+ AutocorrectionMigration::~AutocorrectionMigration()
+ {
+ }
+
+ // -----------------------------------------------------------------------------
+
+ TStringVectorPtr AutocorrectionMigration::getFiles( const ::rtl::OUString& rBaseURL ) const
+ {
+ TStringVectorPtr aResult( new TStringVector );
+ ::osl::Directory aDir( rBaseURL);
+
+ if ( aDir.open() == ::osl::FileBase::E_None )
+ {
+ // iterate over directory content
+ TStringVector aSubDirs;
+ ::osl::DirectoryItem aItem;
+ while ( aDir.getNextItem( aItem ) == ::osl::FileBase::E_None )
+ {
+ ::osl::FileStatus aFileStatus( FileStatusMask_Type | FileStatusMask_FileURL );
+ if ( aItem.getFileStatus( aFileStatus ) == ::osl::FileBase::E_None )
+ {
+ if ( aFileStatus.getFileType() == ::osl::FileStatus::Directory )
+ aSubDirs.push_back( aFileStatus.getFileURL() );
+ else
+ aResult->push_back( aFileStatus.getFileURL() );
+ }
+ }
+
+ // iterate recursive over subfolders
+ TStringVector::const_iterator aI = aSubDirs.begin();
+ while ( aI != aSubDirs.end() )
+ {
+ TStringVectorPtr aSubResult = getFiles( *aI );
+ aResult->insert( aResult->end(), aSubResult->begin(), aSubResult->end() );
+ ++aI;
+ }
+ }
+
+ return aResult;
+ }
+
+ // -----------------------------------------------------------------------------
+
+ ::osl::FileBase::RC AutocorrectionMigration::checkAndCreateDirectory( INetURLObject& rDirURL )
+ {
+ ::osl::FileBase::RC aResult = ::osl::Directory::create( rDirURL.GetMainURL( INetURLObject::DECODE_TO_IURI ) );
+ if ( aResult == ::osl::FileBase::E_NOENT )
+ {
+ INetURLObject aBaseURL( rDirURL );
+ aBaseURL.removeSegment();
+ checkAndCreateDirectory( aBaseURL );
+ return ::osl::Directory::create( rDirURL.GetMainURL( INetURLObject::DECODE_TO_IURI ) );
+ }
+ else
+ {
+ return aResult;
+ }
+ }
+
+ // -----------------------------------------------------------------------------
+
+ void AutocorrectionMigration::copyFiles()
+ {
+ ::rtl::OUString sTargetDir;
+ ::utl::Bootstrap::PathStatus aStatus = ::utl::Bootstrap::locateUserInstallation( sTargetDir );
+ if ( aStatus == ::utl::Bootstrap::PATH_EXISTS )
+ {
+ sTargetDir += sTargetSubDir;
+ TStringVectorPtr aFileList = getFiles( m_sSourceDir );
+ TStringVector::const_iterator aI = aFileList->begin();
+ while ( aI != aFileList->end() )
+ {
+ ::rtl::OUString sSourceLocalName = aI->copy( m_sSourceDir.getLength() );
+ sal_Int32 nStart = sBaseName.getLength();
+ sal_Int32 nEnd = sSourceLocalName.lastIndexOf ( sSuffix );
+ ::rtl::OUString sLanguageType = sSourceLocalName.copy( nStart, nEnd - nStart );
+ ::rtl::OUString sIsoName = MsLangId::convertLanguageToIsoString( (LanguageType) sLanguageType.toInt32() );
+ ::rtl::OUString sTargetLocalName = sBaseName;
+ sTargetLocalName += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "_" ));
+ sTargetLocalName += sIsoName;
+ sTargetLocalName += sSuffix;
+ ::rtl::OUString sTargetName = sTargetDir + sTargetLocalName;
+ INetURLObject aURL( sTargetName );
+ aURL.removeSegment();
+ checkAndCreateDirectory( aURL );
+ ::osl::FileBase::RC aResult = ::osl::File::copy( *aI, sTargetName );
+ if ( aResult != ::osl::FileBase::E_None )
+ {
+ ::rtl::OString aMsg( "AutocorrectionMigration::copyFiles: cannot copy " );
+ aMsg += ::rtl::OUStringToOString( *aI, RTL_TEXTENCODING_UTF8 ) + " to "
+ + ::rtl::OUStringToOString( sTargetName, RTL_TEXTENCODING_UTF8 );
+ OSL_FAIL( aMsg.getStr() );
+ }
+ ++aI;
+ }
+ }
+ else
+ {
+ OSL_FAIL( "AutocorrectionMigration::copyFiles: no user installation!" );
+ }
+ }
+
+ // -----------------------------------------------------------------------------
+ // XServiceInfo
+ // -----------------------------------------------------------------------------
+
+ ::rtl::OUString AutocorrectionMigration::getImplementationName() throw (RuntimeException)
+ {
+ return AutocorrectionMigration_getImplementationName();
+ }
+
+ // -----------------------------------------------------------------------------
+
+ sal_Bool AutocorrectionMigration::supportsService( const ::rtl::OUString& rServiceName ) throw (RuntimeException)
+ {
+ Sequence< ::rtl::OUString > aNames( getSupportedServiceNames() );
+ const ::rtl::OUString* pNames = aNames.getConstArray();
+ const ::rtl::OUString* pEnd = pNames + aNames.getLength();
+ for ( ; pNames != pEnd && !pNames->equals( rServiceName ); ++pNames )
+ ;
+
+ return pNames != pEnd;
+ }
+
+ // -----------------------------------------------------------------------------
+
+ Sequence< ::rtl::OUString > AutocorrectionMigration::getSupportedServiceNames() throw (RuntimeException)
+ {
+ return AutocorrectionMigration_getSupportedServiceNames();
+ }
+
+ // -----------------------------------------------------------------------------
+ // XInitialization
+ // -----------------------------------------------------------------------------
+
+ void AutocorrectionMigration::initialize( const Sequence< Any >& aArguments ) throw (Exception, RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ const Any* pIter = aArguments.getConstArray();
+ const Any* pEnd = pIter + aArguments.getLength();
+ for ( ; pIter != pEnd ; ++pIter )
+ {
+ beans::NamedValue aValue;
+ *pIter >>= aValue;
+ if ( aValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "UserData" ) ) )
+ {
+ if ( !(aValue.Value >>= m_sSourceDir) )
+ {
+ OSL_FAIL( "AutocorrectionMigration::initialize: argument UserData has wrong type!" );
+ }
+ m_sSourceDir += sSourceSubDir;
+ break;
+ }
+ }
+ }
+
+ // -----------------------------------------------------------------------------
+ // XJob
+ // -----------------------------------------------------------------------------
+
+ Any AutocorrectionMigration::execute( const Sequence< beans::NamedValue >& )
+ throw (lang::IllegalArgumentException, Exception, RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ copyFiles();
+
+ return Any();
+ }
+
+ // =============================================================================
+ // component operations
+ // =============================================================================
+
+ Reference< XInterface > SAL_CALL AutocorrectionMigration_create(
+ Reference< XComponentContext > const & )
+ SAL_THROW( () )
+ {
+ return static_cast< lang::XTypeProvider * >( new AutocorrectionMigration() );
+ }
+
+ // -----------------------------------------------------------------------------
+
+//.........................................................................
+} // namespace migration
+//.........................................................................
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/migration/services/autocorrmigration.hxx b/desktop/source/migration/services/autocorrmigration.hxx
new file mode 100644
index 000000000000..20021ceb100a
--- /dev/null
+++ b/desktop/source/migration/services/autocorrmigration.hxx
@@ -0,0 +1,105 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _DESKTOP_AUTOCORRMIGRATION_HXX_
+#define _DESKTOP_AUTOCORRMIGRATION_HXX_
+
+#include "misc.hxx"
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/task/XJob.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <cppuhelper/implbase3.hxx>
+#include <osl/mutex.hxx>
+#include <osl/file.hxx>
+
+
+class INetURLObject;
+
+
+//.........................................................................
+namespace migration
+{
+//.........................................................................
+
+ ::rtl::OUString SAL_CALL AutocorrectionMigration_getImplementationName();
+ ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL AutocorrectionMigration_getSupportedServiceNames();
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL AutocorrectionMigration_create(
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > const & xContext )
+ SAL_THROW( (::com::sun::star::uno::Exception) );
+
+
+ // =============================================================================
+ // class AutocorrectionMigration
+ // =============================================================================
+
+ typedef ::cppu::WeakImplHelper3<
+ ::com::sun::star::lang::XServiceInfo,
+ ::com::sun::star::lang::XInitialization,
+ ::com::sun::star::task::XJob > AutocorrectionMigration_BASE;
+
+ class AutocorrectionMigration : public AutocorrectionMigration_BASE
+ {
+ private:
+ ::osl::Mutex m_aMutex;
+ ::rtl::OUString m_sSourceDir;
+
+ TStringVectorPtr getFiles( const ::rtl::OUString& rBaseURL ) const;
+ ::osl::FileBase::RC checkAndCreateDirectory( INetURLObject& rDirURL );
+ void copyFiles();
+
+ public:
+ AutocorrectionMigration();
+ virtual ~AutocorrectionMigration();
+
+ // XServiceInfo
+ virtual ::rtl::OUString SAL_CALL getImplementationName()
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& rServiceName )
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames()
+ throw (::com::sun::star::uno::RuntimeException);
+
+ // XInitialization
+ virtual void SAL_CALL initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments )
+ throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
+
+ // XJob
+ virtual ::com::sun::star::uno::Any SAL_CALL execute(
+ const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& Arguments )
+ throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::Exception,
+ ::com::sun::star::uno::RuntimeException);
+ };
+
+//.........................................................................
+} // namespace migration
+//.........................................................................
+
+#endif // _DESKTOP_AUTOCORRMIGRATION_HXX_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/migration/services/basicmigration.cxx b/desktop/source/migration/services/basicmigration.cxx
new file mode 100644
index 000000000000..ab8e95055724
--- /dev/null
+++ b/desktop/source/migration/services/basicmigration.cxx
@@ -0,0 +1,277 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+#include "basicmigration.hxx"
+#include <tools/urlobj.hxx>
+#include <unotools/bootstrap.hxx>
+
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+
+
+//.........................................................................
+namespace migration
+{
+//.........................................................................
+
+
+ static ::rtl::OUString sSourceUserBasic = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/user/basic" ) );
+ static ::rtl::OUString sTargetUserBasic = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/user/__basic_80" ) );
+
+
+ // =============================================================================
+ // component operations
+ // =============================================================================
+
+ ::rtl::OUString BasicMigration_getImplementationName()
+ {
+ static ::rtl::OUString* pImplName = 0;
+ if ( !pImplName )
+ {
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ if ( !pImplName )
+ {
+ static ::rtl::OUString aImplName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.desktop.migration.Basic" ) );
+ pImplName = &aImplName;
+ }
+ }
+ return *pImplName;
+ }
+
+ // -----------------------------------------------------------------------------
+
+ Sequence< ::rtl::OUString > BasicMigration_getSupportedServiceNames()
+ {
+ static Sequence< ::rtl::OUString >* pNames = 0;
+ if ( !pNames )
+ {
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ if ( !pNames )
+ {
+ static Sequence< ::rtl::OUString > aNames(1);
+ aNames.getArray()[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.migration.Basic" ) );
+ pNames = &aNames;
+ }
+ }
+ return *pNames;
+ }
+
+ // =============================================================================
+ // BasicMigration
+ // =============================================================================
+
+ BasicMigration::BasicMigration()
+ {
+ }
+
+ // -----------------------------------------------------------------------------
+
+ BasicMigration::~BasicMigration()
+ {
+ }
+
+ // -----------------------------------------------------------------------------
+
+ TStringVectorPtr BasicMigration::getFiles( const ::rtl::OUString& rBaseURL ) const
+ {
+ TStringVectorPtr aResult( new TStringVector );
+ ::osl::Directory aDir( rBaseURL);
+
+ if ( aDir.open() == ::osl::FileBase::E_None )
+ {
+ // iterate over directory content
+ TStringVector aSubDirs;
+ ::osl::DirectoryItem aItem;
+ while ( aDir.getNextItem( aItem ) == ::osl::FileBase::E_None )
+ {
+ ::osl::FileStatus aFileStatus( FileStatusMask_Type | FileStatusMask_FileURL );
+ if ( aItem.getFileStatus( aFileStatus ) == ::osl::FileBase::E_None )
+ {
+ if ( aFileStatus.getFileType() == ::osl::FileStatus::Directory )
+ aSubDirs.push_back( aFileStatus.getFileURL() );
+ else
+ aResult->push_back( aFileStatus.getFileURL() );
+ }
+ }
+
+ // iterate recursive over subfolders
+ TStringVector::const_iterator aI = aSubDirs.begin();
+ while ( aI != aSubDirs.end() )
+ {
+ TStringVectorPtr aSubResult = getFiles( *aI );
+ aResult->insert( aResult->end(), aSubResult->begin(), aSubResult->end() );
+ ++aI;
+ }
+ }
+
+ return aResult;
+ }
+
+ // -----------------------------------------------------------------------------
+
+ ::osl::FileBase::RC BasicMigration::checkAndCreateDirectory( INetURLObject& rDirURL )
+ {
+ ::osl::FileBase::RC aResult = ::osl::Directory::create( rDirURL.GetMainURL( INetURLObject::DECODE_TO_IURI ) );
+ if ( aResult == ::osl::FileBase::E_NOENT )
+ {
+ INetURLObject aBaseURL( rDirURL );
+ aBaseURL.removeSegment();
+ checkAndCreateDirectory( aBaseURL );
+ return ::osl::Directory::create( rDirURL.GetMainURL( INetURLObject::DECODE_TO_IURI ) );
+ }
+ else
+ {
+ return aResult;
+ }
+ }
+
+ // -----------------------------------------------------------------------------
+
+ void BasicMigration::copyFiles()
+ {
+ ::rtl::OUString sTargetDir;
+ ::utl::Bootstrap::PathStatus aStatus = ::utl::Bootstrap::locateUserInstallation( sTargetDir );
+ if ( aStatus == ::utl::Bootstrap::PATH_EXISTS )
+ {
+ sTargetDir += sTargetUserBasic;
+ TStringVectorPtr aFileList = getFiles( m_sSourceDir );
+ TStringVector::const_iterator aI = aFileList->begin();
+ while ( aI != aFileList->end() )
+ {
+ ::rtl::OUString sLocalName = aI->copy( m_sSourceDir.getLength() );
+ ::rtl::OUString sTargetName = sTargetDir + sLocalName;
+ INetURLObject aURL( sTargetName );
+ aURL.removeSegment();
+ checkAndCreateDirectory( aURL );
+ ::osl::FileBase::RC aResult = ::osl::File::copy( *aI, sTargetName );
+ if ( aResult != ::osl::FileBase::E_None )
+ {
+ ::rtl::OString aMsg( "BasicMigration::copyFiles: cannot copy " );
+ aMsg += ::rtl::OUStringToOString( *aI, RTL_TEXTENCODING_UTF8 ) + " to "
+ + ::rtl::OUStringToOString( sTargetName, RTL_TEXTENCODING_UTF8 );
+ OSL_FAIL( aMsg.getStr() );
+ }
+ ++aI;
+ }
+ }
+ else
+ {
+ OSL_FAIL( "BasicMigration::copyFiles: no user installation!" );
+ }
+ }
+
+ // -----------------------------------------------------------------------------
+ // XServiceInfo
+ // -----------------------------------------------------------------------------
+
+ ::rtl::OUString BasicMigration::getImplementationName() throw (RuntimeException)
+ {
+ return BasicMigration_getImplementationName();
+ }
+
+ // -----------------------------------------------------------------------------
+
+ sal_Bool BasicMigration::supportsService( const ::rtl::OUString& rServiceName ) throw (RuntimeException)
+ {
+ Sequence< ::rtl::OUString > aNames( getSupportedServiceNames() );
+ const ::rtl::OUString* pNames = aNames.getConstArray();
+ const ::rtl::OUString* pEnd = pNames + aNames.getLength();
+ for ( ; pNames != pEnd && !pNames->equals( rServiceName ); ++pNames )
+ ;
+
+ return pNames != pEnd;
+ }
+
+ // -----------------------------------------------------------------------------
+
+ Sequence< ::rtl::OUString > BasicMigration::getSupportedServiceNames() throw (RuntimeException)
+ {
+ return BasicMigration_getSupportedServiceNames();
+ }
+
+ // -----------------------------------------------------------------------------
+ // XInitialization
+ // -----------------------------------------------------------------------------
+
+ void BasicMigration::initialize( const Sequence< Any >& aArguments ) throw (Exception, RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ const Any* pIter = aArguments.getConstArray();
+ const Any* pEnd = pIter + aArguments.getLength();
+ for ( ; pIter != pEnd ; ++pIter )
+ {
+ beans::NamedValue aValue;
+ *pIter >>= aValue;
+ if ( aValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "UserData" ) ) )
+ {
+ if ( !(aValue.Value >>= m_sSourceDir) )
+ {
+ OSL_FAIL( "BasicMigration::initialize: argument UserData has wrong type!" );
+ }
+ m_sSourceDir += sSourceUserBasic;
+ break;
+ }
+ }
+ }
+
+ // -----------------------------------------------------------------------------
+ // XJob
+ // -----------------------------------------------------------------------------
+
+ Any BasicMigration::execute( const Sequence< beans::NamedValue >& )
+ throw (lang::IllegalArgumentException, Exception, RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ copyFiles();
+
+ return Any();
+ }
+
+ // =============================================================================
+ // component operations
+ // =============================================================================
+
+ Reference< XInterface > SAL_CALL BasicMigration_create(
+ Reference< XComponentContext > const & )
+ SAL_THROW( () )
+ {
+ return static_cast< lang::XTypeProvider * >( new BasicMigration() );
+ }
+
+ // -----------------------------------------------------------------------------
+
+//.........................................................................
+} // namespace migration
+//.........................................................................
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/migration/services/basicmigration.hxx b/desktop/source/migration/services/basicmigration.hxx
new file mode 100644
index 000000000000..49260cadd522
--- /dev/null
+++ b/desktop/source/migration/services/basicmigration.hxx
@@ -0,0 +1,105 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _DESKTOP_BASICMIGRATION_HXX_
+#define _DESKTOP_BASICMIGRATION_HXX_
+
+#include "misc.hxx"
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/task/XJob.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <cppuhelper/implbase3.hxx>
+#include <osl/mutex.hxx>
+#include <osl/file.hxx>
+
+
+class INetURLObject;
+
+
+//.........................................................................
+namespace migration
+{
+//.........................................................................
+
+ ::rtl::OUString SAL_CALL BasicMigration_getImplementationName();
+ ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL BasicMigration_getSupportedServiceNames();
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL BasicMigration_create(
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > const & xContext )
+ SAL_THROW( (::com::sun::star::uno::Exception) );
+
+
+ // =============================================================================
+ // class BasicMigration
+ // =============================================================================
+
+ typedef ::cppu::WeakImplHelper3<
+ ::com::sun::star::lang::XServiceInfo,
+ ::com::sun::star::lang::XInitialization,
+ ::com::sun::star::task::XJob > BasicMigration_BASE;
+
+ class BasicMigration : public BasicMigration_BASE
+ {
+ private:
+ ::osl::Mutex m_aMutex;
+ ::rtl::OUString m_sSourceDir;
+
+ TStringVectorPtr getFiles( const ::rtl::OUString& rBaseURL ) const;
+ ::osl::FileBase::RC checkAndCreateDirectory( INetURLObject& rDirURL );
+ void copyFiles();
+
+ public:
+ BasicMigration();
+ virtual ~BasicMigration();
+
+ // XServiceInfo
+ virtual ::rtl::OUString SAL_CALL getImplementationName()
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& rServiceName )
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames()
+ throw (::com::sun::star::uno::RuntimeException);
+
+ // XInitialization
+ virtual void SAL_CALL initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments )
+ throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
+
+ // XJob
+ virtual ::com::sun::star::uno::Any SAL_CALL execute(
+ const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& Arguments )
+ throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::Exception,
+ ::com::sun::star::uno::RuntimeException);
+ };
+
+//.........................................................................
+} // namespace migration
+//.........................................................................
+
+#endif // _DESKTOP_BASICMIGRATION_HXX_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/migration/services/cexports.cxx b/desktop/source/migration/services/cexports.cxx
new file mode 100644
index 000000000000..359470ea2865
--- /dev/null
+++ b/desktop/source/migration/services/cexports.cxx
@@ -0,0 +1,79 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include "cppuhelper/implementationentry.hxx"
+#include "basicmigration.hxx"
+#include "wordbookmigration.hxx"
+
+
+extern "C"
+{
+
+::cppu::ImplementationEntry entries [] =
+{
+ {
+ migration::BasicMigration_create, migration::BasicMigration_getImplementationName,
+ migration::BasicMigration_getSupportedServiceNames, ::cppu::createSingleComponentFactory,
+ 0, 0
+ },
+ {
+ migration::WordbookMigration_create, migration::WordbookMigration_getImplementationName,
+ migration::WordbookMigration_getSupportedServiceNames, ::cppu::createSingleComponentFactory,
+ 0, 0
+ },
+ // Extension migration was disabled by Oracle / OpenOffice.org
+#if 0
+ {
+ migration::ExtensionMigration_create, migration::ExtensionMigration_getImplementationName,
+ migration::ExtensionMigration_getSupportedServiceNames, ::cppu::createSingleComponentFactory,
+ 0, 0
+ },
+#endif
+ { 0, 0, 0, 0, 0, 0 }
+};
+
+
+void SAL_CALL component_getImplementationEnvironment(
+ const sal_Char ** ppEnvTypeName, uno_Environment ** )
+{
+ *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
+}
+
+void * SAL_CALL component_getFactory(
+ const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey )
+{
+ return ::cppu::component_getFactoryHelper(
+ pImplName, pServiceManager, pRegistryKey, entries );
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/migration/services/cexportsoo3.cxx b/desktop/source/migration/services/cexportsoo3.cxx
new file mode 100644
index 000000000000..95eaba845ac5
--- /dev/null
+++ b/desktop/source/migration/services/cexportsoo3.cxx
@@ -0,0 +1,64 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include "cppuhelper/implementationentry.hxx"
+#include "oo3extensionmigration.hxx"
+
+extern "C"
+{
+
+::cppu::ImplementationEntry entries [] =
+{
+ {
+ migration::OO3ExtensionMigration_create, migration::OO3ExtensionMigration_getImplementationName,
+ migration::OO3ExtensionMigration_getSupportedServiceNames, ::cppu::createSingleComponentFactory,
+ 0, 0
+ },
+ { 0, 0, 0, 0, 0, 0 }
+};
+
+
+void SAL_CALL component_getImplementationEnvironment(
+ const sal_Char ** ppEnvTypeName, uno_Environment ** )
+{
+ *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
+}
+
+void * SAL_CALL component_getFactory(
+ const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey )
+{
+ return ::cppu::component_getFactoryHelper(
+ pImplName, pServiceManager, pRegistryKey, entries );
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/migration/services/cppumaker.mk b/desktop/source/migration/services/cppumaker.mk
new file mode 100755
index 000000000000..5ab16ed1e3fe
--- /dev/null
+++ b/desktop/source/migration/services/cppumaker.mk
@@ -0,0 +1,36 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+.IF "$(debug)" != ""
+
+# MSVC++: no inlining
+.IF "$(COM)" == "MSC"
+CFLAGS += -Ob0
+.ENDIF
+
+.ENDIF
+
diff --git a/desktop/source/migration/services/jvmfwk.cxx b/desktop/source/migration/services/jvmfwk.cxx
new file mode 100644
index 000000000000..53c3596ae4f4
--- /dev/null
+++ b/desktop/source/migration/services/jvmfwk.cxx
@@ -0,0 +1,531 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include "cppuhelper/implbase4.hxx"
+#include "cppuhelper/implementationentry.hxx"
+#include "rtl/ustrbuf.hxx"
+#include "rtl/ustring.h"
+#include "rtl/ustring.hxx"
+#include "rtl/bootstrap.hxx"
+#include "sal/types.h"
+#include "sal/config.h"
+#include "boost/scoped_array.hpp"
+#include "com/sun/star/lang/XServiceInfo.hpp"
+#include "com/sun/star/lang/XInitialization.hpp"
+#include "com/sun/star/lang/WrappedTargetException.hpp"
+#include "com/sun/star/task/XJob.hpp"
+#include "com/sun/star/configuration/backend/XLayer.hpp"
+#include "com/sun/star/configuration/backend/XLayerHandler.hpp"
+#include "com/sun/star/configuration/backend/MalformedDataException.hpp"
+#include "com/sun/star/configuration/backend/TemplateIdentifier.hpp"
+#include "jvmfwk/framework.h"
+#include "jvmfwk.hxx"
+#include <stack>
+#include <stdio.h>
+
+#include "osl/thread.hxx"
+using ::rtl::OUString;
+
+#define OUSTR(x) rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( x ))
+
+#define SERVICE_NAME "com.sun.star.migration.Java"
+#define IMPL_NAME "com.sun.star.comp.desktop.migration.Java"
+
+#define ENABLE_JAVA 1
+#define USER_CLASS_PATH 2
+
+namespace css = com::sun::star;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::configuration::backend;
+
+namespace migration
+{
+
+class CJavaInfo
+{
+ CJavaInfo(const CJavaInfo&);
+ CJavaInfo& operator = (const CJavaInfo&);
+public:
+ JavaInfo* pData;
+ CJavaInfo();
+ ~CJavaInfo();
+ operator JavaInfo* () const;
+};
+
+CJavaInfo::CJavaInfo(): pData(NULL)
+{
+}
+
+CJavaInfo::~CJavaInfo()
+{
+ jfw_freeJavaInfo(pData);
+}
+
+CJavaInfo::operator JavaInfo*() const
+{
+ return pData;
+}
+
+
+class JavaMigration : public ::cppu::WeakImplHelper4<
+ css::lang::XServiceInfo,
+ css::lang::XInitialization,
+ css::task::XJob,
+ css::configuration::backend::XLayerHandler>
+{
+public:
+ // XServiceInfo
+ virtual OUString SAL_CALL getImplementationName()
+ throw (css::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL supportsService( const OUString & rServiceName )
+ throw (css::uno::RuntimeException);
+ virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames()
+ throw (css::uno::RuntimeException);
+
+ //XInitialization
+ virtual void SAL_CALL initialize( const css::uno::Sequence< css::uno::Any >& aArguments )
+ throw(css::uno::Exception, css::uno::RuntimeException);
+
+ //XJob
+ virtual css::uno::Any SAL_CALL execute(
+ const css::uno::Sequence<css::beans::NamedValue >& Arguments )
+ throw (css::lang::IllegalArgumentException, css::uno::Exception,
+ css::uno::RuntimeException);
+
+ // XLayerHandler
+ virtual void SAL_CALL startLayer()
+ throw(::com::sun::star::lang::WrappedTargetException);
+
+ virtual void SAL_CALL endLayer()
+ throw(
+ ::com::sun::star::configuration::backend::MalformedDataException,
+ ::com::sun::star::lang::WrappedTargetException );
+
+ virtual void SAL_CALL overrideNode(
+ const rtl::OUString& aName,
+ sal_Int16 aAttributes,
+ sal_Bool bClear)
+ throw(
+ ::com::sun::star::configuration::backend::MalformedDataException,
+ ::com::sun::star::lang::WrappedTargetException );
+
+ virtual void SAL_CALL addOrReplaceNode(
+ const rtl::OUString& aName,
+ sal_Int16 aAttributes)
+ throw(
+ ::com::sun::star::configuration::backend::MalformedDataException,
+ ::com::sun::star::lang::WrappedTargetException );
+
+ virtual void SAL_CALL addOrReplaceNodeFromTemplate(
+ const rtl::OUString& aName,
+ const ::com::sun::star::configuration::backend::TemplateIdentifier& aTemplate,
+ sal_Int16 aAttributes )
+ throw(
+ ::com::sun::star::configuration::backend::MalformedDataException,
+ ::com::sun::star::lang::WrappedTargetException );
+
+ virtual void SAL_CALL endNode()
+ throw(
+ ::com::sun::star::configuration::backend::MalformedDataException,
+ ::com::sun::star::lang::WrappedTargetException );
+
+ virtual void SAL_CALL dropNode(
+ const rtl::OUString& aName )
+ throw(
+ ::com::sun::star::configuration::backend::MalformedDataException,
+ ::com::sun::star::lang::WrappedTargetException );
+
+ virtual void SAL_CALL overrideProperty(
+ const rtl::OUString& aName,
+ sal_Int16 aAttributes,
+ const css::uno::Type& aType,
+ sal_Bool bClear )
+ throw(
+ ::com::sun::star::configuration::backend::MalformedDataException,
+ ::com::sun::star::lang::WrappedTargetException );
+
+ virtual void SAL_CALL setPropertyValue(
+ const css::uno::Any& aValue )
+ throw(
+ ::com::sun::star::configuration::backend::MalformedDataException,
+ ::com::sun::star::lang::WrappedTargetException );
+
+ virtual void SAL_CALL setPropertyValueForLocale(
+ const css::uno::Any& aValue,
+ const rtl::OUString& aLocale )
+ throw(
+ ::com::sun::star::configuration::backend::MalformedDataException,
+ ::com::sun::star::lang::WrappedTargetException );
+
+ virtual void SAL_CALL endProperty()
+ throw(
+ ::com::sun::star::configuration::backend::MalformedDataException,
+ ::com::sun::star::lang::WrappedTargetException );
+
+ virtual void SAL_CALL addProperty(
+ const rtl::OUString& aName,
+ sal_Int16 aAttributes,
+ const css::uno::Type& aType )
+ throw(
+ ::com::sun::star::configuration::backend::MalformedDataException,
+ ::com::sun::star::lang::WrappedTargetException );
+
+ virtual void SAL_CALL addPropertyWithValue(
+ const rtl::OUString& aName,
+ sal_Int16 aAttributes,
+ const css::uno::Any& aValue )
+ throw(
+ ::com::sun::star::configuration::backend::MalformedDataException,
+ ::com::sun::star::lang::WrappedTargetException );
+
+
+
+ //----------------
+ ~JavaMigration();
+
+private:
+ OUString m_sUserDir;
+ css::uno::Reference< ::css::configuration::backend::XLayer> m_xLayer;
+
+ void migrateJavarc();
+ typedef ::std::pair< ::rtl::OUString, sal_Int16> TElementType;
+ typedef ::std::stack< TElementType > TElementStack;
+ TElementStack m_aStack;
+
+};
+
+JavaMigration::~JavaMigration()
+{
+ OSL_ASSERT(m_aStack.empty());
+}
+
+OUString jvmfwk_getImplementationName()
+{
+ return OUSTR(IMPL_NAME);
+}
+
+css::uno::Sequence< OUString > jvmfwk_getSupportedServiceNames()
+{
+ OUString str_name = OUSTR(SERVICE_NAME);
+ return css::uno::Sequence< OUString >( &str_name, 1 );
+}
+
+// XServiceInfo
+OUString SAL_CALL JavaMigration::getImplementationName()
+ throw (css::uno::RuntimeException)
+{
+ return jvmfwk_getImplementationName();
+}
+
+sal_Bool SAL_CALL JavaMigration::supportsService( const OUString & rServiceName )
+ throw (css::uno::RuntimeException)
+{
+ css::uno::Sequence< OUString > const & rSNL = getSupportedServiceNames();
+ OUString const * pArray = rSNL.getConstArray();
+ for ( sal_Int32 nPos = rSNL.getLength(); nPos--; )
+ {
+ if (rServiceName.equals( pArray[ nPos ] ))
+ return true;
+ }
+ return false;
+
+}
+
+css::uno::Sequence< OUString > SAL_CALL JavaMigration::getSupportedServiceNames()
+ throw (css::uno::RuntimeException)
+{
+ return jvmfwk_getSupportedServiceNames();
+}
+
+//XInitialization ----------------------------------------------------------------------
+void SAL_CALL JavaMigration::initialize( const css::uno::Sequence< css::uno::Any >& aArguments )
+ throw(css::uno::Exception, css::uno::RuntimeException)
+{
+ const css::uno::Any* pIter = aArguments.getConstArray();
+ const css::uno::Any* pEnd = pIter + aArguments.getLength();
+ css::uno::Sequence<css::beans::NamedValue> aOldConfigValues;
+ css::beans::NamedValue aValue;
+ for(;pIter != pEnd;++pIter)
+ {
+ *pIter >>= aValue;
+ if (aValue.Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("OldConfiguration")))
+ {
+ sal_Bool bSuccess = aValue.Value >>= aOldConfigValues;
+ OSL_ENSURE(bSuccess == sal_True, "[Service implementation " IMPL_NAME
+ "] XInitialization::initialize: Argument OldConfiguration has wrong type.");
+ if (bSuccess)
+ {
+ const css::beans::NamedValue* pIter2 = aOldConfigValues.getConstArray();
+ const css::beans::NamedValue* pEnd2 = pIter2 + aOldConfigValues.getLength();
+ for(;pIter2 != pEnd2;++pIter2)
+ {
+ if ( pIter2->Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("org.openoffice.Office.Java")) )
+ {
+ pIter2->Value >>= m_xLayer;
+ break;
+ }
+ }
+ }
+ }
+ else if (aValue.Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("UserData")))
+ {
+ if ( !(aValue.Value >>= m_sUserDir) )
+ {
+ OSL_FAIL(
+ "[Service implementation " IMPL_NAME
+ "] XInitialization::initialize: Argument UserData has wrong type.");
+ }
+ }
+ }
+
+}
+
+//XJob
+css::uno::Any SAL_CALL JavaMigration::execute(
+ const css::uno::Sequence<css::beans::NamedValue >& )
+ throw (css::lang::IllegalArgumentException, css::uno::Exception,
+ css::uno::RuntimeException)
+{
+ migrateJavarc();
+ if (m_xLayer.is())
+ m_xLayer->readData(this);
+
+ return css::uno::Any();
+}
+
+void JavaMigration::migrateJavarc()
+{
+ if (m_sUserDir.getLength() == 0)
+ return;
+
+ OUString sValue;
+ rtl::Bootstrap javaini(m_sUserDir + OUSTR("/user/config/"SAL_CONFIGFILE("java")));
+ sal_Bool bSuccess = javaini.getFrom(OUSTR("Home"), sValue);
+ OSL_ENSURE(bSuccess, "[Service implementation " IMPL_NAME
+ "] XJob::execute: Could not get Home entry from java.ini/javarc.");
+ if (bSuccess == sal_True && sValue.getLength() > 0)
+ {
+ //get the directory
+ CJavaInfo aInfo;
+ javaFrameworkError err = jfw_getJavaInfoByPath(sValue.pData, &aInfo.pData);
+
+ if (err == JFW_E_NONE)
+ {
+ if (jfw_setSelectedJRE(aInfo) != JFW_E_NONE)
+ {
+ OSL_FAIL("[Service implementation " IMPL_NAME
+ "] XJob::execute: jfw_setSelectedJRE failed.");
+ fprintf(stderr, "\nCannot migrate Java. An error occurred.\n");
+ }
+ }
+ else if (err == JFW_E_FAILED_VERSION)
+ {
+ fprintf(stderr, "\nCannot migrate Java settings because the version of the Java "
+ "is not supported anymore.\n");
+ }
+ }
+}
+
+
+// XLayerHandler
+void SAL_CALL JavaMigration::startLayer()
+ throw(css::lang::WrappedTargetException)
+{
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL JavaMigration::endLayer()
+ throw(
+ MalformedDataException,
+ WrappedTargetException )
+{
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL JavaMigration::overrideNode(
+ const ::rtl::OUString&,
+ sal_Int16,
+ sal_Bool)
+ throw(
+ MalformedDataException,
+ WrappedTargetException )
+
+{
+
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL JavaMigration::addOrReplaceNode(
+ const ::rtl::OUString&,
+ sal_Int16)
+ throw(
+ MalformedDataException,
+ WrappedTargetException )
+{
+
+}
+void SAL_CALL JavaMigration::endNode()
+ throw(
+ MalformedDataException,
+ WrappedTargetException )
+{
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL JavaMigration::dropNode(
+ const ::rtl::OUString& )
+ throw(
+ MalformedDataException,
+ WrappedTargetException )
+{
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL JavaMigration::overrideProperty(
+ const ::rtl::OUString& aName,
+ sal_Int16,
+ const Type&,
+ sal_Bool )
+ throw(
+ MalformedDataException,
+ WrappedTargetException )
+{
+ if (aName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("Enable")))
+ m_aStack.push(TElementStack::value_type(aName,ENABLE_JAVA));
+ else if (aName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("UserClassPath")))
+ m_aStack.push(TElementStack::value_type(aName, USER_CLASS_PATH));
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL JavaMigration::setPropertyValue(
+ const Any& aValue )
+ throw(
+ MalformedDataException,
+ WrappedTargetException )
+{
+ if ( !m_aStack.empty())
+ {
+ switch (m_aStack.top().second)
+ {
+ case ENABLE_JAVA:
+ {
+ sal_Bool val = sal_Bool();
+ if ((aValue >>= val) == sal_False)
+ throw MalformedDataException(
+ OUSTR("[Service implementation " IMPL_NAME
+ "] XLayerHandler::setPropertyValue received wrong type for Enable property"), 0, Any());
+ if (jfw_setEnabled(val) != JFW_E_NONE)
+ throw WrappedTargetException(
+ OUSTR("[Service implementation " IMPL_NAME
+ "] XLayerHandler::setPropertyValue: jfw_setEnabled failed."), 0, Any());
+
+ break;
+ }
+ case USER_CLASS_PATH:
+ {
+ OUString cp;
+ if ((aValue >>= cp) == sal_False)
+ throw MalformedDataException(
+ OUSTR("[Service implementation " IMPL_NAME
+ "] XLayerHandler::setPropertyValue received wrong type for UserClassPath property"), 0, Any());
+
+ if (jfw_setUserClassPath(cp.pData) != JFW_E_NONE)
+ throw WrappedTargetException(
+ OUSTR("[Service implementation " IMPL_NAME
+ "] XLayerHandler::setPropertyValue: jfw_setUserClassPath failed."), 0, Any());
+ break;
+ }
+ default:
+ OSL_ASSERT(0);
+ }
+ }
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL JavaMigration::setPropertyValueForLocale(
+ const Any&,
+ const ::rtl::OUString& )
+ throw(
+ MalformedDataException,
+ WrappedTargetException )
+{
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL JavaMigration::endProperty()
+ throw(
+ MalformedDataException,
+ WrappedTargetException )
+{
+ if (!m_aStack.empty())
+ m_aStack.pop();
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL JavaMigration::addProperty(
+ const rtl::OUString&,
+ sal_Int16,
+ const Type& )
+ throw(
+ MalformedDataException,
+ WrappedTargetException )
+{
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL JavaMigration::addPropertyWithValue(
+ const rtl::OUString&,
+ sal_Int16,
+ const Any& )
+ throw(
+ MalformedDataException,
+ WrappedTargetException )
+{
+}
+
+void SAL_CALL JavaMigration::addOrReplaceNodeFromTemplate(
+ const rtl::OUString&,
+ const TemplateIdentifier&,
+ sal_Int16 )
+ throw(
+ MalformedDataException,
+ WrappedTargetException )
+{
+}
+
+// -----------------------------------------------------------------------------
+//ToDo enable java, user class path
+
+} //end namespace jfw
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/migration/services/jvmfwk.hxx b/desktop/source/migration/services/jvmfwk.hxx
new file mode 100644
index 000000000000..c1938e03ae87
--- /dev/null
+++ b/desktop/source/migration/services/jvmfwk.hxx
@@ -0,0 +1,52 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "cppuhelper/implbase3.hxx"
+#include "cppuhelper/implementationentry.hxx"
+#include "rtl/ustrbuf.hxx"
+#include "rtl/ustring.h"
+#include "rtl/ustring.hxx"
+#include "sal/types.h"
+#include "boost/scoped_array.hpp"
+#include "com/sun/star/lang/XServiceInfo.hpp"
+#include "com/sun/star/lang/XInitialization.hpp"
+#include "com/sun/star/task/XJob.hpp"
+
+
+namespace css = com::sun::star;
+
+namespace migration
+{
+
+rtl::OUString jvmfwk_getImplementationName();
+
+css::uno::Sequence< rtl::OUString > jvmfwk_getSupportedServiceNames();
+
+} //end blind namespace
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/migration/services/makefile.mk b/desktop/source/migration/services/makefile.mk
new file mode 100755
index 000000000000..718ac0387cb9
--- /dev/null
+++ b/desktop/source/migration/services/makefile.mk
@@ -0,0 +1,133 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=desktop
+TARGET = migrationoo2.uno
+ENABLE_EXCEPTIONS=TRUE
+COMP1TYPELIST = migrationoo2
+LIBTARGET=NO
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : ..$/..$/deployment/inc/dp_misc.mk
+.INCLUDE : settings.mk
+DLLPRE =
+
+# ------------------------------------------------------------------
+
+.INCLUDE : cppumaker.mk
+
+.IF "$(SYSTEM_DB)" == "YES"
+CFLAGS+=-DSYSTEM_DB -I$(DB_INCLUDES)
+.ENDIF
+
+SLOFILES= \
+ $(SLO)$/jvmfwk.obj \
+ $(SLO)$/cexports.obj \
+ $(SLO)$/basicmigration.obj \
+ $(SLO)$/wordbookmigration.obj \
+ $(SLO)$/autocorrmigration.obj \
+ $(SLO)$/oo3extensionmigration.obj \
+ $(SLO)$/cexportsoo3.obj
+
+SHL1OBJS= \
+ $(SLO)$/jvmfwk.obj \
+ $(SLO)$/cexports.obj \
+ $(SLO)$/basicmigration.obj \
+ $(SLO)$/wordbookmigration.obj \
+ $(SLO)$/autocorrmigration.obj
+
+SHL1TARGET=$(TARGET)
+SHL1VERSIONMAP = $(SOLARENV)/src/component.map
+
+SHL1STDLIBS= \
+ $(DEPLOYMENTMISCLIB) \
+ $(CPPULIB) \
+ $(CPPUHELPERLIB) \
+ $(SALLIB) \
+ $(UCBHELPERLIB) \
+ $(UNOTOOLSLIB) \
+ $(TOOLSLIB) \
+ $(I18NISOLANGLIB) \
+ $(JVMFWKLIB) \
+ $(XMLSCRIPTLIB) \
+ $(BERKELEYLIB)
+
+SHL1DEPN=
+SHL1IMPLIB=imigrationoo2
+SHL1DEF=$(MISC)$/$(SHL1TARGET).def
+
+DEF1NAME=$(SHL1TARGET)
+
+COMP2TYPELIST = migrationoo3
+SHL2TARGET=migrationoo3.uno
+SHL2VERSIONMAP = $(SOLARENV)/src/component.map
+
+SHL2OBJS= \
+ $(SLO)$/cexportsoo3.obj \
+ $(SLO)$/oo3extensionmigration.obj
+
+SHL2STDLIBS= \
+ $(DEPLOYMENTMISCLIB) \
+ $(CPPULIB) \
+ $(CPPUHELPERLIB) \
+ $(SALLIB) \
+ $(UCBHELPERLIB) \
+ $(UNOTOOLSLIB) \
+ $(TOOLSLIB) \
+ $(I18NISOLANGLIB) \
+ $(JVMFWKLIB) \
+ $(XMLSCRIPTLIB) \
+ $(BERKELEYLIB)
+
+SHL2DEPN=
+SHL2IMPLIB=imigrationoo3
+SHL2DEF=$(MISC)$/$(SHL2TARGET).def
+
+DEF2NAME=$(SHL2TARGET)
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
+ALLTAR : $(MISC)/migrationoo3.component
+
+$(MISC)/migrationoo3.component .ERRREMOVE : \
+ $(SOLARENV)/bin/createcomponent.xslt migrationoo3.component
+ $(XSLTPROC) --nonet --stringparam uri \
+ '$(COMPONENTPREFIX_BASIS_NATIVE)$(SHL2TARGETN:f)' -o $@ \
+ $(SOLARENV)/bin/createcomponent.xslt migrationoo3.component
+
+ALLTAR : $(MISC)/migrationoo2.component
+
+$(MISC)/migrationoo2.component .ERRREMOVE : \
+ $(SOLARENV)/bin/createcomponent.xslt migrationoo2.component
+ $(XSLTPROC) --nonet --stringparam uri \
+ '$(COMPONENTPREFIX_BASIS_NATIVE)$(SHL1TARGETN:f)' -o $@ \
+ $(SOLARENV)/bin/createcomponent.xslt migrationoo2.component
diff --git a/desktop/source/migration/services/migrationoo2.component b/desktop/source/migration/services/migrationoo2.component
new file mode 100755
index 000000000000..2b21ab123b9e
--- /dev/null
+++ b/desktop/source/migration/services/migrationoo2.component
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--**********************************************************************
+*
+* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+*
+* Copyright 2000, 2010 Oracle and/or its affiliates.
+*
+* OpenOffice.org - a multi-platform office productivity suite
+*
+* This file is part of OpenOffice.org.
+*
+* OpenOffice.org is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License version 3
+* only, as published by the Free Software Foundation.
+*
+* OpenOffice.org is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Lesser General Public License version 3 for more details
+* (a copy is included in the LICENSE file that accompanied this code).
+*
+* You should have received a copy of the GNU Lesser General Public License
+* version 3 along with OpenOffice.org. If not, see
+* <http://www.openoffice.org/license.html>
+* for a copy of the LGPLv3 License.
+*
+**********************************************************************-->
+
+<component loader="com.sun.star.loader.SharedLibrary"
+ xmlns="http://openoffice.org/2010/uno-components">
+ <implementation name="com.sun.star.comp.desktop.migration.Basic">
+ <service name="com.sun.star.migration.Basic"/>
+ </implementation>
+ <implementation name="com.sun.star.comp.desktop.migration.Wordbooks">
+ <service name="com.sun.star.migration.Wordbooks"/>
+ </implementation>
+</component>
diff --git a/desktop/source/migration/services/migrationoo2.xml b/desktop/source/migration/services/migrationoo2.xml
new file mode 100755
index 000000000000..5bda732f0fba
--- /dev/null
+++ b/desktop/source/migration/services/migrationoo2.xml
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE module-description PUBLIC "-//StarOffice//DTD ComponentDescription 1.0//EN" "module-description.dtd">
+<module-description xmlns:xlink="http://www.w3.org/1999/xlink">
+ <module-name> migrationoo2.uno </module-name>
+ <component-description>
+ <author> Joachim Lingner </author>
+ <name> com.sun.star.comp.jvmfwk.MigrationOO2</name>
+ <description>
+Specifies a factory object to create proxy objects.
+These proxy object represent a given target object and can be
+be aggregated. The proxy objects act UNO conform and do NOT provide
+original target interfaces on queryInterface() calls.
+</description>
+ <loader-name> com.sun.star.loader.SharedLibrary </loader-name>
+ <language> C++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.reflection.ProxyFactory </supported-service>
+ <service-dependency> ... </service-dependency>
+ <type> com.sun.star.lang.XTypeProvider </type>
+ <type> com.sun.star.lang.XServiceInfo </type>
+ <type> com.sun.star.lang.XSingleServiceFactory </type>
+ <type> com.sun.star.lang.XMultiServiceFactory </type>
+ <type> com.sun.star.lang.XInitialization </type>
+ <type> com.sun.star.lang.WrappedTargetException </type>
+ <type> com.sun.star.registry.XRegistryKey </type>
+ <type> com.sun.star.lang.XSingleComponentFactory </type>
+ <type> com.sun.star.task.XJob </type>
+ <type> com.sun.star.beans.NamedValue </type>
+ <type> com.sun.star.configuration.backend.XLayer </type>
+ <type> com.sun.star.configuration.backend.XLayerHandler </type>
+ <type> com.sun.star.configuration.backend.MalformedDataException </type>
+ <type> com.sun.star.configuration.backend.TemplateIdentifier </type>
+ </component-description>
+ <component-description>
+ <author>Thomas Benisch</author>
+ <name>com.sun.star.comp.desktop.migration.Basic</name>
+ <description>migration service for OpenOffice.org Basic and dialogs</description>
+ <loader-name>com.sun.star.loader.SharedLibrary</loader-name>
+ <language>c++</language>
+ <status value="final"/>
+ <supported-service>com.sun.star.migration.Basic</supported-service>
+ <service-dependency>...</service-dependency>
+ <type>com.sun.star.beans.NamedValue</type>
+ <type>com.sun.star.lang.IllegalArgumentException</type>
+ <type>com.sun.star.lang.XInitialization</type>
+ <type>com.sun.star.task.XJob</type>
+ <type>com.sun.star.lang.XServiceInfo</type>
+ <type>com.sun.star.lang.XTypeProvider</type>
+ <type>com.sun.star.uno.XComponentContext</type>
+ </component-description>
+ <component-description>
+ <author>Thomas Benisch</author>
+ <name>com.sun.star.comp.desktop.migration.Autocorrection</name>
+ <description>migration service for OpenOffice.org autocorrection</description>
+ <loader-name>com.sun.star.loader.SharedLibrary</loader-name>
+ <language>c++</language>
+ <status value="final"/>
+ <supported-service>com.sun.star.migration.Autocorrection</supported-service>
+ <service-dependency>...</service-dependency>
+ <type>com.sun.star.beans.NamedValue</type>
+ <type>com.sun.star.lang.IllegalArgumentException</type>
+ <type>com.sun.star.lang.XInitialization</type>
+ <type>com.sun.star.task.XJob</type>
+ <type>com.sun.star.lang.XServiceInfo</type>
+ <type>com.sun.star.lang.XTypeProvider</type>
+ <type>com.sun.star.uno.XComponentContext</type>
+ </component-description>
+ <project-build-dependency>unotools</project-build-dependency>
+ <project-build-dependency>tools</project-build-dependency>
+ <project-build-dependency>cppuhelper</project-build-dependency>
+ <project-build-dependency>cppu</project-build-dependency>
+ <project-build-dependency>sal</project-build-dependency>
+ <runtime-module-dependency>utl</runtime-module-dependency>
+ <runtime-module-dependency>tl</runtime-module-dependency>
+ <runtime-module-dependency>cppuhelper3$(COM)</runtime-module-dependency>
+ <runtime-module-dependency>cppu3</runtime-module-dependency>
+ <runtime-module-dependency>sal3</runtime-module-dependency>
+</module-description>
diff --git a/desktop/source/migration/services/migrationoo3.component b/desktop/source/migration/services/migrationoo3.component
new file mode 100755
index 000000000000..380c389ab7b9
--- /dev/null
+++ b/desktop/source/migration/services/migrationoo3.component
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--**********************************************************************
+*
+* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+*
+* Copyright 2000, 2010 Oracle and/or its affiliates.
+*
+* OpenOffice.org - a multi-platform office productivity suite
+*
+* This file is part of OpenOffice.org.
+*
+* OpenOffice.org is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License version 3
+* only, as published by the Free Software Foundation.
+*
+* OpenOffice.org is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Lesser General Public License version 3 for more details
+* (a copy is included in the LICENSE file that accompanied this code).
+*
+* You should have received a copy of the GNU Lesser General Public License
+* version 3 along with OpenOffice.org. If not, see
+* <http://www.openoffice.org/license.html>
+* for a copy of the LGPLv3 License.
+*
+**********************************************************************-->
+
+<component loader="com.sun.star.loader.SharedLibrary"
+ xmlns="http://openoffice.org/2010/uno-components">
+ <implementation name="com.sun.star.comp.desktop.migration.OOo3Extensions">
+ <service name="com.sun.star.migration.Extensions"/>
+ </implementation>
+</component>
diff --git a/desktop/source/migration/services/misc.hxx b/desktop/source/migration/services/misc.hxx
new file mode 100644
index 000000000000..54396863bb8c
--- /dev/null
+++ b/desktop/source/migration/services/misc.hxx
@@ -0,0 +1,51 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _DESKTOP_MISC_HXX_
+#define _DESKTOP_MISC_HXX_
+
+#include <rtl/ustring.hxx>
+
+#include <vector>
+#include <memory>
+
+//.........................................................................
+namespace migration
+{
+//.........................................................................
+
+ typedef ::std::vector< ::rtl::OUString > TStringVector;
+ typedef ::std::auto_ptr< TStringVector > TStringVectorPtr;
+
+//.........................................................................
+} // namespace migration
+//.........................................................................
+
+#endif // _DESKTOP_MISC_HXX_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/migration/services/oo3extensionmigration.cxx b/desktop/source/migration/services/oo3extensionmigration.cxx
new file mode 100644
index 000000000000..43d1036b65a7
--- /dev/null
+++ b/desktop/source/migration/services/oo3extensionmigration.cxx
@@ -0,0 +1,564 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include "oo3extensionmigration.hxx"
+#include <rtl/instance.hxx>
+#include <osl/file.hxx>
+#include <osl/thread.h>
+#include <tools/urlobj.hxx>
+#include <unotools/bootstrap.hxx>
+#include <unotools/ucbstreamhelper.hxx>
+#include <unotools/textsearch.hxx>
+#include <comphelper/sequence.hxx>
+#include <comphelper/processfactory.hxx>
+#include <ucbhelper/content.hxx>
+
+#include <com/sun/star/task/XInteractionApprove.hpp>
+#include <com/sun/star/task/XInteractionAbort.hpp>
+#include <com/sun/star/ucb/XCommandInfo.hpp>
+#include <com/sun/star/ucb/TransferInfo.hpp>
+#include <com/sun/star/ucb/NameClash.hpp>
+#include <com/sun/star/ucb/XCommandEnvironment.hpp>
+#include <com/sun/star/xml/xpath/XXPathAPI.hpp>
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <com/sun/star/deployment/ExtensionManager.hpp>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+
+namespace migration
+{
+
+static ::rtl::OUString sExtensionSubDir = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/user/uno_packages/" ) );
+static ::rtl::OUString sSubDirName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "cache" ) );
+static ::rtl::OUString sConfigDir = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/user/registry/data" ) );
+static ::rtl::OUString sOrgDir = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/user/registry/data/org" ) );
+static ::rtl::OUString sExcludeDir1 = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/user/registry/data/org" ) );
+static ::rtl::OUString sExcludeDir2 = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/user/registry/data/org/openoffice" ) );
+static ::rtl::OUString sDescriptionXmlFile = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/description.xml" ) );
+static ::rtl::OUString sExtensionRootSubDirName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/uno_packages" ) );
+
+static ::rtl::OUString sConfigurationDataType = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("application/vnd.sun.star.configuration-data"));
+static ::rtl::OUString sConfigurationSchemaType = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("application/vnd.sun.star.configuration-schema"));
+
+// =============================================================================
+// component operations
+// =============================================================================
+
+::rtl::OUString OO3ExtensionMigration_getImplementationName()
+{
+ static ::rtl::OUString* pImplName = 0;
+ if ( !pImplName )
+ {
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ if ( !pImplName )
+ {
+ static ::rtl::OUString aImplName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.desktop.migration.OOo3Extensions" ) );
+ pImplName = &aImplName;
+ }
+ }
+ return *pImplName;
+}
+
+// -----------------------------------------------------------------------------
+
+Sequence< ::rtl::OUString > OO3ExtensionMigration_getSupportedServiceNames()
+{
+ static Sequence< ::rtl::OUString >* pNames = 0;
+ if ( !pNames )
+ {
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ if ( !pNames )
+ {
+ static Sequence< ::rtl::OUString > aNames(1);
+ aNames.getArray()[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.migration.Extensions" ) );
+ pNames = &aNames;
+ }
+ }
+ return *pNames;
+}
+
+// =============================================================================
+// ExtensionMigration
+// =============================================================================
+
+OO3ExtensionMigration::OO3ExtensionMigration(Reference< XComponentContext > const & ctx) :
+m_ctx(ctx)
+{
+}
+
+// -----------------------------------------------------------------------------
+
+OO3ExtensionMigration::~OO3ExtensionMigration()
+{
+}
+
+::osl::FileBase::RC OO3ExtensionMigration::checkAndCreateDirectory( INetURLObject& rDirURL )
+{
+ ::osl::FileBase::RC aResult = ::osl::Directory::create( rDirURL.GetMainURL( INetURLObject::DECODE_TO_IURI ) );
+ if ( aResult == ::osl::FileBase::E_NOENT )
+ {
+ INetURLObject aBaseURL( rDirURL );
+ aBaseURL.removeSegment();
+ checkAndCreateDirectory( aBaseURL );
+ return ::osl::Directory::create( rDirURL.GetMainURL( INetURLObject::DECODE_TO_IURI ) );
+ }
+ else
+ {
+ return aResult;
+ }
+}
+
+void OO3ExtensionMigration::scanUserExtensions( const ::rtl::OUString& sSourceDir, TStringVector& aMigrateExtensions )
+{
+ osl::Directory aScanRootDir( sSourceDir );
+ osl::FileStatus fs(FileStatusMask_Type | FileStatusMask_FileURL);
+ osl::FileBase::RC nRetCode = aScanRootDir.open();
+ if ( nRetCode == osl::Directory::E_None )
+ {
+ sal_uInt32 nHint( 0 );
+ osl::DirectoryItem aItem;
+ while ( aScanRootDir.getNextItem( aItem, nHint ) == osl::Directory::E_None )
+ {
+ if (( aItem.getFileStatus(fs) == osl::FileBase::E_None ) &&
+ ( fs.getFileType() == osl::FileStatus::Directory ))
+ {
+ //Check next folder as the "real" extension folder is below a temp folder!
+ ::rtl::OUString sExtensionFolderURL = fs.getFileURL();
+
+ osl::DirectoryItem aExtDirItem;
+ osl::Directory aExtensionRootDir( sExtensionFolderURL );
+
+ nRetCode = aExtensionRootDir.open();
+ if (( nRetCode == osl::Directory::E_None ) &&
+ ( aExtensionRootDir.getNextItem( aExtDirItem, nHint ) == osl::Directory::E_None ))
+ {
+ bool bFileStatus = aExtDirItem.getFileStatus(fs) == osl::FileBase::E_None;
+ bool bIsDir = fs.getFileType() == osl::FileStatus::Directory;
+
+ if ( bFileStatus && bIsDir )
+ {
+ sExtensionFolderURL = fs.getFileURL();
+ ScanResult eResult = scanExtensionFolder( sExtensionFolderURL );
+ if ( eResult == SCANRESULT_MIGRATE_EXTENSION )
+ aMigrateExtensions.push_back( sExtensionFolderURL );
+ }
+ }
+ }
+ }
+ }
+}
+
+OO3ExtensionMigration::ScanResult OO3ExtensionMigration::scanExtensionFolder( const ::rtl::OUString& sExtFolder )
+{
+ ScanResult aResult = SCANRESULT_NOTFOUND;
+ osl::Directory aDir(sExtFolder);
+
+ // get sub dirs
+ if (aDir.open() == osl::FileBase::E_None)
+ {
+ // work through directory contents...
+ osl::DirectoryItem item;
+ osl::FileStatus fs(FileStatusMask_Type | FileStatusMask_FileURL);
+ TStringVector aDirectories;
+ while ((aDir.getNextItem(item) == osl::FileBase::E_None ) &&
+ ( aResult == SCANRESULT_NOTFOUND ))
+ {
+ if (item.getFileStatus(fs) == osl::FileBase::E_None)
+ {
+ ::rtl::OUString aDirEntryURL;
+ if (fs.getFileType() == osl::FileStatus::Directory)
+ aDirectories.push_back( fs.getFileURL() );
+ else
+ {
+ aDirEntryURL = fs.getFileURL();
+ if ( aDirEntryURL.indexOf( sDescriptionXmlFile ) > 0 )
+ aResult = scanDescriptionXml( aDirEntryURL ) ? SCANRESULT_MIGRATE_EXTENSION : SCANRESULT_DONTMIGRATE_EXTENSION;
+ }
+ }
+ }
+
+ TStringVector::const_iterator pIter = aDirectories.begin();
+ while ( pIter != aDirectories.end() && aResult == SCANRESULT_NOTFOUND )
+ {
+ aResult = scanExtensionFolder( *pIter );
+ ++pIter;
+ }
+ }
+ return aResult;
+}
+
+bool OO3ExtensionMigration::scanDescriptionXml( const ::rtl::OUString& sDescriptionXmlURL )
+{
+ if ( !m_xDocBuilder.is() )
+ {
+ m_xDocBuilder = uno::Reference< xml::dom::XDocumentBuilder >(
+ m_ctx->getServiceManager()->createInstanceWithContext(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.xml.dom.DocumentBuilder")),
+ m_ctx ), uno::UNO_QUERY );
+ }
+
+ if ( !m_xSimpleFileAccess.is() )
+ {
+ m_xSimpleFileAccess = uno::Reference< ucb::XSimpleFileAccess >(
+ m_ctx->getServiceManager()->createInstanceWithContext(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.ucb.SimpleFileAccess")),
+ m_ctx ), uno::UNO_QUERY );
+ }
+
+ ::rtl::OUString aExtIdentifier;
+ if ( m_xDocBuilder.is() && m_xSimpleFileAccess.is() )
+ {
+ try
+ {
+ uno::Reference< io::XInputStream > xIn =
+ m_xSimpleFileAccess->openFileRead( sDescriptionXmlURL );
+
+ if ( xIn.is() )
+ {
+ uno::Reference< xml::dom::XDocument > xDoc = m_xDocBuilder->parse( xIn );
+ if ( xDoc.is() )
+ {
+ uno::Reference< xml::dom::XElement > xRoot = xDoc->getDocumentElement();
+ if ( xRoot.is() &&
+ xRoot->getTagName().equals(::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("description"))) )
+ {
+ uno::Reference< xml::xpath::XXPathAPI > xPath(
+ m_ctx->getServiceManager()->createInstanceWithContext(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.xml.xpath.XPathAPI")),
+ m_ctx),
+ uno::UNO_QUERY);
+
+ xPath->registerNS(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("desc")),
+ xRoot->getNamespaceURI());
+ xPath->registerNS(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("xlink")),
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("http://www.w3.org/1999/xlink")));
+
+ try
+ {
+ uno::Reference< xml::dom::XNode > xRootNode( xRoot, uno::UNO_QUERY );
+ uno::Reference< xml::dom::XNode > xNode(
+ xPath->selectSingleNode(
+ xRootNode,
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("desc:identifier/@value")) ));
+ if ( xNode.is() )
+ aExtIdentifier = xNode->getNodeValue();
+ }
+ catch ( xml::xpath::XPathException& )
+ {
+ }
+ catch ( xml::dom::DOMException& )
+ {
+ }
+ }
+ }
+ }
+
+ if ( aExtIdentifier.getLength() > 0 )
+ {
+ // scan extension identifier and try to match with our black list entries
+ for ( sal_uInt32 i = 0; i < m_aBlackList.size(); i++ )
+ {
+ utl::SearchParam param(m_aBlackList[i], utl::SearchParam::SRCH_REGEXP);
+ utl::TextSearch ts(param, LANGUAGE_DONTKNOW);
+
+ xub_StrLen start = 0;
+ xub_StrLen end = static_cast<sal_uInt16>(aExtIdentifier.getLength());
+ if (ts.SearchFrwrd(aExtIdentifier, &start, &end))
+ return false;
+ }
+ }
+ }
+ catch ( ucb::CommandAbortedException& )
+ {
+ }
+ catch ( uno::RuntimeException& )
+ {
+ }
+
+ if ( aExtIdentifier.getLength() == 0 )
+ {
+ // Fallback:
+ // Try to use the folder name to match our black list
+ // as some extensions don't provide an identifier in the
+ // description.xml!
+ for ( sal_uInt32 i = 0; i < m_aBlackList.size(); i++ )
+ {
+ utl::SearchParam param(m_aBlackList[i], utl::SearchParam::SRCH_REGEXP);
+ utl::TextSearch ts(param, LANGUAGE_DONTKNOW);
+
+ xub_StrLen start = 0;
+ xub_StrLen end = static_cast<sal_uInt16>(sDescriptionXmlURL.getLength());
+ if (ts.SearchFrwrd(sDescriptionXmlURL, &start, &end))
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+bool OO3ExtensionMigration::migrateExtension( const ::rtl::OUString& sSourceDir )
+{
+ if ( !m_xExtensionManager.is() )
+ {
+ try
+ {
+ m_xExtensionManager = deployment::ExtensionManager::get( m_ctx );
+ }
+ catch ( ucb::CommandFailedException & ){}
+ catch ( uno::RuntimeException & ) {}
+ }
+
+ if ( m_xExtensionManager.is() )
+ {
+ try
+ {
+ TmpRepositoryCommandEnv* pCmdEnv = new TmpRepositoryCommandEnv();
+
+ uno::Reference< ucb::XCommandEnvironment > xCmdEnv(
+ static_cast< cppu::OWeakObject* >( pCmdEnv ), uno::UNO_QUERY );
+ uno::Reference< task::XAbortChannel > xAbortChannel;
+ uno::Reference< deployment::XPackage > xPackage =
+ m_xExtensionManager->addExtension(
+ sSourceDir, uno::Sequence<beans::NamedValue>(),
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("user")), xAbortChannel, xCmdEnv );
+
+ if ( xPackage.is() )
+ return true;
+ }
+ catch ( ucb::CommandFailedException& )
+ {
+ }
+ catch ( ucb::CommandAbortedException& )
+ {
+ }
+ catch ( lang::IllegalArgumentException& )
+ {
+ }
+ }
+
+ return false;
+}
+
+
+// -----------------------------------------------------------------------------
+// XServiceInfo
+// -----------------------------------------------------------------------------
+
+::rtl::OUString OO3ExtensionMigration::getImplementationName() throw (RuntimeException)
+{
+ return OO3ExtensionMigration_getImplementationName();
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Bool OO3ExtensionMigration::supportsService( const ::rtl::OUString& rServiceName ) throw (RuntimeException)
+{
+ Sequence< ::rtl::OUString > aNames( getSupportedServiceNames() );
+ const ::rtl::OUString* pNames = aNames.getConstArray();
+ const ::rtl::OUString* pEnd = pNames + aNames.getLength();
+ for ( ; pNames != pEnd && !pNames->equals( rServiceName ); ++pNames )
+ ;
+
+ return pNames != pEnd;
+}
+
+// -----------------------------------------------------------------------------
+
+Sequence< ::rtl::OUString > OO3ExtensionMigration::getSupportedServiceNames() throw (RuntimeException)
+{
+ return OO3ExtensionMigration_getSupportedServiceNames();
+}
+
+// -----------------------------------------------------------------------------
+// XInitialization
+// -----------------------------------------------------------------------------
+
+void OO3ExtensionMigration::initialize( const Sequence< Any >& aArguments ) throw (Exception, RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ const Any* pIter = aArguments.getConstArray();
+ const Any* pEnd = pIter + aArguments.getLength();
+ for ( ; pIter != pEnd ; ++pIter )
+ {
+ beans::NamedValue aValue;
+ *pIter >>= aValue;
+ if ( aValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "UserData" ) ) )
+ {
+ if ( !(aValue.Value >>= m_sSourceDir) )
+ {
+ OSL_FAIL( "ExtensionMigration::initialize: argument UserData has wrong type!" );
+ }
+ }
+ else if ( aValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ExtensionBlackList" ) ) )
+ {
+ Sequence< ::rtl::OUString > aBlackList;
+ if ( (aValue.Value >>= aBlackList ) && ( aBlackList.getLength() > 0 ))
+ {
+ m_aBlackList.resize( aBlackList.getLength() );
+ ::comphelper::sequenceToArray< ::rtl::OUString >( &m_aBlackList[0], aBlackList );
+ }
+ }
+ }
+}
+
+Any OO3ExtensionMigration::execute( const Sequence< beans::NamedValue >& )
+ throw (lang::IllegalArgumentException, Exception, RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ ::utl::Bootstrap::PathStatus aStatus = ::utl::Bootstrap::locateUserInstallation( m_sTargetDir );
+ if ( aStatus == ::utl::Bootstrap::PATH_EXISTS )
+ {
+ // copy all extensions
+ ::rtl::OUString sSourceDir( m_sSourceDir );
+ sSourceDir += sExtensionSubDir;
+ sSourceDir += sSubDirName;
+ sSourceDir += sExtensionRootSubDirName;
+ TStringVector aExtensionToMigrate;
+ scanUserExtensions( sSourceDir, aExtensionToMigrate );
+ if ( aExtensionToMigrate.size() > 0 )
+ {
+ TStringVector::iterator pIter = aExtensionToMigrate.begin();
+ while ( pIter != aExtensionToMigrate.end() )
+ {
+ migrateExtension( *pIter );
+ ++pIter;
+ }
+ }
+ }
+
+ return Any();
+}
+
+// -----------------------------------------------------------------------------
+// TmpRepositoryCommandEnv
+// -----------------------------------------------------------------------------
+
+TmpRepositoryCommandEnv::TmpRepositoryCommandEnv()
+{
+}
+
+TmpRepositoryCommandEnv::~TmpRepositoryCommandEnv()
+{
+}
+// XCommandEnvironment
+//______________________________________________________________________________
+uno::Reference< task::XInteractionHandler > TmpRepositoryCommandEnv::getInteractionHandler()
+throw ( uno::RuntimeException )
+{
+ return this;
+}
+
+//______________________________________________________________________________
+uno::Reference< ucb::XProgressHandler > TmpRepositoryCommandEnv::getProgressHandler()
+throw ( uno::RuntimeException )
+{
+ return this;
+}
+
+// XInteractionHandler
+void TmpRepositoryCommandEnv::handle(
+ uno::Reference< task::XInteractionRequest> const & xRequest )
+ throw ( uno::RuntimeException )
+{
+ uno::Any request( xRequest->getRequest() );
+ OSL_ASSERT( request.getValueTypeClass() == uno::TypeClass_EXCEPTION );
+
+ bool approve = true;
+ bool abort = false;
+
+ // select:
+ uno::Sequence< Reference< task::XInteractionContinuation > > conts(
+ xRequest->getContinuations() );
+ Reference< task::XInteractionContinuation > const * pConts =
+ conts.getConstArray();
+ sal_Int32 len = conts.getLength();
+ for ( sal_Int32 pos = 0; pos < len; ++pos )
+ {
+ if (approve) {
+ uno::Reference< task::XInteractionApprove > xInteractionApprove(
+ pConts[ pos ], uno::UNO_QUERY );
+ if (xInteractionApprove.is()) {
+ xInteractionApprove->select();
+ // don't query again for ongoing continuations:
+ approve = false;
+ }
+ }
+ else if (abort) {
+ uno::Reference< task::XInteractionAbort > xInteractionAbort(
+ pConts[ pos ], uno::UNO_QUERY );
+ if (xInteractionAbort.is()) {
+ xInteractionAbort->select();
+ // don't query again for ongoing continuations:
+ abort = false;
+ }
+ }
+ }
+}
+
+// XProgressHandler
+void TmpRepositoryCommandEnv::push( uno::Any const & /*Status*/ )
+throw (uno::RuntimeException)
+{
+}
+
+
+void TmpRepositoryCommandEnv::update( uno::Any const & /*Status */)
+throw (uno::RuntimeException)
+{
+}
+
+void TmpRepositoryCommandEnv::pop() throw (uno::RuntimeException)
+{
+}
+
+// =============================================================================
+// component operations
+// =============================================================================
+
+Reference< XInterface > SAL_CALL OO3ExtensionMigration_create(
+ Reference< XComponentContext > const & ctx )
+ SAL_THROW( () )
+{
+ return static_cast< lang::XTypeProvider * >( new OO3ExtensionMigration(
+ ctx) );
+}
+
+// -----------------------------------------------------------------------------
+
+} // namespace migration
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/migration/services/oo3extensionmigration.hxx b/desktop/source/migration/services/oo3extensionmigration.hxx
new file mode 100644
index 000000000000..adadb3b293e6
--- /dev/null
+++ b/desktop/source/migration/services/oo3extensionmigration.hxx
@@ -0,0 +1,163 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _DESKTOP_OO3EXTENSIONMIGRATION_HXX_
+#define _DESKTOP_OO3EXTENSIONMIGRATION_HXX_
+
+#include "misc.hxx"
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/task/XJob.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/xml/dom/XDocumentBuilder.hpp>
+#include <com/sun/star/ucb/XSimpleFileAccess.hpp>
+#include <com/sun/star/deployment/XExtensionManager.hpp>
+
+#include <osl/mutex.hxx>
+#include <osl/file.hxx>
+#include <cppuhelper/implbase3.hxx>
+#include <cppuhelper/compbase3.hxx>
+#include <ucbhelper/content.hxx>
+#include <xmlscript/xmllib_imexp.hxx>
+
+namespace com { namespace sun { namespace star {
+ namespace uno {
+ class XComponentContext;
+ }
+ namespace deployment {
+ class XPackage;
+ }
+}}}
+
+class INetURLObject;
+
+
+namespace migration
+{
+
+ ::rtl::OUString SAL_CALL OO3ExtensionMigration_getImplementationName();
+ ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL OO3ExtensionMigration_getSupportedServiceNames();
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL OO3ExtensionMigration_create(
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > const & xContext )
+ SAL_THROW( (::com::sun::star::uno::Exception) );
+
+
+ // =============================================================================
+ // class ExtensionMigration
+ // =============================================================================
+
+ typedef ::cppu::WeakImplHelper3<
+ ::com::sun::star::lang::XServiceInfo,
+ ::com::sun::star::lang::XInitialization,
+ ::com::sun::star::task::XJob > ExtensionMigration_BASE;
+
+ class OO3ExtensionMigration : public ExtensionMigration_BASE
+ {
+ private:
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > m_ctx;
+ ::com::sun::star::uno::Reference< ::com::sun::star::xml::dom::XDocumentBuilder > m_xDocBuilder;
+ ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XSimpleFileAccess > m_xSimpleFileAccess;
+ ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XExtensionManager > m_xExtensionManager;
+ ::osl::Mutex m_aMutex;
+ ::rtl::OUString m_sSourceDir;
+ ::rtl::OUString m_sTargetDir;
+ TStringVector m_aBlackList;
+
+ enum ScanResult
+ {
+ SCANRESULT_NOTFOUND,
+ SCANRESULT_MIGRATE_EXTENSION,
+ SCANRESULT_DONTMIGRATE_EXTENSION
+ };
+
+ ::osl::FileBase::RC checkAndCreateDirectory( INetURLObject& rDirURL );
+ ScanResult scanExtensionFolder( const ::rtl::OUString& sExtFolder );
+ void scanUserExtensions( const ::rtl::OUString& sSourceDir, TStringVector& aMigrateExtensions );
+ bool scanDescriptionXml( const ::rtl::OUString& sDescriptionXmlFilePath );
+ bool migrateExtension( const ::rtl::OUString& sSourceDir );
+
+ public:
+ OO3ExtensionMigration(::com::sun::star::uno::Reference<
+ ::com::sun::star::uno::XComponentContext > const & ctx);
+ virtual ~OO3ExtensionMigration();
+
+ // XServiceInfo
+ virtual ::rtl::OUString SAL_CALL getImplementationName()
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& rServiceName )
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames()
+ throw (::com::sun::star::uno::RuntimeException);
+
+ // XInitialization
+ virtual void SAL_CALL initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments )
+ throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
+
+ // XJob
+ virtual ::com::sun::star::uno::Any SAL_CALL execute(
+ const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& Arguments )
+ throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::Exception,
+ ::com::sun::star::uno::RuntimeException);
+ };
+
+ class TmpRepositoryCommandEnv
+ : public ::cppu::WeakImplHelper3< ::com::sun::star::ucb::XCommandEnvironment,
+ ::com::sun::star::task::XInteractionHandler,
+ ::com::sun::star::ucb::XProgressHandler >
+ {
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > m_xContext;
+ ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler> m_forwardHandler;
+ public:
+ virtual ~TmpRepositoryCommandEnv();
+ TmpRepositoryCommandEnv();
+
+ // XCommandEnvironment
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler > SAL_CALL
+ getInteractionHandler() throw ( ::com::sun::star::uno::RuntimeException );
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XProgressHandler >
+ SAL_CALL getProgressHandler() throw ( ::com::sun::star::uno::RuntimeException );
+
+ // XInteractionHandler
+ virtual void SAL_CALL handle(
+ ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionRequest > const & xRequest )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ // XProgressHandler
+ virtual void SAL_CALL push( ::com::sun::star::uno::Any const & Status )
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL update( ::com::sun::star::uno::Any const & Status )
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL pop() throw (::com::sun::star::uno::RuntimeException);
+ };
+
+//.........................................................................
+} // namespace migration
+//.........................................................................
+
+#endif // _DESKTOP_OO3EXTENSIONMIGRATION_HXX_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/migration/services/wordbookmigration.cxx b/desktop/source/migration/services/wordbookmigration.cxx
new file mode 100644
index 000000000000..fa114022897a
--- /dev/null
+++ b/desktop/source/migration/services/wordbookmigration.cxx
@@ -0,0 +1,325 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+#include "wordbookmigration.hxx"
+#include <tools/urlobj.hxx>
+#include <unotools/bootstrap.hxx>
+#include <unotools/ucbstreamhelper.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+
+
+//.........................................................................
+namespace migration
+{
+//.........................................................................
+
+
+ static ::rtl::OUString sSourceSubDir = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/user/wordbook" ) );
+ static ::rtl::OUString sTargetSubDir = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/user/wordbook" ) );
+ static ::rtl::OUString sBaseName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/wordbook" ) );
+ static ::rtl::OUString sSuffix = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".dic" ) );
+
+
+ // =============================================================================
+ // component operations
+ // =============================================================================
+
+ ::rtl::OUString WordbookMigration_getImplementationName()
+ {
+ static ::rtl::OUString* pImplName = 0;
+ if ( !pImplName )
+ {
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ if ( !pImplName )
+ {
+ static ::rtl::OUString aImplName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.desktop.migration.Wordbooks" ) );
+ pImplName = &aImplName;
+ }
+ }
+ return *pImplName;
+ }
+
+ // -----------------------------------------------------------------------------
+
+ Sequence< ::rtl::OUString > WordbookMigration_getSupportedServiceNames()
+ {
+ static Sequence< ::rtl::OUString >* pNames = 0;
+ if ( !pNames )
+ {
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ if ( !pNames )
+ {
+ static Sequence< ::rtl::OUString > aNames(1);
+ aNames.getArray()[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.migration.Wordbooks" ) );
+ pNames = &aNames;
+ }
+ }
+ return *pNames;
+ }
+
+ // =============================================================================
+ // WordbookMigration
+ // =============================================================================
+
+ WordbookMigration::WordbookMigration()
+ {
+ }
+
+ // -----------------------------------------------------------------------------
+
+ WordbookMigration::~WordbookMigration()
+ {
+ }
+
+ // -----------------------------------------------------------------------------
+
+ TStringVectorPtr WordbookMigration::getFiles( const ::rtl::OUString& rBaseURL ) const
+ {
+ TStringVectorPtr aResult( new TStringVector );
+ ::osl::Directory aDir( rBaseURL);
+
+ if ( aDir.open() == ::osl::FileBase::E_None )
+ {
+ // iterate over directory content
+ TStringVector aSubDirs;
+ ::osl::DirectoryItem aItem;
+ while ( aDir.getNextItem( aItem ) == ::osl::FileBase::E_None )
+ {
+ ::osl::FileStatus aFileStatus( FileStatusMask_Type | FileStatusMask_FileURL );
+ if ( aItem.getFileStatus( aFileStatus ) == ::osl::FileBase::E_None )
+ {
+ if ( aFileStatus.getFileType() == ::osl::FileStatus::Directory )
+ aSubDirs.push_back( aFileStatus.getFileURL() );
+ else
+ aResult->push_back( aFileStatus.getFileURL() );
+ }
+ }
+
+ // iterate recursive over subfolders
+ TStringVector::const_iterator aI = aSubDirs.begin();
+ while ( aI != aSubDirs.end() )
+ {
+ TStringVectorPtr aSubResult = getFiles( *aI );
+ aResult->insert( aResult->end(), aSubResult->begin(), aSubResult->end() );
+ ++aI;
+ }
+ }
+
+ return aResult;
+ }
+
+ // -----------------------------------------------------------------------------
+
+ ::osl::FileBase::RC WordbookMigration::checkAndCreateDirectory( INetURLObject& rDirURL )
+ {
+ ::osl::FileBase::RC aResult = ::osl::Directory::create( rDirURL.GetMainURL( INetURLObject::DECODE_TO_IURI ) );
+ if ( aResult == ::osl::FileBase::E_NOENT )
+ {
+ INetURLObject aBaseURL( rDirURL );
+ aBaseURL.removeSegment();
+ checkAndCreateDirectory( aBaseURL );
+ return ::osl::Directory::create( rDirURL.GetMainURL( INetURLObject::DECODE_TO_IURI ) );
+ }
+ else
+ {
+ return aResult;
+ }
+ }
+
+#define MAX_HEADER_LENGTH 16
+bool IsUserWordbook( const ::rtl::OUString& rFile )
+{
+ static const sal_Char* pVerStr2 = "WBSWG2";
+ static const sal_Char* pVerStr5 = "WBSWG5";
+ static const sal_Char* pVerStr6 = "WBSWG6";
+ static const sal_Char* pVerOOo7 = "OOoUserDict1";
+
+ bool bRet = false;
+ SvStream* pStream = ::utl::UcbStreamHelper::CreateStream( String(rFile), STREAM_STD_READ );
+ if ( pStream && !pStream->GetError() )
+ {
+ sal_Size nSniffPos = pStream->Tell();
+ static sal_Size nVerOOo7Len = sal::static_int_cast< sal_Size >(strlen( pVerOOo7 ));
+ sal_Char pMagicHeader[MAX_HEADER_LENGTH];
+ pMagicHeader[ nVerOOo7Len ] = '\0';
+ if ((pStream->Read((void *) pMagicHeader, nVerOOo7Len) == nVerOOo7Len))
+ {
+ if ( !strcmp(pMagicHeader, pVerOOo7) )
+ bRet = true;
+ else
+ {
+ sal_uInt16 nLen;
+ pStream->Seek (nSniffPos);
+ *pStream >> nLen;
+ if ( nLen < MAX_HEADER_LENGTH )
+ {
+ pStream->Read(pMagicHeader, nLen);
+ pMagicHeader[nLen] = '\0';
+ if ( !strcmp(pMagicHeader, pVerStr2)
+ || !strcmp(pMagicHeader, pVerStr5)
+ || !strcmp(pMagicHeader, pVerStr6) )
+ bRet = true;
+ }
+ }
+ }
+ }
+
+ delete pStream;
+ return bRet;
+}
+
+
+ // -----------------------------------------------------------------------------
+
+ void WordbookMigration::copyFiles()
+ {
+ ::rtl::OUString sTargetDir;
+ ::utl::Bootstrap::PathStatus aStatus = ::utl::Bootstrap::locateUserInstallation( sTargetDir );
+ if ( aStatus == ::utl::Bootstrap::PATH_EXISTS )
+ {
+ sTargetDir += sTargetSubDir;
+ TStringVectorPtr aFileList = getFiles( m_sSourceDir );
+ TStringVector::const_iterator aI = aFileList->begin();
+ while ( aI != aFileList->end() )
+ {
+ if (IsUserWordbook(*aI) )
+ {
+ ::rtl::OUString sSourceLocalName = aI->copy( m_sSourceDir.getLength() );
+ ::rtl::OUString sTargetName = sTargetDir + sSourceLocalName;
+ INetURLObject aURL( sTargetName );
+ aURL.removeSegment();
+ checkAndCreateDirectory( aURL );
+ ::osl::FileBase::RC aResult = ::osl::File::copy( *aI, sTargetName );
+ if ( aResult != ::osl::FileBase::E_None )
+ {
+ ::rtl::OString aMsg( "WordbookMigration::copyFiles: cannot copy " );
+ aMsg += ::rtl::OUStringToOString( *aI, RTL_TEXTENCODING_UTF8 ) + " to "
+ + ::rtl::OUStringToOString( sTargetName, RTL_TEXTENCODING_UTF8 );
+ OSL_FAIL( aMsg.getStr() );
+ }
+ }
+ ++aI;
+ }
+ }
+ else
+ {
+ OSL_FAIL( "WordbookMigration::copyFiles: no user installation!" );
+ }
+ }
+
+ // -----------------------------------------------------------------------------
+ // XServiceInfo
+ // -----------------------------------------------------------------------------
+
+ ::rtl::OUString WordbookMigration::getImplementationName() throw (RuntimeException)
+ {
+ return WordbookMigration_getImplementationName();
+ }
+
+ // -----------------------------------------------------------------------------
+
+ sal_Bool WordbookMigration::supportsService( const ::rtl::OUString& rServiceName ) throw (RuntimeException)
+ {
+ Sequence< ::rtl::OUString > aNames( getSupportedServiceNames() );
+ const ::rtl::OUString* pNames = aNames.getConstArray();
+ const ::rtl::OUString* pEnd = pNames + aNames.getLength();
+ for ( ; pNames != pEnd && !pNames->equals( rServiceName ); ++pNames )
+ ;
+
+ return pNames != pEnd;
+ }
+
+ // -----------------------------------------------------------------------------
+
+ Sequence< ::rtl::OUString > WordbookMigration::getSupportedServiceNames() throw (RuntimeException)
+ {
+ return WordbookMigration_getSupportedServiceNames();
+ }
+
+ // -----------------------------------------------------------------------------
+ // XInitialization
+ // -----------------------------------------------------------------------------
+
+ void WordbookMigration::initialize( const Sequence< Any >& aArguments ) throw (Exception, RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ const Any* pIter = aArguments.getConstArray();
+ const Any* pEnd = pIter + aArguments.getLength();
+ for ( ; pIter != pEnd ; ++pIter )
+ {
+ beans::NamedValue aValue;
+ *pIter >>= aValue;
+ if ( aValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "UserData" ) ) )
+ {
+ if ( !(aValue.Value >>= m_sSourceDir) )
+ {
+ OSL_FAIL( "WordbookMigration::initialize: argument UserData has wrong type!" );
+ }
+ m_sSourceDir += sSourceSubDir;
+ break;
+ }
+ }
+ }
+
+ // -----------------------------------------------------------------------------
+ // XJob
+ // -----------------------------------------------------------------------------
+
+ Any WordbookMigration::execute( const Sequence< beans::NamedValue >& )
+ throw (lang::IllegalArgumentException, Exception, RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ copyFiles();
+
+ return Any();
+ }
+
+ // =============================================================================
+ // component operations
+ // =============================================================================
+
+ Reference< XInterface > SAL_CALL WordbookMigration_create(
+ Reference< XComponentContext > const & )
+ SAL_THROW( () )
+ {
+ return static_cast< lang::XTypeProvider * >( new WordbookMigration() );
+ }
+
+ // -----------------------------------------------------------------------------
+
+//.........................................................................
+} // namespace migration
+//.........................................................................
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/migration/services/wordbookmigration.hxx b/desktop/source/migration/services/wordbookmigration.hxx
new file mode 100644
index 000000000000..72077e16b657
--- /dev/null
+++ b/desktop/source/migration/services/wordbookmigration.hxx
@@ -0,0 +1,105 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _DESKTOP_WORDBOOKMIGRATION_HXX_
+#define _DESKTOP_WORDBOOKMIGRATION_HXX_
+
+#include "misc.hxx"
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/task/XJob.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <cppuhelper/implbase3.hxx>
+#include <osl/mutex.hxx>
+#include <osl/file.hxx>
+
+
+class INetURLObject;
+
+
+//.........................................................................
+namespace migration
+{
+//.........................................................................
+
+ ::rtl::OUString SAL_CALL WordbookMigration_getImplementationName();
+ ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL WordbookMigration_getSupportedServiceNames();
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL WordbookMigration_create(
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > const & xContext )
+ SAL_THROW( (::com::sun::star::uno::Exception) );
+
+
+ // =============================================================================
+ // class WordbookMigration
+ // =============================================================================
+
+ typedef ::cppu::WeakImplHelper3<
+ ::com::sun::star::lang::XServiceInfo,
+ ::com::sun::star::lang::XInitialization,
+ ::com::sun::star::task::XJob > WordbookMigration_BASE;
+
+ class WordbookMigration : public WordbookMigration_BASE
+ {
+ private:
+ ::osl::Mutex m_aMutex;
+ ::rtl::OUString m_sSourceDir;
+
+ TStringVectorPtr getFiles( const ::rtl::OUString& rBaseURL ) const;
+ ::osl::FileBase::RC checkAndCreateDirectory( INetURLObject& rDirURL );
+ void copyFiles();
+
+ public:
+ WordbookMigration();
+ virtual ~WordbookMigration();
+
+ // XServiceInfo
+ virtual ::rtl::OUString SAL_CALL getImplementationName()
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& rServiceName )
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames()
+ throw (::com::sun::star::uno::RuntimeException);
+
+ // XInitialization
+ virtual void SAL_CALL initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments )
+ throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
+
+ // XJob
+ virtual ::com::sun::star::uno::Any SAL_CALL execute(
+ const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& Arguments )
+ throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::Exception,
+ ::com::sun::star::uno::RuntimeException);
+ };
+
+//.........................................................................
+} // namespace migration
+//.........................................................................
+
+#endif // _DESKTOP_AUTOCORRMIGRATION_HXX_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/migration/wizard.cxx b/desktop/source/migration/wizard.cxx
new file mode 100644
index 000000000000..3489d7186b4f
--- /dev/null
+++ b/desktop/source/migration/wizard.cxx
@@ -0,0 +1,603 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include <migration.hxx>
+#include "wizard.hxx"
+#include "wizard.hrc"
+#include "pages.hxx"
+#include "app.hxx"
+
+#include <rtl/ustring.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <rtl/string.hxx>
+#include <rtl/strbuf.hxx>
+#include <rtl/bootstrap.hxx>
+
+#include <comphelper/processfactory.hxx>
+#include <tools/date.hxx>
+#include <tools/time.hxx>
+#include <tools/datetime.hxx>
+#include <osl/file.hxx>
+#include <osl/time.h>
+#include <osl/module.hxx>
+#include <unotools/bootstrap.hxx>
+#include <vcl/msgbox.hxx>
+
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/XPropertyState.hpp>
+#include <com/sun/star/frame/XDesktop.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/util/XChangesBatch.hpp>
+#include <com/sun/star/container/XNameReplace.hpp>
+#include <com/sun/star/awt/WindowDescriptor.hpp>
+#include <com/sun/star/awt/WindowAttribute.hpp>
+
+using namespace svt;
+using namespace rtl;
+using namespace osl;
+using namespace utl;
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::util;
+using namespace com::sun::star::container;
+
+#define UNISTRING(s) rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(s))
+
+namespace desktop
+{
+
+const FirstStartWizard::WizardState FirstStartWizard::STATE_WELCOME = 0;
+const FirstStartWizard::WizardState FirstStartWizard::STATE_LICENSE = 1;
+const FirstStartWizard::WizardState FirstStartWizard::STATE_MIGRATION = 2;
+const FirstStartWizard::WizardState FirstStartWizard::STATE_USER = 3;
+const FirstStartWizard::WizardState FirstStartWizard::STATE_UPDATE_CHECK = 4;
+const FirstStartWizard::WizardState FirstStartWizard::STATE_REGISTRATION = 5;
+
+static sal_Int32 getBuildId()
+{
+ ::rtl::OUString aDefault;
+ ::rtl::OUString aBuildIdData = utl::Bootstrap::getBuildIdData( aDefault );
+ sal_Int32 nBuildId( 0 );
+ sal_Int32 nIndex1 = aBuildIdData.indexOf(':');
+ sal_Int32 nIndex2 = aBuildIdData.indexOf(')');
+ if (( nIndex1 > 0 ) && ( nIndex2 > 0 ) && ( nIndex2-1 > nIndex1+1 ))
+ {
+ ::rtl::OUString aBuildId = aBuildIdData.copy( nIndex1+1, nIndex2-nIndex1-1 );
+ nBuildId = aBuildId.toInt32();
+ }
+ return nBuildId;
+}
+
+WizardResId::WizardResId( sal_uInt16 nId ) :
+ ResId( nId, *FirstStartWizard::GetResManager() )
+{
+}
+
+ResMgr *FirstStartWizard::pResMgr = 0;
+
+ResMgr *FirstStartWizard::GetResManager()
+{
+ if ( !FirstStartWizard::pResMgr )
+ {
+ String aMgrName = String::CreateFromAscii( "dkt" );
+ FirstStartWizard::pResMgr = ResMgr::CreateResMgr( OUStringToOString( aMgrName, RTL_TEXTENCODING_UTF8 ));
+ }
+ return FirstStartWizard::pResMgr;
+}
+
+FirstStartWizard::FirstStartWizard( Window* pParent, sal_Bool bLicenseNeedsAcceptance, const rtl::OUString &rLicensePath )
+ :RoadmapWizard( pParent, WizardResId(DLG_FIRSTSTART_WIZARD),
+ WZB_NEXT|WZB_PREVIOUS|WZB_FINISH|WZB_CANCEL|WZB_HELP)
+ ,m_bOverride(sal_False)
+ ,m_aDefaultPath(0)
+ ,m_aMigrationPath(0)
+ ,m_bDone(sal_False)
+ ,m_bLicenseNeedsAcceptance( bLicenseNeedsAcceptance )
+ ,m_bLicenseWasAccepted(sal_False)
+ ,m_bAutomaticUpdChk(sal_True)
+ ,m_aThrobber(this, WizardResId(CTRL_THROBBER))
+ ,m_aLicensePath( rLicensePath )
+{
+ FreeResource();
+ // ---
+// enableState(STATE_USER, sal_False);
+// enableState(STATE_REGISTRATION, sal_False);
+
+ Size aTPSize(TP_WIDTH, TP_HEIGHT);
+ SetPageSizePixel(LogicToPixel(aTPSize, MAP_APPFONT));
+
+ //set help id
+ m_pPrevPage->SetHelpId(HID_FIRSTSTART_PREV);
+ m_pNextPage->SetHelpId(HID_FIRSTSTART_NEXT);
+ m_pCancel->SetHelpId(HID_FIRSTSTART_CANCEL);
+ m_pFinish->SetHelpId(HID_FIRSTSTART_FINISH);
+ // m_pHelp->SetUniqueId(UID_FIRSTSTART_HELP);
+ m_pHelp->Hide();
+ m_pHelp->Disable();
+
+ // save button lables
+ m_sNext = m_pNextPage->GetText();
+ m_sCancel = m_pCancel->GetText();
+
+ // save cancel click handler
+ m_lnkCancel = m_pCancel->GetClickHdl();
+
+ m_aDefaultPath = defineWizardPagesDependingFromContext();
+ activatePath(m_aDefaultPath, sal_True);
+
+ ActivatePage();
+
+ // set text of finish putton:
+ m_pFinish->SetText(String(WizardResId(STR_FINISH)));
+ // disable "finish button"
+ enableButtons(WZB_FINISH, sal_False);
+ defaultButton(WZB_NEXT);
+}
+
+void FirstStartWizard::DisableButtonsWhileMigration()
+{
+ enableButtons(0xff, sal_False);
+}
+
+::svt::RoadmapWizardTypes::PathId FirstStartWizard::defineWizardPagesDependingFromContext()
+{
+ ::svt::RoadmapWizardTypes::PathId aDefaultPath = 0;
+
+ sal_Bool bPage_Welcome = sal_True;
+ sal_Bool bPage_License = sal_True;
+ sal_Bool bPage_Migration = sal_True;
+ sal_Bool bPage_User = sal_True;
+ sal_Bool bPage_UpdateCheck = sal_True;
+ sal_Bool bPage_Registration = sal_True;
+
+ bPage_License = m_bLicenseNeedsAcceptance;
+ bPage_Migration = Migration::checkMigration();
+ bPage_UpdateCheck = showOnlineUpdatePage();
+
+ WizardPath aPath;
+ if (bPage_Welcome)
+ aPath.push_back(STATE_WELCOME);
+ if (bPage_License)
+ aPath.push_back(STATE_LICENSE);
+ if (bPage_Migration)
+ aPath.push_back(STATE_MIGRATION);
+ if (bPage_User)
+ aPath.push_back(STATE_USER);
+ if (bPage_UpdateCheck)
+ aPath.push_back(STATE_UPDATE_CHECK);
+ if (bPage_Registration)
+ aPath.push_back(STATE_REGISTRATION);
+
+ declarePath(aDefaultPath, aPath);
+
+ // a) If license must be accepted by the user, all direct links
+ // to wizard tab pages must be disabled. Because such pages
+ // should be accessible only in case license was accepted !
+ // b) But if no license should be shown at all ...
+ // such direct links can be enabled by default.
+ sal_Bool bAllowDirectLink = ( ! bPage_License);
+
+ if (bPage_User)
+ enableState(STATE_USER, bAllowDirectLink);
+ if (bPage_UpdateCheck)
+ enableState(STATE_UPDATE_CHECK, bAllowDirectLink);
+ if (bPage_Migration)
+ enableState(STATE_MIGRATION, bAllowDirectLink);
+ if (bPage_Registration)
+ enableState(STATE_REGISTRATION, bAllowDirectLink);
+
+ return aDefaultPath;
+}
+
+// catch F1 and disable help
+long FirstStartWizard::PreNotify( NotifyEvent& rNEvt )
+{
+ if( rNEvt.GetType() == EVENT_KEYINPUT )
+ {
+ const KeyCode& rKey = rNEvt.GetKeyEvent()->GetKeyCode();
+ if( rKey.GetCode() == KEY_F1 && ! rKey.GetModifier() )
+ return sal_True;
+ }
+ return RoadmapWizard::PreNotify(rNEvt);
+}
+
+
+void FirstStartWizard::enterState(WizardState _nState)
+{
+ RoadmapWizard::enterState(_nState);
+ // default state
+ // all on
+ enableButtons(0xff, sal_True);
+ // finish off
+ enableButtons(WZB_FINISH, sal_False);
+ // default text
+ m_pCancel->SetText(m_sCancel);
+ m_pCancel->SetClickHdl(m_lnkCancel);
+ m_pNextPage->SetText(m_sNext);
+
+ // default
+ defaultButton(WZB_NEXT);
+
+ // specialized state
+ switch (_nState)
+ {
+ case STATE_WELCOME:
+ enableButtons(WZB_PREVIOUS, sal_False);
+ break;
+ case STATE_LICENSE:
+ m_pCancel->SetText(String(WizardResId(STR_LICENSE_DECLINE)));
+ m_pNextPage->SetText(String(WizardResId(STR_LICENSE_ACCEPT)));
+ enableButtons(WZB_NEXT, sal_False);
+ // attach warning dialog to cancel/decline button
+ m_pCancel->SetClickHdl( LINK(this, FirstStartWizard, DeclineHdl) );
+ break;
+ case STATE_REGISTRATION:
+ enableButtons(WZB_NEXT, sal_False);
+ enableButtons(WZB_FINISH, sal_True);
+ defaultButton(WZB_FINISH);
+ break;
+ }
+
+ // focus
+
+}
+
+IMPL_LINK( FirstStartWizard, DeclineHdl, PushButton *, EMPTYARG )
+{
+ QueryBox aBox(this, WizardResId(QB_ASK_DECLINE));
+ sal_Int32 ret = aBox.Execute();
+ if ( ret == BUTTON_OK || ret == BUTTON_YES)
+ {
+ Close();
+ return sal_False;
+ }
+ else
+ return sal_True;
+}
+
+
+TabPage* FirstStartWizard::createPage(WizardState _nState)
+{
+ TabPage *pTabPage = 0;
+ switch (_nState)
+ {
+ case STATE_WELCOME:
+ pTabPage = new WelcomePage(this, WizardResId(TP_WELCOME), m_bLicenseNeedsAcceptance);
+ break;
+ case STATE_LICENSE:
+ pTabPage = new LicensePage(this, WizardResId(TP_LICENSE), m_aLicensePath);
+ break;
+ case STATE_MIGRATION:
+ pTabPage = new MigrationPage(this, WizardResId(TP_MIGRATION), m_aThrobber);
+ break;
+ case STATE_USER:
+ pTabPage = new UserPage(this, WizardResId(TP_USER));
+ break;
+ case STATE_UPDATE_CHECK:
+ pTabPage = new UpdateCheckPage(this, WizardResId(TP_UPDATE_CHECK));
+ break;
+ case STATE_REGISTRATION:
+ pTabPage = new RegistrationPage(this, WizardResId(TP_REGISTRATION));
+ break;
+ }
+ pTabPage->Show();
+
+ return pTabPage;
+}
+
+String FirstStartWizard::getStateDisplayName( WizardState _nState ) const
+{
+ String sName;
+ switch(_nState)
+ {
+ case STATE_WELCOME:
+ sName = String(WizardResId(STR_STATE_WELCOME));
+ break;
+ case STATE_LICENSE:
+ sName = String(WizardResId(STR_STATE_LICENSE));
+ break;
+ case STATE_MIGRATION:
+ sName = String(WizardResId(STR_STATE_MIGRATION));
+ break;
+ case STATE_USER:
+ sName = String(WizardResId(STR_STATE_USER));
+ break;
+ case STATE_UPDATE_CHECK:
+ sName = String(WizardResId(STR_STATE_UPDATE_CHECK));
+ break;
+ case STATE_REGISTRATION:
+ sName = String(WizardResId(STR_STATE_REGISTRATION));
+ break;
+ }
+ return sName;
+}
+
+sal_Bool FirstStartWizard::prepareLeaveCurrentState( CommitPageReason _eReason )
+{
+ // the license acceptance is handled here, because it needs to change the state
+ // of the roadmap wizard which the page implementation does not know.
+ if (
+ (_eReason == eTravelForward) &&
+ (getCurrentState() == STATE_LICENSE ) &&
+ (m_bLicenseWasAccepted == sal_False )
+ )
+ {
+ if (Migration::checkMigration())
+ enableState(FirstStartWizard::STATE_MIGRATION, sal_True);
+ if ( showOnlineUpdatePage() )
+ enableState(FirstStartWizard::STATE_UPDATE_CHECK, sal_True);
+ enableState(FirstStartWizard::STATE_USER, sal_True);
+ enableState(FirstStartWizard::STATE_REGISTRATION, sal_True);
+
+ storeAcceptDate();
+ m_bLicenseWasAccepted = sal_True;
+ }
+
+ return svt::RoadmapWizard::prepareLeaveCurrentState(_eReason);
+}
+
+sal_Bool FirstStartWizard::leaveState(WizardState)
+{
+ if (( getCurrentState() == STATE_MIGRATION ) && m_bLicenseWasAccepted )
+ {
+ // Store accept date and patch level now as it has been
+ // overwritten by the migration process!
+ storeAcceptDate();
+ setPatchLevel();
+ }
+
+ return sal_True;
+}
+
+sal_Bool FirstStartWizard::onFinish()
+{
+ // return sal_True;
+ if ( svt::RoadmapWizard::onFinish() )
+ {
+#ifndef OS2 // cannot enable quickstart on first startup, see shutdownicon.cxx comments.
+ enableQuickstart();
+#endif
+ disableWizard();
+ return sal_True;
+ }
+ else
+ return sal_False;
+}
+
+short FirstStartWizard::Execute()
+{
+ return svt::RoadmapWizard::Execute();
+}
+
+static OUString _makeDateTimeString (const DateTime& aDateTime, sal_Bool bUTC = sal_False)
+{
+ OStringBuffer aDateTimeString;
+ aDateTimeString.append((sal_Int32)aDateTime.GetYear());
+ aDateTimeString.append("-");
+ if (aDateTime.GetMonth()<10) aDateTimeString.append("0");
+ aDateTimeString.append((sal_Int32)aDateTime.GetMonth());
+ aDateTimeString.append("-");
+ if (aDateTime.GetDay()<10) aDateTimeString.append("0");
+ aDateTimeString.append((sal_Int32)aDateTime.GetDay());
+ aDateTimeString.append("T");
+ if (aDateTime.GetHour()<10) aDateTimeString.append("0");
+ aDateTimeString.append((sal_Int32)aDateTime.GetHour());
+ aDateTimeString.append(":");
+ if (aDateTime.GetMin()<10) aDateTimeString.append("0");
+ aDateTimeString.append((sal_Int32)aDateTime.GetMin());
+ aDateTimeString.append(":");
+ if (aDateTime.GetSec()<10) aDateTimeString.append("0");
+ aDateTimeString.append((sal_Int32)aDateTime.GetSec());
+ if (bUTC) aDateTimeString.append("Z");
+
+ return OStringToOUString(aDateTimeString.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US);
+}
+
+static OUString _getCurrentDateString()
+{
+ OUString aString;
+ return _makeDateTimeString(DateTime());
+}
+
+
+static const OUString sConfigSrvc( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.configuration.ConfigurationProvider" ) );
+static const OUString sAccessSrvc( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.configuration.ConfigurationUpdateAccess" ) );
+static const OUString sReadSrvc ( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.configuration.ConfigurationAccess" ) );
+
+void FirstStartWizard::storeAcceptDate()
+{
+
+ try {
+ Reference < XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory();
+ // get configuration provider
+ Reference< XMultiServiceFactory > theConfigProvider = Reference< XMultiServiceFactory >(
+ xFactory->createInstance(sConfigSrvc), UNO_QUERY_THROW);
+ Sequence< Any > theArgs(1);
+ NamedValue v(OUString::createFromAscii("NodePath"),
+ makeAny(OUString::createFromAscii("org.openoffice.Setup/Office")));
+ theArgs[0] <<= v;
+ Reference< XPropertySet > pset = Reference< XPropertySet >(
+ theConfigProvider->createInstanceWithArguments(sAccessSrvc, theArgs), UNO_QUERY_THROW);
+ Any result = pset->getPropertyValue(OUString::createFromAscii("LicenseAcceptDate"));
+
+ OUString aAcceptDate = _getCurrentDateString();
+ pset->setPropertyValue(OUString::createFromAscii("LicenseAcceptDate"), makeAny(aAcceptDate));
+ Reference< XChangesBatch >(pset, UNO_QUERY_THROW)->commitChanges();
+
+ // since the license is accepted the local user registry can be cleaned if required
+ cleanOldOfficeRegKeys();
+ } catch (const Exception&)
+ {
+ }
+
+}
+
+void FirstStartWizard::setPatchLevel()
+{
+ try {
+ Reference < XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory();
+ // get configuration provider
+ Reference< XMultiServiceFactory > theConfigProvider = Reference< XMultiServiceFactory >(
+ xFactory->createInstance(sConfigSrvc), UNO_QUERY_THROW);
+ Sequence< Any > theArgs(1);
+ NamedValue v(OUString::createFromAscii("NodePath"),
+ makeAny(OUString::createFromAscii("org.openoffice.Office.Common/Help/Registration")));
+ theArgs[0] <<= v;
+ Reference< XPropertySet > pset = Reference< XPropertySet >(
+ theConfigProvider->createInstanceWithArguments(sAccessSrvc, theArgs), UNO_QUERY_THROW);
+ Any result = pset->getPropertyValue(OUString::createFromAscii("ReminderDate"));
+
+ OUString aPatchLevel( RTL_CONSTASCII_USTRINGPARAM( "Patch" ));
+ aPatchLevel += OUString::valueOf( getBuildId(), 10 );
+ pset->setPropertyValue(OUString::createFromAscii("ReminderDate"), makeAny(aPatchLevel));
+ Reference< XChangesBatch >(pset, UNO_QUERY_THROW)->commitChanges();
+ } catch (const Exception&)
+ {
+ }
+}
+
+#ifdef WNT
+typedef int ( __stdcall * CleanCurUserRegProc ) ( wchar_t* );
+#endif
+
+void FirstStartWizard::cleanOldOfficeRegKeys()
+{
+#ifdef WNT
+ // after the wizard is completed clean OOo1.1.x entries in the current user registry if required
+ // issue i47658
+
+ OUString aBaseLocationPath;
+ OUString aSharedLocationPath;
+ OUString aInstallMode;
+
+ ::utl::Bootstrap::PathStatus aBaseLocateResult =
+ ::utl::Bootstrap::locateBaseInstallation( aBaseLocationPath );
+ ::utl::Bootstrap::PathStatus aSharedLocateResult =
+ ::utl::Bootstrap::locateSharedData( aSharedLocationPath );
+ aInstallMode = ::utl::Bootstrap::getAllUsersValue( ::rtl::OUString() );
+
+ // TODO: replace the checking for install mode
+ if ( aBaseLocateResult == ::utl::Bootstrap::PATH_EXISTS && aSharedLocateResult == ::utl::Bootstrap::PATH_EXISTS
+ && aInstallMode.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "1" ) ) ) )
+ {
+ ::rtl::OUString aDeregCompletePath =
+ aBaseLocationPath + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/program/regcleanold.dll" ) );
+ ::rtl::OUString aExecCompletePath =
+ aSharedLocationPath + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/regdeinstall/userdeinst.exe" ) );
+
+ osl::Module aCleanModule( aDeregCompletePath );
+ CleanCurUserRegProc pNativeProc = ( CleanCurUserRegProc )(
+ aCleanModule.getFunctionSymbol(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CleanCurUserOldSystemRegistry" ) ) ) );
+
+ if( pNativeProc!=NULL )
+ {
+ ::rtl::OUString aExecCompleteSysPath;
+ if ( osl::File::getSystemPathFromFileURL( aExecCompletePath, aExecCompleteSysPath ) == FileBase::E_None
+ && aExecCompleteSysPath.getLength() )
+ {
+ ( *pNativeProc )( (wchar_t*)( aExecCompleteSysPath.getStr() ) );
+ }
+ }
+ }
+#endif
+}
+
+void FirstStartWizard::disableWizard()
+{
+
+ try {
+ Reference < XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory();
+ // get configuration provider
+ Reference< XMultiServiceFactory > theConfigProvider = Reference< XMultiServiceFactory >(
+ xFactory->createInstance(sConfigSrvc), UNO_QUERY_THROW);
+ Sequence< Any > theArgs(1);
+ NamedValue v(OUString::createFromAscii("NodePath"),
+ makeAny(OUString::createFromAscii("org.openoffice.Setup/Office")));
+ theArgs[0] <<= v;
+ Reference< XPropertySet > pset = Reference< XPropertySet >(
+ theConfigProvider->createInstanceWithArguments(sAccessSrvc, theArgs), UNO_QUERY_THROW);
+ pset->setPropertyValue(OUString::createFromAscii("FirstStartWizardCompleted"), makeAny(sal_True));
+ Reference< XChangesBatch >(pset, UNO_QUERY_THROW)->commitChanges();
+ } catch (const Exception&)
+ {
+ }
+
+}
+
+
+void FirstStartWizard::enableQuickstart()
+{
+ sal_Bool bQuickstart( sal_True );
+ sal_Bool bAutostart( sal_True );
+ Sequence< Any > aSeq( 2 );
+ aSeq[0] <<= bQuickstart;
+ aSeq[1] <<= bAutostart;
+
+ Reference < XInitialization > xQuickstart( ::comphelper::getProcessServiceFactory()->createInstance(
+ OUString::createFromAscii( "com.sun.star.office.Quickstart" )),UNO_QUERY );
+ if ( xQuickstart.is() )
+ xQuickstart->initialize( aSeq );
+
+}
+
+sal_Bool FirstStartWizard::showOnlineUpdatePage()
+{
+ try {
+ Reference < XNameReplace > xUpdateAccess;
+ Reference < XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory() );
+
+ xUpdateAccess = Reference < XNameReplace >(
+ xFactory->createInstance( UNISTRING( "com.sun.star.setup.UpdateCheckConfig" ) ), UNO_QUERY_THROW );
+
+ if ( xUpdateAccess.is() )
+ {
+ sal_Bool bAutoUpdChk = sal_False;
+ Any result = xUpdateAccess->getByName( UNISTRING( "AutoCheckEnabled" ) );
+ result >>= bAutoUpdChk;
+ if ( bAutoUpdChk == sal_False )
+ return sal_True;
+ else
+ return sal_False;
+ }
+ } catch (const Exception&)
+ {
+ }
+ return sal_False;
+}
+
+}
diff --git a/desktop/source/migration/wizard.hrc b/desktop/source/migration/wizard.hrc
new file mode 100755
index 000000000000..8f35488c58b3
--- /dev/null
+++ b/desktop/source/migration/wizard.hrc
@@ -0,0 +1,100 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "desktop.hrc"
+#include "helpid.hrc"
+
+#define TP_WIDTH 220
+#define TP_HEIGHT 205
+
+#define DLG_FIRSTSTART_WIZARD RID_FIRSTSTSTART_START+1
+ // FREE
+#define TP_WELCOME RID_FIRSTSTSTART_START+3
+#define TP_REGISTRATION RID_FIRSTSTSTART_START+4
+#define TP_MIGRATION RID_FIRSTSTSTART_START+5
+#define TP_USER RID_FIRSTSTSTART_START+6
+#define TP_LICENSE RID_FIRSTSTSTART_START+7
+#define TP_UPDATE_CHECK RID_FIRSTSTSTART_START+8
+#define ERRBOX_REG_NOSYSBROWSER RID_FIRSTSTSTART_START+29
+#define QB_ASK_DECLINE RID_FIRSTSTSTART_START+30
+
+// local resIDs
+
+#define FT_WELCOME_HEADER 1
+#define FT_WELCOME_BODY 2
+#define FT_LICENSE_HEADER 1
+#define FT_LICENSE_BODY_1 2
+#define FT_LICENSE_BODY_1_TXT 3
+#define FT_LICENSE_BODY_2 4
+#define FT_LICENSE_BODY_2_TXT 5
+#define ML_LICENSE 6
+#define PB_LICENSE_DOWN 7
+#define FT_MIGRATION_HEADER 1
+#define FT_MIGRATION_BODY 2
+#define CB_MIGRATION 3
+#define FT_UPDATE_CHECK_HEADER 1
+#define FT_UPDATE_CHECK_BODY 2
+#define CB_UPDATE_CHECK 3
+#define FT_REGISTRATION_HEADER 1
+#define FT_REGISTRATION_BODY 2
+#define FL_REGISTRATION 3
+#define FT_REGISTRATION_END 4
+#define RB_REGISTRATION_NOW 5
+#define RB_REGISTRATION_LATER 6
+#define RB_REGISTRATION_NEVER 7
+#define RB_REGISTRATION_REG 8
+#define IMG_REGISTRATION 9
+#define FT_USER_HEADER 10
+#define FT_USER_BODY 11
+#define FT_USER_FIRST 12
+#define FT_USER_LAST 13
+#define FT_USER_FATHER 14
+#define FT_USER_INITIALS 15
+#define ED_USER_FIRST 16
+#define ED_USER_LAST 17
+#define ED_USER_FATHER 18
+#define ED_USER_INITIALS 19
+#define TR_WAITING 20
+#define CTRL_THROBBER 21
+
+// global strings
+#define STR_STATE_WELCOME RID_FIRSTSTSTART_START+100
+#define STR_STATE_LICENSE RID_FIRSTSTSTART_START+101
+#define STR_STATE_MIGRATION RID_FIRSTSTSTART_START+102
+#define STR_STATE_REGISTRATION RID_FIRSTSTSTART_START+103
+#define STR_WELCOME_MIGRATION RID_FIRSTSTSTART_START+104
+// FREE RID_FIRSTSTSTART_START+105
+// FREE RID_FIRSTSTSTART_START+106
+#define STR_LICENSE_ACCEPT RID_FIRSTSTSTART_START+107
+#define STR_LICENSE_DECLINE RID_FIRSTSTSTART_START+108
+#define STR_FINISH RID_FIRSTSTSTART_START+109
+#define STR_STATE_USER RID_FIRSTSTSTART_START+110
+// FREE RID_FIRSTSTSTART_START+111
+#define STR_STATE_UPDATE_CHECK RID_FIRSTSTSTART_START+112
+#define STR_WELCOME_WITHOUT_LICENSE RID_FIRSTSTSTART_START+113
+#define STR_REGISTRATION_OOO RID_FIRSTSTSTART_START+114
+
diff --git a/desktop/source/migration/wizard.hxx b/desktop/source/migration/wizard.hxx
new file mode 100644
index 000000000000..96bd74dcd859
--- /dev/null
+++ b/desktop/source/migration/wizard.hxx
@@ -0,0 +1,105 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _WIZARD_HXX_
+#define _WIZARD_HXX_
+
+#include <rtl/ustring.hxx>
+#include <svtools/roadmapwizard.hxx>
+#include <vcl/throbber.hxx>
+#include <tools/resid.hxx>
+
+namespace desktop
+{
+
+class WizardResId : public ResId
+{
+public:
+ WizardResId( sal_uInt16 nId );
+};
+
+class FirstStartWizard : public svt::RoadmapWizard
+{
+
+public:
+ static const WizardState STATE_WELCOME;
+ static const WizardState STATE_LICENSE;
+ static const WizardState STATE_MIGRATION;
+ static const WizardState STATE_USER;
+ static const WizardState STATE_UPDATE_CHECK;
+ static const WizardState STATE_REGISTRATION;
+
+ static ResMgr* pResMgr;
+ static ResMgr* GetResManager();
+
+ FirstStartWizard( Window* pParent, sal_Bool bLicenseNeedsAcceptance, const rtl::OUString &rLicensePath );
+
+ virtual short Execute();
+ virtual long PreNotify( NotifyEvent& rNEvt );
+
+ void DisableButtonsWhileMigration();
+
+private:
+ sal_Bool m_bOverride;
+ WizardState _currentState;
+ ::svt::RoadmapWizardTypes::PathId m_aDefaultPath;
+ ::svt::RoadmapWizardTypes::PathId m_aMigrationPath;
+ String m_sNext;
+ String m_sCancel;
+ sal_Bool m_bDone;
+ sal_Bool m_bLicenseNeedsAcceptance;
+ sal_Bool m_bLicenseWasAccepted;
+ sal_Bool m_bAutomaticUpdChk;
+ Link m_lnkCancel;
+ Throbber m_aThrobber;
+
+ rtl::OUString m_aLicensePath;
+
+ void storeAcceptDate();
+ void setPatchLevel();
+ void disableWizard();
+ void enableQuickstart();
+
+ DECL_LINK(DeclineHdl, PushButton*);
+
+ void cleanOldOfficeRegKeys();
+ sal_Bool showOnlineUpdatePage();
+ ::svt::RoadmapWizardTypes::PathId defineWizardPagesDependingFromContext();
+
+protected:
+ // from svt::WizardMachine
+ virtual TabPage* createPage(WizardState _nState);
+ virtual sal_Bool prepareLeaveCurrentState( CommitPageReason _eReason );
+ virtual sal_Bool leaveState(WizardState _nState );
+ virtual sal_Bool onFinish();
+ virtual void enterState(WizardState _nState);
+
+ // from svt::RoadmapWizard
+ virtual String getStateDisplayName( WizardState _nState ) const;
+};
+}
+#endif
diff --git a/desktop/source/migration/wizard.src b/desktop/source/migration/wizard.src
new file mode 100644
index 000000000000..78bd3a0e8197
--- /dev/null
+++ b/desktop/source/migration/wizard.src
@@ -0,0 +1,442 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+ /*
+ * encoding for resources: windows-1252
+ */
+
+#include "wizard.hrc"
+#include <svtools/controldims.hrc>
+
+ModalDialog DLG_FIRSTSTART_WIZARD
+{
+ Text [ en-US ] = "Welcome to %PRODUCTNAME %PRODUCTVERSION";
+
+ OutputSize = TRUE ;
+ SVLook = TRUE ;
+ Moveable = TRUE ;
+ Closeable = TRUE ;
+ Hide = TRUE;
+ HelpID = HID_FIRSTSTART_DIALOG;
+
+ FixedImage CTRL_THROBBER
+ {
+ Pos = MAP_APPFONT( 5, 210 );
+ Size = MAP_APPFONT( 11, 11 );
+ Hide = TRUE;
+ };
+};
+
+String STR_STATE_WELCOME
+{
+ Text [ en-US ] = "Welcome";
+};
+String STR_STATE_LICENSE
+{
+ Text [ en-US ] = "License Agreement";
+};
+String STR_STATE_MIGRATION
+{
+ Text [ en-US ] = "Personal Data";
+};
+String STR_STATE_USER
+{
+ Text [ en-US ] = "User name";
+};
+
+String STR_STATE_UPDATE_CHECK
+{
+ Text [ en-US ] = "Online Update";
+};
+
+String STR_STATE_REGISTRATION
+{
+ Text [ en-US ] = "Registration";
+};
+
+String STR_WELCOME_MIGRATION
+{
+ Text [ en-US ] = "This wizard will guide you through the license agreement, the transfer of user data from %OLD_VERSION and the registration of %PRODUCTNAME.\n\nClick 'Next' to continue.";
+
+};
+
+String STR_WELCOME_WITHOUT_LICENSE
+{
+ Text [ en-US ] = "This wizard will guide you through the registration of %PRODUCTNAME.\n\nClick 'Next' to continue.";
+};
+
+String STR_FINISH
+{
+ Text [ en-US ] = "~Finish";
+};
+
+String STR_REGISTRATION_OOO
+{
+ Text [ en-US ] = "You now have the opportunity to support and contribute to the fastest growing open source community in the world.\n\nHelp us prove that %PRODUCTNAME has already gained significant market share by registering.\n\nRegistering is voluntary and without obligation.";
+};
+
+ErrorBox ERRBOX_REG_NOSYSBROWSER
+{
+ BUTTONS = WB_OK ;
+ DEFBUTTON = WB_DEF_OK ;
+
+ Message [ en-US ] = "An error occurred in starting the web browser.\nPlease check the %PRODUCTNAME and web browser settings.";
+};
+
+QueryBox QB_ASK_DECLINE
+{
+ Buttons = WB_YES_NO;
+ DefButton = WB_DEF_NO;
+
+ Message [ en-US ] = "Do you really want to decline?";
+};
+
+
+#define ROWHEIGHT 8
+#define MARGINLEFT 10
+#define MARGINRIGHT 10
+#define BODYWIDTH TP_WIDTH-MARGINLEFT-MARGINRIGHT
+#define MARGINTOP 10
+#define MARGINBOTTOM 2
+#define BODYHEIGHT TP_HEIGHT-MARGINTOP-MARGINBOTTOM
+#define INDENT 10
+#define INDENT2 12
+
+TabPage TP_WELCOME
+{
+ SVLook = TRUE ;
+ Hide = TRUE ;
+ Size = MAP_APPFONT(TP_WIDTH, TP_HEIGHT);
+ HelpID = HID_FIRSTSTART_WELCOME;
+ // bold fixedtext for header
+ FixedText FT_WELCOME_HEADER
+ {
+ NoLabel = TRUE;
+ Pos = MAP_APPFONT(MARGINRIGHT, MARGINTOP);
+ Size = MAP_APPFONT( BODYWIDTH, ROWHEIGHT );
+ Text [ en-US ] = "Welcome to %PRODUCTNAME %PRODUCTVERSION";
+ };
+ FixedText FT_WELCOME_BODY
+ {
+ NoLabel = TRUE;
+ Pos = MAP_APPFONT(MARGINLEFT, MARGINTOP + 2*ROWHEIGHT);
+ Size = MAP_APPFONT( BODYWIDTH, BODYHEIGHT-MARGINTOP - 2*ROWHEIGHT );
+ WordBreak = TRUE;
+ Text [ en-US ] = "This wizard will guide you through the license agreement and the registration of %PRODUCTNAME.\n\nClick 'Next' to continue.";
+ };
+};
+
+TabPage TP_LICENSE
+{
+ SVLook = TRUE ;
+ Hide = TRUE ;
+ Size = MAP_APPFONT(TP_WIDTH, TP_HEIGHT);
+ HelpID = HID_FIRSTSTART_LICENSE;
+ FixedText FT_LICENSE_HEADER
+ {
+ Pos = MAP_APPFONT(MARGINLEFT, MARGINTOP);
+ Size = MAP_APPFONT( BODYWIDTH, ROWHEIGHT );
+ NoLabel = TRUE;
+ Text [ en-US ] = "Please follow these steps to accept the license";
+ };
+ FixedText FT_LICENSE_BODY_1
+ {
+ Pos = MAP_APPFONT(MARGINLEFT, MARGINTOP + 2*ROWHEIGHT);
+ Size = MAP_APPFONT( INDENT, ROWHEIGHT );
+ NoLabel = TRUE;
+ Text [ en-US ] = "1.";
+ };
+ FixedText FT_LICENSE_BODY_1_TXT
+ {
+ Pos = MAP_APPFONT(MARGINLEFT+INDENT, MARGINTOP +2*ROWHEIGHT);
+ Size = MAP_APPFONT( BODYWIDTH-INDENT, 3*ROWHEIGHT);
+ WordBreak = TRUE;
+ NoLabel = TRUE;
+ Text [ en-US ] = "View the complete License Agreement. Please use the scrollbar or the '%PAGEDOWN' button in this dialog to view the entire license text.";
+ };
+ FixedText FT_LICENSE_BODY_2
+ {
+ Pos = MAP_APPFONT(MARGINLEFT, MARGINTOP + 5*ROWHEIGHT);
+ Size = MAP_APPFONT(INDENT, ROWHEIGHT );
+ NoLabel = TRUE;
+ Text [ en-US ] = "2.";
+ };
+ FixedText FT_LICENSE_BODY_2_TXT
+ {
+ Pos = MAP_APPFONT(MARGINLEFT+INDENT, MARGINTOP + 5*ROWHEIGHT);
+ Size = MAP_APPFONT( BODYWIDTH-INDENT, 2*ROWHEIGHT);
+ WordBreak = TRUE;
+ NoLabel = TRUE;
+ Text [ en-US ] = "Click 'Accept' to accept the terms of the Agreement.";
+ };
+ MultiLineEdit ML_LICENSE
+ {
+ HelpID = "desktop:MultiLineEdit:TP_LICENSE:ML_LICENSE";
+ PosSize = MAP_APPFONT (MARGINLEFT+INDENT, MARGINTOP + 8*ROWHEIGHT, BODYWIDTH-INDENT , BODYHEIGHT - 8*ROWHEIGHT - 20-2*MARGINBOTTOM) ;
+ Border = TRUE;
+ VScroll = TRUE;
+ ReadOnly = TRUE;
+ };
+ PushButton PB_LICENSE_DOWN
+ {
+ HelpID = "desktop:PushButton:TP_LICENSE:PB_LICENSE_DOWN";
+ TabStop = TRUE ;
+ Pos = MAP_APPFONT ( TP_WIDTH-MARGINRIGHT-50 , TP_HEIGHT-MARGINBOTTOM-18 ) ;
+ Size = MAP_APPFONT ( 50, 15 ) ;
+ Text [ en-US ] = "Scroll Do~wn";
+ };
+};
+
+String STR_LICENSE_ACCEPT
+{
+ Text [ en-US ] = "~Accept";
+};
+String STR_LICENSE_DECLINE
+{
+ Text [ en-US ] = "~Decline";
+};
+
+
+TabPage TP_MIGRATION
+{
+ SVLook = TRUE ;
+ Hide = TRUE ;
+ Size = MAP_APPFONT(TP_WIDTH, TP_HEIGHT);
+ HelpID = HID_FIRSTSTART_MIGRATION;
+
+ FixedText FT_MIGRATION_HEADER
+ {
+ NoLabel = TRUE;
+ Pos = MAP_APPFONT(MARGINLEFT, MARGINTOP);
+ Size = MAP_APPFONT( BODYWIDTH, ROWHEIGHT );
+ Text [ en-US ] = "Transfer personal data";
+
+ };
+
+ FixedText FT_MIGRATION_BODY
+ {
+ NoLabel = TRUE;
+ Pos = MAP_APPFONT(MARGINLEFT, MARGINTOP+ROWHEIGHT*2);
+ Size = MAP_APPFONT(BODYWIDTH, ROWHEIGHT*8);
+ WordBreak = TRUE;
+ Text [ en-US ] = "Most personal data from %OLDPRODUCT installation can be reused in %PRODUCTNAME %PRODUCTVERSION.\n\nIf you do not want to reuse any settings in %PRODUCTNAME %PRODUCTVERSION, unmark the check box.";
+
+ };
+
+ CheckBox CB_MIGRATION
+ {
+ HelpID = "desktop:CheckBox:TP_MIGRATION:CB_MIGRATION";
+ Pos = MAP_APPFONT(MARGINLEFT, MARGINTOP+ROWHEIGHT*10);
+ Size = MAP_APPFONT(BODYWIDTH, ROWHEIGHT*2);
+ Check = TRUE;
+ Text [ en-US ] = "Transfer personal data";
+ };
+};
+
+TabPage TP_UPDATE_CHECK
+{
+ SVLook = TRUE ;
+ Hide = TRUE ;
+ Size = MAP_APPFONT(TP_WIDTH, TP_HEIGHT);
+ HelpID = HID_FIRSTSTART_UPDATE_CHECK;
+
+ FixedText FT_UPDATE_CHECK_HEADER
+ {
+ NoLabel = TRUE;
+ Pos = MAP_APPFONT(MARGINLEFT, MARGINTOP);
+ Size = MAP_APPFONT( BODYWIDTH, ROWHEIGHT );
+ Text [ en-US ] = "Online Update";
+
+ };
+
+ FixedText FT_UPDATE_CHECK_BODY
+ {
+ NoLabel = TRUE;
+ Pos = MAP_APPFONT(MARGINLEFT, MARGINTOP+ROWHEIGHT*2);
+ Size = MAP_APPFONT(BODYWIDTH, ROWHEIGHT*8);
+ WordBreak = TRUE;
+ Text [ en-US ] = "%PRODUCTNAME searches automatically at regular intervals for new versions.\nIn doing so online update does not transfer personal data.\nAs soon as a new version is available, you will be notified.\n\nYou can configure this feature at Tools / Options... / %PRODUCTNAME / Online Update.";
+
+ };
+
+ CheckBox CB_UPDATE_CHECK
+ {
+ HelpID = "desktop:CheckBox:TP_UPDATE_CHECK:CB_UPDATE_CHECK";
+ Pos = MAP_APPFONT(MARGINLEFT, MARGINTOP+ROWHEIGHT*10);
+ Size = MAP_APPFONT(BODYWIDTH, ROWHEIGHT*2);
+ Check = TRUE;
+ Text [ en-US ] = "~Check for updates automatically";
+ };
+};
+
+#define USERINDENT 40
+#define EDHEIGHT 12
+#define INITIALSWIDTH 50
+#define FTADD 2
+
+TabPage TP_USER
+{
+ SVLook = TRUE ;
+ Hide = TRUE ;
+ Size = MAP_APPFONT(TP_WIDTH, TP_HEIGHT);
+ HelpID = HID_FIRSTSTART_USER;
+
+ FixedText FT_USER_HEADER
+ {
+ NoLabel = TRUE;
+ Pos = MAP_APPFONT(MARGINLEFT, MARGINTOP);
+ Size = MAP_APPFONT( BODYWIDTH, ROWHEIGHT );
+ Text [ en-US ] = "Provide your full name and initials below";
+
+ };
+
+ FixedText FT_USER_BODY
+ {
+ NoLabel = TRUE;
+ Pos = MAP_APPFONT(MARGINLEFT, MARGINTOP+ROWHEIGHT*2);
+ Size = MAP_APPFONT(BODYWIDTH, ROWHEIGHT*3);
+ WordBreak = TRUE;
+ Text [ en-US ] = "The user name will be used in the document properties, templates and when you record changes made to documents.";
+ };
+
+
+ FixedText FT_USER_FIRST
+ {
+ Pos = MAP_APPFONT(MARGINLEFT, MARGINTOP+ROWHEIGHT*7+FTADD);
+ Size = MAP_APPFONT(USERINDENT, ROWHEIGHT);
+ Text [ en-US ] = "~First name";
+ };
+ Edit ED_USER_FIRST
+ {
+ HelpID = "desktop:Edit:TP_USER:ED_USER_FIRST";
+ Border = TRUE;
+ Pos = MAP_APPFONT(MARGINLEFT+USERINDENT, MARGINTOP+ROWHEIGHT*7);
+ Size = MAP_APPFONT(BODYWIDTH-USERINDENT, EDHEIGHT);
+ };
+ FixedText FT_USER_LAST
+ {
+ Pos = MAP_APPFONT(MARGINLEFT, MARGINTOP+ROWHEIGHT*9+FTADD);
+ Size = MAP_APPFONT(USERINDENT, ROWHEIGHT);
+ Text [ en-US ] = "~Last name";
+ };
+ Edit ED_USER_LAST
+ {
+ HelpID = "desktop:Edit:TP_USER:ED_USER_LAST";
+ Border = TRUE;
+ Pos = MAP_APPFONT(MARGINLEFT+USERINDENT, MARGINTOP+ROWHEIGHT*9);
+ Size = MAP_APPFONT(BODYWIDTH-USERINDENT, EDHEIGHT);
+ };
+ FixedText FT_USER_INITIALS
+ {
+ Pos = MAP_APPFONT(MARGINLEFT, MARGINTOP+ROWHEIGHT*11+FTADD);
+ Size = MAP_APPFONT(USERINDENT, ROWHEIGHT);
+ Text [ en-US ] = "~Initials";
+ };
+ Edit ED_USER_INITIALS
+ {
+ HelpID = "desktop:Edit:TP_USER:ED_USER_INITIALS";
+ Border = TRUE;
+ Pos = MAP_APPFONT(MARGINLEFT+USERINDENT, MARGINTOP+ROWHEIGHT*11);
+ Size = MAP_APPFONT(INITIALSWIDTH, EDHEIGHT);
+ };
+
+ FixedText FT_USER_FATHER
+ {
+ Hide = TRUE;
+ Pos = MAP_APPFONT(MARGINLEFT+USERINDENT+INITIALSWIDTH+10, MARGINTOP+ROWHEIGHT*11+FTADD);
+ Size = MAP_APPFONT(USERINDENT, ROWHEIGHT);
+ Text [ en-US ] = "~Father's name";
+ };
+ Edit ED_USER_FATHER
+ {
+ HelpID = "desktop:Edit:TP_USER:ED_USER_FATHER";
+ Border = TRUE;
+ Hide = TRUE;
+ Pos = MAP_APPFONT(MARGINLEFT+USERINDENT*2+INITIALSWIDTH+10, MARGINTOP+ROWHEIGHT*11);
+ Size = MAP_APPFONT(BODYWIDTH-10-USERINDENT*2-INITIALSWIDTH, EDHEIGHT);
+ };
+};
+
+#define RB_HEIGHT (RSC_CD_CHECKBOX_HEIGHT+RSC_SP_GRP_SPACE_Y)
+
+TabPage TP_REGISTRATION
+{
+ SVLook = TRUE ;
+ Hide = TRUE ;
+ Size = MAP_APPFONT(TP_WIDTH, TP_HEIGHT);
+ HelpID = HID_FIRSTSTART_REGISTRATION;
+ FixedText FT_REGISTRATION_HEADER
+ {
+ NoLabel = TRUE;
+ Text [ en-US ] = "%PRODUCTNAME Registration";
+ Pos = MAP_APPFONT(MARGINLEFT, MARGINRIGHT);
+ Size = MAP_APPFONT(BODYWIDTH, MARGINRIGHT);
+ };
+ FixedText FT_REGISTRATION_BODY
+ {
+ NoLabel = TRUE;
+ Text [ en-US ] = "You now have the opportunity to register as a %PRODUCTNAME user. Registration is voluntary and is without obligation.\n\nIf you register, we can inform you about new developments concerning this product.";
+ WordBreak = TRUE;
+ Pos = MAP_APPFONT(MARGINLEFT, MARGINTOP+ROWHEIGHT*2);
+ Size = MAP_APPFONT(BODYWIDTH, ROWHEIGHT*8);
+ };
+ RadioButton RB_REGISTRATION_NOW
+ {
+ HelpID = "desktop:RadioButton:TP_REGISTRATION:RB_REGISTRATION_NOW";
+ Text [ en-US ] = "I want to register ~now";
+ Pos = MAP_APPFONT(MARGINLEFT+INDENT2, ROWHEIGHT*12+2);
+ Size = MAP_APPFONT(BODYWIDTH-INDENT2, RSC_CD_CHECKBOX_HEIGHT);
+ Check = TRUE;
+ };
+ RadioButton RB_REGISTRATION_LATER
+ {
+ HelpID = "desktop:RadioButton:TP_REGISTRATION:RB_REGISTRATION_LATER";
+ Text [ en-US ] = "I want to register ~later";
+ Pos = MAP_APPFONT(MARGINLEFT+INDENT2, ROWHEIGHT*12+2+RB_HEIGHT);
+ Size = MAP_APPFONT(BODYWIDTH-INDENT2, RSC_CD_CHECKBOX_HEIGHT);
+ };
+ RadioButton RB_REGISTRATION_NEVER
+ {
+ HelpID = "desktop:RadioButton:TP_REGISTRATION:RB_REGISTRATION_NEVER";
+ Text [ en-US ] = "I do not want to ~register";
+ Pos = MAP_APPFONT(MARGINLEFT+INDENT2, ROWHEIGHT*12+2+RB_HEIGHT*2);
+ Size = MAP_APPFONT(BODYWIDTH-INDENT2, RSC_CD_CHECKBOX_HEIGHT);
+ };
+ FixedLine FL_REGISTRATION
+ {
+ Pos = MAP_APPFONT(MARGINLEFT, TP_HEIGHT-MARGINBOTTOM-ROWHEIGHT*6);
+ Size = MAP_APPFONT(BODYWIDTH, ROWHEIGHT);
+ };
+ FixedText FT_REGISTRATION_END
+ {
+ NoLabel = TRUE;
+ Text [ en-US ] = "We hope you enjoy working with %PRODUCTNAME.\n\nTo exit the wizard, click 'Finish'.";
+ Pos = MAP_APPFONT(MARGINLEFT, TP_HEIGHT-MARGINBOTTOM-ROWHEIGHT*4);
+ Size = MAP_APPFONT(BODYWIDTH, ROWHEIGHT*4);
+ };
+};
+
diff --git a/desktop/source/offacc/acceptor.cxx b/desktop/source/offacc/acceptor.cxx
new file mode 100644
index 000000000000..4c69ceaa7c12
--- /dev/null
+++ b/desktop/source/offacc/acceptor.cxx
@@ -0,0 +1,338 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include "acceptor.hxx"
+#include <unotools/bootstrap.hxx>
+#include <tools/urlobj.hxx>
+#include <tools/stream.hxx>
+#include <vcl/svapp.hxx>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/uno/XNamingService.hpp>
+
+#include <cppuhelper/factory.hxx>
+
+namespace desktop
+{
+
+extern "C" void workerfunc (void * acc)
+{
+ ((Acceptor*)acc)->run();
+}
+
+static Reference<XInterface> getComponentContext( const Reference<XMultiServiceFactory>& rFactory)
+{
+ Reference<XInterface> rContext;
+ Reference< XPropertySet > rPropSet( rFactory, UNO_QUERY );
+ Any a = rPropSet->getPropertyValue(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ) ) );
+ a >>= rContext;
+ return rContext;
+}
+
+Mutex Acceptor::m_aMutex;
+
+Acceptor::Acceptor( const Reference< XMultiServiceFactory >& rFactory )
+ : m_thread(NULL)
+ , m_aAcceptString()
+ , m_aConnectString()
+ , m_aProtocol()
+ , m_bInit(sal_False)
+ , m_bDying(false)
+{
+ m_rSMgr = rFactory;
+ m_rAcceptor = Reference< XAcceptor > (m_rSMgr->createInstance(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.connection.Acceptor" ))),
+ UNO_QUERY );
+ m_rBridgeFactory = Reference < XBridgeFactory > (m_rSMgr->createInstance(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.bridge.BridgeFactory" ))),
+ UNO_QUERY );
+ // get component context
+ m_rContext = getComponentContext(m_rSMgr);
+}
+
+
+Acceptor::~Acceptor()
+{
+ m_rAcceptor->stopAccepting();
+ oslThread t;
+ {
+ osl::MutexGuard g(m_aMutex);
+ t = m_thread;
+ }
+ //prevent locking if the thread is still waiting
+ m_bDying = true;
+ m_cEnable.set();
+ osl_joinWithThread(t);
+ {
+ // Make the final state of m_bridges visible to this thread (since
+ // m_thread is joined, the code that follows is the only one left
+ // accessing m_bridges):
+ osl::MutexGuard g(m_aMutex);
+ }
+ for (;;) {
+ com::sun::star::uno::Reference< com::sun::star::bridge::XBridge > b(
+ m_bridges.remove());
+ if (!b.is()) {
+ break;
+ }
+ com::sun::star::uno::Reference< com::sun::star::lang::XComponent >(
+ b, com::sun::star::uno::UNO_QUERY_THROW)->dispose();
+ }
+}
+
+void SAL_CALL Acceptor::run()
+{
+ while ( m_rAcceptor.is() && m_rBridgeFactory.is() )
+ {
+ RTL_LOGFILE_CONTEXT( aLog, "desktop (lo119109) Acceptor::run" );
+ try
+ {
+ // wait until we get enabled
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "desktop (lo119109)"\
+ "Acceptor::run waiting for office to come up");
+ m_cEnable.wait();
+ if (m_bDying) //see destructor
+ break;
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "desktop (lo119109)"\
+ "Acceptor::run now enabled and continuing");
+
+ // accept connection
+ Reference< XConnection > rConnection = m_rAcceptor->accept( m_aConnectString );
+ // if we return without a valid connection we mus assume that the acceptor
+ // is destructed so we break out of the run method terminating the thread
+ if (! rConnection.is()) break;
+ OUString aDescription = rConnection->getDescription();
+ RTL_LOGFILE_CONTEXT_TRACE1( aLog, "desktop (lo119109) Acceptor::run connection %s",
+ OUStringToOString(aDescription, RTL_TEXTENCODING_ASCII_US).getStr());
+
+ // create instanceprovider for this connection
+ Reference< XInstanceProvider > rInstanceProvider(
+ (XInstanceProvider*)new AccInstanceProvider(m_rSMgr, rConnection));
+ // create the bridge. The remote end will have a reference to this bridge
+ // thus preventing the bridge from being disposed. When the remote end releases
+ // the bridge, it will be destructed.
+ Reference< XBridge > rBridge = m_rBridgeFactory->createBridge(
+ rtl::OUString() ,m_aProtocol ,rConnection ,rInstanceProvider );
+ osl::MutexGuard g(m_aMutex);
+ m_bridges.add(rBridge);
+ } catch (Exception&) {
+ // connection failed...
+ // something went wrong during connection setup.
+ // just wait for a new connection to accept
+ }
+ }
+}
+
+// XInitialize
+void SAL_CALL Acceptor::initialize( const Sequence<Any>& aArguments )
+ throw( Exception )
+{
+ // prevent multiple initialization
+ ClearableMutexGuard aGuard( m_aMutex );
+ RTL_LOGFILE_CONTEXT( aLog, "destop (lo119109) Acceptor::initialize()" );
+
+ sal_Bool bOk = sal_False;
+
+ // arg count
+ int nArgs = aArguments.getLength();
+
+ // not yet initialized and acceptstring
+ if (!m_bInit && nArgs > 0 && (aArguments[0] >>= m_aAcceptString))
+ {
+ RTL_LOGFILE_CONTEXT_TRACE1( aLog, "desktop (lo119109) Acceptor::initialize string=%s",
+ OUStringToOString(m_aAcceptString, RTL_TEXTENCODING_ASCII_US).getStr());
+
+ // get connect string and protocol from accept string
+ // "<connectString>;<protocol>"
+ sal_Int32 nIndex1 = m_aAcceptString.indexOf( (sal_Unicode) ';' );
+ if (nIndex1 < 0) throw IllegalArgumentException(
+ OUString(RTL_CONSTASCII_USTRINGPARAM("Invalid accept-string format")), m_rContext, 1);
+ m_aConnectString = m_aAcceptString.copy( 0 , nIndex1 ).trim();
+ nIndex1++;
+ sal_Int32 nIndex2 = m_aAcceptString.indexOf( (sal_Unicode) ';' , nIndex1 );
+ if (nIndex2 < 0) nIndex2 = m_aAcceptString.getLength();
+ m_aProtocol = m_aAcceptString.copy( nIndex1, nIndex2 - nIndex1 );
+
+ // start accepting in new thread...
+ m_thread = osl_createThread(workerfunc, this);
+ m_bInit = sal_True;
+ bOk = sal_True;
+ }
+
+ // do we want to enable accepting?
+ sal_Bool bEnable = sal_False;
+ if (((nArgs == 1 && (aArguments[0] >>= bEnable)) ||
+ (nArgs == 2 && (aArguments[1] >>= bEnable))) &&
+ bEnable )
+ {
+ m_cEnable.set();
+ bOk = sal_True;
+ }
+
+ if (!bOk)
+ {
+ throw IllegalArgumentException(
+ OUString(RTL_CONSTASCII_USTRINGPARAM("invalid initialization")), m_rContext, 1);
+ }
+}
+
+// XServiceInfo
+const sal_Char *Acceptor::serviceName = "com.sun.star.office.Acceptor";
+const sal_Char *Acceptor::implementationName = "com.sun.star.office.comp.Acceptor";
+const sal_Char *Acceptor::supportedServiceNames[] = {"com.sun.star.office.Acceptor", NULL};
+OUString Acceptor::impl_getImplementationName()
+{
+ return OUString::createFromAscii( implementationName );
+}
+OUString SAL_CALL Acceptor::getImplementationName()
+ throw (RuntimeException)
+{
+ return Acceptor::impl_getImplementationName();
+}
+Sequence<OUString> Acceptor::impl_getSupportedServiceNames()
+{
+ Sequence<OUString> aSequence;
+ for (int i=0; supportedServiceNames[i]!=NULL; i++) {
+ aSequence.realloc(i+1);
+ aSequence[i]=(OUString::createFromAscii(supportedServiceNames[i]));
+ }
+ return aSequence;
+}
+Sequence<OUString> SAL_CALL Acceptor::getSupportedServiceNames()
+ throw (RuntimeException)
+{
+ return Acceptor::impl_getSupportedServiceNames();
+}
+sal_Bool SAL_CALL Acceptor::supportsService( const OUString&)
+ throw (RuntimeException)
+{
+ return sal_False;
+}
+
+// Factory
+Reference< XInterface > Acceptor::impl_getInstance( const Reference< XMultiServiceFactory >& aFactory )
+{
+ try {
+ return (XComponent*) new Acceptor( aFactory );
+ } catch ( Exception& ) {
+ return (XComponent*) NULL;
+ }
+}
+
+// InstanceProvider
+AccInstanceProvider::AccInstanceProvider(const Reference<XMultiServiceFactory>& aFactory, const Reference<XConnection>& rConnection)
+{
+ m_rSMgr = aFactory;
+ m_rConnection = rConnection;
+}
+
+AccInstanceProvider::~AccInstanceProvider()
+{
+}
+
+Reference<XInterface> SAL_CALL AccInstanceProvider::getInstance (const OUString& aName )
+ throw ( NoSuchElementException )
+{
+
+ Reference<XInterface> rInstance;
+
+ if ( aName.compareToAscii( "StarOffice.ServiceManager" ) == 0)
+ {
+ rInstance = Reference< XInterface >( m_rSMgr );
+ }
+ else if(aName.compareToAscii( "StarOffice.ComponentContext" ) == 0 )
+ {
+ rInstance = getComponentContext( m_rSMgr );
+ }
+ else if ( aName.compareToAscii("StarOffice.NamingService" ) == 0 )
+ {
+ Reference< XNamingService > rNamingService(
+ m_rSMgr->createInstance( OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.uno.NamingService" ))),
+ UNO_QUERY );
+ if ( rNamingService.is() )
+ {
+ rNamingService->registerObject(
+ OUString(RTL_CONSTASCII_USTRINGPARAM( "StarOffice.ServiceManager" )), m_rSMgr );
+ rNamingService->registerObject(
+ OUString(RTL_CONSTASCII_USTRINGPARAM( "StarOffice.ComponentContext" )), getComponentContext( m_rSMgr ));
+ rInstance = rNamingService;
+ }
+ }
+ return rInstance;
+}
+
+}
+
+// component management stuff...
+// ----------------------------------------------------------------------------
+extern "C"
+{
+using namespace desktop;
+
+void SAL_CALL
+component_getImplementationEnvironment(const sal_Char **ppEnvironmentTypeName, uno_Environment **)
+{
+ *ppEnvironmentTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME ;
+}
+
+void * SAL_CALL
+component_getFactory(const sal_Char *pImplementationName, void *pServiceManager, void *)
+{
+ void* pReturn = NULL ;
+ if ( pImplementationName && pServiceManager )
+ {
+ // Define variables which are used in following macros.
+ Reference< XSingleServiceFactory > xFactory;
+ Reference< XMultiServiceFactory > xServiceManager(
+ reinterpret_cast< XMultiServiceFactory* >(pServiceManager));
+
+ if (Acceptor::impl_getImplementationName().compareToAscii( pImplementationName ) == COMPARE_EQUAL )
+ {
+ xFactory = Reference< XSingleServiceFactory >( cppu::createSingleFactory(
+ xServiceManager, Acceptor::impl_getImplementationName(),
+ Acceptor::impl_getInstance, Acceptor::impl_getSupportedServiceNames()) );
+ }
+
+ // Factory is valid - service was found.
+ if ( xFactory.is() )
+ {
+ xFactory->acquire();
+ pReturn = xFactory.get();
+ }
+ }
+
+ // Return with result of this operation.
+ return pReturn ;
+}
+
+} // extern "C"
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/offacc/acceptor.hxx b/desktop/source/offacc/acceptor.hxx
new file mode 100644
index 000000000000..e4e22da631bd
--- /dev/null
+++ b/desktop/source/offacc/acceptor.hxx
@@ -0,0 +1,131 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/uno/Exception.hpp>
+#include <com/sun/star/uno/Reference.h>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/connection/XAcceptor.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/bridge/XInstanceProvider.hpp>
+#include <com/sun/star/bridge/XBridgeFactory.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <cppuhelper/implbase1.hxx>
+#include <cppuhelper/implbase2.hxx>
+#include <cppuhelper/interfacecontainer.h>
+#include <rtl/logfile.hxx>
+
+#include <com/sun/star/registry/XRegistryKey.hpp>
+#include <comphelper/weakbag.hxx>
+#include <osl/mutex.hxx>
+#include <osl/conditn.hxx>
+#include <osl/thread.hxx>
+
+
+using namespace ::rtl;
+using namespace ::osl;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::bridge;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::connection;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::registry;
+
+namespace desktop {
+
+class Acceptor
+ : public ::cppu::WeakImplHelper2<XServiceInfo, XInitialization>
+{
+private:
+ static const sal_Char *serviceName;
+ static const sal_Char *implementationName;
+ static const sal_Char *supportedServiceNames[];
+
+ static Mutex m_aMutex;
+
+ oslThread m_thread;
+ comphelper::WeakBag< com::sun::star::bridge::XBridge > m_bridges;
+
+ Condition m_cEnable;
+
+ Reference< XMultiServiceFactory > m_rSMgr;
+ Reference< XInterface > m_rContext;
+ Reference< XAcceptor > m_rAcceptor;
+ Reference< XBridgeFactory > m_rBridgeFactory;
+
+ OUString m_aAcceptString;
+ OUString m_aConnectString;
+ OUString m_aProtocol;
+
+ sal_Bool m_bInit;
+ bool m_bDying;
+
+public:
+ Acceptor( const Reference< XMultiServiceFactory >& aFactory );
+ virtual ~Acceptor();
+
+ void SAL_CALL run();
+
+ // XService info
+ static OUString impl_getImplementationName();
+ virtual OUString SAL_CALL getImplementationName()
+ throw (RuntimeException);
+ static Sequence<OUString> impl_getSupportedServiceNames();
+ virtual Sequence<OUString> SAL_CALL getSupportedServiceNames()
+ throw (RuntimeException);
+ virtual sal_Bool SAL_CALL supportsService( const OUString& aName )
+ throw (RuntimeException);
+
+ // XInitialize
+ virtual void SAL_CALL initialize( const Sequence<Any>& aArguments )
+ throw ( Exception );
+
+ static Reference<XInterface> impl_getInstance( const Reference< XMultiServiceFactory >& aFactory );
+};
+
+class AccInstanceProvider : public ::cppu::WeakImplHelper1<XInstanceProvider>
+{
+private:
+ Reference<XMultiServiceFactory> m_rSMgr;
+ Reference<XConnection> m_rConnection;
+
+public:
+ AccInstanceProvider(const Reference< XMultiServiceFactory >& aFactory,
+ const Reference< XConnection >& rConnection);
+ virtual ~AccInstanceProvider();
+
+ // XInstanceProvider
+ virtual Reference<XInterface> SAL_CALL getInstance (const OUString& aName )
+ throw ( NoSuchElementException );
+};
+
+
+} //namespace desktop
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/offacc/makefile.mk b/desktop/source/offacc/makefile.mk
new file mode 100755
index 000000000000..809c28414bef
--- /dev/null
+++ b/desktop/source/offacc/makefile.mk
@@ -0,0 +1,70 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+PRJNAME=desktop
+TARGET=offacc
+LIBTARGET=NO
+
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+SLOFILES = $(SLO)$/acceptor.obj
+
+SHL1DEPN= makefile.mk
+SHL1OBJS= $(SLOFILES)
+
+SHL1TARGET= $(TARGET)$(DLLPOSTFIX)
+SHL1IMPLIB= i$(TARGET)
+
+SHL1VERSIONMAP=$(SOLARENV)/src/component.map
+SHL1DEF=$(MISC)$/$(SHL1TARGET).def
+DEF1NAME=$(SHL1TARGET)
+
+SHL1STDLIBS= \
+ $(CPPUHELPERLIB) \
+ $(CPPULIB) \
+ $(SALLIB)
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
+
+ALLTAR : $(MISC)/offacc.component
+
+$(MISC)/offacc.component .ERRREMOVE : $(SOLARENV)/bin/createcomponent.xslt \
+ offacc.component
+ $(XSLTPROC) --nonet --stringparam uri \
+ '$(COMPONENTPREFIX_BASIS_NATIVE)$(SHL1TARGETN:f)' -o $@ \
+ $(SOLARENV)/bin/createcomponent.xslt offacc.component
diff --git a/desktop/source/offacc/offacc.component b/desktop/source/offacc/offacc.component
new file mode 100755
index 000000000000..6f0d4a97a2d2
--- /dev/null
+++ b/desktop/source/offacc/offacc.component
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--**********************************************************************
+*
+* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+*
+* Copyright 2000, 2010 Oracle and/or its affiliates.
+*
+* OpenOffice.org - a multi-platform office productivity suite
+*
+* This file is part of OpenOffice.org.
+*
+* OpenOffice.org is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License version 3
+* only, as published by the Free Software Foundation.
+*
+* OpenOffice.org is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Lesser General Public License version 3 for more details
+* (a copy is included in the LICENSE file that accompanied this code).
+*
+* You should have received a copy of the GNU Lesser General Public License
+* version 3 along with OpenOffice.org. If not, see
+* <http://www.openoffice.org/license.html>
+* for a copy of the LGPLv3 License.
+*
+**********************************************************************-->
+
+<component loader="com.sun.star.loader.SharedLibrary"
+ xmlns="http://openoffice.org/2010/uno-components">
+ <implementation name="com.sun.star.office.comp.Acceptor">
+ <service name="com.sun.star.office.Acceptor"/>
+ </implementation>
+</component>
diff --git a/desktop/source/pagein/file_image.h b/desktop/source/pagein/file_image.h
new file mode 100755
index 000000000000..4d081713a736
--- /dev/null
+++ b/desktop/source/pagein/file_image.h
@@ -0,0 +1,81 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_FILE_IMAGE_H
+#define INCLUDED_FILE_IMAGE_H
+
+#ifndef INCLUDED_STDDEF_H
+#include <stddef.h>
+#define INCLUDED_STDDEF_H
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** file_image.
+ */
+struct file_image_st
+{
+ void * m_base;
+ size_t m_size;
+};
+
+typedef struct file_image_st file_image;
+
+#define FILE_IMAGE_INITIALIZER { 0, 0 }
+
+
+/** file_image_open.
+ */
+int file_image_open (
+ file_image * image,
+ const char * filename);
+
+
+/** file_image_pagein.
+ */
+int file_image_pagein (
+ file_image * image);
+
+
+/** file_image_close.
+ */
+int file_image_close (
+ file_image * image);
+
+
+/** Epilog.
+ */
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* INCLUDED_ODEP_IMAGE_H */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/pagein/file_image_unx.c b/desktop/source/pagein/file_image_unx.c
new file mode 100755
index 000000000000..fa1af9248d60
--- /dev/null
+++ b/desktop/source/pagein/file_image_unx.c
@@ -0,0 +1,153 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "file_image.h"
+
+#include <unistd.h>
+
+#include <errno.h>
+#include <fcntl.h>
+
+#if defined(LINUX)
+# ifndef __USE_BSD
+# define __USE_BSD /* madvise, MADV_WILLNEED */
+# endif
+#endif /* Linux */
+
+#include <sys/mman.h>
+#include <sys/stat.h>
+
+#include <string.h>
+
+/*
+ * file_image_open
+ */
+int file_image_open (file_image * image, const char * filename)
+{
+ int result = 0;
+ int fd;
+ struct stat st;
+ void * p;
+
+ if (image == 0)
+ return (EINVAL);
+
+ image->m_base = MAP_FAILED, image->m_size = 0;
+
+ if ((fd = open (filename, O_RDONLY)) == -1)
+ return (errno);
+
+ if (fstat (fd, &st) == -1)
+ {
+ result = errno;
+ goto cleanup_and_leave;
+ }
+
+ p = mmap (0, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
+ if (p == MAP_FAILED)
+ {
+ result = errno;
+ goto cleanup_and_leave;
+ }
+
+ image->m_base = p, image->m_size = st.st_size;
+
+cleanup_and_leave:
+ close (fd);
+ return (result);
+}
+
+/*
+ * file_image_pagein.
+ */
+int file_image_pagein (file_image * image)
+{
+ file_image w;
+ long s;
+ size_t k;
+ volatile char c = 0;
+
+ if (image == 0)
+ return (EINVAL);
+
+ if ((w.m_base = image->m_base) == 0)
+ return (EINVAL);
+ if ((w.m_size = image->m_size) == 0)
+ return (0);
+
+ if (madvise (w.m_base, w.m_size, MADV_WILLNEED) == -1)
+ {
+#ifndef MACOSX
+ return (errno);
+#else
+ /* madvise MADV_WILLNEED need not succeed here */
+ /* but that is fine */
+#endif
+ }
+
+
+#ifndef MACOSX
+ if ((s = sysconf (_SC_PAGESIZE)) == -1)
+ s = 0x1000;
+#else
+ s = getpagesize();
+#endif
+
+ k = (size_t)(s);
+ while (w.m_size > k)
+ {
+ c ^= ((char*)(w.m_base))[0];
+ w.m_base = (char*)(w.m_base) + k;
+ w.m_size -= k;
+ }
+ if (w.m_size > 0)
+ {
+ c ^= ((char*)(w.m_base))[0];
+ w.m_base = (char*)(w.m_base) + w.m_size;
+ w.m_size -= w.m_size;
+ }
+
+ return (0);
+}
+
+/*
+ * file_image_close
+ */
+int file_image_close (file_image * image)
+{
+ if (image == 0)
+ return (EINVAL);
+
+ if (munmap (image->m_base, image->m_size) == -1)
+ return (errno);
+
+ image->m_base = 0, image->m_size = 0;
+ return (0);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/pagein/makefile.mk b/desktop/source/pagein/makefile.mk
new file mode 100755
index 000000000000..2b02a4d5a421
--- /dev/null
+++ b/desktop/source/pagein/makefile.mk
@@ -0,0 +1,196 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+PRJNAME=desktop
+TARGET=pagein
+TARGETTYPE=CUI
+LIBTARGET=NO
+
+NO_DEFAULT_STL=TRUE
+LIBSALCPPRT=$(0)
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+.INCLUDE .IGNORE : icuversion.mk
+
+.IF "$(OS)"=="MACOSX"
+
+dummy:
+ @echo "Pagein disabled for mac"
+
+.ELSE
+
+# --- Files --------------------------------------------------------
+
+OBJFILES= \
+ $(OBJ)$/pagein.obj \
+ $(OBJ)$/pagein-main.obj \
+ $(OBJ)$/file_image_unx.obj
+
+APP1TARGET=$(TARGET)
+APP1OBJS=$(OBJFILES)
+APP1CODETYPE=C
+
+# depends on libc only.
+STDLIB=
+
+# --- Targets ------------------------------------------------------
+
+ALL: \
+ $(MISC)$/$(TARGET)-calc \
+ $(MISC)$/$(TARGET)-draw \
+ $(MISC)$/$(TARGET)-impress \
+ $(MISC)$/$(TARGET)-writer \
+ $(MISC)$/$(TARGET)-common \
+ ALLTAR
+
+.INCLUDE : target.mk
+
+ICUDLLPOST=$(DLLPOST).$(ICU_MAJOR)$(ICU_MINOR)
+UDKDLLPOST=$(DLLPOST).$(UDK_MAJOR)
+UNODLLPOST=.uno$(DLLPOST)
+DFTDLLPOST=$(DLLPOSTFIX)$(DLLPOST) # Default
+
+URELIBPATH=..$/ure-link$/lib
+UREMISCPATH=..$/ure-link$/share$/misc
+
+$(MISC)$/$(TARGET)-calc : makefile.mk
+ @echo Making: $@
+ @-echo $(DLLPRE)sc$(DFTDLLPOST) > $@
+ @-echo $(DLLPRE)scui$(DFTDLLPOST) >> $@
+ @-echo $(DLLPRE)svx$(DFTDLLPOST) >> $@
+ @-echo $(DLLPRE)svxcore$(DFTDLLPOST) >> $@
+
+$(MISC)$/$(TARGET)-draw : makefile.mk
+ @echo Making: $@
+ @-echo $(DLLPRE)sd$(DFTDLLPOST) > $@
+ @-echo $(DLLPRE)sdui$(DFTDLLPOST) >> $@
+ @-echo $(DLLPRE)svx$(DFTDLLPOST) >> $@
+ @-echo $(DLLPRE)svxcore$(DFTDLLPOST) >> $@
+
+$(MISC)$/$(TARGET)-impress : makefile.mk
+ @echo Making: $@
+ @-echo $(DLLPRE)sd$(DFTDLLPOST) > $@
+ @-echo $(DLLPRE)sdui$(DFTDLLPOST) >> $@
+ @-echo $(DLLPRE)svx$(DFTDLLPOST) >> $@
+ @-echo $(DLLPRE)svxcore$(DFTDLLPOST) >> $@
+
+$(MISC)$/$(TARGET)-writer : makefile.mk
+ @echo Making: $@
+ @-echo $(DLLPRE)sw$(DFTDLLPOST) > $@
+ @-echo $(DLLPRE)swui$(DFTDLLPOST) >> $@
+ @-echo $(DLLPRE)svx$(DFTDLLPOST) >> $@
+ @-echo $(DLLPRE)svxcore$(DFTDLLPOST) >> $@
+
+# sorted in approx. reverse load order (ld.so.1)
+$(MISC)$/$(TARGET)-common : makefile.mk
+ @echo Making: $@
+ @-echo i18npool$(UNODLLPOST) > $@
+.IF "$(SYSTEM_ICU)" != "YES"
+ @-echo $(DLLPRE)icui18n$(ICUDLLPOST) >> $@
+ @-echo $(DLLPRE)icule$(ICUDLLPOST) >> $@
+ @-echo $(DLLPRE)icuuc$(ICUDLLPOST) >> $@
+# @-echo $(DLLPRE)icudata$(ICUDLLPOST) >> $@ - a huge dll, almost none of it used
+.ENDIF # SYSTEM_ICU
+#
+ @-echo $(DLLPRE)lng$(DFTDLLPOST) >> $@
+ @-echo $(DLLPRE)xo$(DFTDLLPOST) >> $@
+#
+
+ @-echo $(DLLPRE)fwe$(DFTDLLPOST) >> $@
+ @-echo $(DLLPRE)fwk$(DFTDLLPOST) >> $@
+ @-echo $(DLLPRE)fwi$(DFTDLLPOST) >> $@
+ @-echo $(DLLPRE)fwl$(DFTDLLPOST) >> $@
+ @-echo $(DLLPRE)package2$(DLLPOST) >> $@
+ @-echo $(DLLPRE)ucpfile1$(DLLPOST) >> $@
+ @-echo $(DLLPRE)ucb1$(DLLPOST) >> $@
+ @-echo configmgr$(UNODLLPOST) >> $@
+#
+ @-echo $(DLLPRE)vclplug_gen$(DFTDLLPOST) >> $@
+.IF "$(ENABLE_GTK)" != ""
+ @-echo $(DLLPRE)vclplug_gtk$(DFTDLLPOST) >> $@
+.ENDIF # ENABLE_GTK
+.IF "$(ENABLE_KDE)" != ""
+ @-echo $(DLLPRE)vclplug_kde$(DFTDLLPOST) >> $@
+.ENDIF # ENABLE_KDE
+#
+ @-echo $(DLLPRE)basegfx$(DFTDLLPOST) >> $@
+ @-echo $(DLLPRE)sot$(DFTDLLPOST) >> $@
+ @-echo $(DLLPRE)xcr$(DFTDLLPOST) >> $@
+ @-echo $(DLLPRE)sb$(DFTDLLPOST) >> $@
+#
+# uno runtime environment
+#
+ @-echo $(URELIBPATH)$/stocservices$(UNODLLPOST) >> $@
+ @-echo $(URELIBPATH)$/bootstrap$(UNODLLPOST) >> $@
+ @-echo $(URELIBPATH)$/$(DLLPRE)reg$(UDKDLLPOST) >> $@
+ @-echo $(URELIBPATH)$/$(DLLPRE)store$(UDKDLLPOST) >> $@
+ @-echo $(URELIBPATH)$/reflection$(UNODLLPOST) >> $@
+ @-echo $(URELIBPATH)$/$(DLLPRE)uno_cppuhelper$(COMID)$(UDKDLLPOST) >> $@
+ @-echo $(URELIBPATH)$/$(DLLPRE)uno_cppu$(UDKDLLPOST) >> $@
+ @-echo $(URELIBPATH)$/$(DLLPRE)uno_sal$(UDKDLLPOST) >> $@
+#
+ @-echo $(DLLPRE)ucbhelper$(UCBHELPER_MAJOR)$(COMID)$(DLLPOST) >> $@
+ @-echo $(DLLPRE)comphelp$(COMPHLP_MAJOR)$(COMID)$(DLLPOST) >> $@
+ @-echo $(DLLPRE)tl$(DFTDLLPOST) >> $@
+ @-echo $(DLLPRE)utl$(DFTDLLPOST) >> $@
+ @-echo $(DLLPRE)svl$(DFTDLLPOST) >> $@
+ @-echo $(DLLPRE)vcl$(DFTDLLPOST) >> $@
+ @-echo $(DLLPRE)tk$(DFTDLLPOST) >> $@
+ @-echo $(UREMISCPATH)$/types.rdb >> $@
+ @-echo services.rdb >> $@
+ @-echo oovbaapi.rdb >> $@
+ @-echo deployment$(DLLPOSTFIX)$(UNODLLPOST) >> $@
+ @-echo $(DLLPRE)deploymentmisc$(DFTDLLPOST) >> $@
+ @-echo $(DLLPRE)ucb1$(DLLPOST) >> $@
+ @-echo $(DLLPRE)xstor$(DLLPOST) >> $@
+ @-echo $(DLLPRE)package2$(DLLPOST) >> $@
+ @-echo $(DLLPRE)filterconfig1$(DLLPOST) >> $@
+ @-echo $(DLLPRE)uui$(DFTDLLPOST) >> $@
+ @-echo $(DLLPRE)lng$(DFTDLLPOST) >> $@
+ @-echo $(DLLPRE)svt$(DFTDLLPOST) >> $@
+ @-echo $(DLLPRE)spl$(DFTDLLPOST) >> $@
+ @-echo $(DLLPRE)basegfx$(DFTDLLPOST) >> $@
+ @-echo $(DLLPRE)avmedia$(DFTDLLPOST) >> $@
+ @-echo $(DLLPRE)helplinker$(DFTDLLPOST) >> $@
+ @-echo $(DLLPRE)vclplug_gen$(DFTDLLPOST) >> $@
+ @-echo $(DLLPRE)icule$(ICUDLLPOST) >> $@
+ @-echo sax$(UNODLLPOST) >> $@
+ @-echo gconfbe1$(UNODLLPOST) >> $@
+ @-echo fsstorage$(UNODLLPOST) >> $@
+ @-echo desktopbe1$(UNODLLPOST) >> $@
+ @-echo localebe1$(UNODLLPOST) >> $@
+ @-echo ucpexpand1$(UNODLLPOST) >> $@
+# stoc bits
+ @-echo $(DLLPRE)sfx$(DFTDLLPOST) >> $@
+ @-echo $(DLLPRE)sofficeapp$(DLLPOST) >> $@
+
+.ENDIF \ No newline at end of file
diff --git a/desktop/source/pagein/pagein-main.c b/desktop/source/pagein/pagein-main.c
new file mode 100644
index 000000000000..f8fe82ab0ab2
--- /dev/null
+++ b/desktop/source/pagein/pagein-main.c
@@ -0,0 +1,12 @@
+#include <stdio.h>
+/*
+ * De-coupled to allow pagein to be re-used in the unx
+ * splash / quick-starter
+ */
+extern int pagein_execute (int argc, char **argv);
+
+int main (int argc, char **argv)
+{
+ return pagein_execute (argc, argv);
+}
+
diff --git a/desktop/source/pagein/pagein.c b/desktop/source/pagein/pagein.c
new file mode 100755
index 000000000000..3ba12f9437a2
--- /dev/null
+++ b/desktop/source/pagein/pagein.c
@@ -0,0 +1,153 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "file_image.h"
+
+#include <unistd.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+
+/* do_pagein */
+static int do_pagein (const char * filename, size_t * size)
+{
+ int result;
+ file_image image = FILE_IMAGE_INITIALIZER;
+
+ if ((result = file_image_open (&image, filename)) != 0)
+ return (result);
+
+ if ((result = file_image_pagein (&image)) != 0)
+ {
+ fprintf (stderr, "file_image_pagein %s: %s\n", filename, strerror(result));
+ goto cleanup_and_leave;
+ }
+
+ if (size)
+ {
+ *size = image.m_size;
+ }
+
+cleanup_and_leave:
+ file_image_close (&image);
+ return (result);
+}
+
+extern int pagein_execute (int argc, char **argv);
+
+/* main */
+int pagein_execute (int argc, char **argv)
+{
+ int i, v = 0;
+ size_t nfiles = 0, nbytes = 0;
+
+ if (argc < 2)
+ {
+ fprintf (
+ stderr,
+ "%s: Usage: pagein [-v[v]] [-L<path>] [@]<filename> ...\n",
+ argv[0]);
+ return (1);
+ }
+
+ for (i = 1; i < argc; i++)
+ {
+ FILE * fp = 0;
+ size_t k = 0;
+
+ if (argv[i][0] == '-')
+ {
+ /* option */
+ int j = 1;
+ switch (argv[i][j])
+ {
+ case 'v':
+ /* verbosity level */
+ for (v += 1, j += 1; argv[i][j]; j++)
+ v += (argv[i][j] == 'v');
+ break;
+ case 'L':
+ /* search path */
+ if (chdir (&(argv[i][2])) == -1)
+ fprintf (stderr, "chdir %s: %s\n", &(argv[i][2]), strerror(errno));
+ break;
+ default:
+ /* ignored */
+ break;
+ }
+
+ /* next argv */
+ continue;
+ }
+
+ if ((argv[i][0] == '@') && ((fp = fopen (argv[i], "r")) == 0))
+ {
+ char path[1024];
+ if ((fp = fopen (&(argv[i][1]), "r")) == 0)
+ {
+ fprintf (stderr, "fopen %s: %s\n", &(argv[i][1]), strerror(errno));
+ continue;
+ }
+ while (fgets (path, sizeof(path), fp) != 0)
+ {
+ path[strlen(path) - 1] = '\0', k = 0;
+ if (do_pagein (path, &k) == 0)
+ {
+ /* accumulate total size */
+ nbytes += k;
+ }
+
+ if (v >= 2)
+ fprintf (stderr, "pagein(\"%s\") = %d bytes\n", path, (int) k);
+ nfiles += 1;
+ }
+ fclose (fp);
+ }
+ else
+ {
+ if (fp != 0)
+ fclose (fp);
+
+ if (do_pagein (argv[i], &k) == 0)
+ {
+ /* accumulate total size */
+ nbytes += k;
+ }
+
+ if (v >= 2)
+ fprintf (stderr, "pagein(\"%s\") = %d bytes\n", argv[i], (int) k);
+ nfiles += 1;
+ }
+ }
+
+ if (v >= 1)
+ fprintf (stderr, "Total: %d files (%d bytes)\n", (int) nfiles, (int) nbytes);
+ return (0);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/pkgchk/unopkg/makefile.mk b/desktop/source/pkgchk/unopkg/makefile.mk
new file mode 100755
index 000000000000..8384f1b24372
--- /dev/null
+++ b/desktop/source/pkgchk/unopkg/makefile.mk
@@ -0,0 +1,104 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ = ..$/..$/..
+
+PRJNAME = desktop
+TARGET = unopkg
+.IF "$(GUI)" == "OS2"
+TARGETTYPE = CUI
+.ELSE
+TARGETTYPE = GUI
+.ENDIF
+ENABLE_EXCEPTIONS = TRUE
+LIBTARGET=NO
+
+PRJINC += ..$/..$/deployment ..$/..
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/source$/deployment$/inc$/dp_misc.mk
+
+.IF "$(SYSTEM_DB)" == "YES"
+CFLAGS+=-DSYSTEM_DB -I$(DB_INCLUDES)
+.ENDIF
+
+.IF "$(LINK_SO)"!=""
+APP1TARGET = so$/unopkg
+APP1OBJS = $(OBJFILES)
+APP1STDLIBS = $(SALLIB) $(UNOPKGAPPLIB)
+APP1DEPN = $(SHL1TARGETN)
+APP1NOSAL = TRUE
+APP1RPATH = BRAND
+.IF "$(OS)" == "WNT"
+APP1ICON = $(SOLARRESDIR)$/icons/so9_main_app.ico
+APP1LINKRES = $(MISC)$/$(TARGET)1.res
+.ENDIF
+.ENDIF # "$(LINK_SO)"!=""
+
+APP2TARGET = unopkg
+APP2OBJS = $(OBJFILES)
+APP2STDLIBS = $(SALLIB) $(UNOPKGAPPLIB)
+APP2DEPN = $(SHL1TARGETN)
+APP2NOSAL = TRUE
+APP2RPATH = BRAND
+.IF "$(OS)" == "WNT"
+APP2ICON = $(SOLARRESDIR)$/icons/ooo3_main_app.ico
+APP2LINKRES = $(MISC)$/$(TARGET)2.res
+.ENDIF
+
+SHL1TARGET = unopkgapp
+SHL1OBJS = $(SLOFILES) $(SLO)$/lockfile.obj
+SHL1STDLIBS = \
+ $(SALLIB) \
+ $(CPPULIB) \
+ $(CPPUHELPERLIB) \
+ $(COMPHELPERLIB) \
+ $(UCBHELPERLIB) \
+ $(UNOTOOLSLIB) \
+ $(TOOLSLIB) \
+ $(VCLLIB) \
+ $(DEPLOYMENTMISCLIB)
+SHL1VERSIONMAP = version.map
+SHL1IMPLIB = i$(SHL1TARGET)
+DEF1NAME = $(SHL1TARGET)
+
+SLOFILES = \
+ $(SLO)$/unopkg_app.obj \
+ $(SLO)$/unopkg_cmdenv.obj \
+ $(SLO)$/unopkg_misc.obj
+
+OBJFILES = $(OBJ)$/unopkg_main.obj
+
+.INCLUDE : target.mk
+
+.IF "$(APP1TARGETN)" != "" # not set during depend=x
+$(APP1TARGETN) : $(MISC)$/binso_created.flg
+.ENDIF # "$(APP1TARGETN)"!=""
+
+$(MISC)$/binso_created.flg:
+ @@-$(MKDIRHIER) $(BIN)$/so && $(TOUCH) $@
+ @@-$(MKDIRHIER) $(MISC)$/so && $(TOUCH) $@
+
diff --git a/desktop/source/pkgchk/unopkg/unopkg_app.cxx b/desktop/source/pkgchk/unopkg/unopkg_app.cxx
new file mode 100644
index 000000000000..5411e40a91ca
--- /dev/null
+++ b/desktop/source/pkgchk/unopkg/unopkg_app.cxx
@@ -0,0 +1,710 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+
+#include "dp_misc.h"
+#include "unopkg_main.h"
+#include "unopkg_shared.h"
+#include "dp_identifier.hxx"
+#include "sal/main.h"
+#include "tools/extendapplicationenvironment.hxx"
+#include "rtl/ustrbuf.hxx"
+#include "rtl/uri.hxx"
+#include "rtl/bootstrap.hxx"
+#include "osl/thread.h"
+#include "osl/process.h"
+#include "osl/conditn.hxx"
+#include "osl/file.hxx"
+#include "cppuhelper/implbase1.hxx"
+#include "cppuhelper/exc_hlp.hxx"
+#include "comphelper/anytostring.hxx"
+#include "comphelper/sequence.hxx"
+#include "com/sun/star/deployment/ExtensionManager.hpp"
+
+#include "com/sun/star/deployment/ui/PackageManagerDialog.hpp"
+#include "com/sun/star/ui/dialogs/XExecutableDialog.hpp"
+#include "com/sun/star/lang/DisposedException.hpp"
+#include "boost/scoped_array.hpp"
+#include "com/sun/star/ui/dialogs/XDialogClosedListener.hpp"
+#include "com/sun/star/bridge/XBridgeFactory.hpp"
+#include <stdio.h>
+#include <vector>
+
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::unopkg;
+using ::rtl::OUString;
+namespace css = ::com::sun::star;
+namespace {
+
+struct ExtensionName
+{
+ OUString m_str;
+ ExtensionName( OUString const & str ) : m_str( str ) {}
+ bool operator () ( Reference<deployment::XPackage> const & e ) const
+ {
+ if (m_str.equals(dp_misc::getIdentifier(e))
+ || m_str.equals(e->getName()))
+ return true;
+ return false;
+ }
+};
+
+//------------------------------------------------------------------------------
+const char s_usingText [] =
+"\n"
+"using: " APP_NAME " add <options> extension-path...\n"
+" " APP_NAME " validate <options> extension-identifier...\n"
+" " APP_NAME " remove <options> extension-identifier...\n"
+" " APP_NAME " list <options> extension-identifier...\n"
+" " APP_NAME " reinstall <options>\n"
+" " APP_NAME " gui\n"
+" " APP_NAME " -V\n"
+" " APP_NAME " -h\n"
+"\n"
+"sub-commands:\n"
+" add add extension\n"
+" validate checks the prerequisites of an installed extension and"
+" registers it if possible\n"
+" remove remove extensions by identifier\n"
+" reinstall expert feature: reinstall all deployed extensions\n"
+" list list information about deployed extensions\n"
+" gui raise Extension Manager Graphical User Interface (GUI)\n"
+"\n"
+"options:\n"
+" -h, --help this help\n"
+" -V, --version version information\n"
+" -v, --verbose verbose output to stdout\n"
+" -f, --force force overwriting existing extensions\n"
+" -s, --suppress-license prevents showing the license\n"
+" --log-file <file> custom log file; default: <cache-dir>/log.txt\n"
+" --shared expert feature: operate on shared installation\n"
+" deployment context;\n"
+" run only when no concurrent Office\n"
+" process(es) are running!\n"
+" --bundled expert feature: operate on bundled extensions. Only\n"
+" works with list, validate, reinstall;\n"
+" --deployment-context expert feature: explicit deployment context\n"
+" <context>\n"
+"\n"
+"To learn more about the Extension Manager and extensions, see:\n"
+"http://wiki.services.openoffice.org/wiki/Documentation/DevGuide/Extensions/Extensions\n\n";
+
+//------------------------------------------------------------------------------
+const OptionInfo s_option_infos [] = {
+ { RTL_CONSTASCII_STRINGPARAM("help"), 'h', false },
+ { RTL_CONSTASCII_STRINGPARAM("version"), 'V', false },
+ { RTL_CONSTASCII_STRINGPARAM("verbose"), 'v', false },
+ { RTL_CONSTASCII_STRINGPARAM("force"), 'f', false },
+ { RTL_CONSTASCII_STRINGPARAM("log-file"), '\0', true },
+ { RTL_CONSTASCII_STRINGPARAM("shared"), '\0', false },
+ { RTL_CONSTASCII_STRINGPARAM("deployment-context"), '\0', true },
+ { RTL_CONSTASCII_STRINGPARAM("bundled"), '\0', false},
+ { RTL_CONSTASCII_STRINGPARAM("suppress-license"), 's', false},
+
+ { 0, 0, '\0', false }
+};
+
+class DialogClosedListenerImpl :
+ public ::cppu::WeakImplHelper1< ui::dialogs::XDialogClosedListener >
+{
+ osl::Condition & m_rDialogClosedCondition;
+
+public:
+ DialogClosedListenerImpl( osl::Condition & rDialogClosedCondition )
+ : m_rDialogClosedCondition( rDialogClosedCondition ) {}
+
+ // XEventListener (base of XDialogClosedListener)
+ virtual void SAL_CALL disposing( lang::EventObject const & Source )
+ throw (RuntimeException);
+
+ // XDialogClosedListener
+ virtual void SAL_CALL dialogClosed(
+ ui::dialogs::DialogClosedEvent const & aEvent )
+ throw (RuntimeException);
+};
+
+// XEventListener (base of XDialogClosedListener)
+void DialogClosedListenerImpl::disposing( lang::EventObject const & )
+ throw (RuntimeException)
+{
+ // nothing to do
+}
+
+// XDialogClosedListener
+void DialogClosedListenerImpl::dialogClosed(
+ ui::dialogs::DialogClosedEvent const & )
+ throw (RuntimeException)
+{
+ m_rDialogClosedCondition.set();
+}
+
+// If a package had been installed with a pre OOo 2.2, it could not normally be
+// found via its identifier; similarly (and for ease of use), a package
+// installed with OOo 2.2 or later could not normally be found via its file
+// name.
+Reference<deployment::XPackage> findPackage(
+ OUString const & repository,
+ Reference<deployment::XExtensionManager> const & manager,
+ Reference<ucb::XCommandEnvironment > const & environment,
+ OUString const & idOrFileName )
+{
+ Sequence< Reference<deployment::XPackage> > ps(
+ manager->getDeployedExtensions(repository,
+ Reference<task::XAbortChannel>(), environment ) );
+ for ( sal_Int32 i = 0; i < ps.getLength(); ++i )
+ if ( dp_misc::getIdentifier( ps[i] ) == idOrFileName )
+ return ps[i];
+ for ( sal_Int32 i = 0; i < ps.getLength(); ++i )
+ if ( ps[i]->getName() == idOrFileName )
+ return ps[i];
+ return Reference<deployment::XPackage>();
+}
+
+} // anon namespace
+
+
+//workaround for some reason the bridge threads which communicate with the uno.exe
+//process are not releases on time
+void disposeBridges(Reference<css::uno::XComponentContext> ctx)
+{
+ if (!ctx.is())
+ return;
+
+ Reference<css::bridge::XBridgeFactory> bridgeFac(
+ ctx->getServiceManager()->createInstanceWithContext(
+ OUSTR("com.sun.star.bridge.BridgeFactory"), ctx),
+ UNO_QUERY);
+
+ if (bridgeFac.is())
+ {
+ const Sequence< Reference<css::bridge::XBridge> >seqBridges = bridgeFac->getExistingBridges();
+ for (sal_Int32 i = 0; i < seqBridges.getLength(); i++)
+ {
+ Reference<css::lang::XComponent> comp(seqBridges[i], UNO_QUERY);
+ if (comp.is())
+ {
+ try {
+ comp->dispose();
+ }
+ catch (css::lang::DisposedException& )
+ {
+ }
+ }
+ }
+ }
+}
+
+extern "C" int unopkg_main()
+{
+ tools::extendApplicationEnvironment();
+ DisposeGuard disposeGuard;
+ bool bNoOtherErrorMsg = false;
+ OUString subCommand;
+ bool option_shared = false;
+ bool option_force = false;
+ bool option_verbose = false;
+ bool option_bundled = false;
+ bool option_suppressLicense = false;
+ bool subcmd_add = false;
+ bool subcmd_gui = false;
+ OUString logFile;
+ OUString repository;
+ OUString cmdArg;
+ ::std::vector<OUString> cmdPackages;
+
+ OptionInfo const * info_shared = getOptionInfo(
+ s_option_infos, OUSTR("shared") );
+ OptionInfo const * info_force = getOptionInfo(
+ s_option_infos, OUSTR("force") );
+ OptionInfo const * info_verbose = getOptionInfo(
+ s_option_infos, OUSTR("verbose") );
+ OptionInfo const * info_log = getOptionInfo(
+ s_option_infos, OUSTR("log-file") );
+ OptionInfo const * info_context = getOptionInfo(
+ s_option_infos, OUSTR("deployment-context") );
+ OptionInfo const * info_help = getOptionInfo(
+ s_option_infos, OUSTR("help") );
+ OptionInfo const * info_version = getOptionInfo(
+ s_option_infos, OUSTR("version") );
+ OptionInfo const * info_bundled = getOptionInfo(
+ s_option_infos, OUSTR("bundled") );
+ OptionInfo const * info_suppressLicense = getOptionInfo(
+ s_option_infos, OUSTR("suppress-license") );
+
+
+ Reference<XComponentContext> xComponentContext;
+ Reference<XComponentContext> xLocalComponentContext;
+
+ try {
+ sal_uInt32 nPos = 0;
+ sal_uInt32 nCount = osl_getCommandArgCount();
+ if (nCount == 0 || isOption( info_help, &nPos ))
+ {
+ dp_misc::writeConsole(s_usingText);
+ return 0;
+ }
+ else if (isOption( info_version, &nPos )) {
+ dp_misc::writeConsole("\n"APP_NAME" Version 3.3\n");
+ return 0;
+ }
+ //consume all bootstrap variables which may occur before the subcommannd
+ while(isBootstrapVariable(&nPos));
+
+ if(nPos >= nCount)
+ return 0;
+ //get the sub command
+ osl_getCommandArg( nPos, &subCommand.pData );
+ ++nPos;
+ subCommand = subCommand.trim();
+ subcmd_add = subCommand.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM("add") );
+ subcmd_gui = subCommand.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM("gui") );
+
+ // sun-command options and packages:
+ while (nPos < nCount)
+ {
+ if (readArgument( &cmdArg, info_log, &nPos )) {
+ logFile = makeAbsoluteFileUrl(
+ cmdArg.trim(), getProcessWorkingDir() );
+ }
+ else if (!readOption( &option_verbose, info_verbose, &nPos ) &&
+ !readOption( &option_shared, info_shared, &nPos ) &&
+ !readOption( &option_force, info_force, &nPos ) &&
+ !readOption( &option_bundled, info_bundled, &nPos ) &&
+ !readOption( &option_suppressLicense, info_suppressLicense, &nPos ) &&
+ !readArgument( &repository, info_context, &nPos ) &&
+ !isBootstrapVariable(&nPos))
+ {
+ osl_getCommandArg( nPos, &cmdArg.pData );
+ ++nPos;
+ cmdArg = cmdArg.trim();
+ if (cmdArg.getLength() > 0)
+ {
+ if (cmdArg[ 0 ] == '-')
+ {
+ // is option:
+ dp_misc::writeConsoleError(
+ OUSTR("\nERROR: unexpected option ") +
+ cmdArg +
+ OUSTR("!\n") +
+ OUSTR(" Use " APP_NAME " ") +
+ toString(info_help) +
+ OUSTR(" to print all options.\n"));
+ return 1;
+ }
+ else
+ {
+ // is package:
+ cmdPackages.push_back(
+ subcmd_add || subcmd_gui
+ ? makeAbsoluteFileUrl(
+ cmdArg, getProcessWorkingDir() )
+ : cmdArg );
+ }
+ }
+ }
+ }
+
+ if (repository.getLength() == 0)
+ {
+ if (option_shared)
+ repository = OUSTR("shared");
+ else if (option_bundled)
+ repository = OUSTR("bundled");
+ else
+ repository = OUSTR("user");
+ }
+ else
+ {
+ if (repository.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM("shared") )) {
+ option_shared = true;
+ }
+ else if (option_shared) {
+ dp_misc::writeConsoleError(
+ OUSTR("WARNING: explicit context given! ") +
+ OUSTR("Ignoring option ") +
+ toString( info_shared ) +
+ OUSTR("!\n") );
+ }
+ }
+
+ if (subCommand.equals(OUSTR("reinstall")))
+ {
+ //We must prevent that services and types are loaded by UNO,
+ //otherwise we cannot delete the registry data folder.
+ OUString extensionUnorc;
+ if (repository.equals(OUSTR("user")))
+ extensionUnorc = OUSTR("$UNO_USER_PACKAGES_CACHE/registry/com.sun.star.comp.deployment.component.PackageRegistryBackend/unorc");
+ else if (repository.equals(OUSTR("shared")))
+ extensionUnorc = OUSTR("$SHARED_EXTENSIONS_USER/registry/com.sun.star.comp.deployment.component.PackageRegistryBackend/unorc");
+ else if (repository.equals(OUSTR("bundled")))
+ extensionUnorc = OUSTR("$BUNDLED_EXTENSIONS_USER/registry/com.sun.star.comp.deployment.component.PackageRegistryBackend/unorc");
+ else
+ OSL_ASSERT(0);
+
+ ::rtl::Bootstrap::expandMacros(extensionUnorc);
+ oslFileError e = osl_removeFile(extensionUnorc.pData);
+ if (e != osl_File_E_None && e != osl_File_E_NOENT)
+ throw Exception(OUSTR("Could not delete ") + extensionUnorc, 0);
+ }
+ else if (subCommand.equals(OUSTR("sync")))
+ {
+ //sync is private!!!! Only to be called from setup!!!
+ //The UserInstallation is diverted to the prereg folder. But only
+ //the lock file is written! This requires that
+ //-env:UNO_JAVA_JFW_INSTALL_DATA is passed to javaldx and unopkg otherwise the
+ //javasettings file is written to the prereg folder.
+ //
+ //For performance reasons unopkg sync is called during the setup and
+ //creates the registration data for the repository of the bundled
+ //extensions. It is then copied to the user installation during
+ //startup of OOo (userdata/extensions/bundled). The registration
+ //data is in the brand installation and must be removed when
+ //uninstalling OOo. We do this here, before UNO is
+ //bootstrapped. Otherwies files could be locked by this process.
+
+ //If there is no folder left in
+ //$BRAND_BASE_DIR/share/extensions
+ //then we can delete the registration data at
+ //$BUNDLED_EXTENSIONS_USER
+ if (hasNoFolder(OUSTR("$BRAND_BASE_DIR/share/extensions")))
+ {
+ removeFolder(OUSTR("$BUNDLED_EXTENSIONS_PREREG"));
+ //return otherwise we create the registration data again
+ return 0;
+ }
+ //redirect the UserInstallation, so we do not create a
+ //user installation for the admin and we also do not need
+ //to call unopkg with -env:UserInstallation
+ ::rtl::Bootstrap::set(OUSTR("UserInstallation"),
+ OUSTR("$BUNDLED_EXTENSIONS_PREREG/.."));
+ //Setting UNO_JAVA_JFW_INSTALL_DATA causes the javasettings to be written
+ //in the office installation. We do not want to create the user data folder
+ //for the admin. The value must also be set in the unopkg script (Linux, etc.)
+ //when calling javaldx
+ ::rtl::Bootstrap::set(OUSTR("UNO_JAVA_JFW_INSTALL_DATA"),
+ OUSTR("$OOO_BASE_DIR/share/config/javasettingsunopkginstall.xml"));
+
+ }
+
+ xComponentContext = getUNO(
+ disposeGuard, option_verbose, option_shared, subcmd_gui,
+ xLocalComponentContext );
+
+ Reference<deployment::XExtensionManager> xExtensionManager(
+ deployment::ExtensionManager::get( xComponentContext ) );
+
+ Reference< ::com::sun::star::ucb::XCommandEnvironment > xCmdEnv(
+ createCmdEnv( xComponentContext, logFile,
+ option_force, option_verbose, option_suppressLicense) );
+
+ //synchronize bundled/shared extensions
+ //Do not synchronize when command is "reinstall". This could add types and services to UNO and
+ //prevent the deletion of the registry data folder
+ //synching is done in XExtensionManager.reinstall
+ if (!subcmd_gui && ! subCommand.equals(OUSTR("reinstall"))
+ && ! subCommand.equals(OUSTR("sync"))
+ && ! dp_misc::office_is_running())
+ dp_misc::syncRepositories(xCmdEnv);
+
+ if (subcmd_add ||
+ subCommand.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM("remove") ))
+ {
+ for ( ::std::size_t pos = 0; pos < cmdPackages.size(); ++pos )
+ {
+ OUString const & cmdPackage = cmdPackages[ pos ];
+ if (subcmd_add)
+ {
+ beans::NamedValue nvSuppress(
+ OUSTR("SUPPRESS_LICENSE"), option_suppressLicense ?
+ makeAny(OUSTR("1")):makeAny(OUSTR("0")));
+ xExtensionManager->addExtension(
+ cmdPackage, Sequence<beans::NamedValue>(&nvSuppress, 1),
+ repository, Reference<task::XAbortChannel>(), xCmdEnv);
+ }
+ else
+ {
+ try
+ {
+ xExtensionManager->removeExtension(
+ cmdPackage, cmdPackage, repository,
+ Reference<task::XAbortChannel>(), xCmdEnv );
+ }
+ catch (lang::IllegalArgumentException &)
+ {
+ Reference<deployment::XPackage> p(
+ findPackage(repository,
+ xExtensionManager, xCmdEnv, cmdPackage ) );
+ if ( !p.is())
+ throw;
+ else if (p.is())
+ xExtensionManager->removeExtension(
+ ::dp_misc::getIdentifier(p), p->getName(),
+ repository,
+ Reference<task::XAbortChannel>(), xCmdEnv );
+ }
+ }
+ }
+ }
+ else if (subCommand.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM("reinstall") ))
+ {
+ xExtensionManager->reinstallDeployedExtensions(
+ repository, Reference<task::XAbortChannel>(), xCmdEnv);
+ }
+ else if (subCommand.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("list") ))
+ {
+ ::std::vector<Reference<deployment::XPackage> > vecExtUnaccepted;
+ ::comphelper::sequenceToContainer(vecExtUnaccepted,
+ xExtensionManager->getExtensionsWithUnacceptedLicenses(
+ repository, xCmdEnv));
+
+ //This vector tells what XPackage in allExtensions has an
+ //unaccepted license.
+ std::vector<bool> vecUnaccepted;
+ std::vector<Reference<deployment::XPackage> > allExtensions;
+ if (cmdPackages.empty())
+ {
+ Sequence< Reference<deployment::XPackage> >
+ packages = xExtensionManager->getDeployedExtensions(
+ repository, Reference<task::XAbortChannel>(), xCmdEnv );
+
+ ::std::vector<Reference<deployment::XPackage> > vec_packages;
+ ::comphelper::sequenceToContainer(vec_packages, packages);
+
+ //First copy the extensions with the unaccepted license
+ //to vector allExtensions.
+ allExtensions.resize(vecExtUnaccepted.size() + vec_packages.size());
+
+ ::std::vector<Reference<deployment::XPackage> >::iterator i_all_ext =
+ ::std::copy(vecExtUnaccepted.begin(), vecExtUnaccepted.end(),
+ allExtensions.begin());
+ //Now copy those we got from getDeployedExtensions
+ ::std::copy(vec_packages.begin(), vec_packages.end(), i_all_ext);
+
+ //Now prepare the vector which tells what extension has an
+ //unaccepted license
+ vecUnaccepted.resize(vecExtUnaccepted.size() + vec_packages.size());
+ ::std::fill_n(vecUnaccepted.begin(), vecExtUnaccepted.size(), true);
+ ::std::fill_n(vecUnaccepted.begin() + vecExtUnaccepted.size(),
+ vec_packages.size(), false);
+
+ dp_misc::writeConsole(
+ OUSTR("All deployed ") + repository + OUSTR(" extensions:\n\n"));
+ }
+ else
+ {
+ //The user provided the names (ids or file names) of the extensions
+ //which shall be listed
+ for ( ::std::size_t pos = 0; pos < cmdPackages.size(); ++pos )
+ {
+ Reference<deployment::XPackage> extension;
+ try
+ {
+ extension = xExtensionManager->getDeployedExtension(
+ repository, cmdPackages[ pos ], cmdPackages[ pos ], xCmdEnv );
+ }
+ catch (lang::IllegalArgumentException &)
+ {
+ extension = findPackage(repository,
+ xExtensionManager, xCmdEnv, cmdPackages[ pos ] );
+ }
+
+ //Now look if the requested extension has an unaccepted license
+ bool bUnacceptedLic = false;
+ if (!extension.is())
+ {
+ ::std::vector<Reference<deployment::XPackage> >::const_iterator
+ i = ::std::find_if(
+ vecExtUnaccepted.begin(),
+ vecExtUnaccepted.end(), ExtensionName(cmdPackages[pos]));
+ if (i != vecExtUnaccepted.end())
+ {
+ extension = *i;
+ bUnacceptedLic = true;
+ }
+ }
+
+ if (extension.is())
+ {
+ allExtensions.push_back(extension);
+ vecUnaccepted.push_back(bUnacceptedLic);
+ }
+
+ else
+ throw lang::IllegalArgumentException(
+ OUSTR("There is no such extension deployed: ") +
+ cmdPackages[pos],0,-1);
+ }
+
+ }
+
+ printf_packages(allExtensions, vecUnaccepted, xCmdEnv );
+ }
+ else if (subCommand.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("validate") ))
+ {
+ ::std::vector<Reference<deployment::XPackage> > vecExtUnaccepted;
+ ::comphelper::sequenceToContainer(
+ vecExtUnaccepted, xExtensionManager->getExtensionsWithUnacceptedLicenses(
+ repository, xCmdEnv));
+
+ for ( ::std::size_t pos = 0; pos < cmdPackages.size(); ++pos )
+ {
+ Reference<deployment::XPackage> extension;
+ try
+ {
+ extension = xExtensionManager->getDeployedExtension(
+ repository, cmdPackages[ pos ], cmdPackages[ pos ], xCmdEnv );
+ }
+ catch (lang::IllegalArgumentException &)
+ {
+ extension = findPackage(
+ repository, xExtensionManager, xCmdEnv, cmdPackages[ pos ] );
+ }
+
+ if (!extension.is())
+ {
+ ::std::vector<Reference<deployment::XPackage> >::const_iterator
+ i = ::std::find_if(
+ vecExtUnaccepted.begin(),
+ vecExtUnaccepted.end(), ExtensionName(cmdPackages[pos]));
+ if (i != vecExtUnaccepted.end())
+ {
+ extension = *i;
+ }
+ }
+
+ if (extension.is())
+ xExtensionManager->checkPrerequisitesAndEnable(
+ extension, Reference<task::XAbortChannel>(), xCmdEnv);
+ }
+ }
+ else if (subCommand.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("gui") ))
+ {
+ Reference<ui::dialogs::XAsynchronousExecutableDialog> xDialog(
+ deployment::ui::PackageManagerDialog::createAndInstall(
+ xComponentContext,
+ cmdPackages.size() > 0 ? cmdPackages[0] : OUString() ));
+
+ osl::Condition dialogEnded;
+ dialogEnded.reset();
+
+ Reference< ui::dialogs::XDialogClosedListener > xListener(
+ new DialogClosedListenerImpl( dialogEnded ) );
+
+ xDialog->startExecuteModal(xListener);
+ dialogEnded.wait();
+ }
+ else if (subCommand.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("sync")))
+ {
+ if (! dp_misc::office_is_running())
+ {
+ xExtensionManager->synchronizeBundledPrereg(
+ Reference<task::XAbortChannel>(), xCmdEnv);
+ }
+ else
+ {
+ dp_misc::writeConsoleError(OUSTR("\nError: office is running"));
+ }
+ }
+ else
+ {
+ dp_misc::writeConsoleError(
+ OUSTR("\nERROR: unknown sub-command ") +
+ subCommand +
+ OUSTR("!\n") +
+ OUSTR(" Use " APP_NAME " ") +
+ toString(info_help) +
+ OUSTR(" to print all options.\n"));
+ return 1;
+ }
+
+ if (option_verbose)
+ dp_misc::writeConsole(OUSTR("\n"APP_NAME" done.\n"));
+ //Force to release all bridges which connect us to the child processes
+ disposeBridges(xLocalComponentContext);
+ return 0;
+ }
+ catch (ucb::CommandFailedException &e)
+ {
+ dp_misc::writeConsoleError(e.Message + OUSTR("\n"));
+ bNoOtherErrorMsg = true;
+ }
+ catch (ucb::CommandAbortedException &)
+ {
+ dp_misc::writeConsoleError("\n"APP_NAME" aborted!\n");
+ }
+ catch (deployment::DeploymentException & exc)
+ {
+ OUString cause;
+ if (option_verbose)
+ {
+ cause = ::comphelper::anyToString(exc.Cause);
+ }
+ else
+ {
+ css::uno::Exception e;
+ if (exc.Cause >>= e)
+ cause = e.Message;
+ }
+
+ dp_misc::writeConsoleError(
+ OUSTR("\nERROR: ") + exc.Message + OUSTR("\n"));
+ if (cause.getLength())
+ dp_misc::writeConsoleError(
+ OUSTR(" Cause: ") + cause + OUSTR("\n"));
+ }
+ catch (LockFileException & e)
+ {
+ if (!subcmd_gui)
+ dp_misc::writeConsoleError(e.Message);
+ bNoOtherErrorMsg = true;
+ }
+ catch (::com::sun::star::uno::Exception & e ) {
+ Any exc( ::cppu::getCaughtException() );
+
+ dp_misc::writeConsoleError(
+ OUSTR("\nERROR: ") +
+ OUString(option_verbose ? e.Message + OUSTR("\nException details: \n") +
+ ::comphelper::anyToString(exc) : e.Message) +
+ OUSTR("\n"));
+ }
+ if (!bNoOtherErrorMsg)
+ dp_misc::writeConsoleError("\n"APP_NAME" failed.\n");
+ disposeBridges(xLocalComponentContext);
+ return 1;
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/pkgchk/unopkg/unopkg_cmdenv.cxx b/desktop/source/pkgchk/unopkg/unopkg_cmdenv.cxx
new file mode 100644
index 000000000000..f39364ae4dd9
--- /dev/null
+++ b/desktop/source/pkgchk/unopkg/unopkg_cmdenv.cxx
@@ -0,0 +1,446 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include "../../deployment/gui/dp_gui.hrc"
+#include "../../deployment/gui/dp_gui_shared.hxx"
+#include "unopkg_shared.h"
+#include "osl/thread.h"
+#include "rtl/memory.h"
+#include "tools/string.hxx"
+#include "tools/resmgr.hxx"
+#include "cppuhelper/implbase3.hxx"
+#include "cppuhelper/exc_hlp.hxx"
+#include "comphelper/anytostring.hxx"
+#include "unotools/configmgr.hxx"
+#include "com/sun/star/lang/WrappedTargetException.hpp"
+#include "com/sun/star/task/XInteractionAbort.hpp"
+#include "com/sun/star/task/XInteractionApprove.hpp"
+#include "com/sun/star/deployment/InstallException.hpp"
+#include "com/sun/star/container/ElementExistException.hpp"
+#include "com/sun/star/deployment/LicenseException.hpp"
+#include "com/sun/star/deployment/VersionException.hpp"
+#include "com/sun/star/deployment/PlatformException.hpp"
+#include "com/sun/star/i18n/XCollator.hpp"
+#include "com/sun/star/i18n/CollatorOptions.hpp"
+
+#include <stdio.h>
+#include "deployment.hrc"
+#include "dp_version.hxx"
+
+namespace css = ::com::sun::star;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::ucb;
+using namespace ::com::sun::star::uno;
+using namespace ::unopkg;
+using ::rtl::OUString;
+
+
+namespace {
+
+//==============================================================================
+struct OfficeLocale :
+ public rtl::StaticWithInit<const lang::Locale, OfficeLocale> {
+ const lang::Locale operator () () {
+ OUString slang;
+ if (! (::utl::ConfigManager::GetDirectConfigProperty(
+ ::utl::ConfigManager::LOCALE ) >>= slang))
+ throw RuntimeException( OUSTR("Cannot determine language!"), 0 );
+ return toLocale(slang);
+ }
+};
+
+//==============================================================================
+class CommandEnvironmentImpl
+ : public ::cppu::WeakImplHelper3< XCommandEnvironment,
+ task::XInteractionHandler,
+ XProgressHandler >
+{
+ sal_Int32 m_logLevel;
+ bool m_option_force_overwrite;
+ bool m_option_verbose;
+ bool m_option_suppress_license;
+ Reference< XComponentContext > m_xComponentContext;
+ Reference< XProgressHandler > m_xLogFile;
+
+ void update_( Any const & Status ) throw (RuntimeException);
+ void printLicense(const OUString & sName,const OUString& sLicense,
+ bool & accept, bool & decline);
+
+public:
+ virtual ~CommandEnvironmentImpl();
+ CommandEnvironmentImpl(
+ Reference<XComponentContext> const & xComponentContext,
+ OUString const & log_file,
+ bool option_force_overwrite,
+ bool option_verbose,
+ bool option_suppress_license);
+
+ // XCommandEnvironment
+ virtual Reference< task::XInteractionHandler > SAL_CALL
+ getInteractionHandler() throw (RuntimeException);
+ virtual Reference< XProgressHandler > SAL_CALL getProgressHandler()
+ throw (RuntimeException);
+
+ // XInteractionHandler
+ virtual void SAL_CALL handle(
+ Reference< task::XInteractionRequest > const & xRequest )
+ throw (RuntimeException);
+
+ // XProgressHandler
+ virtual void SAL_CALL push( Any const & Status ) throw (RuntimeException);
+ virtual void SAL_CALL update( Any const & Status ) throw (RuntimeException);
+ virtual void SAL_CALL pop() throw (RuntimeException);
+};
+
+
+//______________________________________________________________________________
+CommandEnvironmentImpl::CommandEnvironmentImpl(
+ Reference<XComponentContext> const & xComponentContext,
+ OUString const & log_file,
+ bool option_force_overwrite,
+ bool option_verbose,
+ bool option_suppressLicense)
+ : m_logLevel(0),
+ m_option_force_overwrite( option_force_overwrite ),
+ m_option_verbose( option_verbose ),
+ m_option_suppress_license( option_suppressLicense ),
+ m_xComponentContext(xComponentContext)
+{
+ if (log_file.getLength() > 0) {
+ const Any logfile(log_file);
+ m_xLogFile.set(
+ xComponentContext->getServiceManager()
+ ->createInstanceWithArgumentsAndContext(
+ OUSTR("com.sun.star.comp.deployment.ProgressLog"),
+ Sequence<Any>( &logfile, 1 ), xComponentContext ),
+ UNO_QUERY_THROW );
+ }
+}
+
+//______________________________________________________________________________
+CommandEnvironmentImpl::~CommandEnvironmentImpl()
+{
+ try {
+ Reference< lang::XComponent > xComp( m_xLogFile, UNO_QUERY );
+ if (xComp.is())
+ xComp->dispose();
+ }
+ catch (RuntimeException & exc) {
+ (void) exc;
+ OSL_FAIL( ::rtl::OUStringToOString(
+ exc.Message, osl_getThreadTextEncoding() ).getStr() );
+ }
+}
+
+//May throw exceptions
+void CommandEnvironmentImpl::printLicense(
+ const OUString & sName, const OUString& sLicense, bool & accept, bool &decline)
+{
+ ResMgr * pResMgr = DeploymentResMgr::get();
+ String s1tmp(ResId(RID_STR_UNOPKG_ACCEPT_LIC_1, *pResMgr));
+ s1tmp.SearchAndReplaceAllAscii( "$NAME", sName );
+ OUString s1(s1tmp);
+ OUString s2 = String(ResId(RID_STR_UNOPKG_ACCEPT_LIC_2, *pResMgr));
+ OUString s3 = String(ResId(RID_STR_UNOPKG_ACCEPT_LIC_3, *pResMgr));
+ OUString s4 = String(ResId(RID_STR_UNOPKG_ACCEPT_LIC_4, *pResMgr));
+ OUString sYES = String(ResId(RID_STR_UNOPKG_ACCEPT_LIC_YES, *pResMgr));
+ OUString sY = String(ResId(RID_STR_UNOPKG_ACCEPT_LIC_Y, *pResMgr));
+ OUString sNO = String(ResId(RID_STR_UNOPKG_ACCEPT_LIC_NO, *pResMgr));
+ OUString sN = String(ResId(RID_STR_UNOPKG_ACCEPT_LIC_N, *pResMgr));
+
+ OUString sNewLine(RTL_CONSTASCII_USTRINGPARAM("\n"));
+
+ dp_misc::writeConsole(sNewLine + sNewLine + s1 + sNewLine + sNewLine);
+ dp_misc::writeConsole(sLicense + sNewLine + sNewLine);
+ dp_misc::writeConsole(s2 + sNewLine);
+ dp_misc::writeConsole(s3);
+
+ //the user may enter "yes" or "no", we compare in a case insensitive way
+ Reference< css::i18n::XCollator > xCollator(
+ m_xComponentContext->getServiceManager()
+ ->createInstanceWithContext(
+ OUSTR("com.sun.star.i18n.Collator"),m_xComponentContext),
+ UNO_QUERY_THROW );
+ xCollator->loadDefaultCollator(OfficeLocale::get(),
+ css::i18n::CollatorOptions::CollatorOptions_IGNORE_CASE);
+
+ do
+ {
+ OUString sAnswer = dp_misc::readConsole();
+ if (xCollator->compareString(sAnswer, sYES) == 0
+ || xCollator->compareString(sAnswer, sY) == 0)
+ {
+ accept = true;
+ break;
+ }
+ else if(xCollator->compareString(sAnswer, sNO) == 0
+ || xCollator->compareString(sAnswer, sN) == 0)
+ {
+ decline = true;
+ break;
+ }
+ else
+ {
+ dp_misc::writeConsole(sNewLine + sNewLine + s4 + sNewLine);
+ }
+ }
+ while(true);
+}
+
+// XCommandEnvironment
+//______________________________________________________________________________
+Reference< task::XInteractionHandler >
+CommandEnvironmentImpl::getInteractionHandler() throw (RuntimeException)
+{
+ return this;
+}
+
+//______________________________________________________________________________
+Reference< XProgressHandler > CommandEnvironmentImpl::getProgressHandler()
+ throw (RuntimeException)
+{
+ return this;
+}
+
+// XInteractionHandler
+//______________________________________________________________________________
+void CommandEnvironmentImpl::handle(
+ Reference<task::XInteractionRequest> const & xRequest )
+ throw (RuntimeException)
+{
+ Any request( xRequest->getRequest() );
+ OSL_ASSERT( request.getValueTypeClass() == TypeClass_EXCEPTION );
+ dp_misc::TRACE(OUSTR("[unopkg_cmdenv.cxx] incoming request:\n")
+ + ::comphelper::anyToString(request) + OUSTR("\n\n"));
+
+ // selections:
+ bool approve = false;
+ bool abort = false;
+
+ lang::WrappedTargetException wtExc;
+ deployment::LicenseException licExc;
+ deployment::InstallException instExc;
+ deployment::PlatformException platExc;
+ deployment::VersionException verExc;
+
+
+ bool bLicenseException = false;
+ if (request >>= wtExc) {
+ // ignore intermediate errors of legacy packages, i.e.
+ // former pkgchk behaviour:
+ const Reference<deployment::XPackage> xPackage(
+ wtExc.Context, UNO_QUERY );
+ OSL_ASSERT( xPackage.is() );
+ if (xPackage.is()) {
+ const Reference<deployment::XPackageTypeInfo> xPackageType(
+ xPackage->getPackageType() );
+ OSL_ASSERT( xPackageType.is() );
+ if (xPackageType.is()) {
+ approve = (xPackage->isBundle() &&
+ xPackageType->getMediaType().matchAsciiL(
+ RTL_CONSTASCII_STRINGPARAM(
+ "application/"
+ "vnd.sun.star.legacy-package-bundle") ));
+ }
+ }
+ abort = !approve;
+ if (abort) {
+ // notify cause as error:
+ request = wtExc.TargetException;
+ }
+ else {
+ // handable deployment error signalled, e.g.
+ // bundle item registration failed, notify as warning:
+ update_( wtExc.TargetException );
+ }
+ }
+ else if (request >>= licExc)
+ {
+ if ( !m_option_suppress_license )
+ printLicense(licExc.ExtensionName, licExc.Text, approve, abort);
+ else
+ {
+ approve = true;
+ abort = false;
+ }
+ }
+ else if (request >>= instExc)
+ {
+ //Only if the unopgk was started with gui + extension then we user is asked.
+ //In console mode there is no asking.
+ approve = true;
+ }
+ else if (request >>= platExc)
+ {
+ String sMsg(ResId(RID_STR_UNSUPPORTED_PLATFORM, *dp_gui::DeploymentGuiResMgr::get()));
+ sMsg.SearchAndReplaceAllAscii("%Name", platExc.package->getDisplayName());
+ dp_misc::writeConsole(OUSTR("\n") + sMsg + OUSTR("\n\n"));
+ approve = true;
+ }
+ else {
+ deployment::VersionException nc_exc;
+ if (request >>= nc_exc) {
+ approve = m_option_force_overwrite ||
+ (::dp_misc::compareVersions(nc_exc.NewVersion, nc_exc.Deployed->getVersion())
+ == ::dp_misc::GREATER);
+ abort = !approve;
+ }
+ else
+ return; // unknown request => no selection at all
+ }
+
+ //In case of a user declining a license abort is true but this is intended,
+ //therefore no logging
+ if (abort && m_option_verbose && !bLicenseException)
+ {
+ OUString msg = ::comphelper::anyToString(request);
+ dp_misc::writeConsoleError(
+ OUSTR("\nERROR: ") + msg + OUSTR("\n"));
+ }
+
+ // select:
+ Sequence< Reference<task::XInteractionContinuation> > conts(
+ xRequest->getContinuations() );
+ Reference<task::XInteractionContinuation> const * pConts =
+ conts.getConstArray();
+ sal_Int32 len = conts.getLength();
+ for ( sal_Int32 pos = 0; pos < len; ++pos )
+ {
+ if (approve) {
+ Reference<task::XInteractionApprove> xInteractionApprove(
+ pConts[ pos ], UNO_QUERY );
+ if (xInteractionApprove.is()) {
+ xInteractionApprove->select();
+ break;
+ }
+ }
+ else if (abort) {
+ Reference<task::XInteractionAbort> xInteractionAbort(
+ pConts[ pos ], UNO_QUERY );
+ if (xInteractionAbort.is()) {
+ xInteractionAbort->select();
+ break;
+ }
+ }
+ }
+}
+
+// XProgressHandler
+//______________________________________________________________________________
+void CommandEnvironmentImpl::push( Any const & Status )
+ throw (RuntimeException)
+{
+ update_( Status );
+ OSL_ASSERT( m_logLevel >= 0 );
+ ++m_logLevel;
+ if (m_xLogFile.is())
+ m_xLogFile->push( Status );
+}
+
+//______________________________________________________________________________
+void CommandEnvironmentImpl::update_( Any const & Status )
+ throw (RuntimeException)
+{
+ if (! Status.hasValue())
+ return;
+ bool bUseErr = false;
+ OUString msg;
+ if (Status >>= msg) {
+ if (! m_option_verbose)
+ return;
+ }
+ else {
+ ::rtl::OUStringBuffer buf;
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("WARNING: ") );
+ deployment::DeploymentException dp_exc;
+ if (Status >>= dp_exc) {
+ buf.append( dp_exc.Message );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(", Cause: ") );
+ buf.append( ::comphelper::anyToString(dp_exc.Cause) );
+ }
+ else {
+ buf.append( ::comphelper::anyToString(Status) );
+ }
+ msg = buf.makeStringAndClear();
+ bUseErr = true;
+ }
+ OSL_ASSERT( m_logLevel >= 0 );
+ for ( sal_Int32 n = 0; n < m_logLevel; ++n )
+ {
+ if (bUseErr)
+ dp_misc::writeConsoleError(" ");
+ else
+ dp_misc::writeConsole(" ");
+ }
+
+ if (bUseErr)
+ dp_misc::writeConsoleError(msg + OUSTR("\n"));
+ else
+ dp_misc::writeConsole(msg + OUSTR("\n"));
+}
+
+//______________________________________________________________________________
+void CommandEnvironmentImpl::update( Any const & Status )
+ throw (RuntimeException)
+{
+ update_( Status );
+ if (m_xLogFile.is())
+ m_xLogFile->update( Status );
+}
+
+//______________________________________________________________________________
+void CommandEnvironmentImpl::pop() throw (RuntimeException)
+{
+ OSL_ASSERT( m_logLevel > 0 );
+ --m_logLevel;
+ if (m_xLogFile.is())
+ m_xLogFile->pop();
+}
+
+
+} // anon namespace
+
+namespace unopkg {
+
+//==============================================================================
+Reference< XCommandEnvironment > createCmdEnv(
+ Reference< XComponentContext > const & xContext,
+ OUString const & logFile,
+ bool option_force_overwrite,
+ bool option_verbose,
+ bool option_suppress_license)
+{
+ return new CommandEnvironmentImpl(
+ xContext, logFile, option_force_overwrite, option_verbose, option_suppress_license);
+}
+} // unopkg
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/pkgchk/unopkg/unopkg_main.c b/desktop/source/pkgchk/unopkg/unopkg_main.c
new file mode 100755
index 000000000000..07e310c3b402
--- /dev/null
+++ b/desktop/source/pkgchk/unopkg/unopkg_main.c
@@ -0,0 +1,39 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "sal/config.h"
+
+#include "sal/main.h"
+
+#include "unopkg_main.h"
+
+SAL_IMPLEMENT_MAIN() {
+ return unopkg_main();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/pkgchk/unopkg/unopkg_main.h b/desktop/source/pkgchk/unopkg/unopkg_main.h
new file mode 100755
index 000000000000..a4d66cf17c05
--- /dev/null
+++ b/desktop/source/pkgchk/unopkg/unopkg_main.h
@@ -0,0 +1,46 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_DESKTOP_SOURCE_PKGCHK_UNOPKG_UNOPKG_MAIN_H
+#define INCLUDED_DESKTOP_SOURCE_PKGCHK_UNOPKG_UNOPKG_MAIN_H
+
+#include "sal/config.h"
+
+#if defined __cplusplus
+extern "C" {
+#endif
+
+int unopkg_main(void);
+
+#if defined __cplusplus
+}
+#endif
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/pkgchk/unopkg/unopkg_misc.cxx b/desktop/source/pkgchk/unopkg/unopkg_misc.cxx
new file mode 100644
index 000000000000..2021e7698b9b
--- /dev/null
+++ b/desktop/source/pkgchk/unopkg/unopkg_misc.cxx
@@ -0,0 +1,638 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include "deployment.hrc"
+#include "unopkg_shared.h"
+#include "dp_identifier.hxx"
+#include "../../deployment/gui/dp_gui.hrc"
+#include "../../app/lockfile.hxx"
+#include "vcl/svapp.hxx"
+#include "vcl/msgbox.hxx"
+#include "rtl/bootstrap.hxx"
+#include "rtl/strbuf.hxx"
+#include "rtl/ustrbuf.hxx"
+#include "osl/process.h"
+#include "osl/file.hxx"
+#include "osl/thread.hxx"
+#include "tools/getprocessworkingdir.hxx"
+#include "ucbhelper/contentbroker.hxx"
+#include "ucbhelper/configurationkeys.hxx"
+#include "unotools/processfactory.hxx"
+#include "unotools/configmgr.hxx"
+#include "com/sun/star/lang/XMultiServiceFactory.hpp"
+#include "cppuhelper/bootstrap.hxx"
+#include "comphelper/sequence.hxx"
+#include <stdio.h>
+
+using ::rtl::OUString;
+using ::rtl::OString;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::ucb;
+
+namespace unopkg {
+
+bool getLockFilePath(OUString & out);
+
+::rtl::OUString toString( OptionInfo const * info )
+{
+ OSL_ASSERT( info != 0 );
+ ::rtl::OUStringBuffer buf;
+ buf.appendAscii("--");
+ buf.appendAscii(info->m_name);
+ if (info->m_short_option != '\0')
+ {
+ buf.appendAscii(" (short -" );
+ buf.append(info->m_short_option );
+ buf.appendAscii(")");
+ }
+ if (info->m_has_argument)
+ buf.appendAscii(" <argument>" );
+ return buf.makeStringAndClear();
+}
+
+//==============================================================================
+OptionInfo const * getOptionInfo(
+ OptionInfo const * list,
+ OUString const & opt, sal_Unicode copt )
+{
+ for ( ; list->m_name != 0; ++list )
+ {
+ OptionInfo const & option_info = *list;
+ if (opt.getLength() > 0)
+ {
+ if (opt.equalsAsciiL(
+ option_info.m_name, option_info.m_name_length ) &&
+ (copt == '\0' || copt == option_info.m_short_option))
+ {
+ return &option_info;
+ }
+ }
+ else
+ {
+ OSL_ASSERT( copt != '\0' );
+ if (copt == option_info.m_short_option)
+ {
+ return &option_info;
+ }
+ }
+ }
+ OSL_FAIL( ::rtl::OUStringToOString(
+ opt, osl_getThreadTextEncoding() ).getStr() );
+ return 0;
+}
+
+//==============================================================================
+bool isOption( OptionInfo const * option_info, sal_uInt32 * pIndex )
+{
+ OSL_ASSERT( option_info != 0 );
+ if (osl_getCommandArgCount() <= *pIndex)
+ return false;
+
+ OUString arg;
+ osl_getCommandArg( *pIndex, &arg.pData );
+ sal_Int32 len = arg.getLength();
+
+ if (len < 2 || arg[ 0 ] != '-')
+ return false;
+
+ if (len == 2 && arg[ 1 ] == option_info->m_short_option)
+ {
+ ++(*pIndex);
+ dp_misc::TRACE(OUSTR(__FILE__": identified option \'")
+ + OUSTR("\'") + OUString( option_info->m_short_option ) + OUSTR("\n"));
+ return true;
+ }
+ if (arg[ 1 ] == '-' && rtl_ustr_ascii_compare(
+ arg.pData->buffer + 2, option_info->m_name ) == 0)
+ {
+ ++(*pIndex);
+ dp_misc::TRACE(OUSTR( __FILE__": identified option \'")
+ + OUString::createFromAscii(option_info->m_name) + OUSTR("\'\n"));
+ return true;
+ }
+ return false;
+}
+//==============================================================================
+
+bool isBootstrapVariable(sal_uInt32 * pIndex)
+{
+ OSL_ASSERT(osl_getCommandArgCount() >= *pIndex);
+
+ OUString arg;
+ osl_getCommandArg(*pIndex, &arg.pData);
+ if (arg.matchAsciiL("-env:", 5))
+ {
+ ++(*pIndex);
+ return true;
+ }
+ return false;
+}
+
+//==============================================================================
+bool readArgument(
+ OUString * pValue, OptionInfo const * option_info, sal_uInt32 * pIndex )
+{
+ if (isOption( option_info, pIndex ))
+ {
+ if (*pIndex < osl_getCommandArgCount())
+ {
+ OSL_ASSERT( pValue != 0 );
+ osl_getCommandArg( *pIndex, &pValue->pData );
+ dp_misc::TRACE(OUSTR( __FILE__": argument value: ")
+ + *pValue + OUSTR("\n"));
+ ++(*pIndex);
+ return true;
+ }
+ --(*pIndex);
+ }
+ return false;
+}
+
+
+namespace {
+struct ExecutableDir : public rtl::StaticWithInit<
+ const OUString, ExecutableDir> {
+ const OUString operator () () {
+ OUString path;
+ if (osl_getExecutableFile( &path.pData ) != osl_Process_E_None) {
+ throw RuntimeException(
+ OUSTR("cannot locate executable directory!"),0 );
+ }
+ return path.copy( 0, path.lastIndexOf( '/' ) );
+ }
+};
+struct ProcessWorkingDir : public rtl::StaticWithInit<
+ const OUString, ProcessWorkingDir> {
+ const OUString operator () () {
+ OUString workingDir;
+ tools::getProcessWorkingDir(workingDir);
+ return workingDir;
+ }
+};
+} // anon namespace
+
+//==============================================================================
+OUString const & getExecutableDir()
+{
+ return ExecutableDir::get();
+}
+
+//==============================================================================
+OUString const & getProcessWorkingDir()
+{
+ return ProcessWorkingDir::get();
+}
+
+//==============================================================================
+OUString makeAbsoluteFileUrl(
+ OUString const & sys_path, OUString const & base_url, bool throw_exc )
+{
+ // system path to file url
+ OUString file_url;
+ oslFileError rc = osl_getFileURLFromSystemPath( sys_path.pData, &file_url.pData );
+ if ( rc != osl_File_E_None) {
+ OUString tempPath;
+ if ( osl_getSystemPathFromFileURL( sys_path.pData, &tempPath.pData) == osl_File_E_None )
+ {
+ file_url = sys_path;
+ }
+ else if (throw_exc)
+ {
+ throw RuntimeException(
+ OUSTR("cannot get file url from system path: ") +
+ sys_path, Reference< XInterface >() );
+ }
+ }
+
+ OUString abs;
+ if (osl_getAbsoluteFileURL(
+ base_url.pData, file_url.pData, &abs.pData ) != osl_File_E_None)
+ {
+ if (throw_exc) {
+ ::rtl::OUStringBuffer buf;
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
+ "making absolute file url failed: \"") );
+ buf.append( base_url );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
+ "\" (base-url) and \"") );
+ buf.append( file_url );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\" (file-url)!") );
+ throw RuntimeException(
+ buf.makeStringAndClear(), Reference< XInterface >() );
+ }
+ return OUString();
+ }
+ return abs[ abs.getLength() -1 ] == '/'
+ ? abs.copy( 0, abs.getLength() -1 ) : abs;
+}
+
+
+namespace {
+
+//------------------------------------------------------------------------------
+inline void printf_space( sal_Int32 space )
+{
+ while (space--)
+ dp_misc::writeConsole(" ");
+}
+
+//------------------------------------------------------------------------------
+void printf_line(
+ OUString const & name, OUString const & value, sal_Int32 level )
+{
+ printf_space( level );
+ dp_misc::writeConsole(name + OUSTR(": ") + value + OUSTR("\n"));
+}
+
+//------------------------------------------------------------------------------
+void printf_package(
+ Reference<deployment::XPackage> const & xPackage,
+ Reference<XCommandEnvironment> const & xCmdEnv, sal_Int32 level )
+{
+ beans::Optional< OUString > id(
+ level == 0
+ ? beans::Optional< OUString >(
+ true, dp_misc::getIdentifier( xPackage ) )
+ : xPackage->getIdentifier() );
+ if (id.IsPresent)
+ printf_line( OUSTR("Identifier"), id.Value, level );
+ OUString version(xPackage->getVersion());
+ if (version.getLength() != 0)
+ printf_line( OUSTR("Version"), version, level + 1 );
+ printf_line( OUSTR("URL"), xPackage->getURL(), level + 1 );
+
+ beans::Optional< beans::Ambiguous<sal_Bool> > option(
+ xPackage->isRegistered( Reference<task::XAbortChannel>(), xCmdEnv ) );
+ OUString value;
+ if (option.IsPresent) {
+ beans::Ambiguous<sal_Bool> const & reg = option.Value;
+ if (reg.IsAmbiguous)
+ value = OUSTR("unknown");
+ else
+ value = reg.Value ? OUSTR("yes") : OUSTR("no");
+ }
+ else
+ value = OUSTR("n/a");
+ printf_line( OUSTR("is registered"), value, level + 1 );
+
+ const Reference<deployment::XPackageTypeInfo> xPackageType(
+ xPackage->getPackageType() );
+ OSL_ASSERT( xPackageType.is() );
+ if (xPackageType.is()) {
+ printf_line( OUSTR("Media-Type"),
+ xPackageType->getMediaType(), level + 1 );
+ }
+ printf_line( OUSTR("Description"), xPackage->getDescription(), level + 1 );
+ if (xPackage->isBundle()) {
+ Sequence< Reference<deployment::XPackage> > seq(
+ xPackage->getBundle( Reference<task::XAbortChannel>(), xCmdEnv ) );
+ printf_space( level + 1 );
+ dp_misc::writeConsole("bundled Packages: {\n");
+ ::std::vector<Reference<deployment::XPackage> >vec_bundle;
+ ::comphelper::sequenceToContainer(vec_bundle, seq);
+ printf_packages( vec_bundle, ::std::vector<bool>(vec_bundle.size()),
+ xCmdEnv, level + 2 );
+ printf_space( level + 1 );
+ dp_misc::writeConsole("}\n");
+ }
+}
+
+} // anon namespace
+
+void printf_unaccepted_licenses(
+ Reference<deployment::XPackage> const & ext)
+{
+ OUString id(
+ dp_misc::getIdentifier(ext) );
+ printf_line( OUSTR("Identifier"), id, 0 );
+ printf_space(1);
+ dp_misc::writeConsole(OUSTR("License not accepted\n\n"));
+}
+
+//==============================================================================
+void printf_packages(
+ ::std::vector< Reference<deployment::XPackage> > const & allExtensions,
+ ::std::vector<bool> const & vecUnaccepted,
+ Reference<XCommandEnvironment> const & xCmdEnv, sal_Int32 level )
+{
+ OSL_ASSERT(allExtensions.size() == vecUnaccepted.size());
+
+ if (allExtensions.size() == 0)
+ {
+ printf_space( level );
+ dp_misc::writeConsole("<none>\n");
+ }
+ else
+ {
+ typedef ::std::vector< Reference<deployment::XPackage> >::const_iterator I_EXT;
+ int index = 0;
+ for (I_EXT i = allExtensions.begin(); i != allExtensions.end(); i++, index++)
+ {
+ if (vecUnaccepted[index])
+ printf_unaccepted_licenses(*i);
+ else
+ printf_package( *i, xCmdEnv, level );
+ dp_misc::writeConsole(OUSTR("\n"));
+ }
+ }
+}
+
+
+
+namespace {
+
+//------------------------------------------------------------------------------
+Reference<XComponentContext> bootstrapStandAlone(
+ DisposeGuard & disposeGuard, bool /*verbose */)
+{
+ Reference<XComponentContext> xContext =
+ ::cppu::defaultBootstrap_InitialComponentContext();
+
+ // assure disposing of local component context:
+ disposeGuard.reset(
+ Reference<lang::XComponent>( xContext, UNO_QUERY ) );
+
+ Reference<lang::XMultiServiceFactory> xServiceManager(
+ xContext->getServiceManager(), UNO_QUERY_THROW );
+ // set global process service factory used by unotools config helpers
+ ::utl::setProcessServiceFactory( xServiceManager );
+
+ // initialize the ucbhelper ucb,
+ // because the package implementation uses it
+ Sequence<Any> ucb_args( 2 );
+ ucb_args[ 0 ] <<= OUSTR(UCB_CONFIGURATION_KEY1_LOCAL);
+ ucb_args[ 1 ] <<= OUSTR(UCB_CONFIGURATION_KEY2_OFFICE);
+ if (! ::ucbhelper::ContentBroker::initialize( xServiceManager, ucb_args ))
+ throw RuntimeException( OUSTR("cannot initialize UCB!"), 0 );
+
+ disposeGuard.setDeinitUCB();
+ return xContext;
+}
+
+//------------------------------------------------------------------------------
+Reference<XComponentContext> connectToOffice(
+ Reference<XComponentContext> const & xLocalComponentContext,
+ bool verbose )
+{
+ Sequence<OUString> args( 3 );
+ args[ 0 ] = OUSTR("-nologo");
+ args[ 1 ] = OUSTR("-nodefault");
+
+ OUString pipeId( ::dp_misc::generateRandomPipeId() );
+ ::rtl::OUStringBuffer buf;
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("-accept=pipe,name=") );
+ buf.append( pipeId );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(";urp;") );
+ args[ 2 ] = buf.makeStringAndClear();
+ OUString appURL( getExecutableDir() + OUSTR("/soffice") );
+
+ if (verbose)
+ {
+ dp_misc::writeConsole(
+ OUSTR("Raising process: ") +
+ appURL +
+ OUSTR("\nArguments: -nologo -nodefault ") +
+ args[2] +
+ OUSTR("\n"));
+ }
+
+ ::dp_misc::raiseProcess( appURL, args );
+
+ if (verbose)
+ dp_misc::writeConsole("Ok. Connecting...");
+
+ OSL_ASSERT( buf.getLength() == 0 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("uno:pipe,name=") );
+ buf.append( pipeId );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
+ ";urp;StarOffice.ComponentContext") );
+ Reference<XComponentContext> xRet(
+ ::dp_misc::resolveUnoURL(
+ buf.makeStringAndClear(), xLocalComponentContext ),
+ UNO_QUERY_THROW );
+ if (verbose)
+ dp_misc::writeConsole("Ok.\n");
+
+ return xRet;
+}
+
+} // anon namespace
+
+/** returns the path to the lock file used by unopkg.
+ @return the path. An empty string signifies an error.
+*/
+OUString getLockFilePath()
+{
+ OUString ret;
+ OUString sBootstrap(RTL_CONSTASCII_USTRINGPARAM("${$BRAND_BASE_DIR/program/" SAL_CONFIGFILE("bootstrap") ":UserInstallation}"));
+ rtl::Bootstrap::expandMacros(sBootstrap);
+ OUString sAbs;
+ if (::osl::File::E_None == ::osl::File::getAbsoluteFileURL(
+ sBootstrap, OUSTR(".lock"), sAbs))
+ {
+ if (::osl::File::E_None ==
+ ::osl::File::getSystemPathFromFileURL(sAbs, sBootstrap))
+ {
+ ret = sBootstrap;
+ }
+ }
+
+ return ret;
+}
+//==============================================================================
+Reference<XComponentContext> getUNO(
+ DisposeGuard & disposeGuard, bool verbose, bool shared, bool bGui,
+ Reference<XComponentContext> & out_localContext)
+{
+ // do not create any user data (for the root user) in --shared mode:
+ if (shared) {
+ rtl::Bootstrap::set(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CFG_CacheUrl")),
+ rtl::OUString());
+ }
+
+ // hold lock during process runtime:
+ static ::desktop::Lockfile s_lockfile( false /* no IPC server */ );
+ Reference<XComponentContext> xComponentContext(
+ bootstrapStandAlone( disposeGuard, verbose ) );
+ out_localContext = xComponentContext;
+ if (::dp_misc::office_is_running()) {
+ xComponentContext.set(
+ connectToOffice( xComponentContext, verbose ) );
+ }
+ else
+ {
+ if (! s_lockfile.check( 0 ))
+ {
+ String sMsg(ResId(RID_STR_CONCURRENTINSTANCE, *DeploymentResMgr::get()));
+ //Create this string before we call DeInitVCL, because this will kill
+ //the ResMgr
+ String sError(ResId(RID_STR_UNOPKG_ERROR, *DeploymentResMgr::get()));
+
+ sMsg = sMsg + OUSTR("\n") + getLockFilePath();
+
+ if (bGui)
+ {
+ //We show a message box or print to the console that there
+ //is another instance already running
+ if ( ! InitVCL( Reference<lang::XMultiServiceFactory>(
+ xComponentContext->getServiceManager(),
+ UNO_QUERY_THROW ) ))
+ throw RuntimeException( OUSTR("Cannot initialize VCL!"),
+ NULL );
+ {
+ WarningBox warn(NULL, WB_OK | WB_DEF_OK, sMsg);
+ warn.SetText(::utl::ConfigManager::GetDirectConfigProperty(
+ ::utl::ConfigManager::PRODUCTNAME).get<OUString>());
+ warn.SetIcon(0);
+ warn.Execute();
+ }
+ DeInitVCL();
+ }
+
+ throw LockFileException(
+ OUSTR("\n") + sError + sMsg + OUSTR("\n"));
+ }
+ }
+
+ return xComponentContext;
+}
+
+//Determines if a folder does not contains a folder.
+//Return false may also mean that the status could not be determined
+//because some error occurred.
+bool hasNoFolder(OUString const & folderUrl)
+{
+ bool ret = false;
+ OUString url = folderUrl;
+ ::rtl::Bootstrap::expandMacros(url);
+ ::osl::Directory dir(url);
+ osl::File::RC rc = dir.open();
+ if (rc == osl::File::E_None)
+ {
+ bool bFolderExist = false;
+ osl::DirectoryItem i;
+ osl::File::RC rcNext = osl::File::E_None;
+ while ( (rcNext = dir.getNextItem(i)) == osl::File::E_None)
+ {
+ osl::FileStatus stat(FileStatusMask_Type);
+ if (i.getFileStatus(stat) == osl::File::E_None)
+ {
+ if (stat.getFileType() == osl::FileStatus::Directory)
+ {
+ bFolderExist = true;
+ break;
+ }
+ }
+ else
+ {
+ dp_misc::writeConsole(
+ OUSTR("unopkg: Error while investigating ") + url + OUSTR("\n"));
+ break;
+ }
+ i = osl::DirectoryItem();
+ }
+
+ if (rcNext == osl::File::E_NOENT ||
+ rcNext == osl::File::E_None)
+ {
+ if (!bFolderExist)
+ ret = true;
+ }
+ else
+ {
+ dp_misc::writeConsole(
+ OUSTR("unopkg: Error while investigating ") + url + OUSTR("\n"));
+ }
+
+ dir.close();
+ }
+ else
+ {
+ dp_misc::writeConsole(
+ OUSTR("unopkg: Error while investigating ") + url + OUSTR("\n"));
+ }
+ return ret;
+}
+
+void removeFolder(OUString const & folderUrl)
+{
+ OUString url = folderUrl;
+ ::rtl::Bootstrap::expandMacros(url);
+ ::osl::Directory dir(url);
+ ::osl::File::RC rc = dir.open();
+ if (rc == osl::File::E_None)
+ {
+ ::osl::DirectoryItem i;
+ ::osl::File::RC rcNext = ::osl::File::E_None;
+ while ( (rcNext = dir.getNextItem(i)) == ::osl::File::E_None)
+ {
+ ::osl::FileStatus stat(FileStatusMask_Type | FileStatusMask_FileURL);
+ if (i.getFileStatus(stat) == ::osl::File::E_None)
+ {
+ ::osl::FileStatus::Type t = stat.getFileType();
+ if (t == ::osl::FileStatus::Directory)
+ {
+ //remove folder
+ removeFolder(stat.getFileURL());
+ }
+ else if (t == ::osl::FileStatus::Regular)
+ {
+ //remove file
+ ::osl::File::remove(stat.getFileURL());
+ }
+ else
+ {
+ OSL_ASSERT(0);
+ }
+ }
+ else
+ {
+ dp_misc::writeConsole(
+ OUSTR("unopkg: Error while investigating ") + url + OUSTR("\n"));
+ break;
+ }
+ i = ::osl::DirectoryItem();
+ }
+ dir.close();
+ ::osl::Directory::remove(url);
+ }
+ else if (rc != osl::File::E_NOENT)
+ {
+ dp_misc::writeConsole(
+ OUSTR("unopkg: Error while removing ") + url + OUSTR("\n"));
+ }
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/pkgchk/unopkg/unopkg_shared.h b/desktop/source/pkgchk/unopkg/unopkg_shared.h
new file mode 100755
index 000000000000..eddb5b3e0f09
--- /dev/null
+++ b/desktop/source/pkgchk/unopkg/unopkg_shared.h
@@ -0,0 +1,197 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "dp_misc.h"
+#include "com/sun/star/uno/Exception.hpp"
+#include "com/sun/star/lang/XComponent.hpp"
+#include "com/sun/star/uno/XComponentContext.hpp"
+#include "com/sun/star/ucb/XCommandEnvironment.hpp"
+#include "com/sun/star/deployment/XPackage.hpp"
+#include "tools/resmgr.hxx"
+#include "rtl/ustring.hxx"
+#include "unotools/configmgr.hxx"
+#include "ucbhelper/contentbroker.hxx"
+
+
+#define APP_NAME "unopkg"
+
+namespace css = ::com::sun::star;
+
+namespace unopkg {
+
+ inline ::com::sun::star::lang::Locale toLocale( ::rtl::OUString const & slang )
+ {
+ ::com::sun::star::lang::Locale locale;
+ sal_Int32 nIndex = 0;
+ locale.Language = slang.getToken( 0, '-', nIndex );
+ locale.Country = slang.getToken( 0, '-', nIndex );
+ locale.Variant = slang.getToken( 0, '-', nIndex );
+ return locale;
+ }
+
+
+ struct OfficeLocale :
+ public rtl::StaticWithInit<const css::lang::Locale, OfficeLocale> {
+ const css::lang::Locale operator () () {
+ ::rtl::OUString slang;
+ if (! (::utl::ConfigManager::GetDirectConfigProperty(
+ ::utl::ConfigManager::LOCALE ) >>= slang))
+ throw css::uno::RuntimeException( OUSTR("Cannot determine language!"), 0 );
+ if (slang.getLength() == 0)
+ slang = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("en-US"));
+ return toLocale(slang);
+ }
+};
+
+struct DeploymentResMgr : public rtl::StaticWithInit< ResMgr *, DeploymentResMgr >
+{
+ ResMgr * operator () () {
+ return ResMgr::CreateResMgr( "deployment", OfficeLocale::get());
+ }
+};
+
+struct OptionInfo
+{
+ char const * m_name;
+ sal_uInt32 m_name_length;
+ sal_Unicode m_short_option;
+ bool m_has_argument;
+};
+
+struct LockFileException : public css::uno::Exception
+{
+ LockFileException(::rtl::OUString const & sMessage) :
+ css::uno::Exception(sMessage, css::uno::Reference< css::uno::XInterface > ()) {}
+};
+
+//==============================================================================
+::rtl::OUString toString( OptionInfo const * info );
+
+//==============================================================================
+OptionInfo const * getOptionInfo(
+ OptionInfo const * list,
+ ::rtl::OUString const & opt, sal_Unicode copt = '\0' );
+
+//==============================================================================
+bool isOption( OptionInfo const * option_info, sal_uInt32 * pIndex );
+
+//==============================================================================
+bool readArgument(
+ ::rtl::OUString * pValue, OptionInfo const * option_info,
+ sal_uInt32 * pIndex );
+
+//==============================================================================
+inline bool readOption(
+ bool * flag, OptionInfo const * option_info, sal_uInt32 * pIndex )
+{
+ if (isOption( option_info, pIndex )) {
+ OSL_ASSERT( flag != 0 );
+ *flag = true;
+ return true;
+ }
+ return false;
+}
+//==============================================================================
+
+/** checks if an argument is a bootstrap variable. These start with -env:. For example
+ -env:UNO_JAVA_JFW_USER_DATA=file:///d:/user
+*/
+bool isBootstrapVariable(sal_uInt32 * pIndex);
+//==============================================================================
+::rtl::OUString const & getExecutableDir();
+
+//==============================================================================
+::rtl::OUString const & getProcessWorkingDir();
+
+//==============================================================================
+::rtl::OUString makeAbsoluteFileUrl(
+ ::rtl::OUString const & sys_path, ::rtl::OUString const & base_url,
+ bool throw_exc = true );
+
+//##############################################################################
+
+//==============================================================================
+class DisposeGuard
+{
+ css::uno::Reference<css::lang::XComponent> m_xComp;
+ bool m_bDeinitUCB;
+public:
+ DisposeGuard(): m_bDeinitUCB(false) {}
+ inline ~DisposeGuard()
+ {
+ if (m_bDeinitUCB)
+ ::ucbhelper::ContentBroker::deinitialize();
+
+ if (m_xComp.is())
+ m_xComp->dispose();
+ }
+
+ inline void reset(
+ css::uno::Reference<css::lang::XComponent> const & xComp )
+ {
+ m_xComp = xComp;
+ }
+
+ inline void setDeinitUCB()
+ {
+ m_bDeinitUCB = true;
+ }
+
+};
+
+//==============================================================================
+css::uno::Reference<css::ucb::XCommandEnvironment> createCmdEnv(
+ css::uno::Reference<css::uno::XComponentContext> const & xContext,
+ ::rtl::OUString const & logFile,
+ bool option_force_overwrite,
+ bool option_verbose,
+ bool option_suppressLicense);
+//==============================================================================
+void printf_packages(
+ ::std::vector<
+ css::uno::Reference<css::deployment::XPackage> > const & allExtensions,
+ ::std::vector<bool> const & vecUnaccepted,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv,
+ sal_Int32 level = 0 );
+
+//##############################################################################
+
+//==============================================================================
+css::uno::Reference<css::uno::XComponentContext> getUNO(
+ DisposeGuard & disposeGuard, bool verbose, bool shared, bool bGui,
+ css::uno::Reference<css::uno::XComponentContext> & out_LocalComponentContext);
+
+bool hasNoFolder(::rtl::OUString const & folderUrl);
+
+void removeFolder(::rtl::OUString const & folderUrl);
+
+}
+
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/pkgchk/unopkg/version.map b/desktop/source/pkgchk/unopkg/version.map
new file mode 100755
index 000000000000..6d34cb662d2c
--- /dev/null
+++ b/desktop/source/pkgchk/unopkg/version.map
@@ -0,0 +1,34 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+UDK_3_0_0 {
+ global:
+ unopkg_main;
+
+ local:
+ *;
+};
diff --git a/desktop/source/registration/com/sun/star/registration/Registration.java b/desktop/source/registration/com/sun/star/registration/Registration.java
new file mode 100755
index 000000000000..4da6199c621c
--- /dev/null
+++ b/desktop/source/registration/com/sun/star/registration/Registration.java
@@ -0,0 +1,334 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+package com.sun.star.registration;
+
+import com.sun.star.beans.NamedValue;
+import com.sun.star.comp.loader.FactoryHelper;
+import com.sun.star.frame.DispatchResultEvent;
+import com.sun.star.frame.DispatchResultState;
+import com.sun.star.lang.XMultiServiceFactory;
+import com.sun.star.lang.XMultiComponentFactory;
+import com.sun.star.lang.XSingleServiceFactory;
+import com.sun.star.registry.*;
+import com.sun.star.servicetag.*;
+import com.sun.star.system.*;
+import com.sun.star.task.*;
+import com.sun.star.uno.*;
+import com.sun.star.uri.XExternalUriReferenceTranslator;
+import com.sun.star.util.XStringSubstitution;
+
+import java.io.*;
+import java.net.URI;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.Locale;
+import java.util.Set;
+import java.net.HttpURLConnection;
+
+public class Registration {
+
+ public static XSingleServiceFactory __getServiceFactory(String implName,
+ XMultiServiceFactory multiFactory, XRegistryKey regKey) {
+ XSingleServiceFactory xSingleServiceFactory = null;
+
+ if (implName.equals(Registration.class.getName())) {
+ xSingleServiceFactory = FactoryHelper.getServiceFactory(_Registration.class, _serviceName, multiFactory, regKey);
+ }
+
+ return xSingleServiceFactory;
+ }
+
+ static final String _serviceName = "com.sun.star.comp.framework.DoRegistrationJob";
+
+ static public class _Registration implements XJob {
+ XComponentContext xComponentContext;
+
+ XStringSubstitution xPathSubstService = null;
+ XExternalUriReferenceTranslator xUriTranslator = null;
+
+ RegistrationData theRegistrationData = null;
+
+ public _Registration(XComponentContext xComponentContext) {
+ this.xComponentContext = xComponentContext;
+ }
+
+ private String resolvePath(String path) {
+ try {
+ if( xPathSubstService == null || xUriTranslator == null ) {
+ XMultiComponentFactory theServiceManager = xComponentContext.getServiceManager();
+ if( xPathSubstService == null ) {
+ Object o = theServiceManager.createInstanceWithContext(
+ "com.sun.star.util.PathSubstitution",
+ xComponentContext );
+ xPathSubstService = (XStringSubstitution)
+ UnoRuntime.queryInterface(XStringSubstitution.class, o);
+ }
+
+ if( xUriTranslator == null ) {
+ Object o = theServiceManager.createInstanceWithContext(
+ "com.sun.star.uri.ExternalUriReferenceTranslator",
+ xComponentContext );
+ xUriTranslator = (XExternalUriReferenceTranslator)
+ UnoRuntime.queryInterface(XExternalUriReferenceTranslator.class, o);
+ }
+ }
+
+ String s = xPathSubstService.substituteVariables(path, true);
+ return xUriTranslator.translateToExternal(s);
+ } catch (java.lang.Exception e) {
+ return path;
+ }
+ }
+
+ private void openBrowser(String url) {
+ try {
+ XMultiComponentFactory theServiceManager = xComponentContext.getServiceManager();
+
+ Object o = theServiceManager.createInstanceWithContext(
+ "com.sun.star.system.SystemShellExecute",
+ xComponentContext );
+
+ XSystemShellExecute xShellExecuteService = (XSystemShellExecute)
+ UnoRuntime.queryInterface(XSystemShellExecute.class, o);
+
+ xShellExecuteService.execute( url, "", SystemShellExecuteFlags.DEFAULTS );
+ } catch (java.lang.Exception e) {
+ }
+ }
+
+ private ServiceTag getServiceTagFromRegistrationData(File xmlFile, String productURN) {
+ try {
+ RegistrationData storedRegData = RegistrationData.loadFromXML(new FileInputStream(xmlFile));
+ Set<ServiceTag> storedServiceTags = storedRegData.getServiceTags();
+
+ Iterator<ServiceTag> tagIterator = storedServiceTags.iterator();
+ while( tagIterator.hasNext() ) {
+ ServiceTag tag = tagIterator.next();
+ if( tag.getProductURN().equals(productURN) ) {
+ theRegistrationData = storedRegData;
+ return tag;
+ }
+ }
+
+ // product URN has changed, remove registration data file
+ xmlFile.delete();
+ } catch (IOException e) {
+ // fall through intentionally
+ } catch (IllegalArgumentException e) {
+ // file is damaged (or a name clash appeared)
+ xmlFile.delete();
+ }
+ return null;
+ }
+
+ /*
+ * XJob
+ *
+ * NOTE: as this Job hets triggered by the the JobExecutor service from first start
+ * wizard and registration reminder code (because their frames do not implement
+ * XDispatchProvider), making this an XAsyncJob doesn't make sense as the
+ * JobExecutor waits for the jobFinished call on the listener passed.
+ */
+ public Object execute(NamedValue[] args)
+ throws com.sun.star.lang.IllegalArgumentException, com.sun.star.uno.Exception {
+
+ final NamedValue[] f_args = args;
+
+ new Thread(
+ new Runnable () {
+ public void run() {
+ try {
+ executeImpl(f_args);
+ } catch(com.sun.star.uno.Exception e) {
+ }
+ }
+ }
+ ).start();
+
+ NamedValue ret[] = new NamedValue[1];
+ ret[0] = new NamedValue( "Deactivate", new Boolean(false) );
+ return ret;
+ }
+
+ public synchronized void executeImpl(NamedValue[] args)
+ throws com.sun.star.lang.IllegalArgumentException, com.sun.star.uno.Exception {
+
+ // extract the interesting part of the argument list
+ NamedValue[] theJobConfig = null;
+ NamedValue[] theEnvironment = null;
+
+ int c = args.length;
+ for (int i=0; i<c; ++i) {
+ if (args[i].Name.equals("JobConfig"))
+ theJobConfig = (NamedValue[]) AnyConverter.toArray(args[i].Value);
+ else if (args[i].Name.equals("Environment"))
+ theEnvironment = (NamedValue[]) AnyConverter.toArray(args[i].Value);
+ }
+
+ if (theEnvironment==null)
+ throw new com.sun.star.lang.IllegalArgumentException("no environment");
+
+ boolean saveConfig = false;
+
+ String productName = "";
+ String productVersion = "";
+ String productURN = "";
+ String productParent = "";
+ String productParentURN = "";
+ String productDefinedInstanceID = "";
+ String productSource = "";
+ String vendor = "";
+
+ String urlRegData = null;
+ String registrationURL = null;
+
+ c = theJobConfig.length;
+ for (int i=0; i<c; ++i) {
+ if( theJobConfig[i].Name.equals("ProductName") ) {
+ productName = AnyConverter.toString(theJobConfig[i].Value);
+ } else if( theJobConfig[i].Name.equals("ProductVersion") ) {
+ productVersion = AnyConverter.toString(theJobConfig[i].Value);
+ } else if( theJobConfig[i].Name.equals("ProductURN") ) {
+ productURN = AnyConverter.toString(theJobConfig[i].Value);
+ } else if( theJobConfig[i].Name.equals("ProductParent") ) {
+ productParent = AnyConverter.toString(theJobConfig[i].Value);
+ } else if( theJobConfig[i].Name.equals("ProductParentURN") ) {
+ productParentURN = AnyConverter.toString(theJobConfig[i].Value);
+ } else if( theJobConfig[i].Name.equals("ProductSource") ) {
+ productSource = AnyConverter.toString(theJobConfig[i].Value);
+ } else if( theJobConfig[i].Name.equals("Vendor") ) {
+ vendor = AnyConverter.toString(theJobConfig[i].Value);
+ } else if( theJobConfig[i].Name.equals("RegistrationData") ) {
+ urlRegData = resolvePath(AnyConverter.toString(theJobConfig[i].Value));
+ } else if( theJobConfig[i].Name.equals("RegistrationURL") ) {
+ registrationURL = AnyConverter.toString(theJobConfig[i].Value);
+ } else {
+ System.err.println( theJobConfig[i].Name + " = " + AnyConverter.toString(theJobConfig[i].Value) );
+ }
+ }
+
+ if (registrationURL==null)
+ throw new com.sun.star.lang.IllegalArgumentException("no registration url");
+
+ boolean local_only = false;
+
+ c = theEnvironment.length;
+ for (int i=0; i<c; ++i) {
+ if( theEnvironment[i].Name.equals("EventName") ) {
+ if( ! AnyConverter.toString(theEnvironment[i].Value).equals("onRegisterNow") ) {
+ local_only = true;
+ }
+ }
+ }
+
+ try {
+
+ /* ensure only one thread accesses/writes registration.xml at a time
+ * regardless how many instances of this Job exist.
+ */
+ synchronized( _serviceName ) {
+
+ File xmlRegData = new File( new URI( urlRegData ) );
+
+ ServiceTag tag = getServiceTagFromRegistrationData(xmlRegData, productURN);
+ if( tag == null ) {
+ tag = ServiceTag.newInstance(
+ ServiceTag.generateInstanceURN(),
+ productName,
+ productVersion,
+ productURN,
+ productParent,
+ productParentURN,
+ productDefinedInstanceID,
+ vendor,
+ System.getProperty("os.arch"),
+ Installer.getZoneName(),
+ productSource);
+
+ theRegistrationData = new RegistrationData();
+ theRegistrationData.addServiceTag(tag);
+ theRegistrationData.storeToXML( new FileOutputStream( xmlRegData ) );
+ }
+
+ // Store the service tag in local registry, which might have been installed later
+ if( Registry.isSupported() ) {
+ // ignore communication failures with local service tag client
+ try {
+ if( Registry.getSystemRegistry().getServiceTag(tag.getInstanceURN()) == null ) {
+ Registry.getSystemRegistry().addServiceTag(tag);
+ }
+ } catch( java.io.IOException e) {
+ e.printStackTrace();
+ } catch (java.lang.RuntimeException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ if( ! local_only ) {
+ registrationURL = registrationURL.replaceAll("\\$\\{registry_urn\\}", theRegistrationData.getRegistrationURN());
+ registrationURL = registrationURL.replaceAll("\\$\\{locale\\}", Locale.getDefault().getLanguage());
+
+ HttpURLConnection con = (HttpURLConnection) new URL(registrationURL).openConnection();
+ con.setDoInput(true);
+ con.setDoOutput(true);
+ con.setUseCaches(false);
+ con.setAllowUserInteraction(false);
+ con.setRequestMethod("POST");
+
+ con.setRequestProperty("Content-Type", "text/xml;charset=\"utf-8\"");
+ try {
+ con.connect();
+
+ OutputStream out = con.getOutputStream();
+ theRegistrationData.storeToXML(out);
+ out.flush();
+ out.close();
+
+ int returnCode = con.getResponseCode();
+ } catch(java.lang.Exception e) {
+ // IOException and UnknownHostException
+ }
+ openBrowser(registrationURL);
+ }
+ } catch (java.net.MalformedURLException e) {
+ e.printStackTrace();
+ throw new com.sun.star.lang.IllegalArgumentException( e.toString() );
+ } catch (java.net.URISyntaxException e) {
+ e.printStackTrace();
+ throw new com.sun.star.lang.IllegalArgumentException( e.toString() );
+ } catch (java.io.IOException e) {
+ e.printStackTrace();
+ throw new com.sun.star.uno.RuntimeException( e.toString() );
+ } catch (java.lang.RuntimeException e) {
+ e.printStackTrace();
+ throw new com.sun.star.uno.RuntimeException( e.toString() );
+ }
+ }
+ }
+}
diff --git a/desktop/source/registration/com/sun/star/registration/makefile.mk b/desktop/source/registration/com/sun/star/registration/makefile.mk
new file mode 100755
index 000000000000..859802256256
--- /dev/null
+++ b/desktop/source/registration/com/sun/star/registration/makefile.mk
@@ -0,0 +1,62 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJNAME = setup_native
+PRJ = ..$/..$/..$/..$/..$/..
+TARGET = productregistration
+PACKAGE = com$/sun$/star$/registration
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+.IF "$(ENABLE_SVCTAGS)" == "YES"
+
+JARFILES = jurt.jar unoil.jar ridl.jar
+JAVAFILES = \
+ Registration.java
+
+JAVACLASSFILES= $(foreach,i,$(JAVAFILES) $(CLASSDIR)$/$(PACKAGE)$/$(i:b).class)
+
+JARTARGET = $(TARGET).jar
+JARCOMPRESS = TRUE
+JARCLASSDIRS = $(PACKAGE) com$/sun$/star$/servicetag
+CUSTOMMANIFESTFILE = manifest
+.ENDIF # "$(ENABLE_SVCTAGS)" == "YES"
+
+# --- Targets ------------------------------------------------------
+
+
+.INCLUDE : target.mk
+
+ALLTAR : $(MISC)/productregistration.jar.component
+
+$(MISC)/productregistration.jar.component .ERRREMOVE : \
+ $(SOLARENV)/bin/createcomponent.xslt productregistration.jar.component
+ $(XSLTPROC) --nonet --stringparam uri \
+ '$(COMPONENTPREFIX_BASIS_JAVA)productregistration.jar' -o $@ \
+ $(SOLARENV)/bin/createcomponent.xslt productregistration.jar.component
diff --git a/desktop/source/registration/com/sun/star/registration/manifest b/desktop/source/registration/com/sun/star/registration/manifest
new file mode 100755
index 000000000000..952aaa804e96
--- /dev/null
+++ b/desktop/source/registration/com/sun/star/registration/manifest
@@ -0,0 +1,2 @@
+RegistrationClassName: com.sun.star.registration.Registration
+UNO-Type-Path:
diff --git a/desktop/source/registration/com/sun/star/registration/productregistration.jar.component b/desktop/source/registration/com/sun/star/registration/productregistration.jar.component
new file mode 100755
index 000000000000..c022a98ae010
--- /dev/null
+++ b/desktop/source/registration/com/sun/star/registration/productregistration.jar.component
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--**********************************************************************
+*
+* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+*
+* Copyright 2000, 2010 Oracle and/or its affiliates.
+*
+* OpenOffice.org - a multi-platform office productivity suite
+*
+* This file is part of OpenOffice.org.
+*
+* OpenOffice.org is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License version 3
+* only, as published by the Free Software Foundation.
+*
+* OpenOffice.org is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Lesser General Public License version 3 for more details
+* (a copy is included in the LICENSE file that accompanied this code).
+*
+* You should have received a copy of the GNU Lesser General Public License
+* version 3 along with OpenOffice.org. If not, see
+* <http://www.openoffice.org/license.html>
+* for a copy of the LGPLv3 License.
+*
+**********************************************************************-->
+
+<component loader="com.sun.star.loader.Java2"
+ xmlns="http://openoffice.org/2010/uno-components">
+ <implementation name="com.sun.star.registration.Registration">
+ <service name="com.sun.star.comp.framework.DoRegistrationJob"/>
+ </implementation>
+</component>
diff --git a/desktop/source/registration/com/sun/star/servicetag/BrowserSupport.java b/desktop/source/registration/com/sun/star/servicetag/BrowserSupport.java
new file mode 100755
index 000000000000..87d83d5339ac
--- /dev/null
+++ b/desktop/source/registration/com/sun/star/servicetag/BrowserSupport.java
@@ -0,0 +1,201 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+package com.sun.star.servicetag;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.InvocationTargetException;
+import java.io.IOException;
+import java.net.URI;
+
+/**
+ * BrowserSupport class.
+ *
+ * The implementation of the com.sun.servicetag API needs to be
+ * compiled with JDK 5 as well since the consumer of this API
+ * may require to support JDK 5 (e.g. NetBeans).
+ *
+ * The Desktop.browse() method can be backported in this class
+ * if needed. The current implementation only supports JDK 6.
+ */
+class BrowserSupport {
+ private static boolean isBrowseSupported = false;
+ private static Method browseMethod = null;
+ private static Object desktop = null;
+ private static volatile Boolean result = false;
+
+
+ private static void initX() {
+ if (desktop != null) {
+ return;
+ }
+ boolean supported = false;
+ Method browseM = null;
+ Object desktopObj = null;
+ try {
+ // Determine if java.awt.Desktop is supported
+ Class desktopCls = Class.forName("java.awt.Desktop", true, null);
+ Method getDesktopM = desktopCls.getMethod("getDesktop");
+ browseM = desktopCls.getMethod("browse", URI.class);
+
+ Class actionCls = Class.forName("java.awt.Desktop$Action", true, null);
+ final Method isDesktopSupportedMethod = desktopCls.getMethod("isDesktopSupported");
+ Method isSupportedMethod = desktopCls.getMethod("isSupported", actionCls);
+ Field browseField = actionCls.getField("BROWSE");
+ // isDesktopSupported calls getDefaultToolkit which can block
+ // infinitely, see 6636099 for details, to workaround we call
+ // in a thread and time it out, noting that the issue is specific
+ // to X11, it does not hurt for Windows.
+ Thread xthread = new Thread() {
+ public void run() {
+ try {
+ // support only if Desktop.isDesktopSupported() and
+ // Desktop.isSupported(Desktop.Action.BROWSE) return true.
+ result = (Boolean) isDesktopSupportedMethod.invoke(null);
+ } catch (IllegalAccessException e) {
+ // should never reach here
+ InternalError x =
+ new InternalError("Desktop.getDesktop() method not found");
+ x.initCause(e);
+ } catch (InvocationTargetException e) {
+ // browser not supported
+ if (Util.isVerbose()) {
+ e.printStackTrace();
+ }
+ }
+ }
+ };
+ // set it to daemon, so that the vm will exit.
+ xthread.setDaemon(true);
+ xthread.start();
+ try {
+ xthread.join(5 * 1000);
+ } catch (InterruptedException ie) {
+ // ignore the exception
+ }
+ if (result.booleanValue()) {
+ desktopObj = getDesktopM.invoke(null);
+ result = (Boolean) isSupportedMethod.invoke(desktopObj, browseField.get(null));
+ supported = result.booleanValue();
+ }
+ } catch (ClassNotFoundException e) {
+ // browser not supported
+ if (Util.isVerbose()) {
+ e.printStackTrace();
+ }
+ } catch (NoSuchMethodException e) {
+ // browser not supported
+ if (Util.isVerbose()) {
+ e.printStackTrace();
+ }
+ } catch (NoSuchFieldException e) {
+ // browser not supported
+ if (Util.isVerbose()) {
+ e.printStackTrace();
+ }
+ } catch (IllegalAccessException e) {
+ // should never reach here
+ InternalError x =
+ new InternalError("Desktop.getDesktop() method not found");
+ x.initCause(e);
+ throw x;
+ } catch (InvocationTargetException e) {
+ // browser not supported
+ if (Util.isVerbose()) {
+ e.printStackTrace();
+ }
+ }
+ isBrowseSupported = supported;
+ browseMethod = browseM;
+ desktop = desktopObj;
+ }
+
+ static boolean isSupported() {
+ initX();
+ return isBrowseSupported;
+ }
+
+ /**
+ * Launches the default browser to display a {@code URI}.
+ * If the default browser is not able to handle the specified
+ * {@code URI}, the application registered for handling
+ * {@code URIs} of the specified type is invoked. The application
+ * is determined from the protocol and path of the {@code URI}, as
+ * defined by the {@code URI} class.
+ * <p>
+ * This method calls the Desktop.getDesktop().browse() method.
+ * <p>
+ * @param uri the URI to be displayed in the user default browser
+ *
+ * @throws NullPointerException if {@code uri} is {@code null}
+ * @throws UnsupportedOperationException if the current platform
+ * does not support the {@link Desktop.Action#BROWSE} action
+ * @throws IOException if the user default browser is not found,
+ * or it fails to be launched, or the default handler application
+ * failed to be launched
+ * @throws IllegalArgumentException if the necessary permissions
+ * are not available and the URI can not be converted to a {@code URL}
+ */
+ static void browse(URI uri) throws IOException {
+ if (uri == null) {
+ throw new NullPointerException("null uri");
+ }
+ if (!isSupported()) {
+ throw new UnsupportedOperationException("Browse operation is not supported");
+ }
+
+ // Call Desktop.browse() method
+ try {
+ if (Util.isVerbose()) {
+ System.out.println("desktop: " + desktop + ":browsing..." + uri);
+ }
+ browseMethod.invoke(desktop, uri);
+ } catch (IllegalAccessException e) {
+ // should never reach here
+ InternalError x =
+ new InternalError("Desktop.getDesktop() method not found");
+ x.initCause(e);
+ throw x;
+ } catch (InvocationTargetException e) {
+ Throwable x = e.getCause();
+ if (x != null) {
+ if (x instanceof UnsupportedOperationException) {
+ throw (UnsupportedOperationException) x;
+ } else if (x instanceof IllegalArgumentException) {
+ throw (IllegalArgumentException) x;
+ } else if (x instanceof IOException) {
+ throw (IOException) x;
+ } else if (x instanceof SecurityException) {
+ throw (SecurityException) x;
+ } else {
+ // ignore
+ }
+ }
+ }
+ }
+}
diff --git a/desktop/source/registration/com/sun/star/servicetag/Installer.java b/desktop/source/registration/com/sun/star/servicetag/Installer.java
new file mode 100755
index 000000000000..ba1b5c4b86d5
--- /dev/null
+++ b/desktop/source/registration/com/sun/star/servicetag/Installer.java
@@ -0,0 +1,943 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+package com.sun.star.servicetag;
+
+import java.io.*;
+import java.util.HashSet;
+import java.util.Locale;
+import java.util.Properties;
+import java.util.Set;
+import java.util.List;
+import java.util.ArrayList;
+import static com.sun.star.servicetag.Util.*;
+
+/**
+ * Service Tag Installer for Java SE.
+ */
+public class Installer {
+ // System properties for testing
+ private static String SVCTAG_DIR_PATH =
+ "servicetag.dir.path";
+ private static String SVCTAG_ENABLE_REGISTRATION =
+ "servicetag.registration.enabled";
+ private final static String SUN_VENDOR = "Sun Microsystems";
+ private final static String REGISTRATION_XML = "registration.xml";
+ private final static String SERVICE_TAG_FILE = "servicetag";
+ private final static String REGISTRATION_HTML_NAME = "register";
+
+ private final static Locale[] knownSupportedLocales =
+ new Locale[] { Locale.ENGLISH,
+ Locale.JAPANESE,
+ Locale.SIMPLIFIED_CHINESE};
+
+ private final static String javaHome = System.getProperty("java.home");
+ private static File svcTagDir;
+ private static File serviceTagFile;
+ private static File regXmlFile;
+ private static RegistrationData registration;
+ private static boolean supportRegistration;
+ private static String registerHtmlParent;
+ private static Set<Locale> supportedLocales = new HashSet<Locale>();
+ private static Properties swordfishProps = null;
+ private static String[] jreArchs = null;
+ static {
+ String dir = System.getProperty(SVCTAG_DIR_PATH);
+ if (dir == null) {
+ svcTagDir = new File(getJrePath(), "lib" + File.separator + SERVICE_TAG_FILE);
+ } else {
+ svcTagDir = new File(dir);
+ }
+ serviceTagFile = new File(svcTagDir, SERVICE_TAG_FILE);
+ regXmlFile = new File(svcTagDir, REGISTRATION_XML);
+ if (System.getProperty(SVCTAG_ENABLE_REGISTRATION) == null) {
+ supportRegistration = isJdk();
+ } else {
+ supportRegistration = true;
+ }
+ }
+
+ private Installer() {
+ }
+
+ // Implementation of ServiceTag.getJavaServiceTag(String) method
+ static ServiceTag getJavaServiceTag(String source) throws IOException {
+ if (!System.getProperty("java.vendor").startsWith(SUN_VENDOR)) {
+ // Products bundling this implementation may run on
+ // Mac OS which is not a Sun JDK
+ return null;
+ }
+ boolean cleanup = false;
+ try {
+ // Check if we have the swordfish entries for this JRE version
+ if (loadSwordfishEntries() == null) {
+ return null;
+ }
+
+ ServiceTag st = getJavaServiceTag();
+ // Check if the service tag created by this bundle owner
+ if (st != null && st.getSource().equals(source)) {
+ // Install the system service tag if supported
+ // stclient may be installed after the service tag creation
+ if (Registry.isSupported()) {
+ installSystemServiceTag();
+ }
+ return st;
+ }
+
+ // in case any exception thrown during the cleanup
+ cleanup = true;
+
+ // re-create a new one for this bundle owner
+ // first delete the registration data
+ deleteRegistrationData();
+ cleanup = false;
+
+ // create service tag and generate new register.html pages
+ return createServiceTag(source);
+ } finally {
+ if (cleanup) {
+ if (regXmlFile.exists()) {
+ regXmlFile.delete();
+ }
+ if (serviceTagFile.exists()) {
+ serviceTagFile.delete();
+ }
+ }
+ }
+ }
+
+ /**
+ * Returns the Java SE registration data located in
+ * the <JRE>/lib/servicetag/registration.xml by default.
+ *
+ * @throws IllegalArgumentException if the registration data
+ * is of invalid format.
+ */
+ private static synchronized RegistrationData getRegistrationData()
+ throws IOException {
+ if (registration != null) {
+ return registration;
+ }
+ if (regXmlFile.exists()) {
+ BufferedInputStream in = null;
+ try {
+ in = new BufferedInputStream(new FileInputStream(regXmlFile));
+ registration = RegistrationData.loadFromXML(in);
+ } catch (IllegalArgumentException ex) {
+ System.err.println("Error: Bad registration data \"" +
+ regXmlFile + "\":" + ex.getMessage());
+ throw ex;
+ } finally {
+ if (in != null) {
+ in.close();
+ }
+ }
+ } else {
+ registration = new RegistrationData();
+ }
+ return registration;
+ }
+
+ /**
+ * Write the registration data to the registration.xml file.
+ *
+ * The offline registration page has to be regenerated with
+ * the new registration data.
+ *
+ * @throws java.io.IOException
+ */
+ private static synchronized void writeRegistrationXml()
+ throws IOException {
+ if (!svcTagDir.exists()) {
+ // This check is for NetBeans or other products that
+ // bundles this com.sun.servicetag implementation for
+ // pre-6u5 release.
+ if (!svcTagDir.mkdir()) {
+ throw new IOException("Failed to create directory: " + svcTagDir);
+ }
+ }
+
+ // regenerate the new offline registration page
+ deleteRegistrationHtmlPage();
+ getRegistrationHtmlPage();
+
+ BufferedOutputStream out = null;
+ try {
+ out = new BufferedOutputStream(new FileOutputStream(regXmlFile));
+ getRegistrationData().storeToXML(out);
+ } catch (IllegalArgumentException ex) {
+ System.err.println("Error: Bad registration data \"" +
+ regXmlFile + "\":" + ex.getMessage());
+ throw ex;
+ } finally {
+ if (out != null) {
+ out.close();
+ }
+ }
+ }
+
+ /**
+ * Returns the instance urn(s) stored in the servicetag file
+ * or empty set if file not exists.
+ */
+ private static Set<String> getInstalledURNs() throws IOException {
+ Set<String> urnSet = new HashSet<String>();
+ if (serviceTagFile.exists()) {
+ BufferedReader in = null;
+ try {
+ in = new BufferedReader(new FileReader(serviceTagFile));
+ String urn;
+ while ((urn = in.readLine()) != null) {
+ urn = urn.trim();
+ if (urn.length() > 0) {
+ urnSet.add(urn);
+ }
+ }
+ } finally {
+ if (in != null) {
+ in.close();
+ }
+ }
+ }
+ return urnSet;
+ }
+
+ /**
+ * Return the Java SE service tag(s) if it exists.
+ * Typically only one Java SE service tag but it could have two for
+ * Solaris 32-bit and 64-bit on the same install directory.
+ *
+ * @return the service tag(s) for Java SE
+ */
+ private static ServiceTag[] getJavaServiceTagArray() throws IOException {
+ RegistrationData regData = getRegistrationData();
+ Set<ServiceTag> svcTags = regData.getServiceTags();
+ Set<ServiceTag> result = new HashSet<ServiceTag>();
+
+ Properties props = loadSwordfishEntries();
+ String jdkUrn = props.getProperty("servicetag.jdk.urn");
+ String jreUrn = props.getProperty("servicetag.jre.urn");
+ for (ServiceTag st : svcTags) {
+ if (st.getProductURN().equals(jdkUrn) ||
+ st.getProductURN().equals(jreUrn)) {
+ result.add(st);
+ }
+ }
+ return result.toArray(new ServiceTag[0]);
+ }
+
+ /**
+ * Returns the Java SE service tag for this running platform;
+ * or null if not exist.
+ * This method will return the 64-bit service tag if the JDK
+ * supports both 32-bit and 64-bit if already created.
+ */
+ private static ServiceTag getJavaServiceTag() throws IOException {
+ String definedId = getProductDefinedId();
+ for (ServiceTag st : getJavaServiceTagArray()) {
+ if (st.getProductDefinedInstanceID().equals(definedId)) {
+ return st;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Create a service tag for Java SE and install in the system
+ * service tag registry if supported.
+ *
+ * A registration data <JRE>/lib/servicetag/registration.xml
+ * will be created to storeToXML the XML entry for Java SE service tag.
+ * If the system supports service tags, this method will install
+ * the Java SE service tag in the system service tag registry and
+ * its <tt>instance_urn</tt> will be stored to <JRE>/lib/servicetag/servicetag.
+ *
+ * If <JRE>/lib/servicetag/registration.xml exists but is not installed
+ * in the system service tag registry (i.e. servicetag doesn't exist),
+ * this method will install it as described above.
+ *
+ * If the system supports service tag, stclient will be used
+ * to create the Java SE service tag.
+ *
+ * A Solaris 32-bit and 64-bit JDK will be installed in the same
+ * directory but the registration.xml will have 2 service tags.
+ * The servicetag file will also contain 2 instance_urns for that case.
+ */
+ private static ServiceTag createServiceTag(String svcTagSource)
+ throws IOException {
+ // determine if a new service tag is needed to be created
+ ServiceTag newSvcTag = null;
+ if (getJavaServiceTag() == null) {
+ newSvcTag = newServiceTag(svcTagSource);
+ }
+
+ // Add the new service tag in the registration data
+ if (newSvcTag != null) {
+ RegistrationData regData = getRegistrationData();
+
+ // Add the service tag to the registration data in JDK/JRE
+ newSvcTag = regData.addServiceTag(newSvcTag);
+
+ // add if there is a service tag for the OS
+ ServiceTag osTag = SolarisServiceTag.getServiceTag();
+ if (osTag != null && regData.getServiceTag(osTag.getInstanceURN()) == null) {
+ regData.addServiceTag(osTag);
+ }
+ // write to the registration.xml
+ writeRegistrationXml();
+ }
+
+ // Install the system service tag if supported
+ if (Registry.isSupported()) {
+ installSystemServiceTag();
+ }
+ return newSvcTag;
+ }
+
+ private static void installSystemServiceTag() throws IOException {
+ // only install the service tag in the registry if
+ // it has permission to write the servicetag file.
+ if ((!serviceTagFile.exists() && !svcTagDir.canWrite()) ||
+ (serviceTagFile.exists() && !serviceTagFile.canWrite())) {
+ return;
+ }
+
+ Set<String> urns = getInstalledURNs();
+ ServiceTag[] javaSvcTags = getJavaServiceTagArray();
+ if (urns.size() < javaSvcTags.length) {
+ for (ServiceTag st : javaSvcTags) {
+ // Add the service tag in the system service tag registry
+ // if not installed
+ String instanceURN = st.getInstanceURN();
+ if (!urns.contains(instanceURN)) {
+ Registry.getSystemRegistry().addServiceTag(st);
+ }
+ }
+ }
+ writeInstalledUrns();
+ }
+
+ private static ServiceTag newServiceTag(String svcTagSource) throws IOException {
+ // Load the swoRDFish information for the service tag creation
+ Properties props = loadSwordfishEntries();
+
+ // Determine the product URN and name
+ String productURN;
+ String productName;
+
+ if (isJdk()) {
+ // <HOME>/jre exists which implies it's a JDK
+ productURN = props.getProperty("servicetag.jdk.urn");
+ productName = props.getProperty("servicetag.jdk.name");
+ } else {
+ // Otherwise, it's a JRE
+ productURN = props.getProperty("servicetag.jre.urn");
+ productName = props.getProperty("servicetag.jre.name");
+ }
+
+ return ServiceTag.newInstance(ServiceTag.generateInstanceURN(),
+ productName,
+ System.getProperty("java.version"),
+ productURN,
+ props.getProperty("servicetag.parent.name"),
+ props.getProperty("servicetag.parent.urn"),
+ getProductDefinedId(),
+ SUN_VENDOR,
+ System.getProperty("os.arch"),
+ getZoneName(),
+ svcTagSource);
+ }
+
+ /**
+ * Delete the registration data, the offline registration pages and
+ * the service tags in the system service tag registry if installed.
+ *
+ * The registration.xml and servicetag file will be removed.
+ */
+ private static synchronized void deleteRegistrationData()
+ throws IOException {
+ try {
+ // delete the offline registration page
+ deleteRegistrationHtmlPage();
+
+ // Remove the service tag from the system ST registry if exists
+ Set<String> urns = getInstalledURNs();
+ if (urns.size() > 0 && Registry.isSupported()) {
+ for (String u : urns) {
+ Registry.getSystemRegistry().removeServiceTag(u);
+ }
+ }
+ registration = null;
+ } finally {
+ // Delete the registration.xml and servicetag files if exists
+ if (regXmlFile.exists()) {
+ if (!regXmlFile.delete()) {
+ throw new IOException("Failed to delete " + regXmlFile);
+ }
+ }
+ if (serviceTagFile.exists()) {
+ if (!serviceTagFile.delete()) {
+ throw new IOException("Failed to delete " + serviceTagFile);
+ }
+ }
+ }
+ }
+
+ /**
+ * Updates the registration data to contain one single service tag
+ * for the running Java runtime.
+ */
+ private static synchronized void updateRegistrationData(String svcTagSource)
+ throws IOException {
+ RegistrationData regData = getRegistrationData();
+ ServiceTag curSvcTag = newServiceTag(svcTagSource);
+
+ ServiceTag[] javaSvcTags = getJavaServiceTagArray();
+ Set<String> urns = getInstalledURNs();
+ for (ServiceTag st : javaSvcTags) {
+ if (!st.getProductDefinedInstanceID().equals(curSvcTag.getProductDefinedInstanceID())) {
+ String instanceURN = st.getInstanceURN();
+ regData.removeServiceTag(instanceURN);
+
+ // remove it from the system service tag registry if exists
+ if (urns.contains(instanceURN) && Registry.isSupported()) {
+ Registry.getSystemRegistry().removeServiceTag(instanceURN);
+ }
+ }
+ }
+ writeRegistrationXml();
+ writeInstalledUrns();
+ }
+
+ private static void writeInstalledUrns() throws IOException {
+ // if the Registry is not supported,
+ // remove the servicetag file
+ if (!Registry.isSupported() && serviceTagFile.exists()) {
+ serviceTagFile.delete();
+ return;
+ }
+
+ PrintWriter out = null;
+ try {
+ out = new PrintWriter(serviceTagFile);
+
+ ServiceTag[] javaSvcTags = getJavaServiceTagArray();
+ for (ServiceTag st : javaSvcTags) {
+ // Write the instance_run to the servicetag file
+ String instanceURN = st.getInstanceURN();
+ out.println(instanceURN);
+ }
+ } finally {
+ if (out != null) {
+ out.close();
+ }
+ }
+ }
+
+ /**
+ * Load the values associated with the swoRDFish metadata entries
+ * for Java SE. The swoRDFish metadata entries are different for
+ * different release.
+ *
+ * @param version Version of Java SE
+ */
+ private static synchronized Properties loadSwordfishEntries() throws IOException {
+ if (swordfishProps != null) {
+ return swordfishProps;
+ }
+
+ // The version string for Java SE 6 is 1.6.0
+ // We just need the minor number in the version string
+ int version = Util.getJdkVersion();
+
+ String filename = "/com/sun/servicetag/resources/javase_" +
+ version + "_swordfish.properties";
+ InputStream in = Installer.class.getClass().getResourceAsStream(filename);
+ if (in == null) {
+ return null;
+ }
+ swordfishProps = new Properties();
+ try {
+ swordfishProps.load(in);
+ } finally {
+ in.close();
+ }
+ return swordfishProps;
+ }
+
+ /**
+ * Returns the product defined instance ID for Java SE.
+ * It is a list of comma-separated name/value pairs:
+ * "id=<full-version> <arch> [<arch>]*"
+ * "dir=<java.home system property value>"
+ *
+ * where <full-version> is the full version string of the JRE,
+ * <arch> is the architecture that the runtime supports
+ * (i.e. "sparc", "sparcv9", "i386", "amd64" (ISA list))
+ *
+ * For Solaris, it can be dual mode that can support both
+ * 32-bit and 64-bit. the "id" will be set to
+ * "1.6.0_03-b02 sparc sparcv9"
+ *
+ * The "dir" property is included in the service tag to enable
+ * the Service Tag software to determine if a service tag for
+ * Java SE is invalid and perform appropriate service tag
+ * cleanup if necessary. See RFE# 6574781 Service Tags Enhancement.
+ *
+ */
+ private static String getProductDefinedId() {
+ StringBuilder definedId = new StringBuilder();
+ definedId.append("id=");
+ definedId.append(System.getProperty("java.runtime.version"));
+
+ String[] archs = getJreArchs();
+ for (String name : archs) {
+ definedId.append(" " + name);
+ }
+
+ String location = ",dir=" + javaHome;
+ if ((definedId.length() + location.length()) < 256) {
+ definedId.append(",dir=");
+ definedId.append(javaHome);
+ } else {
+ // if it exceeds the limit, we will not include the location
+ if (isVerbose()) {
+ System.err.println("Warning: Product defined instance ID exceeds the field limit:");
+ }
+ }
+
+ return definedId.toString();
+ }
+
+ /**
+ * Returns the architectures that the runtime supports
+ * (i.e. "sparc", "sparcv9", "i386", "amd64" (ISA list))
+ * The directory name where libjava.so is located.
+ *
+ * On Windows, returns the "os.arch" system property value.
+ */
+ private synchronized static String[] getJreArchs() {
+ if (jreArchs != null) {
+ return jreArchs;
+ }
+
+ Set<String> archs = new HashSet<String>();
+
+ String os = System.getProperty("os.name");
+ if (os.equals("SunOS") || os.equals("Linux")) {
+ // Traverse the directories under <JRE>/lib.
+ // If <JRE>/lib/<arch>/libjava.so exists, add <arch>
+ // to the product defined ID
+ File dir = new File(getJrePath() + File.separator + "lib");
+ if (dir.isDirectory()) {
+ String[] children = dir.list();
+ for (String name : children) {
+ File f = new File(dir, name + File.separator + "libjava.so");
+ if (f.exists()) {
+ archs.add(name);
+ }
+ }
+ }
+ } else {
+ // Windows - append the os.arch
+ archs.add(System.getProperty("os.arch"));
+ }
+ jreArchs = archs.toArray(new String[0]);
+ return jreArchs;
+ }
+
+ /**
+ * Return the zonename if zone is supported; otherwise, return
+ * "global".
+ */
+ public static String getZoneName() throws IOException {
+ String zonename = "global";
+
+ String command = "/usr/bin/zonename";
+ File f = new File(command);
+ // com.sun.servicetag package has to be compiled with JDK 5 as well
+ // JDK 5 doesn't support the File.canExecute() method.
+ // Risk not checking isExecute() for the zonename command is very low.
+ if (f.exists()) {
+ ProcessBuilder pb = new ProcessBuilder(command);
+ Process p = pb.start();
+ String output = commandOutput(p);
+ if (p.exitValue() == 0) {
+ zonename = output.trim();
+ }
+
+ }
+ return zonename;
+ }
+
+ private synchronized static String getRegisterHtmlParent() throws IOException {
+ if (registerHtmlParent == null) {
+ File htmlDir; // register.html is put under the JDK directory
+ if (getJrePath().endsWith(File.separator + "jre")) {
+ htmlDir = new File(getJrePath(), "..");
+ } else {
+ // j2se non-image build
+ htmlDir = new File(getJrePath());
+ }
+
+ // initialize the supported locales
+ initSupportedLocales(htmlDir);
+
+ // Determine the location of the offline registration page
+ String path = System.getProperty(SVCTAG_DIR_PATH);
+ if (path == null) {
+ // Default is <JDK>/register.html
+ registerHtmlParent = htmlDir.getCanonicalPath();
+ } else {
+ File f = new File(path);
+ registerHtmlParent = f.getCanonicalPath();
+ if (!f.isDirectory()) {
+ throw new InternalError("Path " + path + " set in \"" +
+ SVCTAG_DIR_PATH + "\" property is not a directory");
+ }
+ }
+ }
+ return registerHtmlParent;
+ }
+
+ /**
+ * Returns the File object of the offline registration page localized
+ * for the default locale in the JDK directory.
+ */
+ static synchronized File getRegistrationHtmlPage() throws IOException {
+ if (!supportRegistration) {
+ // No register.html page generated if JRE
+ return null;
+ }
+
+ String parent = getRegisterHtmlParent();
+
+ // check if the offline registration page is already generated
+ File f = new File(parent, REGISTRATION_HTML_NAME + ".html");
+ if (!f.exists()) {
+ // Generate the localized version of the offline registration Page
+ generateRegisterHtml(parent);
+ }
+
+ String name = REGISTRATION_HTML_NAME;
+ List<Locale> candidateLocales = getCandidateLocales(Locale.getDefault());
+ for (Locale l : candidateLocales) {
+ if (supportedLocales.contains(l)) {
+ name = REGISTRATION_HTML_NAME + "_" + l.toString();
+ break;
+ }
+ }
+ File htmlFile = new File(parent, name + ".html");
+ if (isVerbose()) {
+ System.out.print("Offline registration page: " + htmlFile);
+ System.out.println((htmlFile.exists() ?
+ "" : " not exist. Use register.html"));
+ }
+ if (htmlFile.exists()) {
+ return htmlFile;
+ } else {
+ return new File(parent,
+ REGISTRATION_HTML_NAME + ".html");
+ }
+ }
+
+ private static List<Locale> getCandidateLocales(Locale locale) {
+ String language = locale.getLanguage();
+ String country = locale.getCountry();
+ String variant = locale.getVariant();
+
+ List<Locale> locales = new ArrayList<Locale>(3);
+ if (variant.length() > 0) {
+ locales.add(locale);
+ }
+ if (country.length() > 0) {
+ locales.add((locales.size() == 0) ?
+ locale : new Locale(language, country, ""));
+ }
+ if (language.length() > 0) {
+ locales.add((locales.size() == 0) ?
+ locale : new Locale(language, "", ""));
+ }
+ return locales;
+ }
+
+ // Remove the offline registration pages
+ private static void deleteRegistrationHtmlPage() throws IOException {
+ String parent = getRegisterHtmlParent();
+ if (parent == null) {
+ return;
+ }
+
+ for (Locale locale : supportedLocales) {
+ String name = REGISTRATION_HTML_NAME;
+ if (!locale.equals(Locale.ENGLISH)) {
+ name += "_" + locale.toString();
+ }
+ File f = new File(parent, name + ".html");
+ if (f.exists()) {
+ if (!f.delete()) {
+ throw new IOException("Failed to delete " + f);
+ }
+ }
+ }
+ }
+
+ private static void initSupportedLocales(File jdkDir) {
+ if (supportedLocales.isEmpty()) {
+ // initialize with the known supported locales
+ for (Locale l : knownSupportedLocales) {
+ supportedLocales.add(l);
+ }
+ }
+
+ // Determine unknown supported locales if any
+ // by finding the localized version of README.html
+ // This prepares if a new locale in JDK is supported in
+ // e.g. in the OpenSource world
+ FilenameFilter ff = new FilenameFilter() {
+ public boolean accept(File dir, String name) {
+ String fname = name.toLowerCase();
+ if (fname.startsWith("readme") && fname.endsWith(".html")) {
+ return true;
+ }
+ return false;
+ }
+ };
+
+ String[] readmes = jdkDir.list(ff);
+ for (String name : readmes) {
+ String basename = name.substring(0, name.length() - ".html".length());
+ String[] ss = basename.split("_");
+ switch (ss.length) {
+ case 1:
+ // English version
+ break;
+ case 2:
+ supportedLocales.add(new Locale(ss[1]));
+ break;
+ case 3:
+ supportedLocales.add(new Locale(ss[1], ss[2]));
+ break;
+ default:
+ // ignore
+ break;
+ }
+ }
+ if (isVerbose()) {
+ System.out.println("Supported locales: ");
+ for (Locale l : supportedLocales) {
+ System.out.println(l);
+ }
+ }
+ }
+
+ private static final String JDK_HEADER_PNG_KEY = "@@JDK_HEADER_PNG@@";
+ private static final String JDK_VERSION_KEY = "@@JDK_VERSION@@";
+ private static final String REGISTRATION_URL_KEY = "@@REGISTRATION_URL@@";
+ private static final String REGISTRATION_PAYLOAD_KEY = "@@REGISTRATION_PAYLOAD@@";
+
+ @SuppressWarnings("unchecked")
+ private static void generateRegisterHtml(String parent) throws IOException {
+ int version = Util.getJdkVersion();
+ int update = Util.getUpdateVersion();
+ String jdkVersion = "Version " + version;
+ if (update > 0) {
+ // product name is not translated
+ jdkVersion += " Update " + update;
+ }
+ RegistrationData regData = getRegistrationData();
+ String registerURL = SunConnection.getRegistrationURL(
+ regData.getRegistrationURN()).toString();
+ // Make sure it uses the canonical path before getting the URI.
+ File img = new File(svcTagDir.getCanonicalPath(), "jdk_header.png");
+ String headerImageSrc = img.toURI().toString();
+
+ // Format the registration data in one single line
+ StringBuilder payload = new StringBuilder();
+ String xml = regData.toString().replaceAll("\"", "%22");
+ BufferedReader reader = new BufferedReader(new StringReader(xml));
+ try {
+ String line = null;
+ while ((line = reader.readLine()) != null) {
+ payload.append(line.trim());
+ }
+ } finally {
+ reader.close();
+ }
+
+ String resourceFilename = "/com/sun/servicetag/resources/register";
+ for (Locale locale : supportedLocales) {
+ String name = REGISTRATION_HTML_NAME;
+ String resource = resourceFilename;
+ if (!locale.equals(Locale.ENGLISH)) {
+ name += "_" + locale.toString();
+ resource += "_" + locale.toString();
+ }
+ File f = new File(parent, name + ".html");
+ InputStream in = null;
+ BufferedReader br = null;
+ PrintWriter pw = null;
+ try {
+ in = Installer.class.getClass().getResourceAsStream(resource + ".html");
+ if (in == null) {
+ // if the resource file is missing
+ if (isVerbose()) {
+ System.out.println("Missing resouce file: " + resource + ".html");
+ }
+ continue;
+ }
+ if (isVerbose()) {
+ System.out.println("Generating " + f + " from " + resource + ".html");
+ }
+
+ br = new BufferedReader(new InputStreamReader(in, "UTF-8"));
+ pw = new PrintWriter(f, "UTF-8");
+ String line = null;
+ while ((line = br.readLine()) != null) {
+ String output = line;
+ if (line.contains(JDK_VERSION_KEY)) {
+ output = line.replace(JDK_VERSION_KEY, jdkVersion);
+ } else if (line.contains(JDK_HEADER_PNG_KEY)) {
+ output = line.replace(JDK_HEADER_PNG_KEY, headerImageSrc);
+ } else if (line.contains(REGISTRATION_URL_KEY)) {
+ output = line.replace(REGISTRATION_URL_KEY, registerURL);
+ } else if (line.contains(REGISTRATION_PAYLOAD_KEY)) {
+ output = line.replace(REGISTRATION_PAYLOAD_KEY, payload.toString());
+ }
+ pw.println(output);
+ }
+ f.setReadOnly();
+ pw.flush();
+ } finally {
+ if (pw != null) {
+ pw.close();
+ }
+ if (in != null) {
+ in.close();
+ }
+ if (br!= null) {
+ br.close();
+ }
+ }
+ }
+ }
+
+ /**
+ * A utility class to create a service tag for Java SE.
+ * <p>
+ * <b>Usage:</b><br>
+ * <blockquote><tt>
+ * &lt;JAVA_HOME&gt;/bin/java com.sun.servicetag.Installer
+ * </tt></blockquote>
+ * <p>
+ */
+ public static void main(String[] args) {
+ String source = "Manual";
+
+ // Parse the options (arguments starting with "-" )
+ boolean delete = false;
+ boolean update = false;
+ boolean register = false;
+ int count = 0;
+ while (count < args.length) {
+ String arg = args[count];
+ if (arg.trim().length() == 0) {
+ // skip empty arguments
+ count++;
+ continue;
+ }
+
+ if (arg.equals("-source")) {
+ source = args[++count];
+ } else if (arg.equals("-delete")) {
+ delete = true;
+ } else if (arg.equals("-register")) {
+ register = true;
+ } else {
+ usage();
+ return;
+ }
+ count++;
+ }
+ try {
+ if (delete) {
+ deleteRegistrationData();
+ } else {
+ ServiceTag[] javaSvcTags = getJavaServiceTagArray();
+ String[] archs = getJreArchs();
+ if (javaSvcTags.length > archs.length) {
+ // 64-bit has been uninstalled
+ // so remove the service tag
+ updateRegistrationData(source);
+ } else {
+ // create the service tag
+ createServiceTag(source);
+ }
+ }
+
+ if (register) {
+ // Registration is only supported by JDK
+ // For testing purpose, override with a "servicetag.enable.registration" property
+
+ RegistrationData regData = getRegistrationData();
+ if (supportRegistration && !regData.getServiceTags().isEmpty()) {
+ SunConnection.register(regData);
+ }
+ }
+ System.exit(0);
+ } catch (IOException e) {
+ System.err.println("I/O Error: " + e.getMessage());
+ if (isVerbose()) {
+ e.printStackTrace();
+ }
+ } catch (IllegalArgumentException ex) {
+ if (isVerbose()) {
+ ex.printStackTrace();
+ }
+ } catch (Exception e) {
+ System.err.println("Error: " + e.getMessage());
+ if (isVerbose()) {
+ e.printStackTrace();
+ }
+ }
+ System.exit(1);
+ }
+
+ private static void usage() {
+ System.out.println("Usage:");
+ System.out.print(" " + Installer.class.getName());
+ System.out.println(" [-delete|-source <source>|-register]");
+ System.out.println(" to create a service tag for the Java platform");
+ System.out.println("");
+ System.out.println("Internal Options:");
+ System.out.println(" -source: to specify the source of the service tag to be created");
+ System.out.println(" -delete: to delete the service tag ");
+ System.out.println(" -register: to register the JDK");
+ System.out.println(" -help: to print this help message");
+ }
+}
diff --git a/desktop/source/registration/com/sun/star/servicetag/LinuxSystemEnvironment.java b/desktop/source/registration/com/sun/star/servicetag/LinuxSystemEnvironment.java
new file mode 100755
index 000000000000..ff762d202e35
--- /dev/null
+++ b/desktop/source/registration/com/sun/star/servicetag/LinuxSystemEnvironment.java
@@ -0,0 +1,322 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+package com.sun.star.servicetag;
+
+// The Service Tags team maintains the latest version of the implementation
+// for system environment data collection. JDK will include a copy of
+// the most recent released version for a JDK release. We rename
+// the package to com.sun.servicetag so that the Sun Connection
+// product always uses the latest version from the com.sun.scn.servicetags
+// package. JDK and users of the com.sun.servicetag API
+// (e.g. NetBeans and SunStudio) will use the version in JDK.
+
+import java.io.*;
+import java.util.*;
+
+/**
+ * Linux implementation of the SystemEnvironment class.
+ */
+class LinuxSystemEnvironment extends SystemEnvironment {
+ LinuxSystemEnvironment() {
+ setHostId(getLinuxHostId());
+
+ setSystemModel(getLinuxModel());
+ setSystemManufacturer(getLinuxSystemManufacturer());
+ setCpuManufacturer(getLinuxCpuManufacturer());
+ setSerialNumber(getLinuxSN());
+ setPhysMem(getLinuxPhysMem());
+ setSockets(getLinuxSockets());
+ setCores(getLinuxCores());
+ setVirtCpus(getLinuxVirtCpus());
+ setCpuName(getLinuxCpuName());
+ setClockRate(getLinuxClockRate());
+ }
+ private String dmiInfo = null;
+ private String kstatCpuInfo = null;
+
+ private static final int SN = 1;
+ private static final int SYS = 2;
+ private static final int CPU = 3;
+ private static final int MODEL = 4;
+
+ private String getLinuxHostId() {
+ String output = getCommandOutput("/usr/bin/hostid");
+ // trim off the leading 0x
+ if (output.startsWith("0x")) {
+ output = output.substring(2);
+ }
+ return output;
+ }
+
+ /**
+ * Tries to obtain and return the cpu manufacturer.
+ * @return The cpu manufacturer (an empty string if not found or an error occurred)
+ */
+ private String getLinuxCpuManufacturer() {
+ String tmp = getLinuxPSNInfo(CPU);
+ if (tmp.length() > 0) {
+ return tmp;
+ }
+
+ String contents = getFileContent("/proc/cpuinfo");
+ for (String line : contents.split("\n")) {
+ if (line.contains("vendor_id")) {
+ String[] ss = line.split(":", 2);
+ if (ss.length > 1) {
+ return ss[1].trim();
+ }
+ }
+ }
+
+ // returns an empty string if it can't be found or an error happened
+ return getLinuxDMIInfo("dmi type 4", "manufacturer");
+ }
+
+ private String getLinuxModel() {
+ String tmp = getLinuxPSNInfo(MODEL);
+ if (tmp.length() > 0) {
+ return tmp + "::" + getCommandOutput("/bin/uname","-v");
+ }
+
+ tmp = getLinuxDMIInfo("dmi type 1", "product name");
+ if (tmp.length() > 0) {
+ return tmp + "::" + getCommandOutput("/bin/uname","-v");
+ }
+
+ return getCommandOutput("/bin/uname","-i")
+ + "::" + getCommandOutput("/bin/uname","-v");
+ }
+
+
+ /**
+ * Tries to obtain and return the system manufacturer.
+ * @return The system manufacturer (an empty string if not found or an error occurred)
+ */
+ private String getLinuxSystemManufacturer() {
+ String tmp = getLinuxPSNInfo(SYS);
+ if (tmp.length() > 0) {
+ return tmp;
+ }
+
+ // returns an empty string if it can't be found or an error happened
+ return getLinuxDMIInfo("dmi type 1", "manufacturer");
+ }
+
+ /**
+ * Tries to obtain and return the serial number of the system.
+ * @return The serial number (an empty string if not found or an error occurred)
+ */
+ private String getLinuxSN() {
+ String tmp = getLinuxPSNInfo(SN);
+ if (tmp.length() > 0) {
+ return tmp;
+ }
+
+ // returns an empty string if it can't be found or an error happened
+ return getLinuxDMIInfo("dmi type 1", "serial number");
+ }
+
+ private String getLinuxPSNInfo(int target) {
+ // try to read from the psn file if it exists
+ String contents = getFileContent("/var/run/psn");
+ String[] ss = contents.split("\n");
+ if (target <= ss.length) {
+ return ss[target-1];
+ }
+
+ // default case is to return ""
+ return "";
+ }
+
+ // reads from dmidecode with the given type and target
+ // returns an empty string if nothing was found or an error occurred
+ // Sample output segment:
+ // Handle 0x0001
+ // DMI type 1, 25 bytes.
+ // System Information
+ // Manufacturer: System manufacturer
+ // Product Name: System Product Name
+ // Version: System Version
+ // Serial Number: System Serial Number
+ // UUID: 3091D719-B25B-D911-959D-6D1B12C7686E
+ // Wake-up Type: Power Switch
+
+ private synchronized String getLinuxDMIInfo(String dmiType, String target) {
+ // only try to get dmidecode information once, after that, we can
+ // reuse the output
+ if (dmiInfo == null) {
+ Thread dmidecodeThread = new Thread() {
+ public void run() {
+ dmiInfo = getCommandOutput("/usr/sbin/dmidecode");
+ }
+ };
+ dmidecodeThread.start();
+
+ try {
+ dmidecodeThread.join(3000);
+ if (dmidecodeThread.isAlive()) {
+ dmidecodeThread.interrupt();
+ dmiInfo = "";
+ }
+ } catch (InterruptedException ie) {
+ dmidecodeThread.interrupt();
+ }
+ }
+
+ if (dmiInfo.length() == 0) {
+ return "";
+ }
+ boolean dmiFlag = false;
+ for (String s : dmiInfo.split("\n")) {
+ String line = s.toLowerCase();
+ if (dmiFlag) {
+ if (line.contains(target)) {
+ String key = target + ":";
+ int indx = line.indexOf(key) + key.length();
+ if (line.contains(key) && indx < line.length()) {
+ return line.substring(indx).trim();
+ }
+ String[] ss = line.split(":");
+ return ss[ss.length-1];
+ }
+ } else if (line.contains(dmiType)) {
+ dmiFlag = true;
+ }
+ }
+ return "";
+ }
+
+ private String getLinuxClockRate() {
+ String contents = getFileContent("/proc/cpuinfo");
+ String token = "cpu MHz";
+ for (String line : contents.split("\n")) {
+ if (line.contains(token)) {
+ String[] key = line.split(":", 2);
+ if (key.length > 1) {
+ return key[1].trim();
+ }
+ }
+ }
+ return "";
+ }
+
+ private String getLinuxCpuName() {
+ String contents = getFileContent("/proc/cpuinfo");
+ String token = "model name";
+ for (String line : contents.split("\n")) {
+ if (line.contains(token)) {
+ String[] key = line.split(":", 2);
+ if (key.length > 1) {
+ return key[1].trim();
+ }
+ }
+ }
+ return "";
+ }
+
+ private String getLinuxVirtCpus() {
+ Set<String> set = new HashSet<String>();
+ String contents = getFileContent("/proc/cpuinfo");
+ String token = "processor";
+ for (String line : contents.split("\n")) {
+ if (line.contains(token)) {
+ String[] key = line.split(":", 2);
+ if (key.length > 1) {
+ set.add(key[1].trim());
+ }
+ }
+ }
+ return "" + set.size();
+ }
+
+ private String getLinuxCores() {
+ Set<String> set = new HashSet<String>();
+ String contents = getFileContent("/proc/cpuinfo");
+ String token = "core id";
+ for (String line : contents.split("\n")) {
+ if (line.contains(token)) {
+ String[] key = line.split(":", 2);
+ if (key.length > 1) {
+ set.add(key[1].trim());
+ }
+ }
+ }
+ if (set.size() == 0) {
+ return "1";
+ }
+ return "" + set.size();
+ }
+
+ private String getLinuxPhysMem() {
+ String contents = getFileContent("/proc/meminfo");
+ for (String line : contents.split("\n")) {
+ if (line.contains("MemTotal")) {
+ String[] total = line.split(":", 2);
+ if (total.length > 1) {
+ String[] mem = total[1].trim().split(" ");
+ if (mem.length >= 1) {
+ return mem[0].trim();
+ } else {
+ return total[1].trim();
+ }
+ }
+ }
+ }
+
+ return "";
+ }
+
+ private String getLinuxSockets() {
+ Set<String> physIdSet = new HashSet<String>();
+ Set<String> procSet = new HashSet<String>();
+ String contents = getFileContent("/proc/cpuinfo");
+ String physIdToken = "physical id";
+ String procToken = "processor";
+
+ for (String line : contents.split("\n")) {
+ if (line.contains(physIdToken)) {
+ String[] key = line.split(":", 2);
+ if (key.length > 1) {
+ physIdSet.add(key[1].trim());
+ }
+ }
+
+ if (line.contains(procToken)) {
+ String[] key = line.split(":", 2);
+ if (key.length > 1) {
+ procSet.add(key[1].trim());
+ }
+ }
+ }
+ if (physIdSet.size() != 0) {
+ return "" + physIdSet.size();
+ }
+ return "" + procSet.size();
+ }
+}
diff --git a/desktop/source/registration/com/sun/star/servicetag/RegistrationData.java b/desktop/source/registration/com/sun/star/servicetag/RegistrationData.java
new file mode 100755
index 000000000000..66eb1933210a
--- /dev/null
+++ b/desktop/source/registration/com/sun/star/servicetag/RegistrationData.java
@@ -0,0 +1,531 @@
+
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 1997-2008 Sun Microsystems, Inc. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can obtain
+ * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
+ * or glassfish/bootstrap/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
+ * Sun designates this particular file as subject to the "Classpath" exception
+ * as provided by Sun in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the License
+ * Header, with the fields enclosed by brackets [] replaced by your own
+ * identifying information: "Portions Copyrighted [year]
+ * [name of copyright owner]"
+ *
+ * Contributor(s):
+ *
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package com.sun.star.servicetag;
+
+import java.io.*;
+import java.net.UnknownHostException;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Set;
+
+import static com.sun.star.servicetag.RegistrationDocument.*;
+
+/**
+ * A {@code RegistrationData} object is a container of one or more
+ * {@link #getServiceTags service tags} that identify the
+ * components for product registration.
+ * Each {@code RegistrationData} object has a {@link #getRegistrationURN
+ * uniform resource name} (URN) as its identifier.
+ * <a name="EnvMap"></a>
+ * It also has an <i>environment map</i> with
+ * the following elements:
+ * <blockquote>
+ * <table border=0>
+ * <tr>
+ * <td><tt>hostname</tt></td>
+ * <td>Hostname of the system</td>
+ * <td>e.g. woody</td>
+ * </tr>
+ * <tr>
+ * <td><tt>hostId</tt></td>
+ * <td>Host ID of the system</td>
+ * <td>e.g. 83abc1ab</td>
+ * </tr>
+ * <tr>
+ * <td><tt>osName</tt></td>
+ * <td>Operating system name</td>
+ * <td> e.g. SunOS</td>
+ * </tr>
+ * <tr>
+ * <td><tt>osVersion</tt></td>
+ * <td>Operating system version</td>
+ * <td> e.g. 5.10</td>
+ * </tr>
+ * <tr>
+ * <td><tt>osArchitecture</tt></td>
+ * <td>Operating system architecture</td>
+ * <td> e.g. sparc</td>
+ * </tr>
+ * <tr>
+ * <td><tt>systemModel</tt></td>
+ * <td>System model</td>
+ * <td> e.g. SUNW,Sun-Fire-V440</td>
+ * </tr>
+ * <tr>
+ * <td><tt>systemManufacturer</tt></td>
+ * <td>System manufacturer</td>
+ * <td> e.g. Sun Microsystems</td>
+ * </tr>
+ * <tr>
+ * <td><tt>cpuManufacturer</tt></td>
+ * <td>CPU manufacturer</td>
+ * <td> e.g. Sun Microsystems</td>
+ * </tr>
+ * <tr>
+ * <td><tt>serialNumber</tt></td>
+ * <td>System serial number</td>
+ * <td> e.g. BEL078932</td>
+ * </tr>
+ * <tr>
+ * <td><tt>physmem</tt></td>
+ * <td>Physical memory for the system (in MB)</td>
+ * <td> e.g. 4096</td>
+ * </tr>
+ * </table>
+ * </blockquote>
+ * The <tt>hostname</tt> and <tt>osName</tt> element must have a non-empty value.
+ * If an element is not available on a system and their value will be
+ * empty.
+ * <p>
+ * <a name="XMLSchema">
+ * <b>Registration XML Schema</b></a>
+ * <p>
+ * A {@code RegistrationData} object can be {@link #loadFromXML loaded} from
+ * and {@link #storeToXML stored} into an XML file in the format described
+ * by the
+ * <a href="https://sn-tools.central.sun.com/twiki/pub/ServiceTags/RegistrationRelayService/product_registration.xsd">
+ * registration data schema</a>. The registration data schema is defined by the
+ * Service Tags Technology.
+ * <p>
+ * Typically the registration data is constructed at installation time
+ * and stored in an XML file for later service tag lookup or registration.
+ *
+ * <p>
+ * <b>Example Usage</b>
+ * <p>
+ * The examples below show how the {@code RegistrationData} can be
+ * used for product registration.
+ * Exception handling is not shown in these examples for clarity.
+ * <ol>
+ * <li>This example shows how the JDK creates a JDK service tag, installs it
+ * in the system service tag registry and adds it to the registration data.
+ * <br>
+ * <blockquote><pre>
+ * // create a service tag object with an instance_urn
+ * ServiceTag st = ServiceTag.newInstance(ServiceTag.generateInstanceURN(),
+ * ....);
+ * // Adds to the system service tag registry if supported
+ * if (Registry.isSupported()) {
+ * Registry.getSystemRegistry().addServiceTag(st);
+ * }
+ *
+ * // add to the registration data
+ * RegistrationData registration = new RegistrationData();
+ * registration.addServiceTag(st);
+ * </pre></blockquote>
+ * </li>
+ * <li>At this point, the registration data is ready to
+ * send to Sun Connection for registration. This example shows how to register
+ * the JDK via the <i>Registration Relay Service</i>.
+ * <p>
+ * There are several registration services for Sun Connection. For example,
+ * the <a href="https://sn-tools.central.sun.com/twiki/bin/view/ServiceTags/RegistrationRelayService">
+ * Registration Relay Service</a> is a web application interface that
+ * processes the registration data payload sent via HTTP post
+ * and hosts the registration user interface for a specified
+ * registration URL. Refer to the
+ * Registration Relay Service Specification for details.
+ * <p>
+ * <blockquote><pre>
+ * // Open the connection to the URL of the registration service
+ * HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
+ * con.setDoInput(true);
+ * con.setDoOutput(true);
+ * con.setUseCaches(false);
+ * con.setAllowUserInteraction(false);
+ * con.setRequestMethod("POST");
+ * con.setRequestProperty("Content-Type", "text/xml;charset=\"utf-8\"");
+ * con.connect();
+ *
+ * // send the registration data to the registration service
+ * OutputStream out = con.getOutputStream();
+ * registration.storeToXML(out);
+ * out.close();
+ * </pre></blockquote>
+ * </li>
+ * <li>This example shows how to store the registration data in an XML file.
+ * for later service tag lookup or registration.
+ * <br>
+ * <blockquote><pre>
+ * BufferedOutputStream out = new BufferedOutputStream(
+ * new FileOutputStream(""&lt;JAVA_HOME&gt;/lib/servicetag/registration.xml"));
+ * registration.storeToXML(out);
+ * out.close();
+ * </pre></blockquote>
+ * </li>
+ * <li>This example shows how to install service tags that are in the
+ * registration data in the system service tag registry when determined
+ * to be available. The system service tag registry might not have existed
+ * when the registration data was constructed.
+ * <br>
+ * <blockquote><pre>
+ * if (Registry.isSupported()) {
+ * Set&lt;ServiceTag&gt; svctags = registration.getServiceTags();
+ * for (ServiceTag st : svctags) {
+ * Registry.getSystemRegistry().addServiceTag(st);
+ * }
+ * }
+ * </pre></blockquote>
+ * </li>
+ * </ol>
+ *
+ * @see <a href="https://sunconnection.sun.com/inventory">Sun Connection Inventory Channel</a>
+ */
+public class RegistrationData {
+ private final Map<String, String> environment;
+ private final Map<String, String> cpuInfo;
+ private final Map<String, ServiceTag> svcTagMap;
+ private final String urn;
+
+ /**
+ * Creates a {@code RegistrationData} object with a generated
+ * {@link #getRegistrationURN registration URN}.
+ * The following keys in the {@link #getEnvironmentMap environment map}
+ * will be initialized for the configuration of the
+ * running system:
+ * <blockquote>
+ * <tt>hostname</tt>, <tt>osName</tt>, <tt>osVersion</tt> and
+ * <tt>osArchitecture</tt>
+ * </blockquote>
+ * and the value of other keys may be empty.
+ */
+ public RegistrationData() {
+ this(Util.generateURN());
+ }
+
+ // package private
+ RegistrationData(String urn) {
+ this.urn = urn;
+ SystemEnvironment sysEnv = SystemEnvironment.getSystemEnvironment();
+ this.environment = initEnvironment(sysEnv);
+ this.cpuInfo = initCpuInfo(sysEnv);
+ this.svcTagMap = new LinkedHashMap<String, ServiceTag>();
+ }
+
+ private Map<String, String> initEnvironment(SystemEnvironment sysEnv) {
+ Map<String, String> map = new LinkedHashMap<String, String>();
+ map.put(ST_NODE_HOSTNAME, sysEnv.getHostname());
+ map.put(ST_NODE_HOST_ID, sysEnv.getHostId());
+ map.put(ST_NODE_OS_NAME, sysEnv.getOsName());
+ map.put(ST_NODE_OS_VERSION, sysEnv.getOsVersion());
+ map.put(ST_NODE_OS_ARCH, sysEnv.getOsArchitecture());
+ map.put(ST_NODE_SYSTEM_MODEL, sysEnv.getSystemModel());
+ map.put(ST_NODE_SYSTEM_MANUFACTURER, sysEnv.getSystemManufacturer());
+ map.put(ST_NODE_CPU_MANUFACTURER, sysEnv.getCpuManufacturer());
+ map.put(ST_NODE_SERIAL_NUMBER, sysEnv.getSerialNumber());
+ map.put(ST_NODE_PHYS_MEM, sysEnv.getPhysMem());
+ return map;
+ }
+
+ private Map<String, String> initCpuInfo(SystemEnvironment sysEnv) {
+ Map<String, String> map = new LinkedHashMap<String, String>();
+ map.put(ST_NODE_SOCKETS, sysEnv.getSockets());
+ map.put(ST_NODE_CORES, sysEnv.getCores());
+ map.put(ST_NODE_VIRT_CPUS, sysEnv.getVirtCpus());
+ map.put(ST_NODE_CPU_NAME, sysEnv.getCpuName());
+ map.put(ST_NODE_CLOCK_RATE, sysEnv.getClockRate());
+ return map;
+ }
+
+ /**
+ * Returns the uniform resource name of this registration data
+ * in this format:
+ * <tt>urn:st:&lt;32-char {@link java.util.UUID uuid}&gt;</tt>
+ *
+ * @return the URN of this registration data.
+ */
+ public String getRegistrationURN() {
+ return urn;
+ }
+
+ /**
+ * Returns a map containing the environment information for this
+ * registration data. See the set of <a href="#EnvMap">keys</a>
+ * in the environment map. Subsequent update to the environment
+ * map via the {@link #setEnvironment setEnvironment} method will not be reflected
+ * in the returned map.
+ *
+ * @return an environment map for this registration data.
+ */
+ public Map<String, String> getEnvironmentMap() {
+ return new LinkedHashMap<String,String>(environment);
+ }
+
+ /**
+ * Returns a map containing the cpu information for this
+ * registration data. Subsequent update to the cpu info
+ * map via the {@link #setCpuInfo setCpuInfo} method will not be reflected
+ * in the returned map.
+ *
+ * @return a cpu info map for this registration data.
+ */
+ public Map<String, String> getCpuInfoMap() {
+ return new LinkedHashMap<String,String>(cpuInfo);
+ }
+
+ /**
+ * Sets an element of the specified {@code name} in the environment map
+ * with the given {@code value}.
+ *
+ * @throws IllegalArgumentException if {@code name} is not a valid key
+ * in the environment map, or {@code value} is not valid.
+ */
+ public void setEnvironment(String name, String value) {
+ if (name == null) {
+ throw new NullPointerException("name is null");
+ }
+ if (value == null) {
+ throw new NullPointerException("value is null");
+ }
+ if (environment.containsKey(name)) {
+ if (name.equals(ST_NODE_HOSTNAME) || name.equals(ST_NODE_OS_NAME)) {
+ if (value.length() == 0) {
+ throw new IllegalArgumentException("\"" +
+ name + "\" requires non-empty value.");
+ }
+ }
+ environment.put(name, value);
+ } else {
+ throw new IllegalArgumentException("\"" +
+ name + "\" is not an environment element.");
+ }
+ }
+
+ /**
+ * Sets an element of the specified {@code name} in the cpu info map
+ * with the given {@code value}.
+ *
+ * @throws IllegalArgumentException if {@code name} is not a valid key
+ * in the cpu info map, or {@code value} is not valid.
+ */
+ public void setCpuInfo(String name, String value) {
+ if (name == null) {
+ throw new NullPointerException("name is null");
+ }
+ if (value == null) {
+ throw new NullPointerException("value is null");
+ }
+ if (cpuInfo.containsKey(name)) {
+ cpuInfo.put(name, value);
+ } else {
+ throw new IllegalArgumentException("\"" +
+ name + "\" is not an cpuinfo element.");
+ }
+ }
+
+ /**
+ * Returns all service tags in this registration data.
+ *
+ * @return a {@link Set Set} of the service tags
+ * in this registration data.
+ */
+ public Set<ServiceTag> getServiceTags() {
+ return new HashSet<ServiceTag>(svcTagMap.values());
+ }
+
+ /**
+ * Adds a service tag to this registration data.
+ * If the given service tag has an empty <tt>instance_urn</tt>,
+ * this method will generate a URN and place it in the copy
+ * of the service tag in this registration data.
+ * This method will return the {@code ServiceTag} object
+ * added to this registration data.
+ *
+ * @param st {@code ServiceTag} object to be added.
+ * @return a {@code ServiceTag} object added to this registration data.
+ *
+ * @throws IllegalArgumentException if
+ * a service tag of the same {@link ServiceTag#getInstanceURN
+ * <tt>instance_urn</tt>} already exists in the registry.
+ */
+ public synchronized ServiceTag addServiceTag(ServiceTag st) {
+ ServiceTag svcTag = ServiceTag.newInstanceWithUrnTimestamp(st);
+
+ String instanceURN = svcTag.getInstanceURN();
+ if (svcTagMap.containsKey(instanceURN)) {
+ throw new IllegalArgumentException("Instance_urn = " + instanceURN +
+ " already exists in the registration data.");
+ } else {
+ svcTagMap.put(instanceURN, svcTag);
+ }
+ return svcTag;
+ }
+
+ /**
+ * Returns a service tag of the given <tt>instance_urn</tt> in this registration
+ * data.
+ *
+ * @param instanceURN the <tt>instance_urn</tt> of the service tag
+ * @return the {@code ServiceTag} object of the given <tt>instance_urn</tt>
+ * if exists; otherwise return {@code null}.
+ */
+ public synchronized ServiceTag getServiceTag(String instanceURN) {
+ if (instanceURN == null) {
+ throw new NullPointerException("instanceURN is null");
+ }
+ return svcTagMap.get(instanceURN);
+ }
+
+ /**
+ * Removes a service tag of the given <tt>instance_urn</tt> from this
+ * registration data.
+ *
+ * @param instanceURN the <tt>instance_urn</tt> of
+ * the service tag to be removed.
+ *
+ * @return the removed {@code ServiceTag} object;
+ * or {@code null} if the service tag does not exist in this
+ * registration data.
+ */
+ public synchronized ServiceTag removeServiceTag(String instanceURN) {
+ if (instanceURN == null) {
+ throw new NullPointerException("instanceURN is null");
+ }
+
+ ServiceTag svcTag = null;
+ if (svcTagMap.containsKey(instanceURN)) {
+ svcTag = svcTagMap.remove(instanceURN);
+ }
+ return svcTag;
+ }
+
+ /**
+ * Updates the <tt>product_defined_instance_id</tt> in the service tag
+ * of the given <tt>instance_urn</tt> in this registration data.
+ *
+ * @param instanceURN the <tt>instance_urn</tt> of the service tag to be updated.
+ * @param productDefinedInstanceID the value of the
+ * <tt>product_defined_instance_id</tt> to be set.
+ *
+ * @return the updated {@code ServiceTag} object;
+ * or {@code null} if the service tag does not exist in this
+ * registration data.
+ */
+ public synchronized ServiceTag updateServiceTag(String instanceURN,
+ String productDefinedInstanceID) {
+ ServiceTag svcTag = getServiceTag(instanceURN);
+ if (svcTag == null) {
+ return null;
+ }
+
+ svcTag = ServiceTag.newInstanceWithUrnTimestamp(svcTag);
+ // update the product defined instance ID field
+ svcTag.setProductDefinedInstanceID(productDefinedInstanceID);
+ svcTagMap.put(instanceURN, svcTag);
+ return svcTag;
+ }
+
+ /**
+ * Reads the registration data from the XML document on the
+ * specified input stream. The XML document must be
+ * in the format described by the <a href="#XMLSchema">
+ * registration data schema</a>.
+ * The specified stream is closed after this method returns.
+ *
+ * @param in the input stream from which to read the XML document.
+ * @return a {@code RegistrationData} object read from the input
+ * stream.
+ *
+ * @throws IllegalArgumentException if the input stream
+ * contains an invalid registration data.
+ *
+ * @throws IOException if an error occurred when reading from the input stream.
+ */
+ public static RegistrationData loadFromXML(InputStream in) throws IOException {
+ try {
+ return RegistrationDocument.load(in);
+ } finally {
+ in.close();
+ }
+ }
+
+ /**
+ * Writes the registration data to the specified output stream
+ * in the format described by the <a href="#XMLSchema">
+ * registration data schema</a> with "UTF-8" encoding.
+ * The specified stream remains open after this method returns.
+ *
+ * @param os the output stream on which to write the XML document.
+ *
+ * @throws IOException if an error occurred when writing to the output stream.
+ */
+ public void storeToXML(OutputStream os) throws IOException {
+ RegistrationDocument.store(os, this);
+ os.flush();
+ }
+
+ /**
+ * Returns a newly allocated byte array containing the registration
+ * data in XML format.
+ *
+ * @return a newly allocated byte array containing the registration
+ * data in XML format.
+ */
+ public byte[] toXML() {
+ try {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ storeToXML(out);
+ return out.toByteArray();
+ } catch (IOException e) {
+ // should not reach here
+ return new byte[0];
+ }
+ }
+
+ /**
+ * Returns a string representation of this registration data in XML
+ * format.
+ *
+ * @return a string representation of this registration data in XML
+ * format.
+ */
+ @Override
+ public String toString() {
+ try {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ storeToXML(out);
+ return out.toString("UTF-8");
+ } catch (IOException e) {
+ // should not reach here
+ return "Error creating the return string.";
+ }
+ }
+}
diff --git a/desktop/source/registration/com/sun/star/servicetag/RegistrationDocument.java b/desktop/source/registration/com/sun/star/servicetag/RegistrationDocument.java
new file mode 100755
index 000000000000..fb13b581c0ce
--- /dev/null
+++ b/desktop/source/registration/com/sun/star/servicetag/RegistrationDocument.java
@@ -0,0 +1,440 @@
+
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 1997-2008 Sun Microsystems, Inc. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can obtain
+ * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
+ * or glassfish/bootstrap/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
+ * Sun designates this particular file as subject to the "Classpath" exception
+ * as provided by Sun in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the License
+ * Header, with the fields enclosed by brackets [] replaced by your own
+ * identifying information: "Portions Copyrighted [year]
+ * [name of copyright owner]"
+ *
+ * Contributor(s):
+ *
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package com.sun.star.servicetag;
+
+import java.io.*;
+import java.net.URL;
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.SAXException;
+import org.xml.sax.InputSource;
+
+import javax.xml.XMLConstants;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.validation.Schema;
+import javax.xml.validation.SchemaFactory;
+import javax.xml.validation.Validator;
+
+// For write operation
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+/**
+ * XML Support Class for Product Registration.
+ */
+class RegistrationDocument {
+
+ private static final String REGISTRATION_DATA_SCHEMA =
+ "/com/sun/star/servicetag/resources/product_registration.xsd";
+ private static final String REGISTRATION_DATA_VERSION = "1.0";
+ private static final String SERVICE_TAG_VERSION = "1.0";
+ final static String ST_NODE_REGISTRATION_DATA = "registration_data";
+ final static String ST_ATTR_REGISTRATION_VERSION = "version";
+ final static String ST_NODE_ENVIRONMENT = "environment";
+ final static String ST_NODE_HOSTNAME = "hostname";
+ final static String ST_NODE_HOST_ID = "hostId";
+ final static String ST_NODE_OS_NAME = "osName";
+ final static String ST_NODE_OS_VERSION = "osVersion";
+ final static String ST_NODE_OS_ARCH = "osArchitecture";
+ final static String ST_NODE_SYSTEM_MODEL = "systemModel";
+ final static String ST_NODE_SYSTEM_MANUFACTURER = "systemManufacturer";
+ final static String ST_NODE_CPU_MANUFACTURER = "cpuManufacturer";
+ final static String ST_NODE_SERIAL_NUMBER = "serialNumber";
+ final static String ST_NODE_PHYS_MEM = "physmem";
+ final static String ST_NODE_CPU_INFO = "cpuinfo";
+ final static String ST_NODE_SOCKETS = "sockets";
+ final static String ST_NODE_CORES = "cores";
+ final static String ST_NODE_VIRT_CPUS = "virtcpus";
+ final static String ST_NODE_CPU_NAME = "name";
+ final static String ST_NODE_CLOCK_RATE = "clockrate";
+ final static String ST_NODE_REGISTRY = "registry";
+ final static String ST_ATTR_REGISTRY_URN = "urn";
+ final static String ST_ATTR_REGISTRY_VERSION = "version";
+ final static String ST_NODE_SERVICE_TAG = "service_tag";
+ final static String ST_NODE_INSTANCE_URN = "instance_urn";
+ final static String ST_NODE_PRODUCT_NAME = "product_name";
+ final static String ST_NODE_PRODUCT_VERSION = "product_version";
+ final static String ST_NODE_PRODUCT_URN = "product_urn";
+ final static String ST_NODE_PRODUCT_PARENT_URN = "product_parent_urn";
+ final static String ST_NODE_PRODUCT_PARENT = "product_parent";
+ final static String ST_NODE_PRODUCT_DEFINED_INST_ID = "product_defined_inst_id";
+ final static String ST_NODE_PRODUCT_VENDOR = "product_vendor";
+ final static String ST_NODE_PLATFORM_ARCH = "platform_arch";
+ final static String ST_NODE_TIMESTAMP = "timestamp";
+ final static String ST_NODE_CONTAINER = "container";
+ final static String ST_NODE_SOURCE = "source";
+ final static String ST_NODE_INSTALLER_UID = "installer_uid";
+
+ static RegistrationData load(InputStream in) throws IOException {
+ Document document = initializeDocument(in);
+
+ // Gets the registration URN
+ Element root = getRegistrationDataRoot(document);
+ Element registryRoot =
+ getSingletonElementFromRoot(root, ST_NODE_REGISTRY);
+ String urn = registryRoot.getAttribute(ST_ATTR_REGISTRY_URN);
+
+ // Construct a new RegistrationData object from the DOM tree
+ // Initialize the environment map and service tags
+ RegistrationData regData = new RegistrationData(urn);
+ addServiceTags(registryRoot, regData);
+
+ Element envRoot = getSingletonElementFromRoot(root, ST_NODE_ENVIRONMENT);
+ buildEnvironmentMap(envRoot, regData);
+
+ Element cpuInfo = getSingletonElementFromRoot(envRoot, ST_NODE_CPU_INFO);
+ buildCpuInfoMap(cpuInfo, regData);
+ return regData;
+ }
+
+ static void store(OutputStream os, RegistrationData registration)
+ throws IOException {
+ // create a new document with the root node
+ Document document = initializeDocument();
+
+ // create the nodes for the environment map and the service tags
+ // in the registration data
+ addEnvironmentNodes(document,
+ registration.getEnvironmentMap(),
+ registration.getCpuInfoMap());
+ addServiceTagRegistry(document,
+ registration.getRegistrationURN(),
+ registration.getServiceTags());
+ transform(document, os);
+ }
+
+ // initialize a document from an input stream
+ private static Document initializeDocument(InputStream in) throws IOException {
+ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+ SchemaFactory sf = null;
+ try {
+ // Some Java versions (e.g., 1.5.0_06-b05) fail with a
+ // NullPointerException if SchemaFactory.newInstance is called with
+ // a null context class loader, so work around that here (and the
+ // class loader of this class hopefully is not the null bootstrap
+ // class loader):
+ ClassLoader cl = Thread.currentThread().getContextClassLoader();
+ if (cl == null) {
+ Thread.currentThread().setContextClassLoader(
+ RegistrationDocument.class.getClassLoader());
+ }
+ try {
+ sf = SchemaFactory.newInstance(
+ XMLConstants.W3C_XML_SCHEMA_NS_URI);
+ } finally {
+ Thread.currentThread().setContextClassLoader(cl);
+ }
+
+ Schema schema = null;
+ try {
+ // Even using the workaround above is not enough on some
+ // Java versions. Therefore try to workaround the validation
+ // completely!
+ URL xsdUrl = RegistrationDocument.class.getResource(REGISTRATION_DATA_SCHEMA);
+ schema = sf.newSchema(xsdUrl);
+ }
+ catch (NullPointerException nex) {
+ }
+
+ Validator validator = null;
+ if (schema != null)
+ validator = schema.newValidator();
+
+ DocumentBuilder builder = factory.newDocumentBuilder();
+ Document doc = builder.parse(new InputSource(in));
+
+ if (validator != null)
+ validator.validate(new DOMSource(doc));
+
+ return doc;
+ } catch (SAXException sxe) {
+ IllegalArgumentException e = new IllegalArgumentException("Error generated in parsing");
+ e.initCause(sxe);
+ throw e;
+ } catch (ParserConfigurationException pce) {
+ // Parser with specific options can't be built
+ // should not reach here
+ InternalError x = new InternalError("Error in creating the new document");
+ x.initCause(pce);
+ throw x;
+ }
+ }
+
+ // initialize a new document for the registration data
+ private static Document initializeDocument() throws IOException {
+ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+ try {
+ DocumentBuilder builder = factory.newDocumentBuilder();
+ Document doc = builder.newDocument();
+
+ // initialize the document with the registration_data root
+ Element root = doc.createElement(ST_NODE_REGISTRATION_DATA);
+ doc.appendChild(root);
+ root.setAttribute(ST_ATTR_REGISTRATION_VERSION, REGISTRATION_DATA_VERSION);
+
+ return doc;
+ } catch (ParserConfigurationException pce) {
+ // Parser with specified options can't be built
+ // should not reach here
+ InternalError x = new InternalError("Error in creating the new document");
+ x.initCause(pce);
+ throw x;
+ }
+ }
+
+ // Transform the current DOM tree with the given output stream.
+ private static void transform(Document document, OutputStream os) {
+ try {
+ // Use a Transformer for output
+ TransformerFactory tFactory = TransformerFactory.newInstance();
+ tFactory.setAttribute("indent-number", new Integer(3));
+
+ Transformer transformer = tFactory.newTransformer();
+
+ transformer.setOutputProperty(OutputKeys.INDENT, "yes");
+ transformer.setOutputProperty(OutputKeys.METHOD, "xml");
+ transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
+ transformer.setOutputProperty(OutputKeys.STANDALONE, "yes");
+ transformer.transform(new DOMSource(document),
+ new StreamResult(new BufferedWriter(new OutputStreamWriter(os, "UTF-8"))));
+ } catch (UnsupportedEncodingException ue) {
+ // Should not reach here
+ InternalError x = new InternalError("Error generated during transformation");
+ x.initCause(ue);
+ throw x;
+ } catch (TransformerConfigurationException tce) {
+ // Error generated by the parser
+ // Should not reach here
+ InternalError x = new InternalError("Error in creating the new document");
+ x.initCause(tce);
+ throw x;
+ } catch (TransformerException te) {
+ // Error generated by the transformer
+ InternalError x = new InternalError("Error generated during transformation");
+ x.initCause(te);
+ throw x;
+ }
+ }
+
+ private static void addServiceTagRegistry(Document document,
+ String registryURN,
+ Set<ServiceTag> svcTags) {
+ // add service tag registry node and its attributes
+ Element reg = document.createElement(ST_NODE_REGISTRY);
+ reg.setAttribute(ST_ATTR_REGISTRY_URN, registryURN);
+ reg.setAttribute(ST_ATTR_REGISTRY_VERSION, SERVICE_TAG_VERSION);
+
+ Element root = getRegistrationDataRoot(document);
+ root.appendChild(reg);
+
+ // adds the elements for the service tags
+ for (ServiceTag st : svcTags) {
+ addServiceTagElement(document, reg, st);
+ }
+ }
+
+ private static void addServiceTagElement(Document document,
+ Element registryRoot,
+ ServiceTag st) {
+ Element svcTag = document.createElement(ST_NODE_SERVICE_TAG);
+ registryRoot.appendChild(svcTag);
+ addChildElement(document, svcTag,
+ ST_NODE_INSTANCE_URN, st.getInstanceURN());
+ addChildElement(document, svcTag,
+ ST_NODE_PRODUCT_NAME, st.getProductName());
+ addChildElement(document, svcTag,
+ ST_NODE_PRODUCT_VERSION, st.getProductVersion());
+ addChildElement(document, svcTag,
+ ST_NODE_PRODUCT_URN, st.getProductURN());
+ addChildElement(document, svcTag,
+ ST_NODE_PRODUCT_PARENT_URN, st.getProductParentURN());
+ addChildElement(document, svcTag,
+ ST_NODE_PRODUCT_PARENT, st.getProductParent());
+ addChildElement(document, svcTag,
+ ST_NODE_PRODUCT_DEFINED_INST_ID,
+ st.getProductDefinedInstanceID());
+ addChildElement(document, svcTag,
+ ST_NODE_PRODUCT_VENDOR, st.getProductVendor());
+ addChildElement(document, svcTag,
+ ST_NODE_PLATFORM_ARCH, st.getPlatformArch());
+ addChildElement(document, svcTag,
+ ST_NODE_TIMESTAMP, Util.formatTimestamp(st.getTimestamp()));
+ addChildElement(document, svcTag,
+ ST_NODE_CONTAINER, st.getContainer());
+ addChildElement(document, svcTag,
+ ST_NODE_SOURCE, st.getSource());
+ addChildElement(document, svcTag,
+ ST_NODE_INSTALLER_UID,
+ String.valueOf(st.getInstallerUID()));
+ }
+
+ private static void addChildElement(Document document, Element root,
+ String element, String text) {
+ Element node = document.createElement(element);
+ node.appendChild(document.createTextNode(text));
+ root.appendChild(node);
+ }
+
+ // Constructs service tags from the document
+ private static void addServiceTags(Element registryRoot,
+ RegistrationData registration) {
+ NodeList children = registryRoot.getElementsByTagName(ST_NODE_SERVICE_TAG);
+ int length = (children == null ? 0 : children.getLength());
+ for (int i = 0; i < length; i++) {
+ Element svcTagElement = (Element) children.item(i);
+ ServiceTag st = getServiceTag(svcTagElement);
+ registration.addServiceTag(st);
+ }
+ }
+
+ // build environment map from the document
+ private static void buildEnvironmentMap(Element envRoot,
+ RegistrationData registration) {
+ registration.setEnvironment(ST_NODE_HOSTNAME, getTextValue(envRoot, ST_NODE_HOSTNAME));
+ registration.setEnvironment(ST_NODE_HOST_ID, getTextValue(envRoot, ST_NODE_HOST_ID));
+ registration.setEnvironment(ST_NODE_OS_NAME, getTextValue(envRoot, ST_NODE_OS_NAME));
+ registration.setEnvironment(ST_NODE_OS_VERSION, getTextValue(envRoot, ST_NODE_OS_VERSION));
+ registration.setEnvironment(ST_NODE_OS_ARCH, getTextValue(envRoot, ST_NODE_OS_ARCH));
+ registration.setEnvironment(ST_NODE_SYSTEM_MODEL, getTextValue(envRoot, ST_NODE_SYSTEM_MODEL));
+ registration.setEnvironment(ST_NODE_SYSTEM_MANUFACTURER, getTextValue(envRoot, ST_NODE_SYSTEM_MANUFACTURER));
+ registration.setEnvironment(ST_NODE_CPU_MANUFACTURER, getTextValue(envRoot, ST_NODE_CPU_MANUFACTURER));
+ registration.setEnvironment(ST_NODE_SERIAL_NUMBER, getTextValue(envRoot, ST_NODE_SERIAL_NUMBER));
+ registration.setEnvironment(ST_NODE_PHYS_MEM, getTextValue(envRoot, ST_NODE_PHYS_MEM));
+ }
+
+ private static void buildCpuInfoMap(Element cpuInfoRoot,
+ RegistrationData registration) {
+ registration.setCpuInfo(ST_NODE_SOCKETS, getTextValue(cpuInfoRoot, ST_NODE_SOCKETS));
+ registration.setCpuInfo(ST_NODE_CORES, getTextValue(cpuInfoRoot, ST_NODE_CORES));
+ registration.setCpuInfo(ST_NODE_VIRT_CPUS, getTextValue(cpuInfoRoot, ST_NODE_VIRT_CPUS));
+ registration.setCpuInfo(ST_NODE_CPU_NAME, getTextValue(cpuInfoRoot, ST_NODE_CPU_NAME));
+ registration.setCpuInfo(ST_NODE_CLOCK_RATE, getTextValue(cpuInfoRoot, ST_NODE_CLOCK_RATE));
+ }
+
+ // add the nodes representing the environment map in the document
+ private static void addEnvironmentNodes(Document document,
+ Map<String, String> envMap,
+ Map<String, String> cpuInfoMap) {
+ Element root = getRegistrationDataRoot(document);
+
+ Element env = document.createElement(ST_NODE_ENVIRONMENT);
+ root.appendChild(env);
+ Set<Map.Entry<String, String>> keys = envMap.entrySet();
+ for (Map.Entry<String, String> entry : keys) {
+ addChildElement(document, env, entry.getKey(), entry.getValue());
+ }
+
+ Element cpuInfo = document.createElement(ST_NODE_CPU_INFO);
+ env.appendChild(cpuInfo);
+ keys = cpuInfoMap.entrySet();
+ for (Map.Entry<String, String> entry : keys) {
+ addChildElement(document, cpuInfo, entry.getKey(), entry.getValue());
+ }
+ }
+
+ private static Element getRegistrationDataRoot(Document doc) {
+ Element root = doc.getDocumentElement();
+ if (!root.getNodeName().equals(ST_NODE_REGISTRATION_DATA)) {
+ throw new IllegalArgumentException("Not a " +
+ ST_NODE_REGISTRATION_DATA +
+ " node \"" + root.getNodeName() + "\"");
+ }
+ return root;
+ }
+
+ private static Element getSingletonElementFromRoot(Element root, String name) {
+ NodeList children = root.getElementsByTagName(name);
+ int length = (children == null ? 0 : children.getLength());
+ if (length != 1) {
+ throw new IllegalArgumentException("Invalid number of " + name +
+ " nodes = " + length);
+ }
+ Element e = (Element) children.item(0);
+ if (!e.getNodeName().equals(name)) {
+ throw new IllegalArgumentException("Not a " + name +
+ " node \"" + e.getNodeName() + "\"");
+ }
+ return e;
+ }
+
+ // Constructs one ServiceTag instance from a service tag element root
+ private static ServiceTag getServiceTag(Element svcTagElement) {
+ return new ServiceTag(
+ getTextValue(svcTagElement, ST_NODE_INSTANCE_URN),
+ getTextValue(svcTagElement, ST_NODE_PRODUCT_NAME),
+ getTextValue(svcTagElement, ST_NODE_PRODUCT_VERSION),
+ getTextValue(svcTagElement, ST_NODE_PRODUCT_URN),
+ getTextValue(svcTagElement, ST_NODE_PRODUCT_PARENT),
+ getTextValue(svcTagElement, ST_NODE_PRODUCT_PARENT_URN),
+ getTextValue(svcTagElement, ST_NODE_PRODUCT_DEFINED_INST_ID),
+ getTextValue(svcTagElement, ST_NODE_PRODUCT_VENDOR),
+ getTextValue(svcTagElement, ST_NODE_PLATFORM_ARCH),
+ getTextValue(svcTagElement, ST_NODE_CONTAINER),
+ getTextValue(svcTagElement, ST_NODE_SOURCE),
+ Util.getIntValue(getTextValue(svcTagElement, ST_NODE_INSTALLER_UID)),
+ Util.parseTimestamp(getTextValue(svcTagElement, ST_NODE_TIMESTAMP))
+ );
+ }
+
+ private static String getTextValue(Element e, String tagName) {
+ String value = "";
+ NodeList nl = e.getElementsByTagName(tagName);
+ if (nl != null && nl.getLength() > 0) {
+ Element el = (Element) nl.item(0);
+ Node node = el.getFirstChild();
+ if (node != null) {
+ value = node.getNodeValue();
+ }
+ }
+ return value;
+ }
+}
diff --git a/desktop/source/registration/com/sun/star/servicetag/Registry.java b/desktop/source/registration/com/sun/star/servicetag/Registry.java
new file mode 100755
index 000000000000..1415a75fd28a
--- /dev/null
+++ b/desktop/source/registration/com/sun/star/servicetag/Registry.java
@@ -0,0 +1,553 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+package com.sun.star.servicetag;
+
+import java.io.*;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Properties;
+import java.util.Set;
+
+import static com.sun.star.servicetag.Util.*;
+import static com.sun.star.servicetag.RegistrationDocument.*;
+
+/**
+ * A service tag registry is a XML-based registry containing
+ * the list of {@link ServiceTag service tags} installed in the system.
+ * The {@code Registry} class provides interfaces
+ * to add, remove, update, and get a service tag from a service tag
+ * registry.
+ * This {@code Registry} class may not be supported
+ * on all systems. The {@link #isSupported} method
+ * can be called to determine if it is supported.
+ * <p>
+ * A registry may implement restrictions to only allow certain users
+ * to {@link #updateServiceTag update} and
+ * to {@link #removeServiceTag remove} a service tag record. Typically,
+ * only the owner of the service tag, the owner of the registry
+ * and superuser are authorized to update or remove a service tag in
+ * the registry.
+ *
+ * @see <a href="https://sn-tools.central.sun.com/twiki/bin/view/ServiceTags/ServiceTagDevGuideHelper">
+ * Service Tag User Guide</a>
+ */
+public class Registry {
+
+ private static final String STCLIENT_SOLARIS = "/usr/bin/stclient";
+ private static final String STCLIENT_LINUX = "/opt/sun/servicetag/bin/stclient";
+ // stclient exit value (see sthelper.h)
+ private static final int ST_ERR_NOT_AUTH = 245;
+ private static final int ST_ERR_REC_NOT_FOUND = 225;
+
+ // The stclient output has to be an exported interface
+ private static final String INSTANCE_URN_DESC = "Product instance URN=";
+ private static boolean initialized = false;
+ private static boolean supportsHelperClass = true; // default
+ private static File stclient = null;
+ private static String stclientPath = null;
+ private static Registry registry = new Registry();
+
+ // System properties for testing
+ private static String SVCTAG_STCLIENT_CMD = "servicetag.stclient.cmd";
+ private static String SVCTAG_STHELPER_SUPPORTED = "servicetag.sthelper.supported";
+
+ private Registry() {
+ }
+
+ private synchronized static String getSTclient() {
+ if (!initialized) {
+ // the system property always overrides the default setting
+ if (System.getProperty(SVCTAG_STHELPER_SUPPORTED) != null) {
+ supportsHelperClass = Boolean.getBoolean(SVCTAG_STHELPER_SUPPORTED);
+ }
+
+ // This is only used for testing
+ stclientPath = System.getProperty(SVCTAG_STCLIENT_CMD);
+ if (stclientPath != null) {
+ return stclientPath;
+ }
+
+ // Initialization to determine the platform's stclient pathname
+ String os = System.getProperty("os.name");
+ if (os.equals("SunOS")) {
+ stclient = new File(STCLIENT_SOLARIS);
+ } else if (os.equals("Linux")) {
+ stclient = new File(STCLIENT_LINUX);
+ } else if (os.startsWith("Windows")) {
+ stclient = getWindowsStClientFile();
+ } else {
+ if (isVerbose()) {
+ System.out.println("Running on non-Sun JDK");
+ }
+ }
+ initialized = true;
+ }
+
+ // com.sun.servicetag package has to be compiled with JDK 5 as well
+ // JDK 5 doesn't support the File.canExecute() method.
+ // Risk not checking isExecute() for the stclient command is very low.
+
+ if (stclientPath == null && stclient != null && stclient.exists()) {
+ stclientPath = stclient.getAbsolutePath();
+ }
+ return stclientPath;
+ }
+
+ /**
+ * Returns the system service tag registry. The {@code Registry} class
+ * may not be supported on some platforms; use the {@link #isSupported}
+ * method to determine if it is supported.
+ *
+ * @return the {@code Registry} object for the system service tag registry.
+ *
+ * @throws UnsupportedOperationException if the {@code Registry} class is
+ * not supported.
+ */
+ public static Registry getSystemRegistry() {
+ if (isSupported()) {
+ return registry;
+ } else {
+ throw new UnsupportedOperationException("Registry class is not supported");
+ }
+ }
+
+ /**
+ * Returns {@code true} if the {@code Registry} class is supported on this system.
+ *
+ * @return {@code true} if the {@code Registry} class is supported;
+ * otherwise, return {@code false}.
+ */
+ public static boolean isSupported() {
+ return (getSTclient() != null && supportsHelperClass);
+ }
+
+ private static List<String> getCommandList() {
+ // Set up the arguments to call stclient
+ List<String> command = new ArrayList<String>();
+ if (System.getProperty(SVCTAG_STCLIENT_CMD) != null) {
+ // This is for jtreg testing use. This will be set to something
+ // like:
+ // $JAVA_HOME/bin/java -cp $TEST_DIR \
+ // -Dstclient.registry.path=$TEST_DIR/registry.xml \
+ // SvcTagClient
+ // On Windows, the JAVA_HOME and TEST_DIR path could contain
+ // space e.g. c:\Program Files\Java\jdk1.6.0_05\bin\java.
+ // The SVCTAG_STCLIENT_CMD must be set with a list of
+ // space-separated parameters. If a parameter contains spaces,
+ // it must be quoted with '"'.
+
+ String cmd = getSTclient();
+ int len = cmd.length();
+ int i = 0;
+ while (i < len) {
+ char separator = ' ';
+ if (cmd.charAt(i) == '"') {
+ separator = '"';
+ i++;
+ }
+ // look for the separator or matched the closing '"'
+ int j;
+ for (j = i+1; j < len; j++) {
+ if (cmd.charAt(j) == separator) {
+ break;
+ }
+ }
+
+ if (i == j-1) {
+ // add an empty parameter
+ command.add("\"\"");
+ } else {
+ // double quotes and space are not included
+ command.add(cmd.substring(i,j));
+ }
+
+ // skip spaces
+ for (i = j+1; i < len; i++) {
+ if (!Character.isSpaceChar(cmd.charAt(i))) {
+ break;
+ }
+ }
+ }
+ if (isVerbose()) {
+ System.out.println("Command list:");
+ for (String s : command) {
+ System.out.println(s);
+ }
+ }
+ } else {
+ command.add(getSTclient());
+ }
+ return command;
+ }
+
+ // Returns null if the service tag record not found;
+ // or throw UnauthorizedAccessException or IOException
+ // based on the exitValue.
+ private static ServiceTag checkReturnError(int exitValue,
+ String output,
+ ServiceTag st) throws IOException {
+ switch (exitValue) {
+ case ST_ERR_REC_NOT_FOUND:
+ return null;
+ case ST_ERR_NOT_AUTH:
+ if (st != null) {
+ throw new UnauthorizedAccessException(
+ "Not authorized to access " + st.getInstanceURN() +
+ " installer_uid=" + st.getInstallerUID());
+ } else {
+ throw new UnauthorizedAccessException(
+ "Not authorized:" + output);
+ }
+ default:
+ throw new IOException("stclient exits with error" +
+ " (" + exitValue + ")\n" + output);
+ }
+ }
+
+ /**
+ * Adds a service tag to this registry.
+ * If the given service tag has an empty <tt>instance_urn</tt>,
+ * this helper class will generate a URN and place it in the
+ * copy of the service tag in this registry.
+ * This method will return the {@code ServiceTag} representing
+ * the service tag entry to this registry.
+ *
+ * @param st {@code ServiceTag} object
+ * @return a {@code ServiceTag} object representing the service tag
+ * entry to this registry.
+ *
+ * @throws IllegalArgumentException if a service tag of the same
+ * <tt>instance_urn</tt> already exists in this registry.
+ *
+ * @throws java.io.IOException if an I/O error occurs in this operation.
+ */
+ public ServiceTag addServiceTag(ServiceTag st) throws IOException {
+ List<String> command = getCommandList();
+ command.add("-a");
+ if (st.getInstanceURN().length() > 0) {
+ ServiceTag sysSvcTag = getServiceTag(st.getInstanceURN());
+ if (sysSvcTag != null) {
+ throw new IllegalArgumentException("Instance_urn = " +
+ st.getInstanceURN() + " already exists");
+ }
+ command.add("-i");
+ command.add(st.getInstanceURN());
+ }
+ command.add("-p");
+ command.add(st.getProductName());
+ command.add("-e");
+ command.add(st.getProductVersion());
+ command.add("-t");
+ command.add(st.getProductURN());
+ if (st.getProductParentURN().length() > 0) {
+ command.add("-F");
+ command.add(st.getProductParentURN());
+ }
+ command.add("-P");
+ command.add(st.getProductParent());
+ if (st.getProductDefinedInstanceID().length() > 0) {
+ command.add("-I");
+ command.add(st.getProductDefinedInstanceID());
+ }
+ command.add("-m");
+ command.add(st.getProductVendor());
+ command.add("-A");
+ command.add(st.getPlatformArch());
+ command.add("-z");
+ command.add(st.getContainer());
+ command.add("-S");
+ command.add(st.getSource());
+
+ BufferedReader in = null;
+ try {
+ ProcessBuilder pb = new ProcessBuilder(command);
+ Process p = pb.start();
+ String output = commandOutput(p);
+ if (isVerbose()) {
+ System.out.println("Output from stclient -a command:");
+ System.out.println(output);
+ }
+ String urn = "";
+ if (p.exitValue() == 0) {
+ // Obtain the instance urn from the stclient output
+ in = new BufferedReader(new StringReader(output));
+ String line = null;
+ while ((line = in.readLine()) != null) {
+ line = line.trim();
+ if (line.startsWith(INSTANCE_URN_DESC)) {
+ urn = line.substring(INSTANCE_URN_DESC.length());
+ break;
+ }
+ }
+ if (urn.length() == 0) {
+ throw new IOException("Error in creating service tag:\n" +
+ output);
+ }
+ return getServiceTag(urn);
+ } else {
+ return checkReturnError(p.exitValue(), output, st);
+ }
+ } finally {
+ if (in != null) {
+ in.close();
+ }
+ }
+ }
+
+ /**
+ * Removes a service tag of the given <tt>instance_urn</tt> from this
+ * registry.
+ *
+ * @param instanceURN the <tt>instance_urn</tt> of the service tag
+ * to be removed.
+ *
+ * @return the {@code ServiceTag} object removed from this registry;
+ * or {@code null} if the service tag does not exist in this registry.
+ *
+ * @throws UnauthorizedAccessException if the user is not authorized to
+ * remove the service tag of the given <tt>instance_urn</tt>
+ * from this registry.
+ *
+ * @throws java.io.IOException if an I/O error occurs in this operation.
+ */
+ public ServiceTag removeServiceTag(String instanceURN) throws IOException {
+ ServiceTag st = getServiceTag(instanceURN);
+ if (st == null) {
+ return null;
+ }
+
+ List<String> command = getCommandList();
+ command.add("-d");
+ command.add("-i");
+ command.add(instanceURN);
+
+ ProcessBuilder pb = new ProcessBuilder(command);
+ Process p = pb.start();
+ String output = commandOutput(p);
+ if (isVerbose()) {
+ System.out.println("Output from stclient -d command:");
+ System.out.println(output);
+ }
+ if (p.exitValue() == 0) {
+ return st;
+ } else {
+ return checkReturnError(p.exitValue(), output, st);
+ }
+ }
+
+ /**
+ * Updates the <tt>product_defined_instance_id</tt> in the service tag
+ * of the specified <tt>instance_urn</tt> in this registry.
+ *
+ * @param instanceURN the <tt>instance_urn</tt> of the service tag to be updated.
+ * @param productDefinedInstanceID the value of the
+ * <tt>product_defined_instance_id</tt> to be set.
+ *
+ * @return the updated {@code ServiceTag} object;
+ * or {@code null} if the service tag does not exist in this
+ * registry.
+ *
+ * @throws UnauthorizedAccessException if the user is not authorized to
+ * update the service tag from this registry.
+ *
+ * @throws IOException if an I/O error occurs in this operation.
+ */
+ public ServiceTag updateServiceTag(String instanceURN,
+ String productDefinedInstanceID)
+ throws IOException {
+ ServiceTag svcTag = getServiceTag(instanceURN);
+ if (svcTag == null) {
+ return null;
+ }
+
+ List<String> command = getCommandList();
+ command.add("-u");
+ command.add("-i");
+ command.add(instanceURN);
+ command.add("-I");
+ if (productDefinedInstanceID.length() > 0) {
+ command.add(productDefinedInstanceID);
+ } else {
+ command.add("\"\"");
+ }
+
+ ProcessBuilder pb = new ProcessBuilder(command);
+ Process p = pb.start();
+ String output = commandOutput(p);
+ if (isVerbose()) {
+ System.out.println("Output from stclient -u command:");
+ System.out.println(output);
+ }
+
+ if (p.exitValue() == 0) {
+ return getServiceTag(instanceURN);
+ } else {
+ return checkReturnError(p.exitValue(), output, svcTag);
+ }
+ }
+
+ /**
+ * Returns a {@code ServiceTag} object of the given <tt>instance_urn</tt>
+ * in this registry.
+ *
+ * @param instanceURN the <tt>instance_urn</tt> of the service tag
+ * @return a {@code ServiceTag} object of the given <tt>instance_urn</tt>
+ * in this registry; or {@code null} if not found.
+ *
+ * @throws java.io.IOException if an I/O error occurs in this operation.
+ */
+ public ServiceTag getServiceTag(String instanceURN) throws IOException {
+ if (instanceURN == null) {
+ throw new NullPointerException("instanceURN is null");
+ }
+
+ List<String> command = getCommandList();
+ command.add("-g");
+ command.add("-i");
+ command.add(instanceURN);
+
+ ProcessBuilder pb = new ProcessBuilder(command);
+ Process p = pb.start();
+ String output = commandOutput(p);
+ if (isVerbose()) {
+ System.out.println("Output from stclient -g command:");
+ System.out.println(output);
+ }
+ if (p.exitValue() == 0) {
+ return parseServiceTag(output);
+ } else {
+ return checkReturnError(p.exitValue(), output, null);
+ }
+ }
+
+ private ServiceTag parseServiceTag(String output) throws IOException {
+ BufferedReader in = null;
+ try {
+ Properties props = new Properties();
+ // parse the service tag output from stclient
+ in = new BufferedReader(new StringReader(output));
+ String line = null;
+ while ((line = in.readLine()) != null) {
+ if ((line = line.trim()).length() > 0) {
+ String[] ss = line.trim().split("=", 2);
+ if (ss.length == 2) {
+ props.setProperty(ss[0].trim(), ss[1].trim());
+ } else {
+ props.setProperty(ss[0].trim(), "");
+ }
+ }
+ }
+
+ String urn = props.getProperty(ST_NODE_INSTANCE_URN);
+ String productName = props.getProperty(ST_NODE_PRODUCT_NAME);
+ String productVersion = props.getProperty(ST_NODE_PRODUCT_VERSION);
+ String productURN = props.getProperty(ST_NODE_PRODUCT_URN);
+ String productParent = props.getProperty(ST_NODE_PRODUCT_PARENT);
+ String productParentURN = props.getProperty(ST_NODE_PRODUCT_PARENT_URN);
+ String productDefinedInstanceID =
+ props.getProperty(ST_NODE_PRODUCT_DEFINED_INST_ID);
+ String productVendor = props.getProperty(ST_NODE_PRODUCT_VENDOR);
+ String platformArch = props.getProperty(ST_NODE_PLATFORM_ARCH);
+ String container = props.getProperty(ST_NODE_CONTAINER);
+ String source = props.getProperty(ST_NODE_SOURCE);
+ int installerUID =
+ Util.getIntValue(props.getProperty(ST_NODE_INSTALLER_UID));
+ Date timestamp =
+ Util.parseTimestamp(props.getProperty(ST_NODE_TIMESTAMP));
+
+ return new ServiceTag(urn,
+ productName,
+ productVersion,
+ productURN,
+ productParent,
+ productParentURN,
+ productDefinedInstanceID,
+ productVendor,
+ platformArch,
+ container,
+ source,
+ installerUID,
+ timestamp);
+ } finally {
+ if (in != null) {
+ in.close();
+ }
+ }
+
+ }
+
+ /**
+ * Returns the service tags of the specified
+ * <tt>product_urn</tt> in this registry.
+ *
+ * @param productURN the <tt>product_urn</tt> to look up
+ * @return a {@code Set} of {@code ServiceTag} objects
+ * of the specified <tt>product_urn</tt> in this registry.
+ *
+ * @throws java.io.IOException if an I/O error occurs in this operation.
+ */
+ public Set<ServiceTag> findServiceTags(String productURN) throws IOException {
+ if (productURN == null) {
+ throw new NullPointerException("productURN is null");
+ }
+
+ List<String> command = getCommandList();
+ command.add("-f");
+ command.add("-t");
+ command.add(productURN);
+
+ BufferedReader in = null;
+ try {
+ ProcessBuilder pb = new ProcessBuilder(command);
+ Process p = pb.start();
+ String output = commandOutput(p);
+
+ Set<ServiceTag> instances = new HashSet<ServiceTag>();
+ if (p.exitValue() == 0) {
+ // parse the service tag output from stclient
+ in = new BufferedReader(new StringReader(output));
+ String line = null;
+ while ((line = in.readLine()) != null) {
+ String s = line.trim();
+ if (s.startsWith("urn:st:")) {
+ instances.add(getServiceTag(s));
+ }
+ }
+ } else {
+ checkReturnError(p.exitValue(), output, null);
+ }
+ return instances;
+ } finally {
+ if (in != null) {
+ in.close();
+ }
+ }
+ }
+}
diff --git a/desktop/source/registration/com/sun/star/servicetag/ServiceTag.java b/desktop/source/registration/com/sun/star/servicetag/ServiceTag.java
new file mode 100755
index 000000000000..4adb36772517
--- /dev/null
+++ b/desktop/source/registration/com/sun/star/servicetag/ServiceTag.java
@@ -0,0 +1,636 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+package com.sun.star.servicetag;
+
+import java.util.Date;
+import java.io.IOException;
+import static com.sun.star.servicetag.RegistrationDocument.*;
+
+/**
+ * A service tag is an XML-based data structure that identifies a product or
+ * a component on a system. The service tag schema is defined by the
+ * Service Tags Technology. The location of the DTD file is platform dependent.
+ * On Solaris, see <tt>/usr/share/lib/xml/dtd/servicetag.dtd</tt>.
+ * <p>
+ * A valid {@code ServiceTag} instance must comply to the service tag schema
+ * and contain the following fields:
+ * <ul>
+ * <li>{@link #getInstanceURN <tt>instance_urn</tt>}</li>
+ * <li>{@link #getProductName <tt>product_name</tt>}</li>
+ * <li>{@link #getProductVersion <tt>product_version</tt>}</li>
+ * <li>{@link #getProductURN <tt>product_urn</tt>}</li>
+ * <li>{@link #getProductParent <tt>product_parent</tt>}</li>
+ * <li>{@link #getProductParentURN <tt>product_parent_urn</tt>}</li>
+ * <li>{@link #getProductDefinedInstanceID <tt>product_defined_inst_id</tt>}</li>
+ * <li>{@link #getProductVendor <tt>product_vendor</tt>}</li>
+ * <li>{@link #getPlatformArch <tt>platform_arch</tt>}</li>
+ * <li>{@link #getContainer <tt>container</tt>}</li>
+ * <li>{@link #getSource <tt>source</tt>}</li>
+ * <li>{@link #getInstallerUID <tt>installer_uid</tt>}</li>
+ * <li>{@link #getTimestamp <tt>timestamp</tt>}</li>
+ * </ul>
+ *
+ * The <tt>instance_urn</tt> can be specified when a {@code ServiceTag}
+ * object is created, or it can be generated when it is added to
+ * a {@link RegistrationData} object, or {@link Registry
+ * system service tag registry}. The <tt>installer_uid</tt> and
+ * <tt>timestamp</tt> are set when a {@code ServiceTag} object
+ * is added to a {@link RegistrationData} object, or {@link Registry
+ * system service tag registry}.
+ *
+ * @see <a href="https://sunconnection.sun.com/FAQ/sc_faq.html">Service Tags FAQ</a>
+ */
+public class ServiceTag {
+
+ private String instanceURN;
+ private String productName;
+ private String productVersion;
+ private String productURN;
+ private String productParent;
+ private String productParentURN;
+ private String productDefinedInstanceID;
+ private String productVendor;
+ private String platformArch;
+ private String container;
+ private String source;
+ private int installerUID;
+ private Date timestamp;
+
+ // Service Tag Field Lengths (defined in sthelper.h)
+ // Since the constants defined in sthelper.h includes the null-terminated
+ // character, so minus 1 from the sthelper.h defined values.
+ private final int MAX_URN_LEN = 256 - 1;
+ private final int MAX_PRODUCT_NAME_LEN = 256 - 1;
+ private final int MAX_PRODUCT_VERSION_LEN = 64 - 1;
+ private final int MAX_PRODUCT_PARENT_LEN = 256 - 1;
+ private final int MAX_PRODUCT_VENDOR_LEN = 64 - 1;
+ private final int MAX_PLATFORM_ARCH_LEN = 64 - 1;
+ private final int MAX_CONTAINER_LEN = 64 - 1;
+ private final int MAX_SOURCE_LEN = 64 - 1;
+
+ // private constructors
+ private ServiceTag() {
+ }
+ // package private
+ ServiceTag(String instanceURN,
+ String productName,
+ String productVersion,
+ String productURN,
+ String productParent,
+ String productParentURN,
+ String productDefinedInstanceID,
+ String productVendor,
+ String platformArch,
+ String container,
+ String source,
+ int installerUID,
+ Date timestamp) {
+ setInstanceURN(instanceURN);
+ setProductName(productName);
+ setProductVersion(productVersion);
+ setProductURN(productURN);
+ setProductParentURN(productParentURN);
+ setProductParent(productParent);
+ setProductDefinedInstanceID(productDefinedInstanceID);
+ setProductVendor(productVendor);
+ setPlatformArch(platformArch);
+ setContainer(container);
+ setSource(source);
+ setInstallerUID(installerUID);
+ setTimestamp(timestamp);
+ }
+
+ /**
+ * Creates a service tag object with no <tt>instance_urn</tt>.
+ *
+ * @param productName the name of the product.
+ * @param productVersion the version of the product.
+ * @param productURN the uniform resource name of the product
+ * @param productParent the name of the product's parent.
+ * @param productParentURN the uniform resource name of the product's parent.
+ * @param productDefinedInstanceID the instance identifier.
+ * @param productVendor the vendor of the product.
+ * @param platformArch the operating system architecture.
+ * @param container the container of the product.
+ * @param source the source of the product.
+ *
+ * @throws IllegalArgumentException if any value of the input fields
+ * does not conform to the service tag XML schema.
+ */
+ public static ServiceTag newInstance(String productName,
+ String productVersion,
+ String productURN,
+ String productParent,
+ String productParentURN,
+ String productDefinedInstanceID,
+ String productVendor,
+ String platformArch,
+ String container,
+ String source) {
+ return new ServiceTag("", /* empty instance_urn */
+ productName,
+ productVersion,
+ productURN,
+ productParent,
+ productParentURN,
+ productDefinedInstanceID,
+ productVendor,
+ platformArch,
+ container,
+ source,
+ -1,
+ null);
+ }
+
+ /**
+ * Creates a service tag object with a specified <tt>instance_urn</tt>.
+ *
+ * @param instanceURN the uniform resource name of this instance.
+ * @param productName the name of the product.
+ * @param productVersion the version of the product.
+ * @param productURN the uniform resource name of the product
+ * @param productParent the name of the product's parent.
+ * @param productParentURN the uniform resource name of the product's parent.
+ * @param productDefinedInstanceID the instance identifier.
+ * @param productVendor the vendor of the product.
+ * @param platformArch the operating system architecture.
+ * @param container the container of the product.
+ * @param source the source of the product.
+ *
+ * @throws IllegalArgumentException if any value of the input fields
+ * does not conform to the service tag XML schema.
+ */
+ public static ServiceTag newInstance(String instanceURN,
+ String productName,
+ String productVersion,
+ String productURN,
+ String productParent,
+ String productParentURN,
+ String productDefinedInstanceID,
+ String productVendor,
+ String platformArch,
+ String container,
+ String source) {
+ return new ServiceTag(instanceURN,
+ productName,
+ productVersion,
+ productURN,
+ productParent,
+ productParentURN,
+ productDefinedInstanceID,
+ productVendor,
+ platformArch,
+ container,
+ source,
+ -1,
+ null);
+ }
+
+ // Creates a copy of the ServiceTag instance
+ // with instance_urn and timestamp initialized
+ static ServiceTag newInstanceWithUrnTimestamp(ServiceTag st) {
+ String instanceURN =
+ (st.getInstanceURN().length() == 0 ? Util.generateURN() :
+ st.getInstanceURN());
+ ServiceTag svcTag = new ServiceTag(instanceURN,
+ st.getProductName(),
+ st.getProductVersion(),
+ st.getProductURN(),
+ st.getProductParent(),
+ st.getProductParentURN(),
+ st.getProductDefinedInstanceID(),
+ st.getProductVendor(),
+ st.getPlatformArch(),
+ st.getContainer(),
+ st.getSource(),
+ st.getInstallerUID(),
+ new Date());
+ return svcTag;
+ }
+
+ /**
+ * Returns a uniform resource name (URN) in this format:
+ * <blockquote>
+ * "<tt>urn:st:<32-char {@link java.util.UUID uuid}></tt>"
+ * </blockquote>
+ * @return a URN.
+ */
+ public static String generateInstanceURN() {
+ return Util.generateURN();
+ }
+
+ /**
+ * Returns the uniform resource name of this service tag instance.
+ *
+ * @return the <tt>instance_urn</tt> of this service tag.
+ */
+ public String getInstanceURN() {
+ return instanceURN;
+ }
+
+ /**
+ * Returns the name of the product.
+ *
+ * @return the product name.
+ */
+ public String getProductName() {
+ return productName;
+ }
+
+ /**
+ * Returns the version of the product.
+ *
+ * @return the product version.
+ */
+ public String getProductVersion() {
+ return productVersion;
+ }
+
+ /**
+ * Returns the uniform resource name of the product.
+ *
+ * @return the product URN.
+ */
+ public String getProductURN() {
+ return productURN;
+ }
+
+ /**
+ * Returns the uniform resource name of the product's parent.
+ *
+ * @return the product's parent URN.
+ */
+ public String getProductParentURN() {
+ return productParentURN;
+ }
+
+ /**
+ * Returns the name of the product's parent.
+ *
+ * @return the product's parent name.
+ */
+ public String getProductParent() {
+ return productParent;
+ }
+
+ /**
+ * Returns the identifier defined for this product instance.
+ *
+ * @return the identifier defined for this product instance.
+ */
+ public String getProductDefinedInstanceID() {
+ return productDefinedInstanceID;
+ }
+
+ /**
+ * Returns the vendor of the product.
+ *
+ * @return the product vendor.
+ */
+ public String getProductVendor() {
+ return productVendor;
+ }
+
+ /**
+ * Returns the platform architecture on which the product
+ * is running on.
+ *
+ * @return the platform architecture on which the product is running on.
+ */
+ public String getPlatformArch() {
+ return platformArch;
+ }
+
+ /**
+ * Returns the timestamp. This timestamp is set when this service tag
+ * is added to or updated in a {@code RegistrationData} object or
+ * the system service tag registry.
+ * This method may return {@code null}.
+ *
+ * @return timestamp when this service tag
+ * is added to or updated in a {@code RegistrationData} object or
+ * the system service tag registry, or {@code null}.
+ */
+ public Date getTimestamp() {
+ if (timestamp != null) {
+ return (Date) timestamp.clone();
+ } else {
+ return null;
+ }
+ }
+
+
+ /**
+ * Returns the container of the product.
+ *
+ * @return the container of the product.
+ */
+ public String getContainer() {
+ return container;
+ }
+
+ /**
+ * Returns the source of this service tag.
+ *
+ * @return source of this service tag.
+ */
+ public String getSource() {
+ return source;
+ }
+
+ /**
+ * Returns the UID. The UID is set when this service tag
+ * is added to or updated in the system service tag registry.
+ * This is platform dependent whose default value is {@code -1}.
+ * When this service tag is added to a {@code RegistrationData},
+ * the UID is not set.
+ *
+ * @return the UID of whom this service tag
+ * is added to or updated in the system service tag registry,
+ * or {@code -1}.
+ */
+ public int getInstallerUID() {
+ return installerUID;
+ }
+
+ // The following setter methods are used to validate the
+ // input field when constructing a ServiceTag instance
+
+ private void setInstanceURN(String instanceURN) {
+ if (instanceURN == null) {
+ throw new NullPointerException("Parameter instanceURN cannot be null");
+ }
+ if (instanceURN.length() > MAX_URN_LEN) {
+ throw new IllegalArgumentException("instanceURN \"" + instanceURN +
+ "\" exceeds maximum length " + MAX_URN_LEN);
+ }
+ this.instanceURN = instanceURN;
+ }
+
+ private void setProductName(String productName) {
+ if (productName == null) {
+ throw new NullPointerException("Parameter productName cannot be null");
+ }
+ if (productName.length() == 0) {
+ throw new IllegalArgumentException("product name cannot be empty");
+ }
+ if (productName.length() > MAX_PRODUCT_NAME_LEN) {
+ throw new IllegalArgumentException("productName \"" + productName +
+ "\" exceeds maximum length " + MAX_PRODUCT_NAME_LEN);
+ }
+ this.productName = productName;
+ }
+
+ private void setProductVersion(String productVersion) {
+ if (productVersion == null) {
+ throw new NullPointerException("Parameter productVersion cannot be null");
+ }
+
+ if (productVersion.length() == 0) {
+ throw new IllegalArgumentException("product version cannot be empty");
+ }
+ if (productVersion.length() > MAX_PRODUCT_VERSION_LEN) {
+ throw new IllegalArgumentException("productVersion \"" +
+ productVersion + "\" exceeds maximum length " +
+ MAX_PRODUCT_VERSION_LEN);
+ }
+ this.productVersion = productVersion;
+ }
+
+ private void setProductURN(String productURN) {
+ if (productURN == null) {
+ throw new NullPointerException("Parameter productURN cannot be null");
+ }
+ if (productURN.length() == 0) {
+ throw new IllegalArgumentException("product URN cannot be empty");
+ }
+ if (productURN.length() > MAX_URN_LEN) {
+ throw new IllegalArgumentException("productURN \"" + productURN +
+ "\" exceeds maximum length " + MAX_URN_LEN);
+ }
+ this.productURN = productURN;
+ }
+
+ private void setProductParentURN(String productParentURN) {
+ if (productParentURN == null) {
+ throw new NullPointerException("Parameter productParentURN cannot be null");
+ }
+ // optional field - can be empty
+ if (productParentURN.length() > MAX_URN_LEN) {
+ throw new IllegalArgumentException("productParentURN \"" +
+ productParentURN + "\" exceeds maximum length " +
+ MAX_URN_LEN);
+ }
+ this.productParentURN = productParentURN;
+ }
+
+ private void setProductParent(String productParent) {
+ if (productParent == null) {
+ throw new NullPointerException("Parameter productParent cannot be null");
+ }
+ if (productParent.length() == 0) {
+ throw new IllegalArgumentException("product parent cannot be empty");
+ }
+ if (productParent.length() > MAX_PRODUCT_PARENT_LEN) {
+ throw new IllegalArgumentException("productParent \"" +
+ productParent + "\" exceeds maximum length " +
+ MAX_PRODUCT_PARENT_LEN);
+ }
+ this.productParent = productParent;
+ }
+
+ void setProductDefinedInstanceID(String productDefinedInstanceID) {
+ if (productDefinedInstanceID == null) {
+ throw new NullPointerException("Parameter productDefinedInstanceID cannot be null");
+ }
+ if (productDefinedInstanceID.length() > MAX_URN_LEN) {
+ throw new IllegalArgumentException("productDefinedInstanceID \"" +
+ productDefinedInstanceID + "\" exceeds maximum length " +
+ MAX_URN_LEN);
+ }
+ // optional field - can be empty
+ this.productDefinedInstanceID = productDefinedInstanceID;
+ }
+
+ private void setProductVendor(String productVendor) {
+ if (productVendor == null) {
+ throw new NullPointerException("Parameter productVendor cannot be null");
+ }
+ if (productVendor.length() == 0) {
+ throw new IllegalArgumentException("product vendor cannot be empty");
+ }
+ if (productVendor.length() > MAX_PRODUCT_VENDOR_LEN) {
+ throw new IllegalArgumentException("productVendor \"" +
+ productVendor + "\" exceeds maximum length " +
+ MAX_PRODUCT_VENDOR_LEN);
+ }
+ this.productVendor = productVendor;
+ }
+
+ private void setPlatformArch(String platformArch) {
+ if (platformArch == null) {
+ throw new NullPointerException("Parameter platformArch cannot be null");
+ }
+ if (platformArch.length() == 0) {
+ throw new IllegalArgumentException("platform architecture cannot be empty");
+ }
+ if (platformArch.length() > MAX_PLATFORM_ARCH_LEN) {
+ throw new IllegalArgumentException("platformArch \"" +
+ platformArch + "\" exceeds maximum length " +
+ MAX_PLATFORM_ARCH_LEN);
+ }
+ this.platformArch = platformArch;
+ }
+
+ private void setTimestamp(Date timestamp) {
+ // can be null
+ this.timestamp = timestamp;
+ }
+
+ private void setContainer(String container) {
+ if (container == null) {
+ throw new NullPointerException("Parameter container cannot be null");
+ }
+ if (container.length() == 0) {
+ throw new IllegalArgumentException("container cannot be empty");
+ }
+ if (container.length() > MAX_CONTAINER_LEN) {
+ throw new IllegalArgumentException("container \"" +
+ container + "\" exceeds maximum length " +
+ MAX_CONTAINER_LEN);
+ }
+ this.container = container;
+ }
+
+ private void setSource(String source) {
+ if (source == null) {
+ throw new NullPointerException("Parameter source cannot be null");
+ }
+ if (source.length() == 0) {
+ throw new IllegalArgumentException("source cannot be empty");
+ }
+ if (source.length() > MAX_SOURCE_LEN) {
+ throw new IllegalArgumentException("source \"" + source +
+ "\" exceeds maximum length " + MAX_SOURCE_LEN);
+ }
+ this.source = source;
+ }
+
+ private void setInstallerUID(int installerUID) {
+ this.installerUID = installerUID;
+ }
+
+ /**
+ * Compares this service tag to the specified object.
+ * The result is {@code true} if and only if the argument is
+ * not {@code null} and is a {@code ServiceTag} object whose
+ * <tt>instance_urn</tt> is the same as the
+ * <tt>instance_urn</tt> of this service tag.
+ *
+ * @return {@code true} if this service tag is the same as
+ * the specified object.
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == null || !(obj instanceof ServiceTag)) {
+ return false;
+ }
+ ServiceTag st = (ServiceTag) obj;
+ if (st == this) {
+ return true;
+ }
+ return st.getInstanceURN().equals(getInstanceURN());
+ }
+
+ /**
+ * Returns the hash code value for this service tag.
+ * @return the hash code value for this service tag.
+ */
+ @Override
+ public int hashCode() {
+ int hash = 7;
+ hash = 19 * hash + (this.instanceURN != null ? this.instanceURN.hashCode() : 0);
+ return hash;
+ }
+
+ /**
+ * Returns the string representation of this service tag.
+ * The format is implementation specific.
+ *
+ * @return the string representation of this service tag.
+ */
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append(ST_NODE_INSTANCE_URN).append("=").append(instanceURN).append("\n");
+ sb.append(ST_NODE_PRODUCT_NAME).append("=").append(productName).append("\n");
+ sb.append(ST_NODE_PRODUCT_VERSION).append("=").append(productVersion).append("\n");
+ sb.append(ST_NODE_PRODUCT_URN).append("=").append(productURN).append("\n");
+ sb.append(ST_NODE_PRODUCT_PARENT_URN).append("=").append(productParentURN).append("\n");
+ sb.append(ST_NODE_PRODUCT_PARENT).append("=").append(productParent).append("\n");
+ sb.append(ST_NODE_PRODUCT_DEFINED_INST_ID).append("=").append(productDefinedInstanceID).append("\n");
+ sb.append(ST_NODE_PRODUCT_VENDOR).append("=").append(productVendor).append("\n");
+ sb.append(ST_NODE_PLATFORM_ARCH).append("=").append(platformArch).append("\n");
+ sb.append(ST_NODE_TIMESTAMP).append("=").append(Util.formatTimestamp(timestamp)).append("\n");
+ sb.append(ST_NODE_CONTAINER).append("=").append(container).append("\n");
+ sb.append(ST_NODE_SOURCE).append("=").append(source).append("\n");
+ sb.append(ST_NODE_INSTALLER_UID).append("=").append(String.valueOf(installerUID)).append("\n");
+ return sb.toString();
+ }
+
+
+ /**
+ * Returns the {@link ServiceTag} instance for the running Java
+ * platform. The {@link ServiceTag#setSource source} field
+ * of the {@code ServiceTag} will be set to the given {@code source}.
+ * This method will return {@code null} if there is no service tag
+ * for the running Java platform.
+ * <p>
+ * This method is designed for Sun software that bundles the JDK
+ * or the JRE to use. It is recommended that the {@code source}
+ * string contains information about the bundling software
+ * such as the name and the version of the software bundle,
+ * for example,
+ * <blockquote>
+ * <tt>NetBeans IDE 6.0 with JDK 6 Update 5 Bundle</tt>
+ * </blockquote>
+ * in a NetBeans/JDK bundle.
+ * <p>
+ * At the first time to call this method the application
+ * is required to have the write permission to the installed
+ * directory of this running JDK or JRE instance.
+ *
+ * @param source the source that bundles the JDK or the JRE.
+ * @return a {@code ServiceTag} object for the Java platform,
+ * or {@code null} if not supported.
+ * @throws IOException if an error occurs in this operation.
+ */
+ public static ServiceTag getJavaServiceTag(String source) throws IOException {
+ return Installer.getJavaServiceTag(source);
+ }
+
+}
diff --git a/desktop/source/registration/com/sun/star/servicetag/SolarisServiceTag.java b/desktop/source/registration/com/sun/star/servicetag/SolarisServiceTag.java
new file mode 100755
index 000000000000..4f99d890577f
--- /dev/null
+++ b/desktop/source/registration/com/sun/star/servicetag/SolarisServiceTag.java
@@ -0,0 +1,64 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+package com.sun.star.servicetag;
+
+import java.io.IOException;
+import java.util.Set;
+
+/**
+ * Utility class to obtain the service tag for the Solaris Operating System.
+ */
+class SolarisServiceTag {
+ private final static String[] SolarisProductURNs = new String[] {
+ "urn:uuid:a7a38948-2bd5-11d6-98ce-9d3ac1c0cfd7", /* Solaris 8 */
+ "urn:uuid:4f82caac-36f3-11d6-866b-85f428ef944e", /* Solaris 9 */
+ "urn:uuid:a19de03b-48bc-11d9-9607-080020a9ed93", /* Solaris 9 sparc */
+ "urn:uuid:4c35c45b-4955-11d9-9607-080020a9ed93", /* Solaris 9 x86 */
+ "urn:uuid:5005588c-36f3-11d6-9cec-fc96f718e113", /* Solaris 10 */
+ "urn:uuid:6df19e63-7ef5-11db-a4bd-080020a9ed93" /* Solaris 11 */
+ };
+
+ /**
+ * Returns null if not found.
+ *
+ * There is only one service tag for the operating system.
+ */
+ static ServiceTag getServiceTag() throws IOException {
+ if (Registry.isSupported()) {
+ Registry streg = Registry.getSystemRegistry();
+ for (String parentURN : SolarisProductURNs) {
+ Set<ServiceTag> instances = streg.findServiceTags(parentURN);
+ for (ServiceTag st : instances) {
+ // there should have only one service tag for the OS
+ return st;
+ }
+ }
+ }
+ return null;
+ }
+}
diff --git a/desktop/source/registration/com/sun/star/servicetag/SolarisSystemEnvironment.java b/desktop/source/registration/com/sun/star/servicetag/SolarisSystemEnvironment.java
new file mode 100755
index 000000000000..4a5a980938e1
--- /dev/null
+++ b/desktop/source/registration/com/sun/star/servicetag/SolarisSystemEnvironment.java
@@ -0,0 +1,420 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+package com.sun.star.servicetag;
+
+// The Service Tags team maintains the latest version of the implementation
+// for system environment data collection. JDK will include a copy of
+// the most recent released version for a JDK release. We rename
+// the package to com.sun.servicetag so that the Sun Connection
+// product always uses the latest version from the com.sun.scn.servicetags
+// package. JDK and users of the com.sun.servicetag API
+// (e.g. NetBeans and SunStudio) will use the version in JDK.
+
+import java.io.*;
+import java.util.Set;
+import java.util.HashSet;
+
+/**
+ * Solaris implementation of the SystemEnvironment class.
+ */
+class SolarisSystemEnvironment extends SystemEnvironment {
+ private static final int SN = 1;
+ private static final int SYS = 2;
+ private static final int CPU = 3;
+ private static final int MODEL = 4;
+ private String kstatCpuInfo = null;
+
+ SolarisSystemEnvironment() {
+ setHostId(getCommandOutput("/usr/bin/hostid"));
+ setSystemModel(getSolarisModel());
+ setSystemManufacturer(getSolarisSystemManufacturer());
+ setCpuManufacturer(getSolarisCpuManufacturer());
+ setSerialNumber(getSolarisSN());
+ setPhysMem(getSolarisPhysMem());
+ setSockets(getSolarisSockets());
+ setCores(getSolarisCores());
+ setVirtCpus(getSolarisVirtCpus());
+ setCpuName(getSolarisCpuName());
+ setClockRate(getSolarisClockRate());
+ }
+
+ private String getSolarisClockRate() {
+ String data = getSolarisKstatCpuInfo();
+
+ String lines[] = data.split("\n");
+ String token = "clock_MHz";
+ for (int i=0; i<lines.length; i++) {
+ String line = lines[i].trim();
+ if (line.startsWith(token)) {
+ return line.substring(line.indexOf(token) + token.length()).trim();
+ }
+ }
+ return "";
+ }
+
+ private String getSolarisCpuName() {
+ String data = getSolarisKstatCpuInfo();
+
+ String lines[] = data.split("\n");
+ String token = "brand";
+ for (int i=0; i<lines.length; i++) {
+ String line = lines[i].trim();
+ if (line.startsWith(token)) {
+ return line.substring(line.indexOf(token) + token.length()).trim();
+ }
+ }
+ return "";
+ }
+
+ private String getSolarisVirtCpus() {
+ String data = getSolarisKstatCpuInfo();
+
+ int cnt = 0;
+ String lines[] = data.split("\n");
+ String token = " cpu_info ";
+ for (int i=0; i<lines.length; i++) {
+ String line = lines[i].trim();
+ if (line.indexOf(token) != -1) {
+ cnt++;
+ }
+ }
+ return "" + cnt;
+ }
+
+ private String getSolarisCores() {
+ String data = getSolarisKstatCpuInfo();
+
+ Set<String> set = new HashSet<String>();
+ String lines[] = data.split("\n");
+ String coreIdToken = "core_id";
+ String coreId = "";
+ String chipIdToken = "chip_id";
+ String chipId = "";
+ for (int i=0; i<lines.length; i++) {
+ String line = lines[i].trim();
+ if (line.startsWith(chipIdToken)) {
+ chipId = line.substring(line.indexOf(chipIdToken) + chipIdToken.length()).trim();
+ }
+ if (line.startsWith(coreIdToken)) {
+ coreId = line.substring(line.indexOf(coreIdToken) + coreIdToken.length()).trim();
+ set.add(chipId + "," + coreId);
+ }
+ }
+ return "" + set.size();
+ }
+
+ private String getSolarisPhysMem() {
+ String data = getCommandOutput("/usr/sbin/prtconf");
+
+ int cnt = 0;
+ String lines[] = data.split("\n");
+ String token = "Memory size:";
+ for (int i=0; i<lines.length; i++) {
+ String line = lines[i].trim();
+ if (line.startsWith(token)) {
+ line = line.substring(line.indexOf(token) + token.length()).trim();
+ if (line.indexOf(" ") != -1) {
+ return line.substring(0, line.indexOf(" ")).trim();
+ }
+ }
+ }
+ return "";
+ }
+
+ private String getSolarisSockets() {
+ String data = getSolarisKstatCpuInfo();
+
+ Set<String> set = new HashSet<String>();
+ String lines[] = data.split("\n");
+ String token = "chip_id";
+ for (int i=0; i<lines.length; i++) {
+ String line = lines[i].trim();
+ if (line.startsWith(token)) {
+ String id = line.substring(line.indexOf(token) + token.length()).trim();
+ set.add(id);
+ }
+ }
+ return "" + set.size();
+ }
+
+ private synchronized String getSolarisKstatCpuInfo() {
+ // only try to get kstat cpu_info information once, after that, we can
+ // reuse the output
+ if (kstatCpuInfo == null) {
+ Thread thread = new Thread() {
+ public void run() {
+ kstatCpuInfo = getCommandOutput("/usr/bin/kstat", "cpu_info");
+ }
+ };
+ thread.start();
+
+ try {
+ thread.join(2000);
+ if (thread.isAlive()) {
+ thread.interrupt();
+ kstatCpuInfo = "";
+ }
+ } catch (InterruptedException ie) {
+ thread.interrupt();
+ }
+ }
+ return kstatCpuInfo;
+ }
+
+ private String getSolarisModel() {
+ String tmp = getFileContent("/var/run/psn");
+ if (tmp.length() > 0) {
+ String[] lines = tmp.split("\n");
+ if (MODEL <= lines.length) {
+ return lines[MODEL-1] + "::"
+ + getCommandOutput("/usr/bin/uname", "-v");
+ }
+ }
+
+ if ("sparc".equalsIgnoreCase(System.getProperty("os.arch"))) {
+ return getCommandOutput("/usr/bin/uname", "-i") + "::"
+ + getCommandOutput("/usr/bin/uname", "-v");
+ } else {
+ String model = getSmbiosData("1", "Product: ");
+ if (model == null || model.trim().equals("")) {
+ model = getCommandOutput("/usr/bin/uname", "-i");
+ }
+ if (model == null) {
+ model = "";
+ }
+ return model.trim() + "::"
+ + getCommandOutput("/usr/bin/uname", "-v");
+ }
+ }
+
+ /**
+ * Tries to obtain the cpu manufacturer.
+ * @return The cpu manufacturer (an empty string if not found or an error occurred)
+ */
+ private String getSolarisCpuManufacturer() {
+ String tmp = getFileContent("/var/run/psn");
+ if (tmp.length() > 0) {
+ String[] lines = tmp.split("\n");
+ if (CPU <= lines.length) {
+ return lines[CPU-1];
+ }
+ }
+
+ // not fully accurate, this could be another manufacturer (fujitsu for example)
+ if ("sparc".equalsIgnoreCase(System.getProperty("os.arch"))) {
+ return "Sun Microsystems, Inc";
+ }
+
+ // if we're here, then we'll try smbios (type 4)
+ return getSmbiosData("4", "Manufacturer: ");
+ }
+
+ /**
+ * Tries to obtain the system manufacturer.
+ * @return The system manufacturer (an empty string if not found or an error occurred)
+ */
+ private String getSolarisSystemManufacturer() {
+ String tmp = getFileContent("/var/run/psn");
+ if (tmp.length() > 0) {
+ String[] lines = tmp.split("\n");
+ if (SYS <= lines.length) {
+ return lines[SYS-1];
+ }
+ }
+
+ // not fully accurate, this could be another manufacturer (fujitsu for example)
+ if ("sparc".equalsIgnoreCase(System.getProperty("os.arch"))) {
+ if (getCommandOutput("/usr/bin/uname", "-m").equals("sun4us")) {
+ return "Fujitsu";
+ }
+ return "Sun Microsystems, Inc";
+ }
+
+ // if we're here, then we'll try smbios (type 1)
+ return getSmbiosData("1", "Manufacturer: ");
+ }
+
+ /**
+ * Tries to obtain the serial number.
+ * @return The serial number (empty string if not found or an error occurred)
+ */
+ private String getSolarisSN() {
+ // try to read from the psn file if it exists
+ String tmp = getFileContent("/var/run/psn");
+ if (tmp.length() > 0) {
+ String[] lines = tmp.split("\n");
+ if (SN <= lines.length) {
+ return lines[SN-1];
+ }
+ }
+
+ // if we're here, then we'll try sneep
+ String tmpSN = getSneepSN();
+ if (tmpSN.length() > 0) {
+ return tmpSN;
+ }
+
+ // if we're here, then we'll try smbios (type 1)
+ tmpSN = getSmbiosData("1", "Serial Number: ");
+ if (tmpSN.length() > 0) {
+ return tmpSN;
+ }
+
+ // if we're here, then we'll try smbios (type 3)
+ tmpSN = getSmbiosData("3", "Serial Number: ");
+ if (tmpSN.length() > 0) {
+ return tmpSN;
+ }
+
+ if ("sparc".equalsIgnoreCase(System.getProperty("os.arch"))) {
+ tmpSN = getSNViaPrtfruX();
+ if (tmpSN.length() > 0) {
+ return tmpSN;
+ }
+ tmpSN = getSNViaPrtfru();
+ if (tmpSN.length() > 0) {
+ return tmpSN;
+ }
+ }
+
+ // give up and return
+ return "";
+ }
+
+ // Sample smbios output segment:
+ // ID SIZE TYPE
+ // 1 150 SMB_TYPE_SYSTEM (system information)
+ // Manufacturer: Sun Microsystems
+ // Product: Sun Fire X4600
+ // Version: To Be Filled By O.E.M.
+ // Serial Number: 00:14:4F:45:0C:2A
+ private String getSmbiosData(String type, String target) {
+ String output = getCommandOutput("/usr/sbin/smbios", "-t", type);
+ for (String s : output.split("\n")) {
+ if (s.contains(target)) {
+ int indx = s.indexOf(target) + target.length();
+ if (indx < s.length()) {
+ String tmp = s.substring(indx).trim();
+ String lowerCaseStr = tmp.toLowerCase();
+ if (!lowerCaseStr.startsWith("not available")
+ && !lowerCaseStr.startsWith("to be filled by o.e.m")) {
+ return tmp;
+ }
+ }
+ }
+ }
+
+ return "";
+ }
+
+ private String getSneepSN() {
+ String basedir = getCommandOutput("pkgparam","SUNWsneep","BASEDIR");
+ File f = new File(basedir + "/bin/sneep");
+ if (f.exists()) {
+ String sneepSN = getCommandOutput(basedir + "/bin/sneep");
+ if (sneepSN.equalsIgnoreCase("unknown")) {
+ return "";
+ } else {
+ return sneepSN;
+ }
+ } else {
+ return "";
+ }
+ }
+
+ private String getSNViaPrtfruX() {
+ String data = getCommandOutput("/usr/sbin/prtfru", "-x");
+
+ boolean FRUTREE_FLAG = false;
+ boolean FRUNAME_FLAG = false;
+ boolean MB_LABEL_FLAG = false;
+ boolean SYSTEM_BOARD_FLAG = false;
+
+ String lines[] = data.split("\n");
+ for (int i=0; i<lines.length; i++) {
+ String line = lines[i];
+ if (SYSTEM_BOARD_FLAG) {
+ String tok = "<Sun_Serial_No value=\"";
+ int index = line.indexOf(tok);
+ if (index != -1) {
+ String val = line.substring(index+tok.length());
+ String vals[] = val.split("\"");
+ if (vals.length > 0) {
+ return vals[0].trim();
+ }
+ break;
+ }
+ }
+
+ if (line.indexOf("</ContainerData>") != -1) {
+ FRUTREE_FLAG = false;
+ FRUNAME_FLAG = false;
+ SYSTEM_BOARD_FLAG = false;
+ }
+
+ if (FRUNAME_FLAG && line.indexOf("<Container name=\"system-board\">") != -1 ) {
+ SYSTEM_BOARD_FLAG = true;
+ }
+
+ if (FRUTREE_FLAG && line.indexOf("<Fru name=\"chassis\">") != -1 ) {
+ FRUNAME_FLAG = true;
+ }
+
+ if (line.indexOf("<Location name=\"frutree\">") != -1) {
+ FRUTREE_FLAG = true;
+ }
+ }
+
+ return "";
+ }
+
+ private String getSNViaPrtfru() {
+ String data = getCommandOutput("/usr/sbin/prtfru");
+ boolean CHASSIS_FLAG = false;
+
+ String lines[] = data.split("\n");
+ for (int i=0; i<lines.length; i++) {
+ String line = lines[i];
+ if (CHASSIS_FLAG) {
+ String tok = "/ManR/Sun_Serial_No:";
+ int index = line.indexOf(tok);
+ if (index != -1) {
+ String val = line.substring(index+tok.length());
+ return val.trim();
+ }
+ }
+
+ if (line.indexOf("/frutree/chassis/system-board (container)") != -1) {
+ CHASSIS_FLAG = true;
+ } else if (line.indexOf("/frutree/chassis/MB?Label=MB/system-board (container)") != -1) {
+ CHASSIS_FLAG = true;
+ }
+ }
+ return "";
+ }
+}
diff --git a/desktop/source/registration/com/sun/star/servicetag/SunConnection.java b/desktop/source/registration/com/sun/star/servicetag/SunConnection.java
new file mode 100755
index 000000000000..db525ea637f4
--- /dev/null
+++ b/desktop/source/registration/com/sun/star/servicetag/SunConnection.java
@@ -0,0 +1,292 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+package com.sun.star.servicetag;
+
+import java.io.*;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.io.OutputStreamWriter;
+import java.util.Locale;
+import javax.net.ssl.HttpsURLConnection;
+
+/**
+ * Sun Connection Class for Product Registration.
+ *
+ * Registration Web Application Interface
+ * 1) POST the product registry to the output stream of the registration
+ * relay service.
+ * 2) Open the webapp URL from a browser with the following parameters:
+ * registry-urn
+ * product=jdk
+ * locale=<locale-lang>
+ *
+ * @see https://sn-tools.central.sun.com/twiki/pub/ServiceTags/RegistrationRelayService/
+ *
+ */
+class SunConnection {
+
+ private static String JDK_REGISTRATION_URL =
+ "https://inventory.sun.com/RegistrationWeb/register";
+ private static String SANDBOX_TESTING_URL =
+ "https://connection-tst.sun.com/RegistrationWeb/register";
+
+ // System properties for testing
+ private static String SVCTAG_REGISTER_TESTING = "servicetag.register.testing";
+ private static String SVCTAG_REGISTRATION_URL = "servicetag.registration.url";
+ private static String SVCTAG_CONNECTION_TIMEOUT = "servicetag.connection.timeout";
+
+ private SunConnection() {
+ }
+
+ /**
+ * Returns a URL for JDK registration interfacing with the Sun Connection
+ * registration relay service in this form:
+ * <registration-url>/<registry_urn>?product=jdk&locale=<locale-lang>
+ *
+ * The <registration-url> can be overridden by an environment
+ * variable or a system property.
+ *
+ * 1) "servicetag.register.testing" system property to switch to the
+ * Sun Connection registration sandbox testing.
+ * 2) "servicetag.registration.url" system property to override
+ * the URL
+ * 3) Default production URL
+ *
+ */
+ static URL getRegistrationURL(String registrationURN) {
+ String url = System.getProperty(SVCTAG_REGISTRATION_URL);
+ if (url == null) {
+ if (System.getProperty(SVCTAG_REGISTER_TESTING) != null) {
+ url = SANDBOX_TESTING_URL;
+ } else {
+ url = JDK_REGISTRATION_URL;
+ }
+ }
+
+ // trim whitespaces
+ url = url.trim();
+ if (url.length() == 0) {
+ throw new InternalError("Empty registration url set");
+ }
+
+ // Add the registry_urn in the URL's query
+ String registerURL = rewriteURL(url, registrationURN);
+ try {
+ return new URL(registerURL);
+ } catch (MalformedURLException ex) {
+ // should never reach here
+ InternalError x =
+ new InternalError(ex.getMessage());
+ x.initCause(ex);
+ throw x;
+ }
+ }
+
+ private static String rewriteURL(String url, String registryURN) {
+ StringBuilder sb = new StringBuilder(url.trim());
+ int len = sb.length();
+ if (sb.charAt(len-1) != '/') {
+ sb.append('/');
+ }
+ sb.append(registryURN);
+ sb.append("?");
+ sb.append("product=jdk");
+ sb.append("&");
+ sb.append("locale=").append(Locale.getDefault().getLanguage());
+ return sb.toString();
+ }
+
+ /**
+ * Registers all products in the given product registry. If it fails
+ * to post the service tag registry, open the browser with the offline
+ * registration page.
+ *
+ * @param regData registration data to be posted to the Sun Connection
+ * for registration.
+ *
+ * @throws IOException if I/O error occurs in this operation
+ */
+ public static void register(RegistrationData regData) throws IOException {
+ // Gets the URL for SunConnection registration relay service
+ URL url = getRegistrationURL(regData.getRegistrationURN());
+
+ // Post the Product Registry to Sun Connection
+ boolean succeed = postRegistrationData(url, regData);
+ if (succeed) {
+ // service tags posted successfully
+ // now prompt for registration
+ openBrowser(url);
+ } else {
+ // open browser with the offline registration page
+ openOfflineRegisterPage();
+ }
+ }
+
+ /**
+ * Opens a browser for JDK product registration.
+ * @param url Registration Webapp URL
+ */
+ private static void openBrowser(URL url) throws IOException {
+ if (!BrowserSupport.isSupported()) {
+ if (Util.isVerbose()) {
+ System.out.println("Browser is not supported");
+ }
+ return;
+ }
+
+ try {
+ BrowserSupport.browse(url.toURI());
+ } catch (URISyntaxException ex) {
+ InternalError x = new InternalError("Error in registering: " + ex.getMessage());
+ x.initCause(ex);
+ throw x;
+ } catch (IllegalArgumentException ex) {
+ if (Util.isVerbose()) {
+ ex.printStackTrace();
+ }
+ } catch (UnsupportedOperationException ex) {
+ // ignore if not supported
+ if (Util.isVerbose()) {
+ ex.printStackTrace();
+ }
+ }
+ }
+
+ /**
+ * POST service tag registry to Sun Connection
+ * @param loc the URL of the webapp to handle the POST request
+ * @param streg the Service Tag registry
+ * @return true if posting succeeds; otherwise, false.
+ */
+ private static boolean postRegistrationData(URL url,
+ RegistrationData registration) {
+ try {
+ HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
+ con.setDoInput(true);
+ con.setDoOutput(true);
+ con.setUseCaches(false);
+ con.setAllowUserInteraction(false);
+
+ // default 10 seconds timeout
+ String timeout = System.getProperty(SVCTAG_CONNECTION_TIMEOUT, "10");
+ con.setConnectTimeout(Util.getIntValue(timeout) * 1000);
+
+ if (Util.isVerbose()) {
+ System.out.println("Connecting to post registration data at " + url);
+ }
+
+ con.setRequestMethod("POST");
+ con.setRequestProperty("Content-Type", "text/xml;charset=\"utf-8\"");
+ con.connect();
+
+ OutputStream out = con.getOutputStream();
+ registration.storeToXML(out);
+ out.flush();
+ out.close();
+
+ int returnCode = con.getResponseCode();
+ if (Util.isVerbose()) {
+ System.out.println("POST return status = " + returnCode);
+ printReturnData(con, returnCode);
+ }
+ return (returnCode == HttpURLConnection.HTTP_OK);
+ } catch (MalformedURLException me) {
+ // should never reach here
+ InternalError x = new InternalError("Error in registering: " + me.getMessage());
+ x.initCause(me);
+ throw x;
+ } catch (Exception ioe) {
+ // SocketTimeoutException, IOException or UnknownHostException
+ if (Util.isVerbose()) {
+ ioe.printStackTrace();
+ }
+ return false;
+ }
+ }
+
+ /**
+ * Opens the offline registratioin page in the browser.
+ *
+ */
+ private static void openOfflineRegisterPage()
+ throws IOException {
+ if (!BrowserSupport.isSupported()) {
+ if (Util.isVerbose()) {
+ System.out.println("Browser is not supported");
+ }
+ return;
+ }
+
+ File registerPage = Installer.getRegistrationHtmlPage();
+ try {
+ BrowserSupport.browse(registerPage.toURI());
+ } catch (FileNotFoundException ex) {
+ // should never reach here
+ InternalError x =
+ new InternalError("Error in launching " + registerPage + ": " + ex.getMessage());
+ x.initCause(ex);
+ throw x;
+ } catch (IllegalArgumentException ex) {
+ if (Util.isVerbose()) {
+ ex.printStackTrace();
+ }
+ } catch (UnsupportedOperationException ex) {
+ // ignore if not supported
+ if (Util.isVerbose()) {
+ ex.printStackTrace();
+ }
+ }
+ }
+
+ private static void printReturnData(HttpURLConnection con, int returnCode)
+ throws IOException {
+ BufferedReader reader = null;
+ try {
+ if (returnCode < 400) {
+ reader = new BufferedReader(
+ new InputStreamReader(con.getInputStream()));
+ } else {
+ reader = new BufferedReader(
+ new InputStreamReader(con.getErrorStream()));
+ }
+ StringBuilder sb = new StringBuilder();
+ String line;
+ while ((line = reader.readLine()) != null) {
+ sb.append(line).append("\n");
+ }
+ System.out.println("Response is : ");
+ System.out.println(sb.toString());
+ } finally {
+ if (reader != null) {
+ reader.close();
+ }
+ }
+ }
+}
diff --git a/desktop/source/registration/com/sun/star/servicetag/SysnetRegistryHelper.java b/desktop/source/registration/com/sun/star/servicetag/SysnetRegistryHelper.java
new file mode 100755
index 000000000000..362136cc6f46
--- /dev/null
+++ b/desktop/source/registration/com/sun/star/servicetag/SysnetRegistryHelper.java
@@ -0,0 +1,375 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+package com.sun.star.servicetag;
+
+import java.io.*;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Properties;
+import java.util.Set;
+
+import static com.sun.star.servicetag.Util.*;
+import static com.sun.star.servicetag.RegistrationDocument.*;
+
+/**
+ * Class containing additional methods that are not yet
+ * in the JDK Registry class. Note that all methods in this class
+ * will be superceeded by the JDK classes.
+ */
+public class SysnetRegistryHelper {
+
+ private static final String STCLIENT_SOLARIS = "/usr/bin/stclient";
+ private static final String STCLIENT_LINUX = "/opt/sun/servicetag/bin/stclient";
+ // stclient exit value (see sthelper.h)
+ private static final int ST_ERR_NOT_AUTH = 245;
+ private static final int ST_ERR_REC_NOT_FOUND = 225;
+
+ // The stclient output has to be an exported interface
+ private static final String INSTANCE_URN_OPEN_ELEMENT = "<instance_urn>";
+ private static final String INSTANCE_URN_CLOSE_ELEMENT = "</instance_urn>";
+ private static final String REGISTRY_URN = "<registry urn=\"";
+ private static final String INSTANCE_URN_DESC = "Product instance URN=";
+ private static boolean initialized = false;
+ private static boolean supportsHelperClass = true; // default
+ private static File stclient = null;
+ private static String stclientPath = null;
+
+ // System properties for testing
+ private static String SVCTAG_STCLIENT_CMD = "servicetag.stclient.cmd";
+ private static String SVCTAG_STHELPER_SUPPORTED = "servicetag.sthelper.supported";
+
+ private synchronized static String getSTclient() {
+ if (!initialized) {
+ // the system property always overrides the default setting
+ if (System.getProperty(SVCTAG_STHELPER_SUPPORTED) != null) {
+ supportsHelperClass = Boolean.getBoolean(SVCTAG_STHELPER_SUPPORTED);
+ }
+
+ // This is only used for testing
+ stclientPath = System.getProperty(SVCTAG_STCLIENT_CMD);
+ if (stclientPath != null) {
+ return stclientPath;
+ }
+
+ // Initialization to determine the platform's stclient pathname
+ String os = System.getProperty("os.name");
+ if (os.equals("SunOS")) {
+ stclient = new File(STCLIENT_SOLARIS);
+ } else if (os.equals("Linux")) {
+ stclient = new File(STCLIENT_LINUX);
+ } else if (os.startsWith("Windows")) {
+ stclient = getWindowsStClientFile();
+ } else {
+ if (isVerbose()) {
+ System.out.println("Running on non-Sun JDK");
+ }
+ }
+ initialized = true;
+ }
+
+ // com.sun.servicetag package has to be compiled with JDK 5 as well
+ // JDK 5 doesn't support the File.canExecute() method.
+ // Risk not checking isExecute() for the stclient command is very low.
+
+ if (stclientPath == null && stclient != null && stclient.exists()) {
+ stclientPath = stclient.getAbsolutePath();
+ }
+ return stclientPath;
+ }
+
+ private static List<String> getCommandList() {
+ // Set up the arguments to call stclient
+ List<String> command = new ArrayList<String>();
+ if (System.getProperty(SVCTAG_STCLIENT_CMD) != null) {
+ // This is for jtreg testing use. This will be set to something
+ // like:
+ // $JAVA_HOME/bin/java -cp $TEST_DIR \
+ // -Dstclient.registry.path=$TEST_DIR/registry.xml \
+ // SvcTagClient
+ // On Windows, the JAVA_HOME and TEST_DIR path could contain
+ // space e.g. c:\Program Files\Java\jdk1.6.0_05\bin\java.
+ // The SVCTAG_STCLIENT_CMD must be set with a list of
+ // space-separated parameters. If a parameter contains spaces,
+ // it must be quoted with '"'.
+
+ String cmd = getSTclient();
+ int len = cmd.length();
+ int i = 0;
+ while (i < len) {
+ char separator = ' ';
+ if (cmd.charAt(i) == '"') {
+ separator = '"';
+ i++;
+ }
+ // look for the separator or matched the closing '"'
+ int j;
+ for (j = i+1; j < len; j++) {
+ if (cmd.charAt(j) == separator) {
+ break;
+ }
+ }
+
+ if (i == j-1) {
+ // add an empty parameter
+ command.add("\"\"");
+ } else {
+ // double quotes and space are not included
+ command.add(cmd.substring(i,j));
+ }
+
+ // skip spaces
+ for (i = j+1; i < len; i++) {
+ if (!Character.isSpaceChar(cmd.charAt(i))) {
+ break;
+ }
+ }
+ }
+ if (isVerbose()) {
+ System.out.println("Command list:");
+ for (String s : command) {
+ System.out.println(s);
+ }
+ }
+ } else {
+ command.add(getSTclient());
+ }
+ return command;
+ }
+
+ // Returns null if the service tag record not found;
+ // or throw UnauthorizedAccessException or IOException
+ // based on the exitValue.
+ private static ServiceTag checkReturnError(int exitValue,
+ String output,
+ ServiceTag st) throws IOException {
+ switch (exitValue) {
+ case ST_ERR_REC_NOT_FOUND:
+ return null;
+ case ST_ERR_NOT_AUTH:
+ if (st != null) {
+ throw new UnauthorizedAccessException(
+ "Not authorized to access " + st.getInstanceURN() +
+ " installer_uid=" + st.getInstallerUID());
+ } else {
+ throw new UnauthorizedAccessException(
+ "Not authorized:" + output);
+ }
+ default:
+ throw new IOException("stclient exits with error" +
+ " (" + exitValue + ")\n" + output);
+ }
+ }
+
+ /**
+ * Returns a {@code ServiceTag} object of the given <tt>instance_urn</tt>
+ * in this registry.
+ *
+ * @param instanceURN the <tt>instance_urn</tt> of the service tag
+ * @return a {@code ServiceTag} object of the given <tt>instance_urn</tt>
+ * in this registry; or {@code null} if not found.
+ *
+ * @throws java.io.IOException if an I/O error occurs in this operation.
+ */
+ private static ServiceTag getServiceTag(String instanceURN) throws IOException {
+ if (instanceURN == null) {
+ throw new NullPointerException("instanceURN is null");
+ }
+
+ List<String> command = getCommandList();
+ command.add("-g");
+ command.add("-i");
+ command.add(instanceURN);
+
+ ProcessBuilder pb = new ProcessBuilder(command);
+ Process p = pb.start();
+ String output = commandOutput(p);
+ if (isVerbose()) {
+ System.out.println("Output from stclient -g command:");
+ System.out.println(output);
+ }
+ if (p.exitValue() == 0) {
+ return parseServiceTag(output);
+ } else {
+ return checkReturnError(p.exitValue(), output, null);
+ }
+ }
+
+ private static ServiceTag parseServiceTag(String output) throws IOException {
+ BufferedReader in = null;
+ try {
+ Properties props = new Properties();
+ // parse the service tag output from stclient
+ in = new BufferedReader(new StringReader(output));
+ String line = null;
+ while ((line = in.readLine()) != null) {
+ if ((line = line.trim()).length() > 0) {
+ String[] ss = line.trim().split("=", 2);
+ if (ss.length == 2) {
+ props.setProperty(ss[0].trim(), ss[1].trim());
+ } else {
+ props.setProperty(ss[0].trim(), "");
+ }
+ }
+ }
+
+ String urn = props.getProperty(ST_NODE_INSTANCE_URN);
+ String productName = props.getProperty(ST_NODE_PRODUCT_NAME);
+ String productVersion = props.getProperty(ST_NODE_PRODUCT_VERSION);
+ String productURN = props.getProperty(ST_NODE_PRODUCT_URN);
+ String productParent = props.getProperty(ST_NODE_PRODUCT_PARENT);
+ String productParentURN = props.getProperty(ST_NODE_PRODUCT_PARENT_URN);
+ String productDefinedInstanceID =
+ props.getProperty(ST_NODE_PRODUCT_DEFINED_INST_ID);
+ String productVendor = props.getProperty(ST_NODE_PRODUCT_VENDOR);
+ String platformArch = props.getProperty(ST_NODE_PLATFORM_ARCH);
+ String container = props.getProperty(ST_NODE_CONTAINER);
+ String source = props.getProperty(ST_NODE_SOURCE);
+ int installerUID =
+ Util.getIntValue(props.getProperty(ST_NODE_INSTALLER_UID));
+ Date timestamp =
+ Util.parseTimestamp(props.getProperty(ST_NODE_TIMESTAMP));
+
+ return new ServiceTag(urn,
+ productName,
+ productVersion,
+ productURN,
+ productParent,
+ productParentURN,
+ productDefinedInstanceID,
+ productVendor,
+ platformArch,
+ container,
+ source,
+ installerUID,
+ timestamp);
+ } finally {
+ if (in != null) {
+ in.close();
+ }
+ }
+
+ }
+
+ /**
+ * Returns the urn of this registry.
+ *
+ * @return a {@code String} for the urn of this registry.
+ *
+ * @throws java.io.IOException if an I/O error occurs in this operation.
+ */
+ // Once JDK makes this method available, we'll deprecate this method
+ // @deprecated Use the JDK version when available.
+ public static String getRegistryURN() throws IOException {
+ List<String> command = getCommandList();
+ command.add("-x");
+
+ BufferedReader in = null;
+ try {
+ ProcessBuilder pb = new ProcessBuilder(command);
+ Process p = pb.start();
+ String output = commandOutput(p);
+
+ String registryURN = null;
+ if (p.exitValue() == 0) {
+ // parse the service tag output from stclient
+ in = new BufferedReader(new StringReader(output));
+ String line = null;
+ while ((line = in.readLine()) != null) {
+ String s = line.trim();
+ if (s.indexOf(REGISTRY_URN) != -1) {
+ s = s.substring(s.indexOf(REGISTRY_URN)
+ + REGISTRY_URN.length());
+ if (s.indexOf("\"") != -1) {
+ s = s.substring(0, s.indexOf("\""));
+ registryURN = s;
+ break;
+ }
+ }
+ }
+ } else {
+ checkReturnError(p.exitValue(), output, null);
+ }
+ return registryURN;
+ } finally {
+ if (in != null) {
+ in.close();
+ }
+ }
+ }
+
+ /**
+ * Returns all the service tags in this registry.
+ *
+ * @return a {@code Set} of {@code ServiceTag} objects
+ * in this registry.
+ *
+ * @throws java.io.IOException if an I/O error occurs in this operation.
+ */
+ // Once JDK makes this method available, we'll deprecate this method
+ // @deprecated Use the JDK version when available.
+ public static Set<ServiceTag> getServiceTags() throws IOException {
+ List<String> command = getCommandList();
+ command.add("-x");
+
+ BufferedReader in = null;
+ try {
+ ProcessBuilder pb = new ProcessBuilder(command);
+ Process p = pb.start();
+ String output = commandOutput(p);
+
+ Set<ServiceTag> instances = new HashSet<ServiceTag>();
+ if (p.exitValue() == 0) {
+ // parse the service tag output from stclient
+ in = new BufferedReader(new StringReader(output));
+ String line = null;
+ while ((line = in.readLine()) != null) {
+ String s = line.trim();
+ if (s.indexOf(INSTANCE_URN_OPEN_ELEMENT) != -1
+ && s.indexOf(INSTANCE_URN_CLOSE_ELEMENT) != -1) {
+ s = s.substring(s.indexOf(INSTANCE_URN_OPEN_ELEMENT)
+ + INSTANCE_URN_OPEN_ELEMENT.length(),
+ s.indexOf(INSTANCE_URN_CLOSE_ELEMENT));
+ try {
+ instances.add(getServiceTag(s));
+ } catch (Exception e) {
+ }
+ }
+ }
+ } else {
+ checkReturnError(p.exitValue(), output, null);
+ }
+ return instances;
+ } finally {
+ if (in != null) {
+ in.close();
+ }
+ }
+ }
+}
diff --git a/desktop/source/registration/com/sun/star/servicetag/SystemEnvironment.java b/desktop/source/registration/com/sun/star/servicetag/SystemEnvironment.java
new file mode 100755
index 000000000000..76eaca37e39a
--- /dev/null
+++ b/desktop/source/registration/com/sun/star/servicetag/SystemEnvironment.java
@@ -0,0 +1,436 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+package com.sun.star.servicetag;
+
+// The Service Tags team maintains the latest version of the implementation
+// for system environment data collection. JDK will include a copy of
+// the most recent released version for a JDK release. We rename
+// the package to com.sun.servicetag so that the Sun Connection
+// product always uses the latest version from the com.sun.scn.servicetags
+// package. JDK and users of the com.sun.servicetag API
+// (e.g. NetBeans and SunStudio) will use the version in JDK.
+
+import java.io.*;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+/**
+ * SystemEnvironment class collects the environment data with the
+ * best effort from the underlying platform.
+ */
+public class SystemEnvironment {
+ private String hostname;
+ private String hostId;
+ private String osName;
+ private String osVersion;
+ private String osArchitecture;
+ private String systemModel;
+ private String systemManufacturer;
+ private String cpuManufacturer;
+ private String serialNumber;
+ private String physmem;
+ private String sockets;
+ private String cores;
+ private String virtcpus;
+ private String cpuname;
+ private String clockrate;
+ private static SystemEnvironment sysEnv = null;
+
+ public static synchronized SystemEnvironment getSystemEnvironment() {
+ if (sysEnv == null) {
+ String os = System.getProperty("os.name");
+ if (os.equals("SunOS")) {
+ sysEnv = new SolarisSystemEnvironment();
+ } else if (os.equals("Linux")) {
+ sysEnv = new LinuxSystemEnvironment();
+ } else if (os.startsWith("Windows")) {
+ sysEnv = new WindowsSystemEnvironment();
+ } else {
+ sysEnv = new SystemEnvironment();
+ }
+ }
+ return sysEnv;
+ }
+
+ // package-private
+ SystemEnvironment() {
+ try {
+ this.hostname = InetAddress.getLocalHost().getHostName();
+ } catch (UnknownHostException ex) {
+ this.hostname = "Unknown host";
+ }
+ this.hostId = "";
+ this.osName = System.getProperty("os.name");
+ this.osVersion = System.getProperty("os.version");
+ this.osArchitecture = System.getProperty("os.arch");
+ this.systemModel = "";
+ this.systemManufacturer = "";
+ this.cpuManufacturer = "";
+ this.serialNumber = "";
+ this.physmem = "0";
+ this.sockets = "0";
+ this.cores = "0";
+ this.virtcpus = "0";
+ this.cpuname = "";
+ this.clockrate = "0";
+ }
+
+
+ /**
+ * Sets the hostname.
+ * @param hostname The hostname to set.
+ */
+ public void setHostname(String hostname) {
+ this.hostname = hostname;
+ }
+
+ /**
+ * Sets the OS name.
+ * @param osName The osName to set.
+ */
+ public void setOsName(String osName) {
+ this.osName = osName;
+ }
+
+ /**
+ * Sets the OS version.
+ * @param osVersion The osVersion to set.
+ */
+ public void setOsVersion(String osVersion) {
+ this.osVersion = osVersion;
+ }
+
+ /**
+ * Sets the OS architecture.
+ * @param osArchitecture The osArchitecture to set.
+ */
+ public void setOsArchitecture(String osArchitecture) {
+ this.osArchitecture = osArchitecture;
+ }
+
+ /**
+ * Sets the system model.
+ * @param systemModel The systemModel to set.
+ */
+ public void setSystemModel(String systemModel) {
+ this.systemModel = systemModel;
+ }
+
+ /**
+ * Sets the system manufacturer.
+ * @param systemManufacturer The systemManufacturer to set.
+ */
+ public void setSystemManufacturer(String systemManufacturer) {
+ this.systemManufacturer = systemManufacturer;
+ }
+
+ /**
+ * Sets the cpu manufacturer.
+ * @param cpuManufacturer The cpuManufacturer to set.
+ */
+ public void setCpuManufacturer(String cpuManufacturer) {
+ this.cpuManufacturer = cpuManufacturer;
+ }
+
+ /**
+ * Sets the serial number.
+ * @param serialNumber The serialNumber to set.
+ */
+ public void setSerialNumber(String serialNumber) {
+ this.serialNumber = serialNumber;
+ }
+
+ /**
+ * Sets the physmem
+ * @param physmem The physmem to set.
+ */
+ public void setPhysMem(String physmem) {
+ if (physmem.length() == 0)
+ physmem = "0";
+ this.physmem = physmem;
+ }
+
+ /**
+ * Sets the sockets
+ * @param sockets The sockets to set.
+ */
+ public void setSockets(String sockets) {
+ if (sockets.length() == 0)
+ sockets = "0";
+ this.sockets = sockets;
+ }
+
+ /**
+ * Sets the cores
+ * @param cores The cores to set.
+ */
+ public void setCores(String cores) {
+ if (cores.length() == 0)
+ cores ="0";
+ this.cores = cores;
+ }
+
+ /**
+ * Sets the virtcpus
+ * @param virtcpus The virtcpus to set.
+ */
+ public void setVirtCpus(String virtcpus) {
+ if (virtcpus.length() == 0)
+ virtcpus = "0";
+ this.virtcpus = virtcpus;
+ }
+
+ /**
+ * Sets the cpuname
+ * @param cpuname The cpuname to set.
+ */
+ public void setCpuName(String cpuname) {
+ this.cpuname = cpuname;
+ }
+
+ /**
+ * Sets the clockrate
+ * @param clockrate The clockrate to set.
+ */
+ public void setClockRate(String clockrate) {
+ if (clockrate.length() == 0)
+ this.clockrate = "0";
+ else
+ {
+ Float f = Float.parseFloat(clockrate);
+ Integer nClockrate = f.intValue();
+ this.clockrate = nClockrate.toString();
+ }
+ }
+
+ /**
+ * Sets the hostid. Truncates to a max length of 16 chars.
+ * @param hostId The hostid to set.
+ */
+ public void setHostId(String hostId) {
+ if (hostId == null || hostId.equals("null")) {
+ hostId = "";
+ }
+ if (hostId.length() > 16) {
+ hostId = hostId.substring(0,16);
+ }
+ this.hostId = hostId;
+ }
+
+ /**
+ * Returns the hostname.
+ * @return The hostname.
+ */
+ public String getHostname() {
+ return hostname;
+ }
+
+ /**
+ * Returns the osName.
+ * @return The osName.
+ */
+ public String getOsName() {
+ return osName;
+ }
+
+ /**
+ * Returns the osVersion.
+ * @return The osVersion.
+ */
+ public String getOsVersion() {
+ return osVersion;
+ }
+
+ /**
+ * Returns the osArchitecture.
+ * @return The osArchitecture.
+ */
+ public String getOsArchitecture() {
+ return osArchitecture;
+ }
+
+ /**
+ * Returns the systemModel.
+ * @return The systemModel.
+ */
+ public String getSystemModel() {
+ return systemModel;
+ }
+
+ /**
+ * Returns the systemManufacturer.
+ * @return The systemManufacturer.
+ */
+ public String getSystemManufacturer() {
+ return systemManufacturer;
+ }
+
+ /**
+ * Returns the serialNumber.
+ * @return The serialNumber.
+ */
+ public String getSerialNumber() {
+ return serialNumber;
+ }
+
+ public String getPhysMem() {
+ return physmem;
+ }
+
+ public String getSockets() {
+ return sockets;
+ }
+
+ public String getCores() {
+ return cores;
+ }
+
+ public String getVirtCpus() {
+ return virtcpus;
+ }
+
+ public String getCpuName() {
+ return cpuname;
+ }
+
+ public String getClockRate() {
+ return clockrate;
+ }
+
+ /**
+ * Returns the hostId.
+ * @return The hostId.
+ */
+ public String getHostId() {
+ return hostId;
+ }
+
+ /**
+ * Returns the cpuManufacturer.
+ * @return The cpuManufacturer.
+ */
+ public String getCpuManufacturer() {
+ return cpuManufacturer;
+ }
+
+ protected String getCommandOutput(String... command) {
+ StringBuilder sb = new StringBuilder();
+ BufferedReader br = null;
+ Process p = null;
+ try {
+ ProcessBuilder pb = new ProcessBuilder(command);
+ p = pb.start();
+ p.waitFor();
+
+ if (p.exitValue() == 0) {
+ br = new BufferedReader(new InputStreamReader(p.getInputStream()));
+ String line = null;
+ while ((line = br.readLine()) != null) {
+ line = line.trim();
+ if (line.length() > 0) {
+ if (sb.length() > 0) {
+ sb.append("\n");
+ }
+ sb.append(line);
+ }
+ }
+ }
+ return sb.toString();
+ } catch (InterruptedException ie) {
+ // in case the command hangs
+ if (p != null) {
+ p.destroy();
+ }
+ return "";
+ } catch (Exception e) {
+ // ignore exception
+ return "";
+ } finally {
+ if (p != null) {
+ try {
+ p.getErrorStream().close();
+ } catch (IOException e) {
+ // ignore
+ }
+ try {
+ p.getInputStream().close();
+ } catch (IOException e) {
+ // ignore
+ }
+ try {
+ p.getOutputStream().close();
+ } catch (IOException e) {
+ // ignore
+ }
+ p = null;
+ }
+ if (br != null) {
+ try {
+ br.close();
+ } catch (IOException e) {
+ // ignore
+ }
+ }
+ }
+ }
+
+ protected String getFileContent(String filename) {
+ File f = new File(filename);
+ if (!f.exists()) {
+ return "";
+ }
+
+ StringBuilder sb = new StringBuilder();
+ BufferedReader br = null;
+ try {
+ br = new BufferedReader(new FileReader(f));
+ String line = null;
+ while ((line = br.readLine()) != null) {
+ line = line.trim();
+ if (line.length() > 0) {
+ if (sb.length() > 0) {
+ sb.append("\n");
+ }
+ sb.append(line);
+ }
+ }
+ return sb.toString();
+ } catch (Exception e) {
+ // ignore exception
+ return "";
+ } finally {
+ if (br != null) {
+ try {
+ br.close();
+ } catch (IOException e) {
+ // ignore
+ }
+ }
+ }
+ }
+}
diff --git a/desktop/source/registration/com/sun/star/servicetag/UnauthorizedAccessException.java b/desktop/source/registration/com/sun/star/servicetag/UnauthorizedAccessException.java
new file mode 100755
index 000000000000..898fb614c267
--- /dev/null
+++ b/desktop/source/registration/com/sun/star/servicetag/UnauthorizedAccessException.java
@@ -0,0 +1,55 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+package com.sun.star.servicetag;
+
+/**
+ * Thrown if the user is not authorized to
+ * {@link Registry#updateServiceTag update} or
+ * {@link Registry#removeServiceTag remove}
+ * a service tag from a {@link Registry}.
+ */
+public class UnauthorizedAccessException extends RuntimeException {
+
+ /**
+ * Constructs an <code>UnauthorizedAccessException</code> object
+ * without detail message.
+ */
+ public UnauthorizedAccessException() {
+ }
+
+
+ /**
+ * Constructs an <code>UnauthorizedAccessException</code> object
+ * with the specified detail message.
+ *
+ * @param msg the detail message.
+ */
+ public UnauthorizedAccessException(String msg) {
+ super(msg);
+ }
+}
diff --git a/desktop/source/registration/com/sun/star/servicetag/Util.java b/desktop/source/registration/com/sun/star/servicetag/Util.java
new file mode 100755
index 000000000000..1f54775e7d3c
--- /dev/null
+++ b/desktop/source/registration/com/sun/star/servicetag/Util.java
@@ -0,0 +1,293 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+package com.sun.star.servicetag;
+
+import java.io.*;
+import java.util.Date;
+import java.text.SimpleDateFormat;
+import java.text.ParseException;
+import java.util.TimeZone;
+import java.util.UUID;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
+// Utility class for com.sun.servicetag package
+class Util {
+ private static boolean verbose = (System.getProperty("servicetag.verbose") != null);
+ private static String jrepath = null;
+
+ // for debugging and tracing
+ static boolean isVerbose() {
+ return verbose;
+ }
+
+ /**
+ * Gets the pathname of JRE in the running platform
+ * This can be a JDK or JRE.
+ */
+ static synchronized String getJrePath() {
+ if (jrepath == null) {
+ // Determine the JRE path by checking the existence of
+ // <HOME>/jre/lib and <HOME>/lib.
+ String javaHome = System.getProperty("java.home");
+ jrepath = javaHome + File.separator + "jre";
+ File f = new File(jrepath, "lib");
+ if (!f.exists()) {
+ // java.home usually points to the JRE path
+ jrepath = javaHome;
+ }
+ }
+ return jrepath;
+ }
+
+ /**
+ * Tests if the running platform is a JDK.
+ */
+ static boolean isJdk() {
+ // <HOME>/jre exists which implies it's a JDK
+ return getJrePath().endsWith(File.separator + "jre");
+ }
+
+ /**
+ * Generates the URN string of "urn:st" namespace
+ */
+ static String generateURN() {
+ return "urn:st:" + UUID.randomUUID().toString();
+ }
+
+ static int getIntValue(String value) {
+ try {
+ return Integer.parseInt(value);
+ } catch (NumberFormatException e) {
+ throw new IllegalArgumentException("\"" + value + "\"" +
+ " expected to be an integer");
+ }
+ }
+
+ /**
+ * Formats the Date into a timestamp string in YYYY-MM-dd HH:mm:ss GMT.
+ * @param timestamp Date
+ * @return a string representation of the timestamp
+ * in the YYYY-MM-dd HH:mm:ss GMT format.
+ */
+ static String formatTimestamp(Date timestamp) {
+ if (timestamp == null) {
+ return "[No timestamp]";
+ }
+ SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
+ df.setTimeZone(TimeZone.getTimeZone("GMT"));
+ return df.format(timestamp);
+ }
+
+ /**
+ * Parses a timestamp string in YYYY-MM-dd HH:mm:ss GMT format.
+ * @param timestamp Timestamp in the YYYY-MM-dd HH:mm:ss GMT format.
+ * @return Date
+ */
+ static Date parseTimestamp(String timestamp) {
+ SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
+ df.setTimeZone(TimeZone.getTimeZone("GMT"));
+ try {
+ return df.parse(timestamp);
+ } catch (ParseException e) {
+ // should not reach here
+ e.printStackTrace();
+ return new Date();
+ }
+ }
+
+ static String commandOutput(Process p) throws IOException {
+ Reader r = null;
+ Reader err = null;
+ try {
+ r = new InputStreamReader(p.getInputStream());
+ err = new InputStreamReader(p.getErrorStream());
+ String output = commandOutput(r);
+ String errorMsg = commandOutput(err);
+ p.waitFor();
+ return output + errorMsg.trim();
+ } catch (InterruptedException e) {
+ if (isVerbose()) {
+ e.printStackTrace();
+ }
+ return e.getMessage();
+ } finally {
+ if (r != null) {
+ r.close();
+ }
+ if (err != null) {
+ err.close();
+ }
+ }
+ }
+
+ static String commandOutput(Reader r) throws IOException {
+ StringBuilder sb = new StringBuilder();
+ int c;
+ while ((c = r.read()) > 0) {
+ if (c != '\r') {
+ sb.append((char) c);
+ }
+ }
+ return sb.toString();
+ }
+
+ static int getJdkVersion() {
+ parseVersion();
+ return jdkVersion;
+ }
+
+ static int getUpdateVersion() {
+ parseVersion();
+ return jdkUpdate;
+ }
+
+ private static int jdkVersion = 0;
+ private static int jdkUpdate = 0;
+ private static synchronized void parseVersion() {
+ if (jdkVersion > 0) {
+ return;
+ }
+
+ // parse java.runtime.version
+ // valid format of the version string is:
+ // n.n.n[_uu[c]][-<identifer>]-bxx
+ String cs = System.getProperty("java.runtime.version");
+ if (cs.length() >= 5 &&
+ Character.isDigit(cs.charAt(0)) && cs.charAt(1) == '.' &&
+ Character.isDigit(cs.charAt(2)) && cs.charAt(3) == '.' &&
+ Character.isDigit(cs.charAt(4))) {
+ jdkVersion = Character.digit(cs.charAt(2), 10);
+ cs = cs.substring(5, cs.length());
+ if (cs.charAt(0) == '_' && cs.length() >= 3 &&
+ Character.isDigit(cs.charAt(1)) &&
+ Character.isDigit(cs.charAt(2))) {
+ int nextChar = 3;
+ try {
+ String uu = cs.substring(1, 3);
+ jdkUpdate = Integer.valueOf(uu).intValue();
+ } catch (NumberFormatException e) {
+ // not conforming to the naming convention
+ return;
+ }
+ }
+ } else {
+ throw new InternalError("Invalid java.runtime.version" + cs);
+ }
+ }
+
+ /**
+ * Returns this java string as a null-terminated byte array
+ */
+ private static byte[] stringToByteArray(String str) {
+ return (str + "\u0000").getBytes();
+ }
+
+ /**
+ * Converts a null-terminated byte array to java string
+ */
+ private static String byteArrayToString(byte[] array) {
+ return new String(array, 0, array.length -1);
+ }
+
+ /**
+ * Gets the stclient path using a well known location from
+ * the Windows platform Registry, otherwise it will return null.
+ */
+ static File getWindowsStClientFile() {
+ File out = null;
+ String regKey = "software\\microsoft\\windows\\currentversion\\app paths\\stclient.exe";
+ String keyName = "" ; // use the default key
+ String path = getRegistryKey(regKey, keyName);
+
+ if (path != null && (new File(path)).exists()) {
+ out = new File(path);
+ }
+ if (isVerbose()) {
+ System.out.println("stclient=" + out);
+ }
+ return out;
+ }
+
+ /**
+ * This uses reflection to access a private java windows registry
+ * interface, any changes to that Class must be appropriately adjusted.
+ * Returns a null if unsuccessful.
+ */
+ private static String getRegistryKey(String regKey, String keyName) {
+ String out = null;
+ try {
+ Class<?> clazz = Class.forName("java.util.prefs.WindowsPreferences");
+
+ // Get the registry methods
+ Method winRegOpenKeyM = clazz.getDeclaredMethod("WindowsRegOpenKey",
+ int.class, byte[].class, int.class);
+ winRegOpenKeyM.setAccessible(true);
+
+ Method winRegCloseKeyM = clazz.getDeclaredMethod("WindowsRegCloseKey",
+ int.class);
+ winRegCloseKeyM.setAccessible(true);
+
+ Method winRegQueryValueM = clazz.getDeclaredMethod("WindowsRegQueryValueEx",
+ int.class, byte[].class);
+ winRegQueryValueM.setAccessible(true);
+
+ // Get all the constants we need
+ int HKLM = getValueFromStaticField("HKEY_LOCAL_MACHINE", clazz);
+ int KEY_READ = getValueFromStaticField("KEY_READ", clazz);
+ int ERROR_CODE = getValueFromStaticField("ERROR_CODE", clazz);
+ int NATIVE_HANDLE = getValueFromStaticField("NATIVE_HANDLE", clazz);
+ int ERROR_SUCCESS = getValueFromStaticField("ERROR_SUCCESS", clazz);
+
+ // Convert keys
+ byte[] reg = stringToByteArray(regKey);
+ byte[] key = stringToByteArray(keyName);
+
+ // Open the registry
+ int[] result = (int[]) winRegOpenKeyM.invoke(null, HKLM, reg, KEY_READ);
+
+ if (result[ERROR_CODE] == ERROR_SUCCESS) {
+ byte[] stvalue = (byte[]) winRegQueryValueM.invoke(null,
+ result[NATIVE_HANDLE], key);
+ out = byteArrayToString(stvalue);
+ winRegCloseKeyM.invoke(null, result[NATIVE_HANDLE]);
+ }
+ } catch (Exception ex) {
+ if (isVerbose()) {
+ ex.printStackTrace();
+ }
+ }
+ return out;
+ }
+
+ private static int getValueFromStaticField(String fldName, Class<?> klass) throws Exception {
+ Field f = klass.getDeclaredField(fldName);
+ f.setAccessible(true);
+ return f.getInt(null);
+ }
+}
diff --git a/desktop/source/registration/com/sun/star/servicetag/WindowsSystemEnvironment.java b/desktop/source/registration/com/sun/star/servicetag/WindowsSystemEnvironment.java
new file mode 100755
index 000000000000..3aa799e16d5e
--- /dev/null
+++ b/desktop/source/registration/com/sun/star/servicetag/WindowsSystemEnvironment.java
@@ -0,0 +1,232 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+package com.sun.star.servicetag;
+
+// The Service Tags team maintains the latest version of the implementation
+// for system environment data collection. JDK will include a copy of
+// the most recent released version for a JDK release. We rename
+// the package to com.sun.servicetag so that the Sun Connection
+// product always uses the latest version from the com.sun.scn.servicetags
+// package. JDK and users of the com.sun.servicetag API
+// (e.g. NetBeans and SunStudio) will use the version in JDK.
+
+import java.io.*;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Windows implementation of the SystemEnvironment class.
+ */
+class WindowsSystemEnvironment extends SystemEnvironment {
+ WindowsSystemEnvironment() {
+ super();
+
+ // run a call to make sure things are initialized
+ // ignore the first call result as the system may
+ // give inconsistent data on the first invocation ever
+ getWmicResult("computersystem", "get", "model");
+
+ setSystemModel(getWmicResult("computersystem", "get", "model"));
+ setSystemManufacturer(getWmicResult("computersystem", "get", "manufacturer"));
+ setSerialNumber(getWmicResult("bios", "get", "serialnumber"));
+
+ String cpuMfr = getWmicResult("cpu", "get", "manufacturer");
+ // this isn't as good an option, but if we couldn't get anything
+ // from wmic, try the processor_identifier
+ if (cpuMfr.length() == 0) {
+ String procId = System.getenv("processor_identifer");
+ if (procId != null) {
+ String[] s = procId.split(",");
+ cpuMfr = s[s.length - 1].trim();
+ }
+ }
+ setCpuManufacturer(cpuMfr);
+
+ setSockets(getWindowsSockets());
+ setCores(getWindowsCores());
+ setVirtCpus(getWindowsVirtCpus());
+ setPhysMem(getWindowsPhysMem());
+ setCpuName(getWmicResult("cpu", "get", "Name"));
+ setClockRate(getWmicResult("cpu", "get", "MaxClockSpeed"));
+
+ // try to remove the temp file that gets created from running wmic cmds
+ try {
+ // look in the current working directory
+ File f = new File("TempWmicBatchFile.bat");
+ if (f.exists()) {
+ f.delete();
+ }
+ } catch (Exception e) {
+ // ignore the exception
+ }
+ }
+
+ private String getWindowsVirtCpus() {
+ String res = getWmicResult("cpu", "get", "NumberOfLogicalProcessors");
+ if (res == null || res.equals("")) {
+ res = "1";
+ }
+ return res;
+ }
+
+ private String getWindowsCores() {
+ String res = getWmicResult("cpu", "get", "NumberOfCores");
+ if (res == null || res.equals("")) {
+ res = "1";
+ }
+ return res;
+ }
+
+ private String getWindowsSockets() {
+ String res = getFullWmicResult("cpu", "get", "DeviceID");
+ Set<String> set = new HashSet<String>();
+ for (String line : res.split("\n")) {
+ line = line.trim();
+ if (line.equals("")) {
+ continue;
+ }
+ set.add(line);
+ }
+ if (set.size() == 0) {
+ return "1";
+ }
+ return "" + set.size();
+ }
+
+ private String getWindowsPhysMem() {
+ String mem = getWmicResult("computersystem", "get", "TotalPhysicalMemory");
+ long l = Long.parseLong(mem);
+ return "" + ((long) (l / (1024*1024)));
+ }
+
+
+ /**
+ * This method invokes wmic outside of the normal environment
+ * collection routines.
+ *
+ * An initial call to wmic can be costly in terms of time.
+ *
+ * <code>
+ * Details of why the first call is costly can be found at:
+ *
+ * http://support.microsoft.com/kb/290216/en-us
+ *
+ * "When you run the Wmic.exe utility for the first time, the utility
+ * compiles its .mof files into the repository. To save time during
+ * Windows installation, this operation takes place as necessary."
+ * </code>
+ */
+ private String getWmicResult(String alias, String verb, String property) {
+ String res = "";
+ BufferedReader in = null;
+ try {
+ ProcessBuilder pb = new ProcessBuilder("cmd", "/C", "WMIC", alias, verb, property);
+ Process p = pb.start();
+ // need this for executing windows commands (at least
+ // needed for executing wmic command)
+ BufferedWriter bw = new BufferedWriter(
+ new OutputStreamWriter(p.getOutputStream()));
+ bw.write(13);
+ bw.flush();
+ bw.close();
+
+ p.waitFor();
+ if (p.exitValue() == 0) {
+ in = new BufferedReader(new InputStreamReader(p.getInputStream()));
+ String line = null;
+ while ((line = in.readLine()) != null) {
+ line = line.trim();
+ if (line.length() == 0) {
+ continue;
+ }
+ res = line;
+ }
+ // return the *last* line read
+ return res;
+ }
+
+ } catch (Exception e) {
+ // ignore the exception
+ } finally {
+ if (in != null) {
+ try {
+ in.close();
+ } catch (IOException e) {
+ // ignore
+ }
+ }
+ }
+ return res.trim();
+ }
+
+ private String getFullWmicResult(String alias, String verb, String property) {
+ String res = "";
+ BufferedReader in = null;
+ try {
+ ProcessBuilder pb = new ProcessBuilder("cmd", "/C", "WMIC", alias, verb, property);
+ Process p = pb.start();
+ // need this for executing windows commands (at least
+ // needed for executing wmic command)
+ BufferedWriter bw = new BufferedWriter(
+ new OutputStreamWriter(p.getOutputStream()));
+ bw.write(13);
+ bw.flush();
+ bw.close();
+
+ p.waitFor();
+ if (p.exitValue() == 0) {
+ in = new BufferedReader(new InputStreamReader(p.getInputStream()));
+ String line = null;
+ while ((line = in.readLine()) != null) {
+ line = line.trim();
+ if (line.length() == 0) {
+ continue;
+ }
+ if (line.toLowerCase().indexOf(property.toLowerCase()) != -1) {
+ continue;
+ }
+ res += line + "\n";
+ }
+ }
+
+ } catch (Exception e) {
+ // ignore the exception
+ } finally {
+ if (in != null) {
+ try {
+ in.close();
+ } catch (IOException e) {
+ // ignore
+ }
+ }
+ }
+ return res;
+ }
+}
diff --git a/desktop/source/registration/com/sun/star/servicetag/makefile.mk b/desktop/source/registration/com/sun/star/servicetag/makefile.mk
new file mode 100755
index 000000000000..784964652950
--- /dev/null
+++ b/desktop/source/registration/com/sun/star/servicetag/makefile.mk
@@ -0,0 +1,79 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJNAME = setup_native
+PRJ = ..$/..$/..$/..$/..$/..
+TARGET = servicetag
+PACKAGE = com$/sun$/star$/servicetag
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+.IF "$(ENABLE_SVCTAGS)" == "YES"
+
+JARFILES = jurt.jar unoil.jar ridl.jar
+JAVAFILES = \
+ BrowserSupport.java \
+ Installer.java \
+ LinuxSystemEnvironment.java \
+ RegistrationData.java \
+ RegistrationDocument.java \
+ Registry.java \
+ ServiceTag.java \
+ SolarisServiceTag.java \
+ SolarisSystemEnvironment.java \
+ SunConnection.java \
+ SysnetRegistryHelper.java \
+ SystemEnvironment.java \
+ UnauthorizedAccessException.java \
+ Util.java \
+ WindowsSystemEnvironment.java
+
+JAVACLASSFILES= $(foreach,i,$(JAVAFILES) $(CLASSDIR)$/$(PACKAGE)$/$(i:b).class)
+
+JARTARGET = $(TARGET).jar
+JARCOMPRESS = TRUE
+JARCLASSDIRS = $(PACKAGE)
+
+JAVARES= $(CLASSDIR)$/$(PACKAGE)$/resources$/product_registration.xsd
+
+.ENDIF # "$(ENABLE_SVCTAGS)" == "YES"
+
+# --- Targets ------------------------------------------------------
+
+
+.INCLUDE : target.mk
+
+.IF "$(ENABLE_SVCTAGS)" == "YES"
+ALLTAR: $(JAVARES)
+
+$(JAVARES) : $$(@:d:d:f)$/$$(@:f)
+ $(MKDIRHIER) $(@:d)
+ $(COPY) $< $@
+
+.ENDIF # "$(ENABLE_SVCTAGS)" == "YES"
diff --git a/desktop/source/registration/com/sun/star/servicetag/resources/product_registration.xsd b/desktop/source/registration/com/sun/star/servicetag/resources/product_registration.xsd
new file mode 100755
index 000000000000..6681a563a01e
--- /dev/null
+++ b/desktop/source/registration/com/sun/star/servicetag/resources/product_registration.xsd
@@ -0,0 +1,366 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
+
+<xs:element name="registration_data">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="environment"
+ minOccurs="1"
+ maxOccurs="1">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element ref="hostname"
+ minOccurs='1'
+ maxOccurs='1'/>
+ <xs:element ref="hostId"
+ minOccurs='1'
+ maxOccurs='1'/>
+ <xs:element ref="osName"
+ minOccurs='1'
+ maxOccurs='1'/>
+ <xs:element ref="osVersion"
+ minOccurs='1'
+ maxOccurs='1'/>
+ <xs:element ref="osArchitecture"
+ minOccurs='1'
+ maxOccurs='1'/>
+ <xs:element ref="systemModel"
+ minOccurs='1'
+ maxOccurs='1'/>
+ <xs:element ref="systemManufacturer"
+ minOccurs='1'
+ maxOccurs='1'/>
+ <xs:element ref="cpuManufacturer"
+ minOccurs='1'
+ maxOccurs='1'/>
+ <xs:element ref="serialNumber"
+ minOccurs='1'
+ maxOccurs='1'/>
+ <xs:element ref="physmem"
+ minOccurs='0'
+ maxOccurs='1'/>
+ <xs:element name="cpuinfo"
+ minOccurs='0'
+ maxOccurs='1'>
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element ref="sockets"
+ minOccurs='0'
+ maxOccurs='1'/>
+ <xs:element ref="cores"
+ minOccurs='0'
+ maxOccurs='1'/>
+ <xs:element ref="virtcpus"
+ minOccurs='0'
+ maxOccurs='1'/>
+ <xs:element ref="name"
+ minOccurs='0'
+ maxOccurs='1'/>
+ <xs:element ref="clockrate"
+ minOccurs='0'
+ maxOccurs='1'/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="registry"
+ minOccurs="1"
+ maxOccurs="1">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="service_tag"
+ minOccurs="0"
+ maxOccurs="1024">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element ref="instance_urn"
+ minOccurs='1'
+ maxOccurs='1'/>
+ <xs:element ref="product_name"
+ minOccurs='1'
+ maxOccurs='1'/>
+ <xs:element ref="product_version"
+ minOccurs='1'
+ maxOccurs='1'/>
+ <xs:element ref="product_urn"
+ minOccurs='1'
+ maxOccurs='1'/>
+ <xs:element ref="product_parent_urn"
+ minOccurs='1'
+ maxOccurs='1'/>
+ <xs:element ref="product_parent"
+ minOccurs='1'
+ maxOccurs='1'/>
+ <xs:element ref="product_defined_inst_id"
+ minOccurs='1'
+ maxOccurs='1'/>
+ <xs:element ref="product_vendor"
+ minOccurs='1'
+ maxOccurs='1'/>
+ <xs:element ref="platform_arch"
+ minOccurs='1'
+ maxOccurs='1'/>
+ <xs:element ref="timestamp"
+ minOccurs='1'
+ maxOccurs='1'/>
+ <xs:element ref="container"
+ minOccurs='1'
+ maxOccurs='1'/>
+ <xs:element ref="source"
+ minOccurs='1'
+ maxOccurs='1'/>
+ <xs:element ref="installer_uid"
+ minOccurs='1'
+ maxOccurs='1'/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ </xs:sequence>
+ <xs:attribute name="urn"
+ type="xs:string"
+ use="required"/>
+ <xs:attribute name="version"
+ type="xs:string"
+ use="required"/>
+ </xs:complexType>
+ </xs:element>
+ </xs:sequence>
+ <xs:attribute name="version"
+ type="xs:string"
+ use="required"/>
+ </xs:complexType>
+</xs:element>
+
+ <!-- definition of simple elements -->
+ <xs:element name="hostname">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:minLength value="1"/>
+ <xs:maxLength value="255"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+
+ <xs:element name="hostId">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:minLength value="0"/>
+ <xs:maxLength value="16"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+
+ <xs:element name="osName">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:minLength value="1"/>
+ <xs:maxLength value="256"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+
+ <xs:element name="osVersion">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:minLength value="0"/>
+ <xs:maxLength value="50"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+
+ <xs:element name="osArchitecture">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:minLength value="0"/>
+ <xs:maxLength value="256"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+
+ <xs:element name="systemModel">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:minLength value="0"/>
+ <xs:maxLength value="50"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+
+ <xs:element name="systemManufacturer">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:minLength value="0"/>
+ <xs:maxLength value="50"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+
+ <xs:element name="cpuManufacturer">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:minLength value="0"/>
+ <xs:maxLength value="50"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+
+ <xs:element name="serialNumber">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:minLength value="0"/>
+ <xs:maxLength value="256"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+
+ <xs:element name="instance_urn">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:minLength value="1"/>
+ <xs:maxLength value="255"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+
+ <xs:element name="product_name">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:maxLength value="255"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+
+ <xs:element name="product_version">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:maxLength value="63"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+
+ <xs:element name="product_urn">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:minLength value="1"/>
+ <xs:maxLength value="255"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+
+ <xs:element name="product_parent_urn">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:minLength value="0"/>
+ <xs:maxLength value="255"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+
+ <xs:element name="product_parent">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:minLength value="0"/>
+ <xs:maxLength value="255"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+
+ <xs:element name="product_defined_inst_id">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:minLength value="0"/>
+ <xs:maxLength value="255"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+
+ <xs:element name="product_vendor">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:minLength value="0"/>
+ <xs:maxLength value="63"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+
+ <xs:element name="platform_arch">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:minLength value="0"/>
+ <xs:maxLength value="63"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+
+ <xs:element name="timestamp">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:maxLength value="24"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+
+ <xs:element name="container">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:maxLength value="63"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+
+ <xs:element name="source">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:maxLength value="63"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+
+ <xs:element name="installer_uid">
+ <xs:simpleType>
+ <xs:restriction base="xs:integer">
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+
+ <xs:element name="physmem">
+ <xs:simpleType>
+ <xs:restriction base="xs:integer"/>
+ </xs:simpleType>
+ </xs:element>
+
+ <xs:element name="sockets">
+ <xs:simpleType>
+ <xs:restriction base="xs:integer"/>
+ </xs:simpleType>
+ </xs:element>
+
+ <xs:element name="cores">
+ <xs:simpleType>
+ <xs:restriction base="xs:integer"/>
+ </xs:simpleType>
+ </xs:element>
+
+ <xs:element name="virtcpus">
+ <xs:simpleType>
+ <xs:restriction base="xs:integer"/>
+ </xs:simpleType>
+ </xs:element>
+
+ <xs:element name="name">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:maxLength value="128"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+
+ <xs:element name="clockrate">
+ <xs:simpleType>
+ <xs:restriction base="xs:integer"/>
+ </xs:simpleType>
+ </xs:element>
+
+</xs:schema>
diff --git a/desktop/source/so_comp/evaluation.cxx b/desktop/source/so_comp/evaluation.cxx
new file mode 100644
index 000000000000..8890d26462ec
--- /dev/null
+++ b/desktop/source/so_comp/evaluation.cxx
@@ -0,0 +1,209 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include "evaluation.hxx"
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <com/sun/star/registry/XRegistryKey.hpp>
+#include <com/sun/star/util/Date.hpp>
+#include <rtl/ustrbuf.hxx>
+#include <uno/environment.h>
+#include <cppuhelper/factory.hxx>
+#include <unotools/configmgr.hxx>
+#include <vcl/msgbox.hxx>
+#include <tools/resmgr.hxx>
+#include <tools/resid.hxx>
+#include "../app/desktop.hrc"
+
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::registry;
+
+using ::rtl::OUString;
+
+namespace desktop {
+
+static SOEvaluation* pSOEval=0;
+
+const char* SOEvaluation::interfaces[] =
+{
+ "com.sun.star.beans.XExactName",
+ "com.sun.star.beans.XMaterialHolder",
+ "com.sun.star.lang.XComponent",
+ "com.sun.star.lang.XServiceInfo",
+ NULL,
+};
+
+const char* SOEvaluation::implementationName = "com.sun.star.comp.desktop.Evaluation";
+const char* SOEvaluation::serviceName = "com.sun.star.office.Evaluation";
+
+OUString SOEvaluation::GetImplementationName()
+{
+ return OUString::createFromAscii(implementationName);
+}
+
+Sequence< OUString > SOEvaluation::GetSupportedServiceNames()
+{
+ sal_Int32 nSize = (sizeof( interfaces ) / sizeof( const char *)) - 1;
+ Sequence< OUString > aResult( nSize );
+
+ for( sal_Int32 i = 0; i < nSize; i++ )
+ aResult[i] = OUString::createFromAscii( interfaces[i] );
+ return aResult;
+}
+
+Reference< XInterface > SAL_CALL SOEvaluation::CreateInstance(
+ const Reference< XMultiServiceFactory >& rSMgr )
+{
+ static osl::Mutex aMutex;
+ if ( pSOEval == 0 )
+ {
+ osl::MutexGuard guard( aMutex );
+ if ( pSOEval == 0 )
+ return (XComponent*) ( new SOEvaluation( rSMgr ) );
+ }
+ return (XComponent*)0;
+}
+
+SOEvaluation::SOEvaluation( const Reference< XMultiServiceFactory >& xFactory ) :
+ m_aListeners( m_aMutex ),
+ m_xServiceManager( xFactory )
+{
+}
+
+SOEvaluation::~SOEvaluation()
+{
+}
+
+// XComponent
+void SAL_CALL SOEvaluation::dispose() throw ( RuntimeException )
+{
+ EventObject aObject;
+ aObject.Source = (XComponent*)this;
+ m_aListeners.disposeAndClear( aObject );
+}
+
+void SAL_CALL SOEvaluation::addEventListener( const Reference< XEventListener > & aListener) throw ( RuntimeException )
+{
+ m_aListeners.addInterface( aListener );
+}
+
+void SAL_CALL SOEvaluation::removeEventListener( const Reference< XEventListener > & aListener ) throw ( RuntimeException )
+{
+ m_aListeners.removeInterface( aListener );
+}
+
+// XExactName
+rtl::OUString SAL_CALL SOEvaluation::getExactName( const rtl::OUString& rApproximateName ) throw ( RuntimeException )
+{
+ // get the tabreg service for an evaluation version
+ // without this service office shouldn't run at all
+ OUString aTitle = rApproximateName;
+ OUString aEval;
+ sal_Bool bExpired = sal_True;
+ Reference < XMaterialHolder > xHolder( m_xServiceManager->createInstance(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.tab.tabreg" ) ) ), UNO_QUERY );
+ if ( xHolder.is() )
+ {
+ // get a sequence of strings for the defined locales
+ // a registered version doesn't provide data
+ bExpired = sal_False;
+ Any aData = xHolder->getMaterial();
+ Sequence < NamedValue > aSeq;
+ if ( aData >>= aSeq )
+ {
+ // this is an evaluation version, because it provides "material"
+ bExpired = sal_True;
+ for (int i=0; i<aSeq.getLength(); i++ )
+ {
+ NamedValue& rValue = aSeq[i];
+ if ( rValue.Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("expired")) )
+ rValue.Value >>= bExpired;
+ else if (rValue.Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("title")) )
+ rValue.Value >>= aEval;
+ }
+ // append eval string to title
+ aTitle += OUString(RTL_CONSTASCII_USTRINGPARAM(" ")) + aEval;
+ if ( bExpired )
+ throw RuntimeException();
+ }
+ }
+
+ return aTitle;
+}
+
+// XMaterialHolder
+Any SAL_CALL SOEvaluation::getMaterial() throw( RuntimeException )
+{
+ // Time bomb implementation. Return empty Any to do nothing or
+ // provide a com::sun::star::util::Date with the time bomb date.
+ Any a;
+
+ // change here to force recompile 00002
+#ifdef TIMEBOMB
+ // Code for extracting/providing time bomb date!
+ int nDay = TIMEBOMB % 100;
+ int nMonth = ( TIMEBOMB % 10000 ) / 100;
+ int nYear = TIMEBOMB / 10000;
+ com::sun::star::util::Date aDate( nDay, nMonth, nYear );
+ a <<= aDate;
+#endif
+ return a;
+}
+
+// XServiceInfo
+::rtl::OUString SAL_CALL SOEvaluation::getImplementationName()
+throw ( RuntimeException )
+{
+ return SOEvaluation::GetImplementationName();
+}
+
+sal_Bool SAL_CALL SOEvaluation::supportsService( const ::rtl::OUString& rServiceName )
+throw ( RuntimeException )
+{
+ sal_Int32 nSize = (sizeof( interfaces ) / sizeof( const char *))-1;
+
+ for( sal_Int32 i = 0; i < nSize; i++ )
+ if ( rServiceName.equalsAscii( interfaces[i] ))
+ return sal_True;
+ return sal_False;
+}
+
+Sequence< ::rtl::OUString > SAL_CALL SOEvaluation::getSupportedServiceNames()
+throw ( RuntimeException )
+{
+ return SOEvaluation::GetSupportedServiceNames();
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/so_comp/evaluation.hxx b/desktop/source/so_comp/evaluation.hxx
new file mode 100644
index 000000000000..aff94c3ac6f4
--- /dev/null
+++ b/desktop/source/so_comp/evaluation.hxx
@@ -0,0 +1,95 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+/* makefile.mk changed 20030409, LO */
+
+#ifndef _SOCOMP_EVALUATION_HXX_
+#define _SOCOMP_EVALUATION_HXX_
+
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/uno/Exception.hpp>
+#include <com/sun/star/uno/Reference.h>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/lang/XEventListener.hpp>
+#include <com/sun/star/beans/XExactName.hpp>
+#include <com/sun/star/beans/XMaterialHolder.hpp>
+#include <cppuhelper/implbase4.hxx>
+#include <cppuhelper/interfacecontainer.h>
+
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#include <osl/mutex.hxx>
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::beans;
+
+namespace desktop {
+
+class SOEvaluation : public ::cppu::WeakImplHelper4< XExactName, XMaterialHolder, XComponent, XServiceInfo >
+{
+ ::osl::Mutex m_aMutex;
+ ::cppu::OInterfaceContainerHelper m_aListeners;
+ Reference< XMultiServiceFactory > m_xServiceManager;
+
+public:
+ SOEvaluation( const Reference < XMultiServiceFactory >& xFactory );
+ virtual ~SOEvaluation();
+
+ static Reference< XSingleServiceFactory > GetSOEvaluationFactory( Reference< XMultiServiceFactory > & xSMgr );
+ static ::rtl::OUString GetImplementationName();
+ static Sequence< rtl::OUString > GetSupportedServiceNames();
+
+ // XComponent
+ virtual void SAL_CALL dispose() throw ( RuntimeException );
+ virtual void SAL_CALL addEventListener( const Reference< XEventListener > & aListener) throw ( RuntimeException );
+ virtual void SAL_CALL removeEventListener(const Reference< XEventListener > & aListener) throw ( RuntimeException );
+
+ // XExactName
+ virtual rtl::OUString SAL_CALL getExactName( const rtl::OUString& rApproximateName ) throw ( RuntimeException );
+
+ // XMaterialHolder
+ virtual Any SAL_CALL getMaterial() throw ( RuntimeException );
+
+ // XServiceInfo
+ virtual ::rtl::OUString SAL_CALL getImplementationName() throw ( RuntimeException );
+ virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& rServiceName ) throw ( RuntimeException );
+ virtual Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() throw ( RuntimeException );
+
+ static const char* interfaces[];
+ static const char* implementationName;
+ static const char* serviceName;
+ static Reference<XInterface> SAL_CALL CreateInstance(
+ const Reference< XMultiServiceFactory >&);
+
+
+
+};
+}
+#endif // _SOCOMP_EVALUATION_HXX_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/so_comp/makefile.mk b/desktop/source/so_comp/makefile.mk
new file mode 100755
index 000000000000..4d8d479b9658
--- /dev/null
+++ b/desktop/source/so_comp/makefile.mk
@@ -0,0 +1,79 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+PRJNAME=desktop
+TARGET=socomp
+LIBTARGET=NO
+
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+SLOFILES = $(SLO)$/evaluation.obj \
+ $(SLO)$/oemjob.obj \
+ $(SLO)$/services.obj
+
+SHL1DEPN= makefile.mk
+SHL1OBJS= $(SLOFILES)
+
+
+SHL1TARGET= $(TARGET)
+SHL1IMPLIB= i$(TARGET)
+
+SHL1VERSIONMAP=$(SOLARENV)/src/component.map
+SHL1DEF=$(MISC)$/$(SHL1TARGET).def
+DEF1NAME=$(SHL1TARGET)
+
+SHL1STDLIBS= \
+ $(FWELIB) \
+ $(VCLLIB) \
+ $(SVLLIB) \
+ $(SVTOOLLIB) \
+ $(COMPHELPERLIB) \
+ $(UNOTOOLSLIB) \
+ $(TOOLSLIB) \
+ $(CPPUHELPERLIB) \
+ $(CPPULIB) \
+ $(SALLIB)
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
+ALLTAR : $(MISC)/socomp.component
+
+$(MISC)/socomp.component .ERRREMOVE : $(SOLARENV)/bin/createcomponent.xslt \
+ socomp.component
+ $(XSLTPROC) --nonet --stringparam uri \
+ '$(COMPONENTPREFIX_BASIS_NATIVE)$(SHL1TARGETN:f)' -o $@ \
+ $(SOLARENV)/bin/createcomponent.xslt socomp.component
diff --git a/desktop/source/so_comp/oemjob.cxx b/desktop/source/so_comp/oemjob.cxx
new file mode 100644
index 000000000000..bdb45e5eb0a7
--- /dev/null
+++ b/desktop/source/so_comp/oemjob.cxx
@@ -0,0 +1,250 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include "oemjob.hxx"
+#include <rtl/bootstrap.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <osl/file.hxx>
+#include <unotools/bootstrap.hxx>
+#include <tools/config.hxx>
+#include <com/sun/star/frame/XDesktop.hpp>
+#include <com/sun/star/frame/XFrame.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/util/XCloseable.hpp>
+#include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
+#include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
+#include <com/sun/star/beans/NamedValue.hpp>
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::ui::dialogs;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::util;
+
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+using ::rtl::Bootstrap;
+
+namespace desktop{
+
+char const OEM_PRELOAD_SECTION[] = "Bootstrap";
+char const OEM_PRELOAD[] = "Preload";
+char const STR_TRUE[] = "1";
+char const STR_FALSE[] = "0";
+
+const char* OEMPreloadJob::interfaces[] =
+{
+ "com.sun.star.task.XJob",
+ NULL,
+};
+const char* OEMPreloadJob::implementationName = "com.sun.star.comp.desktop.OEMPreloadJob";
+const char* OEMPreloadJob::serviceName = "com.sun.star.office.OEMPreloadJob";
+
+OUString OEMPreloadJob::GetImplementationName()
+{
+ return OUString::createFromAscii(implementationName);
+}
+
+Sequence< OUString > OEMPreloadJob::GetSupportedServiceNames()
+{
+ sal_Int32 nSize = (sizeof( interfaces ) / sizeof( const char *)) - 1;
+ Sequence< OUString > aResult( nSize );
+
+ for( sal_Int32 i = 0; i < nSize; i++ )
+ aResult[i] = OUString::createFromAscii( interfaces[i] );
+ return aResult;
+}
+
+Reference< XInterface > SAL_CALL OEMPreloadJob::CreateInstance(
+ const Reference< XMultiServiceFactory >& rSMgr )
+{
+ static osl::Mutex aMutex;
+ osl::MutexGuard guard( aMutex );
+ return (XComponent*) ( new OEMPreloadJob( rSMgr ) );
+}
+
+OEMPreloadJob::OEMPreloadJob( const Reference< XMultiServiceFactory >& xFactory ) :
+ m_aListeners( m_aMutex ),
+ m_xServiceManager( xFactory )
+{
+}
+
+OEMPreloadJob::~OEMPreloadJob()
+{
+}
+
+// XComponent
+void SAL_CALL OEMPreloadJob::dispose() throw ( RuntimeException )
+{
+ EventObject aObject;
+ aObject.Source = (XComponent*)this;
+ m_aListeners.disposeAndClear( aObject );
+}
+
+void SAL_CALL OEMPreloadJob::addEventListener( const Reference< XEventListener > & aListener) throw ( RuntimeException )
+{
+ m_aListeners.addInterface( aListener );
+}
+
+void SAL_CALL OEMPreloadJob::removeEventListener( const Reference< XEventListener > & aListener ) throw ( RuntimeException )
+{
+ m_aListeners.removeInterface( aListener );
+}
+
+// XServiceInfo
+::rtl::OUString SAL_CALL OEMPreloadJob::getImplementationName()
+throw ( RuntimeException )
+{
+ return OEMPreloadJob::GetImplementationName();
+}
+
+sal_Bool SAL_CALL OEMPreloadJob::supportsService( const ::rtl::OUString& rServiceName )
+throw ( RuntimeException )
+{
+ sal_Int32 nSize = sizeof( interfaces ) / sizeof( const char *);
+
+ for( sal_Int32 i = 0; i < nSize; i++ )
+ if ( rServiceName.equalsAscii( interfaces[i] ))
+ return sal_True;
+ return sal_False;
+}
+
+Sequence< ::rtl::OUString > SAL_CALL OEMPreloadJob::getSupportedServiceNames()
+throw ( RuntimeException )
+{
+ return OEMPreloadJob::GetSupportedServiceNames();
+}
+
+// XJob
+Any SAL_CALL OEMPreloadJob::execute(const Sequence<NamedValue>&)
+throw ( RuntimeException )
+{
+ sal_Bool bCont = sal_False;
+ // are we an OEM version at all?
+ if (checkOEMPreloadFlag())
+ {
+ // create OEM preload service dialog
+ Reference <XExecutableDialog> xDialog( m_xServiceManager->createInstance(
+ OUString(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.comp.preload.OEMPreloadWizard"))),
+ UNO_QUERY );
+ if ( xDialog.is() ){
+ // execute OEM preload dialog and check return value
+ if ( xDialog->execute() == ExecutableDialogResults::OK ) {
+ // user accepted.
+ // make sure the job does not get called again.
+ bCont = sal_True;
+ disableOEMPreloadFlag();
+ } else {
+ // user declined...
+ // terminate.
+ bCont = sal_False;
+ }
+ }
+ } else {
+ // don't try again
+ bCont = sal_True;
+ }
+ Any r;
+ r <<= bCont;
+ return r;
+}
+
+static sal_Bool existsURL( OUString const& _sURL )
+{
+ using namespace osl;
+ DirectoryItem aDirItem;
+
+ if (_sURL.getLength() != 0)
+ return ( DirectoryItem::get( _sURL, aDirItem ) == DirectoryItem::E_None );
+
+ return sal_False;
+}
+
+// locate soffice.ini/.rc file
+static OUString locateIniFile()
+{
+ OUString aUserDataPath;
+ OUString aSofficeIniFileURL;
+
+ // Retrieve the default file URL for the soffice.ini/rc
+ Bootstrap().getIniName( aSofficeIniFileURL );
+
+ if ( utl::Bootstrap::locateUserData( aUserDataPath ) == utl::Bootstrap::PATH_EXISTS )
+ {
+ const char CONFIG_DIR[] = "/config";
+
+ sal_Int32 nIndex = aSofficeIniFileURL.lastIndexOf( '/');
+ if ( nIndex > 0 )
+ {
+ OUString aUserSofficeIniFileURL;
+ OUStringBuffer aBuffer( aUserDataPath );
+ aBuffer.appendAscii( CONFIG_DIR );
+ aBuffer.append( aSofficeIniFileURL.copy( nIndex ));
+ aUserSofficeIniFileURL = aBuffer.makeStringAndClear();
+
+ if ( existsURL( aUserSofficeIniFileURL ))
+ return aUserSofficeIniFileURL;
+ }
+ }
+ // Fallback try to use the soffice.ini/rc from program folder
+ return aSofficeIniFileURL;
+}
+
+// check whether the OEMPreload flag was set in soffice.ini/.rc
+sal_Bool OEMPreloadJob::checkOEMPreloadFlag()
+{
+ OUString aSofficeIniFileURL;
+ aSofficeIniFileURL = locateIniFile();
+ Config aConfig(aSofficeIniFileURL);
+ aConfig.SetGroup( OEM_PRELOAD_SECTION );
+ ByteString sResult = aConfig.ReadKey( OEM_PRELOAD );
+ if ( sResult == STR_TRUE )
+ return sal_True;
+ else
+ return sal_False;
+}
+
+void OEMPreloadJob::disableOEMPreloadFlag()
+{
+ OUString aSofficeIniFileURL = locateIniFile();
+ if ( aSofficeIniFileURL.getLength() > 0 )
+ {
+ Config aConfig(aSofficeIniFileURL);
+ aConfig.SetGroup( OEM_PRELOAD_SECTION );
+ aConfig.WriteKey( OEM_PRELOAD, STR_FALSE );
+ aConfig.Flush();
+ }
+}
+
+} // namespace desktop
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/so_comp/oemjob.hxx b/desktop/source/so_comp/oemjob.hxx
new file mode 100644
index 000000000000..140ee0e9af10
--- /dev/null
+++ b/desktop/source/so_comp/oemjob.hxx
@@ -0,0 +1,95 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _SOCOMP_OEMJOB_HXX_
+#define _SOCOMP_OEMJOB_HXX_
+
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/uno/Exception.hpp>
+#include <com/sun/star/uno/Reference.h>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/task/XJob.hpp>
+#include <cppuhelper/implbase3.hxx>
+#include <cppuhelper/interfacecontainer.h>
+
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#include <osl/mutex.hxx>
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::task;
+
+namespace desktop{
+
+class OEMPreloadJob : public ::cppu::WeakImplHelper3< XJob, XComponent, XServiceInfo >
+{
+
+private:
+ ::osl::Mutex m_aMutex;
+ ::cppu::OInterfaceContainerHelper m_aListeners;
+ Reference< XMultiServiceFactory > m_xServiceManager;
+
+ sal_Bool checkOEMPreloadFlag();
+ void disableOEMPreloadFlag();
+
+public:
+ OEMPreloadJob( const Reference < XMultiServiceFactory >& xFactory );
+ virtual ~OEMPreloadJob();
+
+ static ::rtl::OUString GetImplementationName();
+ static Sequence< rtl::OUString > GetSupportedServiceNames();
+
+
+ // XComponent
+ virtual void SAL_CALL dispose() throw ( RuntimeException );
+ virtual void SAL_CALL addEventListener( const Reference< XEventListener > & aListener) throw ( RuntimeException );
+ virtual void SAL_CALL removeEventListener(const Reference< XEventListener > & aListener) throw ( RuntimeException );
+
+ // XServiceInfo
+ virtual ::rtl::OUString SAL_CALL getImplementationName() throw ( RuntimeException );
+ virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& rServiceName ) throw ( RuntimeException );
+ virtual Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() throw ( RuntimeException );
+
+ //XJob
+ virtual Any SAL_CALL execute(const Sequence<NamedValue>& args)throw ( RuntimeException );
+
+
+ static const char* interfaces[];
+ static const char* implementationName;
+ static const char* serviceName;
+ static Reference<XInterface> SAL_CALL CreateInstance(
+ const Reference< XMultiServiceFactory >&);
+
+
+};
+}
+
+#endif // _SOCOMP_OEMJOB_HXX_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/so_comp/services.cxx b/desktop/source/so_comp/services.cxx
new file mode 100644
index 000000000000..a2bd31eec013
--- /dev/null
+++ b/desktop/source/so_comp/services.cxx
@@ -0,0 +1,137 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include "evaluation.hxx"
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <com/sun/star/registry/XRegistryKey.hpp>
+#include <com/sun/star/util/Date.hpp>
+#include <uno/environment.h>
+#include <cppuhelper/factory.hxx>
+#include <unotools/configmgr.hxx>
+
+#include "oemjob.hxx"
+#include "evaluation.hxx"
+
+#include <string.h>
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::registry;
+using namespace ::desktop;
+
+using ::rtl::OUString;
+
+static const char* pServices[] =
+{
+ SOEvaluation::serviceName,
+ OEMPreloadJob::serviceName,
+ NULL
+};
+
+static const char* pImplementations[] =
+{
+ SOEvaluation::implementationName,
+ OEMPreloadJob::implementationName,
+ NULL
+};
+
+typedef Reference<XInterface>(* fProvider)(const Reference<XMultiServiceFactory>&);
+
+static const fProvider pInstanceProviders[] =
+{
+ SOEvaluation::CreateInstance,
+ OEMPreloadJob::CreateInstance,
+ NULL
+};
+
+static const char** pSupportedServices[] =
+{
+ SOEvaluation::interfaces,
+ OEMPreloadJob::interfaces,
+ NULL
+};
+
+static Sequence<OUString>
+getSupportedServiceNames(int p) {
+ const char **names = pSupportedServices[p];
+ Sequence<OUString> aSeq;
+ for(int i = 0; names[i] != NULL; i++) {
+ aSeq.realloc(i+1);
+ aSeq[i] = OUString::createFromAscii(names[i]);
+ }
+ return aSeq;
+}
+
+extern "C"
+{
+void SAL_CALL
+component_getImplementationEnvironment(
+ const sal_Char** ppEnvironmentTypeName,
+ uno_Environment**)
+{
+ *ppEnvironmentTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME ;
+}
+
+void* SAL_CALL
+component_getFactory(
+ const sal_Char* pImplementationName,
+ void* pServiceManager,
+ void*)
+{
+ // Set default return value for this operation - if it failed.
+ if ( pImplementationName && pServiceManager )
+ {
+ Reference< XSingleServiceFactory > xFactory;
+ Reference< XMultiServiceFactory > xServiceManager(
+ reinterpret_cast< XMultiServiceFactory* >( pServiceManager ) ) ;
+
+ // search implementation
+ for (int i = 0; (pImplementations[i]!=NULL); i++) {
+ if ( strcmp(pImplementations[i], pImplementationName ) == 0 ) {
+ // found implementation
+ xFactory = Reference<XSingleServiceFactory>(cppu::createSingleFactory(
+ xServiceManager, OUString::createFromAscii(pImplementationName),
+ pInstanceProviders[i], getSupportedServiceNames(i)));
+ if ( xFactory.is() ) {
+ // Factory is valid - service was found.
+ xFactory->acquire();
+ return xFactory.get();
+ }
+ }
+ } // for()
+ }
+ // Return with result of this operation.
+ return NULL;
+}
+} // extern "C"
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/so_comp/socomp.component b/desktop/source/so_comp/socomp.component
new file mode 100755
index 000000000000..a53035223c39
--- /dev/null
+++ b/desktop/source/so_comp/socomp.component
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--**********************************************************************
+*
+* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+*
+* Copyright 2000, 2010 Oracle and/or its affiliates.
+*
+* OpenOffice.org - a multi-platform office productivity suite
+*
+* This file is part of OpenOffice.org.
+*
+* OpenOffice.org is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License version 3
+* only, as published by the Free Software Foundation.
+*
+* OpenOffice.org is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Lesser General Public License version 3 for more details
+* (a copy is included in the LICENSE file that accompanied this code).
+*
+* You should have received a copy of the GNU Lesser General Public License
+* version 3 along with OpenOffice.org. If not, see
+* <http://www.openoffice.org/license.html>
+* for a copy of the LGPLv3 License.
+*
+**********************************************************************-->
+
+<component loader="com.sun.star.loader.SharedLibrary"
+ xmlns="http://openoffice.org/2010/uno-components">
+ <implementation name="com.sun.star.comp.desktop.Evaluation">
+ <service name="com.sun.star.office.Evaluation"/>
+ </implementation>
+ <implementation name="com.sun.star.comp.desktop.OEMPreloadJob">
+ <service name="com.sun.star.office.OEMPreloadJob"/>
+ </implementation>
+</component>
diff --git a/desktop/source/splash/makefile.mk b/desktop/source/splash/makefile.mk
new file mode 100755
index 000000000000..8db499d7c913
--- /dev/null
+++ b/desktop/source/splash/makefile.mk
@@ -0,0 +1,80 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+PRJNAME=desktop
+TARGET=spl
+LIBTARGET=NO
+
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+SLOFILES = $(SLO)$/splash.obj \
+ $(SLO)$/services_spl.obj
+
+SHL1DEPN= makefile.mk
+SHL1OBJS= $(SLOFILES) \
+ $(SLO)$/migration.obj
+
+
+SHL1TARGET=$(TARGET)$(DLLPOSTFIX)
+SHL1IMPLIB=i$(TARGET)
+
+SHL1VERSIONMAP=$(SOLARENV)/src/component.map
+SHL1DEF=$(MISC)$/$(SHL1TARGET).def
+DEF1NAME=$(SHL1TARGET)
+
+SHL1STDLIBS= \
+ $(VCLLIB) \
+ $(SVLLIB) \
+ $(SVTOOLLIB) \
+ $(COMPHELPERLIB) \
+ $(UNOTOOLSLIB) \
+ $(TOOLSLIB) \
+ $(UCBHELPERLIB) \
+ $(CPPUHELPERLIB) \
+ $(CPPULIB) \
+ $(SALLIB) \
+ $(SFXLIB)
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
+ALLTAR : $(MISC)/spl.component
+
+$(MISC)/spl.component .ERRREMOVE : $(SOLARENV)/bin/createcomponent.xslt \
+ spl.component
+ $(XSLTPROC) --nonet --stringparam uri \
+ '$(COMPONENTPREFIX_BASIS_NATIVE)$(SHL1TARGETN:f)' -o $@ \
+ $(SOLARENV)/bin/createcomponent.xslt spl.component
diff --git a/desktop/source/splash/services_spl.cxx b/desktop/source/splash/services_spl.cxx
new file mode 100644
index 000000000000..e4e80fbe13f3
--- /dev/null
+++ b/desktop/source/splash/services_spl.cxx
@@ -0,0 +1,128 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <com/sun/star/registry/XRegistryKey.hpp>
+#include <com/sun/star/util/Date.hpp>
+#include <uno/environment.h>
+#include <cppuhelper/factory.hxx>
+#include <unotools/configmgr.hxx>
+
+#include "splash.hxx"
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::registry;
+using namespace ::desktop;
+
+using ::rtl::OUString;
+
+static const char* pServices[] =
+{
+ SplashScreen::serviceName,
+ NULL
+};
+
+static const char* pImplementations[] =
+{
+ SplashScreen::implementationName,
+ NULL
+};
+
+typedef Reference<XInterface>(* fProvider)(const Reference<XMultiServiceFactory>&);
+
+static const fProvider pInstanceProviders[] =
+{
+ SplashScreen::getInstance,
+ NULL
+};
+
+static const char** pSupportedServices[] =
+{
+ SplashScreen::interfaces,
+ NULL
+};
+
+static Sequence<OUString>
+getSupportedServiceNames(int p) {
+ const char **names = pSupportedServices[p];
+ Sequence<OUString> aSeq;
+ for(int i = 0; names[i] != NULL; i++) {
+ aSeq.realloc(i+1);
+ aSeq[i] = OUString::createFromAscii(names[i]);
+ }
+ return aSeq;
+}
+
+extern "C"
+{
+void SAL_CALL
+component_getImplementationEnvironment(
+ const sal_Char** ppEnvironmentTypeName,
+ uno_Environment**)
+{
+ *ppEnvironmentTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME ;
+}
+
+void* SAL_CALL
+component_getFactory(
+ const sal_Char* pImplementationName,
+ void* pServiceManager,
+ void*)
+{
+ // Set default return value for this operation - if it failed.
+ if ( pImplementationName && pServiceManager )
+ {
+ Reference< XSingleServiceFactory > xFactory;
+ Reference< XMultiServiceFactory > xServiceManager(
+ reinterpret_cast< XMultiServiceFactory* >( pServiceManager ) ) ;
+
+ // search implementation
+ for (int i = 0; (pImplementations[i]!=NULL); i++) {
+ if ( strcmp(pImplementations[i], pImplementationName ) == 0 ) {
+ // found implementation
+ xFactory = Reference<XSingleServiceFactory>(cppu::createSingleFactory(
+ xServiceManager, OUString::createFromAscii(pImplementationName),
+ pInstanceProviders[i], getSupportedServiceNames(i)));
+ if ( xFactory.is() ) {
+ // Factory is valid - service was found.
+ xFactory->acquire();
+ return xFactory.get();
+ }
+ }
+ } // for()
+ }
+ // Return with result of this operation.
+ return NULL;
+}
+} // extern "C"
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/splash/spl.component b/desktop/source/splash/spl.component
new file mode 100755
index 000000000000..2caecf5c0e4b
--- /dev/null
+++ b/desktop/source/splash/spl.component
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--**********************************************************************
+*
+* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+*
+* Copyright 2000, 2010 Oracle and/or its affiliates.
+*
+* OpenOffice.org - a multi-platform office productivity suite
+*
+* This file is part of OpenOffice.org.
+*
+* OpenOffice.org is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License version 3
+* only, as published by the Free Software Foundation.
+*
+* OpenOffice.org is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Lesser General Public License version 3 for more details
+* (a copy is included in the LICENSE file that accompanied this code).
+*
+* You should have received a copy of the GNU Lesser General Public License
+* version 3 along with OpenOffice.org. If not, see
+* <http://www.openoffice.org/license.html>
+* for a copy of the LGPLv3 License.
+*
+**********************************************************************-->
+
+<component loader="com.sun.star.loader.SharedLibrary"
+ xmlns="http://openoffice.org/2010/uno-components">
+ <implementation name="com.sun.star.comp.desktop.FirstStart">
+ <service name="com.sun.star.task.Job"/>
+ </implementation>
+ <implementation name="com.sun.star.office.comp.SplashScreen">
+ <service name="com.sun.star.office.SplashScreen"/>
+ </implementation>
+</component>
diff --git a/desktop/source/splash/splash.cxx b/desktop/source/splash/splash.cxx
new file mode 100644
index 000000000000..42e1dfd51c0d
--- /dev/null
+++ b/desktop/source/splash/splash.cxx
@@ -0,0 +1,580 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include "splash.hxx"
+#include <stdio.h>
+#include <unotools/bootstrap.hxx>
+#include <tools/urlobj.hxx>
+#include <tools/stream.hxx>
+#include <sfx2/sfx.hrc>
+#include <vcl/svapp.hxx>
+#include <vcl/salnativewidgets.hxx>
+
+#include <com/sun/star/registry/XRegistryKey.hpp>
+#include <rtl/bootstrap.hxx>
+#include <rtl/logfile.hxx>
+#include <rtl/locale.hxx>
+#include <rtl/strbuf.hxx>
+#include <rtl/math.hxx>
+#include <vcl/graph.hxx>
+#include <svtools/filter.hxx>
+
+#define NOT_LOADED ((long)-1)
+
+using namespace ::rtl;
+using namespace ::com::sun::star::registry;
+
+namespace desktop
+{
+
+SplashScreen::SplashScreen(const Reference< XMultiServiceFactory >& rSMgr)
+ : IntroWindow()
+ , _vdev(*((IntroWindow*)this))
+ , _cProgressFrameColor(sal::static_int_cast< ColorData >(NOT_LOADED))
+ , _cProgressBarColor(sal::static_int_cast< ColorData >(NOT_LOADED))
+ , _bNativeProgress(true)
+ , _iMax(100)
+ , _iProgress(0)
+ , _eBitmapMode(BM_DEFAULTMODE)
+ , _bPaintBitmap(sal_True)
+ , _bPaintProgress(sal_False)
+ , _bShowLogo(sal_True)
+ , _bFullScreenSplash(sal_False)
+ , _bProgressEnd(sal_False)
+ , _tlx(NOT_LOADED)
+ , _tly(NOT_LOADED)
+ , _barwidth(NOT_LOADED)
+ , _barheight(NOT_LOADED)
+ , _barspace(2)
+ , _fXPos(-1.0)
+ , _fYPos(-1.0)
+ , _fWidth(-1.0)
+ , _fHeight(-1.0)
+ , _xoffset(12)
+ , _yoffset(18)
+{
+ _rFactory = rSMgr;
+
+ loadConfig();
+}
+
+SplashScreen::~SplashScreen()
+{
+ Application::RemoveEventListener(
+ LINK( this, SplashScreen, AppEventListenerHdl ) );
+ Hide();
+
+}
+
+void SAL_CALL SplashScreen::start(const OUString&, sal_Int32 nRange)
+ throw (RuntimeException)
+{
+ _iMax = nRange;
+ if (_bVisible) {
+ _bProgressEnd = sal_False;
+ SolarMutexGuard aSolarGuard;
+ if ( _eBitmapMode == BM_FULLSCREEN )
+ ShowFullScreenMode( sal_True );
+ Show();
+ Paint(Rectangle());
+ Flush();
+ }
+}
+
+void SAL_CALL SplashScreen::end()
+ throw (RuntimeException)
+{
+ _iProgress = _iMax;
+ if (_bVisible )
+ {
+ if ( _eBitmapMode == BM_FULLSCREEN )
+ EndFullScreenMode();
+ Hide();
+ }
+ _bProgressEnd = sal_True;
+}
+
+void SAL_CALL SplashScreen::reset()
+ throw (RuntimeException)
+{
+ _iProgress = 0;
+ if (_bVisible && !_bProgressEnd )
+ {
+ if ( _eBitmapMode == BM_FULLSCREEN )
+ ShowFullScreenMode( sal_True );
+ Show();
+ updateStatus();
+ }
+}
+
+void SAL_CALL SplashScreen::setText(const OUString& rText)
+ throw (RuntimeException)
+{
+ SolarMutexGuard aSolarGuard;
+ if ( _sProgressText != rText )
+ {
+ _sProgressText = rText;
+
+ if (_bVisible && !_bProgressEnd)
+ {
+ if ( _eBitmapMode == BM_FULLSCREEN )
+ ShowFullScreenMode( sal_True );
+ Show();
+ updateStatus();
+ }
+ }
+}
+
+void SAL_CALL SplashScreen::setValue(sal_Int32 nValue)
+ throw (RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT( aLog, "::SplashScreen::setValue (lo119109)" );
+ RTL_LOGFILE_CONTEXT_TRACE1( aLog, "value=%d", nValue );
+
+ SolarMutexGuard aSolarGuard;
+ if (_bVisible && !_bProgressEnd) {
+ if ( _eBitmapMode == BM_FULLSCREEN )
+ ShowFullScreenMode( sal_True );
+ Show();
+ if (nValue >= _iMax) _iProgress = _iMax;
+ else _iProgress = nValue;
+ updateStatus();
+ }
+}
+
+// XInitialize
+void SAL_CALL
+SplashScreen::initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any>& aArguments )
+ throw (RuntimeException)
+{
+ ::osl::ClearableMutexGuard aGuard( _aMutex );
+ if (aArguments.getLength() > 0)
+ {
+ aArguments[0] >>= _bVisible;
+ if (aArguments.getLength() > 1 )
+ aArguments[1] >>= _sAppName;
+
+ // start to determine bitmap and all other required value
+ if ( _bShowLogo )
+ SetScreenBitmap (_aIntroBmp);
+ Size aSize = _aIntroBmp.GetSizePixel();
+ SetOutputSizePixel( aSize );
+ _vdev.SetOutputSizePixel( aSize );
+ _height = aSize.Height();
+ _width = aSize.Width();
+ if (_width > 500)
+ {
+ Point xtopleft(212,216);
+ if ( NOT_LOADED == _tlx || NOT_LOADED == _tly )
+ {
+ _tlx = xtopleft.X(); // top-left x
+ _tly = xtopleft.Y(); // top-left y
+ }
+ if ( NOT_LOADED == _barwidth )
+ _barwidth = 263;
+ if ( NOT_LOADED == _barheight )
+ _barheight = 8;
+ if (( _eBitmapMode == BM_FULLSCREEN ) &&
+ _bFullScreenSplash )
+ {
+ if( ( _fXPos >= 0.0 ) && ( _fYPos >= 0.0 ))
+ {
+ _tlx = sal_Int32( double( aSize.Width() ) * _fXPos );
+ _tly = sal_Int32( double( aSize.Height() ) * _fYPos );
+ }
+ if ( _fWidth >= 0.0 )
+ _barwidth = sal_Int32( double( aSize.Width() ) * _fWidth );
+ if ( _fHeight >= 0.0 )
+ _barheight = sal_Int32( double( aSize.Width() ) * _fHeight );
+ }
+ }
+ else
+ {
+ if ( NOT_LOADED == _barwidth )
+ _barwidth = _width - (2 * _xoffset);
+ if ( NOT_LOADED == _barheight )
+ _barheight = 6;
+ if ( NOT_LOADED == _tlx || NOT_LOADED == _tly )
+ {
+ _tlx = _xoffset; // top-left x
+ _tly = _height - _yoffset; // top-left y
+ }
+ }
+
+ if ( sal::static_int_cast< ColorData >(NOT_LOADED) ==
+ _cProgressFrameColor.GetColor() )
+ _cProgressFrameColor = Color( COL_LIGHTGRAY );
+
+ if ( sal::static_int_cast< ColorData >(NOT_LOADED) ==
+ _cProgressBarColor.GetColor() )
+ {
+ // progress bar: new color only for big bitmap format
+ if ( _width > 500 )
+ _cProgressBarColor = Color( 157, 202, 18 );
+ else
+ _cProgressBarColor = Color( COL_BLUE );
+ }
+
+ Application::AddEventListener(
+ LINK( this, SplashScreen, AppEventListenerHdl ) );
+
+ SetBackgroundBitmap( _aIntroBmp );
+ }
+}
+
+void SplashScreen::updateStatus()
+{
+ if (!_bVisible || _bProgressEnd) return;
+ if (!_bPaintProgress) _bPaintProgress = sal_True;
+ Paint(Rectangle());
+ Flush();
+}
+
+// internal private methods
+IMPL_LINK( SplashScreen, AppEventListenerHdl, VclWindowEvent *, inEvent )
+{
+ if ( inEvent != 0 )
+ {
+ switch ( inEvent->GetId() )
+ {
+ case VCLEVENT_WINDOW_SHOW:
+ Paint( Rectangle() );
+ break;
+ default:
+ break;
+ }
+ }
+ return 0;
+}
+
+// Read keys from edition/edition.ini or soffice{.ini|rc}:
+OUString implReadBootstrapKey( const OUString& _rKey )
+{
+ OUString sValue(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "${.override:${BRAND_BASE_DIR}/program/edition/edition.ini:")) +
+ _rKey + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("}")));
+ rtl::Bootstrap::expandMacros(sValue);
+ return sValue;
+}
+
+void SplashScreen::loadConfig()
+{
+ _bShowLogo = !implReadBootstrapKey(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Logo"))).
+ equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("0"));
+
+ OUString sProgressFrameColor = implReadBootstrapKey(
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "ProgressFrameColor" ) ) );
+ OUString sProgressBarColor = implReadBootstrapKey(
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "ProgressBarColor" ) ) );
+ OUString sSize = implReadBootstrapKey(
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "ProgressSize" ) ) );
+ OUString sPosition = implReadBootstrapKey(
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "ProgressPosition" ) ) );
+ OUString sFullScreenSplash = implReadBootstrapKey(
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "FullScreenSplash" ) ) );
+ OUString sNativeProgress = implReadBootstrapKey(
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "NativeProgress" ) ) );
+
+
+ // Determine full screen splash mode
+ _bFullScreenSplash = (( sFullScreenSplash.getLength() > 0 ) &&
+ ( !sFullScreenSplash.equalsAsciiL( "0", 1 )));
+
+ // Try to retrieve the relative values for the progress bar. The current
+ // schema uses the screen ratio to retrieve the associated values.
+ if ( _bFullScreenSplash )
+ determineProgressRatioValues( _fXPos, _fYPos, _fWidth, _fHeight );
+
+ if ( sProgressFrameColor.getLength() )
+ {
+ sal_uInt8 nRed = 0;
+ sal_Int32 idx = 0;
+ sal_Int32 temp = sProgressFrameColor.getToken( 0, ',', idx ).toInt32();
+ if ( idx != -1 )
+ {
+ nRed = static_cast< sal_uInt8 >( temp );
+ temp = sProgressFrameColor.getToken( 0, ',', idx ).toInt32();
+ }
+ if ( idx != -1 )
+ {
+ sal_uInt8 nGreen = static_cast< sal_uInt8 >( temp );
+ sal_uInt8 nBlue = static_cast< sal_uInt8 >( sProgressFrameColor.getToken( 0, ',', idx ).toInt32() );
+ _cProgressFrameColor = Color( nRed, nGreen, nBlue );
+ }
+ }
+
+ if ( sProgressBarColor.getLength() )
+ {
+ sal_uInt8 nRed = 0;
+ sal_Int32 idx = 0;
+ sal_Int32 temp = sProgressBarColor.getToken( 0, ',', idx ).toInt32();
+ if ( idx != -1 )
+ {
+ nRed = static_cast< sal_uInt8 >( temp );
+ temp = sProgressBarColor.getToken( 0, ',', idx ).toInt32();
+ }
+ if ( idx != -1 )
+ {
+ sal_uInt8 nGreen = static_cast< sal_uInt8 >( temp );
+ sal_uInt8 nBlue = static_cast< sal_uInt8 >( sProgressBarColor.getToken( 0, ',', idx ).toInt32() );
+ _cProgressBarColor = Color( nRed, nGreen, nBlue );
+ }
+ }
+
+ if( sNativeProgress.getLength() )
+ {
+ _bNativeProgress = sNativeProgress.toBoolean();
+ }
+
+ if ( sSize.getLength() )
+ {
+ sal_Int32 idx = 0;
+ sal_Int32 temp = sSize.getToken( 0, ',', idx ).toInt32();
+ if ( idx != -1 )
+ {
+ _barwidth = temp;
+ _barheight = sSize.getToken( 0, ',', idx ).toInt32();
+ }
+ }
+
+ if ( _barheight >= 10 )
+ _barspace = 3; // more space between frame and bar
+
+ if ( sPosition.getLength() )
+ {
+ sal_Int32 idx = 0;
+ sal_Int32 temp = sPosition.getToken( 0, ',', idx ).toInt32();
+ if ( idx != -1 )
+ {
+ _tlx = temp;
+ _tly = sPosition.getToken( 0, ',', idx ).toInt32();
+ }
+ }
+}
+
+void SplashScreen::SetScreenBitmap(BitmapEx &rBitmap)
+{
+ sal_Int32 nWidth( 0 );
+ sal_Int32 nHeight( 0 );
+
+ // determine desktop resolution
+ sal_uInt32 nCount = Application::GetScreenCount();
+ if ( nCount > 0 )
+ {
+ // retrieve size from first screen
+ Rectangle aScreenArea = Application::GetScreenPosSizePixel((unsigned int)0);
+ nWidth = aScreenArea.GetWidth();
+ nHeight = aScreenArea.GetHeight();
+ }
+
+ // create file name from screen resolution information
+ OStringBuffer aStrBuf( 128 );
+ OStringBuffer aResBuf( 32 );
+ aStrBuf.append( "intro_" );
+ if ( _sAppName.getLength() > 0 )
+ {
+ aStrBuf.append( OUStringToOString(_sAppName, RTL_TEXTENCODING_UTF8) );
+ aStrBuf.append( "_" );
+ }
+ aResBuf.append( OString::valueOf( nWidth ));
+ aResBuf.append( "x" );
+ aResBuf.append( OString::valueOf( nHeight ));
+
+ aStrBuf.append( aResBuf.getStr() );
+ if (Application::LoadBrandBitmap (aStrBuf.makeStringAndClear().getStr(), rBitmap))
+ return;
+
+ aStrBuf.append( "intro_" );
+ aStrBuf.append( aResBuf.getStr() );
+ if (Application::LoadBrandBitmap (aResBuf.makeStringAndClear().getStr(), rBitmap))
+ return;
+
+ Application::LoadBrandBitmap ("intro", rBitmap);
+}
+
+void SplashScreen::determineProgressRatioValues(
+ double& rXRelPos, double& rYRelPos,
+ double& rRelWidth, double& rRelHeight )
+{
+ sal_Int32 nWidth( 0 );
+ sal_Int32 nHeight( 0 );
+ sal_Int32 nScreenRatio( 0 );
+
+ // determine desktop resolution
+ sal_uInt32 nCount = Application::GetScreenCount();
+ if ( nCount > 0 )
+ {
+ // retrieve size from first screen
+ Rectangle aScreenArea = Application::GetScreenPosSizePixel((unsigned int)0);
+ nWidth = aScreenArea.GetWidth();
+ nHeight = aScreenArea.GetHeight();
+ nScreenRatio = sal_Int32( math::round( double( nWidth ) / double( nHeight ), 2 ) * 100 );
+ }
+
+ char szFullScreenProgressRatio[] = "FullScreenProgressRatio0";
+ char szFullScreenProgressPos[] = "FullScreenProgressPos0";
+ char szFullScreenProgressSize[] = "FullScreenProgressSize0";
+ for ( sal_Int32 i = 0; i <= 9; i++ )
+ {
+ char cNum = '0' + char( i );
+ szFullScreenProgressRatio[23] = cNum;
+ szFullScreenProgressPos[21] = cNum;
+ szFullScreenProgressSize[22] = cNum;
+
+ OUString sFullScreenProgressRatio = implReadBootstrapKey(
+ OUString::createFromAscii( szFullScreenProgressRatio ) );
+
+ if ( sFullScreenProgressRatio.getLength() > 0 )
+ {
+ double fRatio = sFullScreenProgressRatio.toDouble();
+ sal_Int32 nRatio = sal_Int32( math::round( fRatio, 2 ) * 100 );
+ if ( nRatio == nScreenRatio )
+ {
+ OUString sFullScreenProgressPos = implReadBootstrapKey(
+ OUString::createFromAscii( szFullScreenProgressPos ) );
+ OUString sFullScreenProgressSize = implReadBootstrapKey(
+ OUString::createFromAscii( szFullScreenProgressSize ) );
+
+ if ( sFullScreenProgressPos.getLength() )
+ {
+ sal_Int32 idx = 0;
+ double temp = sFullScreenProgressPos.getToken( 0, ',', idx ).toDouble();
+ if ( idx != -1 )
+ {
+ rXRelPos = temp;
+ rYRelPos = sFullScreenProgressPos.getToken( 0, ',', idx ).toDouble();
+ }
+ }
+
+ if ( sFullScreenProgressSize.getLength() )
+ {
+ sal_Int32 idx = 0;
+ double temp = sFullScreenProgressSize.getToken( 0, ',', idx ).toDouble();
+ if ( idx != -1 )
+ {
+ rRelWidth = temp;
+ rRelHeight = sFullScreenProgressSize.getToken( 0, ',', idx ).toDouble();
+ }
+ }
+ }
+ }
+ else
+ break;
+ }
+}
+
+void SplashScreen::Paint( const Rectangle&)
+{
+ if(!_bVisible) return;
+
+ //native drawing
+ sal_Bool bNativeOK = sal_False;
+
+ // in case of native controls we need to draw directly to the window
+ if( _bNativeProgress && IsNativeControlSupported( CTRL_INTROPROGRESS, PART_ENTIRE_CONTROL ) )
+ {
+ DrawBitmapEx( Point(), _aIntroBmp );
+
+ ImplControlValue aValue( _iProgress * _barwidth / _iMax);
+ Rectangle aDrawRect( Point(_tlx, _tly), Size( _barwidth, _barheight ) );
+ Rectangle aNativeControlRegion, aNativeContentRegion;
+
+ if( GetNativeControlRegion( CTRL_INTROPROGRESS, PART_ENTIRE_CONTROL, aDrawRect,
+ CTRL_STATE_ENABLED, aValue, rtl::OUString(),
+ aNativeControlRegion, aNativeContentRegion ) )
+ {
+ long nProgressHeight = aNativeControlRegion.GetHeight();
+ aDrawRect.Top() -= (nProgressHeight - _barheight)/2;
+ aDrawRect.Bottom() += (nProgressHeight - _barheight)/2;
+ }
+
+ if( (bNativeOK = DrawNativeControl( CTRL_INTROPROGRESS, PART_ENTIRE_CONTROL, aDrawRect,
+ CTRL_STATE_ENABLED, aValue, _sProgressText )) != sal_False )
+ {
+ return;
+ }
+ }
+ //non native drawing
+ // draw bitmap
+ if (_bPaintBitmap)
+ _vdev.DrawBitmapEx( Point(), _aIntroBmp );
+
+ if (_bPaintProgress) {
+ // draw progress...
+ long length = (_iProgress * _barwidth / _iMax) - (2 * _barspace);
+ if (length < 0) length = 0;
+
+ // border
+ _vdev.SetFillColor();
+ _vdev.SetLineColor( _cProgressFrameColor );
+ _vdev.DrawRect(Rectangle(_tlx, _tly, _tlx+_barwidth, _tly+_barheight));
+ _vdev.SetFillColor( _cProgressBarColor );
+ _vdev.SetLineColor();
+ _vdev.DrawRect(Rectangle(_tlx+_barspace, _tly+_barspace, _tlx+_barspace+length, _tly+_barheight-_barspace));
+ _vdev.DrawText( Rectangle(_tlx, _tly+_barheight+5, _tlx+_barwidth, _tly+_barheight+5+20), _sProgressText, TEXT_DRAW_CENTER );
+ }
+ DrawOutDev(Point(), GetOutputSizePixel(), Point(), _vdev.GetOutputSizePixel(), _vdev );
+}
+
+
+// get service instance...
+SplashScreen *SplashScreen::_pINSTANCE = NULL;
+osl::Mutex SplashScreen::_aMutex;
+
+Reference< XInterface > SplashScreen::getInstance(const Reference< XMultiServiceFactory >& rSMgr)
+{
+ if ( _pINSTANCE == 0 )
+ {
+ osl::MutexGuard guard(_aMutex);
+ if (_pINSTANCE == 0)
+ return (XComponent*)new SplashScreen(rSMgr);
+ }
+
+ return (XComponent*)0;
+}
+
+// static service info...
+const char* SplashScreen::interfaces[] =
+{
+ "com.sun.star.task.XStartusIndicator",
+ "com.sun.star.lang.XInitialization",
+ NULL,
+};
+const sal_Char *SplashScreen::serviceName = "com.sun.star.office.SplashScreen";
+const sal_Char *SplashScreen::implementationName = "com.sun.star.office.comp.SplashScreen";
+const sal_Char *SplashScreen::supportedServiceNames[] = {"com.sun.star.office.SplashScreen", NULL};
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/splash/splash.hxx b/desktop/source/splash/splash.hxx
new file mode 100644
index 000000000000..0d4858402b83
--- /dev/null
+++ b/desktop/source/splash/splash.hxx
@@ -0,0 +1,134 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/uno/Exception.hpp>
+#include <com/sun/star/uno/Reference.h>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/task/XStatusIndicator.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <cppuhelper/implbase2.hxx>
+#include <cppuhelper/interfacecontainer.h>
+#include <vcl/introwin.hxx>
+#include <vcl/bitmapex.hxx>
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#include <osl/mutex.hxx>
+#include <vcl/virdev.hxx>
+
+
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::task;
+
+namespace desktop {
+
+class SplashScreen
+ : public ::cppu::WeakImplHelper2< XStatusIndicator, XInitialization >
+ , public IntroWindow
+{
+private:
+ struct FullScreenProgressRatioValue
+ {
+ double _fXRelPos;
+ double _fYRelPos;
+ double _fRelWidth;
+ double _fRelHeight;
+ };
+ enum BitmapMode { BM_FULLSCREEN, BM_DEFAULTMODE };
+
+ // don't allow anybody but ourselves to create instances of this class
+ SplashScreen(const SplashScreen&);
+ SplashScreen(void);
+ SplashScreen operator =(const SplashScreen&);
+
+ SplashScreen(const Reference< XMultiServiceFactory >& xFactory);
+
+ DECL_LINK( AppEventListenerHdl, VclWindowEvent * );
+ virtual ~SplashScreen();
+ void loadConfig();
+ void updateStatus();
+ void SetScreenBitmap(BitmapEx &rBitmap);
+ void determineProgressRatioValues( double& rXRelPos, double& rYRelPos, double& rRelWidth, double& rRelHeight );
+
+ static SplashScreen *_pINSTANCE;
+
+ static osl::Mutex _aMutex;
+ Reference< XMultiServiceFactory > _rFactory;
+
+ VirtualDevice _vdev;
+ BitmapEx _aIntroBmp;
+ Color _cProgressFrameColor;
+ Color _cProgressBarColor;
+ bool _bNativeProgress;
+ OUString _sAppName;
+ OUString _sProgressText;
+ std::vector< FullScreenProgressRatioValue > _sFullScreenProgressRatioValues;
+
+ sal_Int32 _iMax;
+ sal_Int32 _iProgress;
+ BitmapMode _eBitmapMode;
+ sal_Bool _bPaintBitmap;
+ sal_Bool _bPaintProgress;
+ sal_Bool _bVisible;
+ sal_Bool _bShowLogo;
+ sal_Bool _bFullScreenSplash;
+ sal_Bool _bProgressEnd;
+ long _height, _width, _tlx, _tly, _barwidth;
+ long _barheight, _barspace;
+ double _fXPos, _fYPos;
+ double _fWidth, _fHeight;
+ const long _xoffset, _yoffset;
+
+public:
+ static const char* interfaces[];
+ static const sal_Char *serviceName;
+ static const sal_Char *implementationName;
+ static const sal_Char *supportedServiceNames[];
+
+ static Reference< XInterface > getInstance(const Reference < XMultiServiceFactory >& xFactory);
+
+ // XStatusIndicator
+ virtual void SAL_CALL end() throw ( RuntimeException );
+ virtual void SAL_CALL reset() throw ( RuntimeException );
+ virtual void SAL_CALL setText(const OUString& aText) throw ( RuntimeException );
+ virtual void SAL_CALL setValue(sal_Int32 nValue) throw ( RuntimeException );
+ virtual void SAL_CALL start(const OUString& aText, sal_Int32 nRange) throw ( RuntimeException );
+
+ // XInitialize
+ virtual void SAL_CALL initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any>& aArguments )
+ throw ( RuntimeException );
+
+ // workwindow
+ virtual void Paint( const Rectangle& );
+
+};
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */