summaryrefslogtreecommitdiff
path: root/desktop
diff options
context:
space:
mode:
Diffstat (limited to 'desktop')
-rw-r--r--desktop/inc/app.hxx220
-rwxr-xr-xdesktop/inc/deployment.hrc78
-rwxr-xr-xdesktop/inc/makefile.mk47
-rw-r--r--desktop/inc/migration.hxx45
-rw-r--r--desktop/inc/pch/precompiled_desktop.cxx31
-rw-r--r--desktop/inc/pch/precompiled_desktop.hxx43
-rw-r--r--desktop/os2/source/applauncher/launcher.cxx121
-rw-r--r--desktop/os2/source/applauncher/launcher.hxx11
-rwxr-xr-xdesktop/os2/source/applauncher/makefile.mk121
-rw-r--r--desktop/os2/source/applauncher/officeloader.cxx6
-rw-r--r--desktop/os2/source/applauncher/os2quickstart.cxx6
-rw-r--r--desktop/os2/source/applauncher/sbase.cxx6
-rw-r--r--desktop/os2/source/applauncher/scalc.cxx6
-rw-r--r--desktop/os2/source/applauncher/sdraw.cxx6
-rw-r--r--desktop/os2/source/applauncher/simpress.cxx6
-rw-r--r--desktop/os2/source/applauncher/smath.cxx6
-rw-r--r--desktop/os2/source/applauncher/swriter.cxx6
-rw-r--r--desktop/prj/build.lst52
-rw-r--r--desktop/prj/d.lst152
-rwxr-xr-xdesktop/qa/deployment_misc/makefile.mk56
-rw-r--r--desktop/qa/deployment_misc/test_dp_version.cxx96
-rwxr-xr-xdesktop/qa/deployment_misc/version.map34
-rw-r--r--desktop/registry/data/org/openoffice/Office/Jobs.xcu74
-rwxr-xr-xdesktop/registry/data/org/openoffice/Office/makefile.mk77
-rwxr-xr-xdesktop/scripts/basis-link1
-rwxr-xr-xdesktop/scripts/makefile.mk67
-rwxr-xr-xdesktop/scripts/mozwrapper.sh8
-rwxr-xr-xdesktop/scripts/odf-basis-link1
-rwxr-xr-xdesktop/scripts/sbase.sh4
-rwxr-xr-xdesktop/scripts/scalc.sh4
-rwxr-xr-xdesktop/scripts/sdraw.sh4
-rwxr-xr-xdesktop/scripts/simpress.sh4
-rwxr-xr-xdesktop/scripts/smaster.sh4
-rwxr-xr-xdesktop/scripts/smath.sh4
-rwxr-xr-xdesktop/scripts/so-basis-link1
-rwxr-xr-xdesktop/scripts/soffice.sh101
-rwxr-xr-xdesktop/scripts/sweb.sh4
-rwxr-xr-xdesktop/scripts/swriter.sh4
-rwxr-xr-xdesktop/scripts/unoinfo.sh55
-rwxr-xr-xdesktop/scripts/unopkg.sh115
-rwxr-xr-xdesktop/scripts/ure-link1
-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
-rw-r--r--desktop/test/deployment/active/Addons.xcu67
-rwxr-xr-xdesktop/test/deployment/active/Dispatch.java101
-rwxr-xr-xdesktop/test/deployment/active/MANIFEST.MF3
-rw-r--r--desktop/test/deployment/active/ProtocolHandler.xcu48
-rwxr-xr-xdesktop/test/deployment/active/Provider.java81
-rwxr-xr-xdesktop/test/deployment/active/Services.java72
-rw-r--r--desktop/test/deployment/active/active_native.cxx320
-rwxr-xr-xdesktop/test/deployment/active/active_python.py120
-rwxr-xr-xdesktop/test/deployment/active/description.xml36
-rwxr-xr-xdesktop/test/deployment/active/makefile.mk87
-rwxr-xr-xdesktop/test/deployment/active/manifest.xml43
-rw-r--r--desktop/test/deployment/boxt/Addons.xcu50
-rw-r--r--desktop/test/deployment/boxt/ProtocolHandler.xcu38
-rw-r--r--desktop/test/deployment/boxt/boxt.cxx190
-rwxr-xr-xdesktop/test/deployment/boxt/description.xml39
-rwxr-xr-xdesktop/test/deployment/boxt/makefile.mk68
-rwxr-xr-xdesktop/test/deployment/boxt/manifest.xml37
-rw-r--r--desktop/test/deployment/dependencies/broken-dependency.oxtbin0 -> 1655 bytes
-rw-r--r--desktop/test/deployment/dependencies/double-dependencies.oxtbin0 -> 1651 bytes
-rw-r--r--desktop/test/deployment/dependencies/empty-dependencies.oxtbin0 -> 1624 bytes
-rw-r--r--desktop/test/deployment/dependencies/funny-dependency.oxtbin0 -> 1730 bytes
-rw-r--r--desktop/test/deployment/dependencies/license-dependency.oxtbin0 -> 1891 bytes
-rw-r--r--desktop/test/deployment/dependencies/many-dependencies.oxtbin0 -> 1702 bytes
-rw-r--r--desktop/test/deployment/dependencies/minattr22.oxtbin0 -> 1690 bytes
-rw-r--r--desktop/test/deployment/dependencies/minattr23.oxtbin0 -> 1690 bytes
-rw-r--r--desktop/test/deployment/dependencies/minattr24.oxtbin0 -> 1690 bytes
-rw-r--r--desktop/test/deployment/dependencies/no-dependencies.oxtbin0 -> 1611 bytes
-rw-r--r--desktop/test/deployment/dependencies/no-description.oxtbin0 -> 1360 bytes
-rwxr-xr-xdesktop/test/deployment/dependencies/readme.txt82
-rw-r--r--desktop/test/deployment/dependencies/unknown-dependency.oxtbin0 -> 1633 bytes
-rw-r--r--desktop/test/deployment/dependencies/version10000.oxtbin0 -> 1668 bytes
-rw-r--r--desktop/test/deployment/dependencies/version21.oxtbin0 -> 1666 bytes
-rw-r--r--desktop/test/deployment/dependencies/version21ns.oxtbin0 -> 1661 bytes
-rw-r--r--desktop/test/deployment/dependencies/version21other.oxtbin0 -> 1679 bytes
-rw-r--r--desktop/test/deployment/dependencies/version22.oxtbin0 -> 1666 bytes
-rw-r--r--desktop/test/deployment/dependencies/version23.oxtbin0 -> 1666 bytes
-rw-r--r--desktop/test/deployment/dependencies/versionempty.oxtbin0 -> 1675 bytes
-rw-r--r--desktop/test/deployment/dependencies/versionnone.oxtbin0 -> 1674 bytes
-rw-r--r--desktop/test/deployment/description/desc1.oxtbin0 -> 2096 bytes
-rw-r--r--desktop/test/deployment/description/desc2.oxtbin0 -> 2091 bytes
-rw-r--r--desktop/test/deployment/description/desc3.oxtbin0 -> 2070 bytes
-rw-r--r--desktop/test/deployment/description/desc4.oxtbin0 -> 2061 bytes
-rw-r--r--desktop/test/deployment/description/desc5.oxtbin0 -> 2041 bytes
-rwxr-xr-xdesktop/test/deployment/description/readme.txt23
-rw-r--r--desktop/test/deployment/display_name/name1.oxtbin0 -> 704 bytes
-rw-r--r--desktop/test/deployment/display_name/name2.oxtbin0 -> 699 bytes
-rw-r--r--desktop/test/deployment/display_name/name3.oxtbin0 -> 681 bytes
-rw-r--r--desktop/test/deployment/display_name/name4.oxtbin0 -> 675 bytes
-rw-r--r--desktop/test/deployment/display_name/name5.oxtbin0 -> 654 bytes
-rwxr-xr-xdesktop/test/deployment/display_name/readme.txt26
-rwxr-xr-xdesktop/test/deployment/executable_content/build/hello.c47
-rwxr-xr-xdesktop/test/deployment/executable_content/build/makefile.mk51
-rwxr-xr-xdesktop/test/deployment/executable_content/build/readme.txt2
-rw-r--r--desktop/test/deployment/executable_content/hello.oxtbin0 -> 35048 bytes
-rwxr-xr-xdesktop/test/deployment/executable_content/readme.txt12
-rw-r--r--desktop/test/deployment/identifier/explicit/identifier.oxtbin0 -> 1660 bytes
-rw-r--r--desktop/test/deployment/identifier/legacy/identifier.oxtbin0 -> 1634 bytes
-rwxr-xr-xdesktop/test/deployment/identifier/readme.txt33
-rw-r--r--desktop/test/deployment/locationtest/LocationTest.idl40
-rwxr-xr-xdesktop/test/deployment/locationtest/LocationTest.java165
-rw-r--r--desktop/test/deployment/locationtest/LocationTest.odtbin0 -> 7681 bytes
-rwxr-xr-xdesktop/test/deployment/locationtest/MANIFEST.MF2
-rwxr-xr-xdesktop/test/deployment/locationtest/delzip1
-rwxr-xr-xdesktop/test/deployment/locationtest/description.xml13
-rwxr-xr-xdesktop/test/deployment/locationtest/makefile.mk87
-rwxr-xr-xdesktop/test/deployment/locationtest/manifest.xml5
-rwxr-xr-xdesktop/test/deployment/options/handler/com/sun/star/comp/extensionoptions/MANIFEST.MF2
-rwxr-xr-xdesktop/test/deployment/options/handler/com/sun/star/comp/extensionoptions/OptionsEventHandler.java449
-rwxr-xr-xdesktop/test/deployment/options/handler/com/sun/star/comp/extensionoptions/makefile.mk53
-rw-r--r--desktop/test/deployment/options/leaf1.oxtbin0 -> 8308 bytes
-rw-r--r--desktop/test/deployment/options/leaf1mod.oxtbin0 -> 8310 bytes
-rw-r--r--desktop/test/deployment/options/leaf2.oxtbin0 -> 8338 bytes
-rw-r--r--desktop/test/deployment/options/leaves1.oxtbin0 -> 21158 bytes
-rw-r--r--desktop/test/deployment/options/leaves2.oxtbin0 -> 21153 bytes
-rw-r--r--desktop/test/deployment/options/leaves3.oxtbin0 -> 21080 bytes
-rw-r--r--desktop/test/deployment/options/modules1.oxtbin0 -> 24317 bytes
-rw-r--r--desktop/test/deployment/options/modules2.oxtbin0 -> 24196 bytes
-rw-r--r--desktop/test/deployment/options/nodes1.oxtbin0 -> 1882 bytes
-rw-r--r--desktop/test/deployment/options/nodes2.oxtbin0 -> 24287 bytes
-rw-r--r--desktop/test/deployment/options/nodes3.oxtbin0 -> 24315 bytes
-rw-r--r--desktop/test/deployment/options/nodes4.oxtbin0 -> 24318 bytes
-rw-r--r--desktop/test/deployment/options/nodes5.oxtbin0 -> 12616 bytes
-rwxr-xr-xdesktop/test/deployment/options/readme.txt200
-rw-r--r--desktop/test/deployment/passive/Addons.xcu67
-rwxr-xr-xdesktop/test/deployment/passive/Dispatch.java101
-rwxr-xr-xdesktop/test/deployment/passive/MANIFEST.MF3
-rw-r--r--desktop/test/deployment/passive/ProtocolHandler.xcu48
-rwxr-xr-xdesktop/test/deployment/passive/Provider.java81
-rwxr-xr-xdesktop/test/deployment/passive/Services.java49
-rwxr-xr-xdesktop/test/deployment/passive/description.xml36
-rwxr-xr-xdesktop/test/deployment/passive/makefile.mk141
-rwxr-xr-xdesktop/test/deployment/passive/manifest.xml40
-rwxr-xr-xdesktop/test/deployment/passive/passive_java.component38
-rwxr-xr-xdesktop/test/deployment/passive/passive_native.component38
-rw-r--r--desktop/test/deployment/passive/passive_native.cxx289
-rwxr-xr-xdesktop/test/deployment/passive/passive_python.component38
-rwxr-xr-xdesktop/test/deployment/passive/passive_python.py101
-rw-r--r--desktop/test/deployment/simple_license/BadDesc.oxtbin0 -> 9663 bytes
-rw-r--r--desktop/test/deployment/simple_license/BadNamespace.oxtbin0 -> 9736 bytes
-rw-r--r--desktop/test/deployment/simple_license/BadRoot.oxtbin0 -> 9073 bytes
-rw-r--r--desktop/test/deployment/simple_license/Locale1.oxtbin0 -> 2126 bytes
-rw-r--r--desktop/test/deployment/simple_license/Locale2.oxtbin0 -> 2121 bytes
-rw-r--r--desktop/test/deployment/simple_license/Locale3.oxtbin0 -> 2101 bytes
-rw-r--r--desktop/test/deployment/simple_license/Locale4.oxtbin0 -> 2094 bytes
-rw-r--r--desktop/test/deployment/simple_license/Locale5.oxtbin0 -> 2072 bytes
-rw-r--r--desktop/test/deployment/simple_license/Locale6.oxtbin0 -> 1397 bytes
-rw-r--r--desktop/test/deployment/simple_license/LongLic.oxtbin0 -> 9521 bytes
-rw-r--r--desktop/test/deployment/simple_license/MissingLic.oxtbin0 -> 9214 bytes
-rw-r--r--desktop/test/deployment/simple_license/MissingLicRef.oxtbin0 -> 9332 bytes
-rw-r--r--desktop/test/deployment/simple_license/NoDefLang.oxtbin0 -> 9360 bytes
-rw-r--r--desktop/test/deployment/simple_license/NoDesc.oxtbin0 -> 8722 bytes
-rw-r--r--desktop/test/deployment/simple_license/NoLang.oxtbin0 -> 9217 bytes
-rw-r--r--desktop/test/deployment/simple_license/Prefix.oxtbin0 -> 1112 bytes
-rw-r--r--desktop/test/deployment/simple_license/ShortLicense.oxtbin0 -> 9381 bytes
-rw-r--r--desktop/test/deployment/simple_license/ShortLicenseShared.oxtbin0 -> 9382 bytes
-rw-r--r--desktop/test/deployment/simple_license/suppress_license.oxtbin0 -> 2143 bytes
-rw-r--r--desktop/test/deployment/simple_license/tests_simple_license.odtbin0 -> 16629 bytes
-rw-r--r--desktop/test/deployment/update/changing_display_name/change1.oxtbin0 -> 1650 bytes
-rw-r--r--desktop/test/deployment/update/changing_display_name/change1_mod.oxtbin0 -> 1673 bytes
-rwxr-xr-xdesktop/test/deployment/update/changing_display_name/readme.txt13
-rw-r--r--desktop/test/deployment/update/changing_display_name/update1/change1.oxtbin0 -> 1675 bytes
-rwxr-xr-xdesktop/test/deployment/update/changing_display_name/update1/change1.update.xml10
-rw-r--r--desktop/test/deployment/update/changing_display_name/update2/change1.oxtbin0 -> 1687 bytes
-rwxr-xr-xdesktop/test/deployment/update/changing_display_name/update2/change1.update.xml10
-rw-r--r--desktop/test/deployment/update/default_url/default1.oxtbin0 -> 1544 bytes
-rw-r--r--desktop/test/deployment/update/default_url/default2.oxtbin0 -> 1544 bytes
-rwxr-xr-xdesktop/test/deployment/update/default_url/readme.txt9
-rw-r--r--desktop/test/deployment/update/default_url/update/default1.oxtbin0 -> 1546 bytes
-rwxr-xr-xdesktop/test/deployment/update/default_url/update/default1.update.xml10
-rw-r--r--desktop/test/deployment/update/default_url/update/default2.oxtbin0 -> 1546 bytes
-rwxr-xr-xdesktop/test/deployment/update/default_url/update/default2.update.xml10
-rwxr-xr-xdesktop/test/deployment/update/default_url/update/feed1.xml33
-rw-r--r--desktop/test/deployment/update/defect/fail1.oxtbin0 -> 2189 bytes
-rw-r--r--desktop/test/deployment/update/defect/fail2.oxtbin0 -> 2188 bytes
-rw-r--r--desktop/test/deployment/update/defect/fail3.oxtbin0 -> 2188 bytes
-rw-r--r--desktop/test/deployment/update/defect/fail4.oxtbin0 -> 2189 bytes
-rw-r--r--desktop/test/deployment/update/defect/info1.oxtbin0 -> 2188 bytes
-rw-r--r--desktop/test/deployment/update/defect/info2.oxtbin0 -> 2187 bytes
-rw-r--r--desktop/test/deployment/update/defect/info3.oxtbin0 -> 2187 bytes
-rwxr-xr-xdesktop/test/deployment/update/defect/readme.txt15
-rw-r--r--desktop/test/deployment/update/defect/update/fail1.oxtbin0 -> 2193 bytes
-rwxr-xr-xdesktop/test/deployment/update/defect/update/fail1.update.xml10
-rw-r--r--desktop/test/deployment/update/defect/update/fail2.oxtbin0 -> 2436 bytes
-rwxr-xr-xdesktop/test/deployment/update/defect/update/fail2.update.xml10
-rw-r--r--desktop/test/deployment/update/defect/update/fail3.oxtbin0 -> 2396 bytes
-rwxr-xr-xdesktop/test/deployment/update/defect/update/fail3.update.xml10
-rw-r--r--desktop/test/deployment/update/defect/update/fail4.oxt0
-rwxr-xr-xdesktop/test/deployment/update/defect/update/fail4.update.xml10
-rwxr-xr-xdesktop/test/deployment/update/defect/update/info1.update.xml0
-rwxr-xr-xdesktop/test/deployment/update/defect/update/info2.update.xml1
-rw-r--r--desktop/test/deployment/update/defect/update/info3.oxtbin0 -> 2189 bytes
-rwxr-xr-xdesktop/test/deployment/update/defect/update/info3.update.xml10
-rwxr-xr-xdesktop/test/deployment/update/dependencies/publisher_en.html9
-rwxr-xr-xdesktop/test/deployment/update/dependencies/readme.txt32
-rwxr-xr-xdesktop/test/deployment/update/dependencies/release-notes_en.html8
-rw-r--r--desktop/test/deployment/update/dependencies/update-dependencies.oxtbin0 -> 1751 bytes
-rwxr-xr-xdesktop/test/deployment/update/dependencies/update/update-dependencies.update.xml71
-rw-r--r--desktop/test/deployment/update/license/lic1.oxtbin0 -> 3608 bytes
-rw-r--r--desktop/test/deployment/update/license/lic2.oxtbin0 -> 3625 bytes
-rw-r--r--desktop/test/deployment/update/license/lic3.oxtbin0 -> 3624 bytes
-rwxr-xr-xdesktop/test/deployment/update/license/readme.txt9
-rw-r--r--desktop/test/deployment/update/license/update/lic1.oxtbin0 -> 3610 bytes
-rwxr-xr-xdesktop/test/deployment/update/license/update/lic1.update.xml10
-rw-r--r--desktop/test/deployment/update/license/update/lic2.oxtbin0 -> 3627 bytes
-rwxr-xr-xdesktop/test/deployment/update/license/update/lic2.update.xml10
-rw-r--r--desktop/test/deployment/update/license/update/lic3.oxtbin0 -> 3626 bytes
-rwxr-xr-xdesktop/test/deployment/update/license/update/lic3.update.xml10
-rw-r--r--desktop/test/deployment/update/platform/all1.oxtbin0 -> 692 bytes
-rw-r--r--desktop/test/deployment/update/platform/all2.oxtbin0 -> 702 bytes
-rw-r--r--desktop/test/deployment/update/platform/all3.oxtbin0 -> 297 bytes
-rw-r--r--desktop/test/deployment/update/platform/freebsd_x86.oxtbin0 -> 706 bytes
-rw-r--r--desktop/test/deployment/update/platform/freebsd_x86_64.oxtbin0 -> 711 bytes
-rw-r--r--desktop/test/deployment/update/platform/invalid1.oxtbin0 -> 653 bytes
-rw-r--r--desktop/test/deployment/update/platform/invalid2.oxtbin0 -> 653 bytes
-rw-r--r--desktop/test/deployment/update/platform/invalid3.oxtbin0 -> 655 bytes
-rw-r--r--desktop/test/deployment/update/platform/linux_arm_eabi.oxtbin0 -> 709 bytes
-rw-r--r--desktop/test/deployment/update/platform/linux_arm_oabi.oxtbin0 -> 710 bytes
-rw-r--r--desktop/test/deployment/update/platform/linux_ia64.oxtbin0 -> 706 bytes
-rw-r--r--desktop/test/deployment/update/platform/linux_mips_eb.oxtbin0 -> 709 bytes
-rw-r--r--desktop/test/deployment/update/platform/linux_mips_el.oxtbin0 -> 708 bytes
-rw-r--r--desktop/test/deployment/update/platform/linux_powerpc.oxtbin0 -> 708 bytes
-rw-r--r--desktop/test/deployment/update/platform/linux_powerpc64.oxtbin0 -> 710 bytes
-rw-r--r--desktop/test/deployment/update/platform/linux_s390.oxtbin0 -> 705 bytes
-rw-r--r--desktop/test/deployment/update/platform/linux_s390x.oxtbin0 -> 706 bytes
-rw-r--r--desktop/test/deployment/update/platform/linux_sparc.oxtbin0 -> 706 bytes
-rw-r--r--desktop/test/deployment/update/platform/linux_x86.oxtbin0 -> 705 bytes
-rw-r--r--desktop/test/deployment/update/platform/linux_x86_64.oxtbin0 -> 708 bytes
-rw-r--r--desktop/test/deployment/update/platform/macosx_powerpc.oxtbin0 -> 710 bytes
-rw-r--r--desktop/test/deployment/update/platform/macosx_x86.oxtbin0 -> 707 bytes
-rw-r--r--desktop/test/deployment/update/platform/mul1.oxtbin0 -> 952 bytes
-rw-r--r--desktop/test/deployment/update/platform/os2_x86.oxtbin0 -> 706 bytes
-rwxr-xr-xdesktop/test/deployment/update/platform/readme.txt49
-rw-r--r--desktop/test/deployment/update/platform/solaris_sparc.oxtbin0 -> 709 bytes
-rw-r--r--desktop/test/deployment/update/platform/solaris_x86.oxtbin0 -> 706 bytes
-rw-r--r--desktop/test/deployment/update/platform/windows_x86.oxtbin0 -> 707 bytes
-rw-r--r--desktop/test/deployment/update/publisher/pub1.oxtbin0 -> 1882 bytes
-rw-r--r--desktop/test/deployment/update/publisher/pub10.oxtbin0 -> 1742 bytes
-rw-r--r--desktop/test/deployment/update/publisher/pub11.oxtbin0 -> 1601 bytes
-rw-r--r--desktop/test/deployment/update/publisher/pub2.oxtbin0 -> 1866 bytes
-rw-r--r--desktop/test/deployment/update/publisher/pub3.oxtbin0 -> 1829 bytes
-rw-r--r--desktop/test/deployment/update/publisher/pub4.oxtbin0 -> 1812 bytes
-rw-r--r--desktop/test/deployment/update/publisher/pub5.oxtbin0 -> 1769 bytes
-rw-r--r--desktop/test/deployment/update/publisher/pub6.oxtbin0 -> 1814 bytes
-rw-r--r--desktop/test/deployment/update/publisher/pub7.oxtbin0 -> 1769 bytes
-rw-r--r--desktop/test/deployment/update/publisher/pub8.oxtbin0 -> 1853 bytes
-rw-r--r--desktop/test/deployment/update/publisher/pub9.oxtbin0 -> 1779 bytes
-rwxr-xr-xdesktop/test/deployment/update/publisher/publisher_de-DE-altmark.html9
-rwxr-xr-xdesktop/test/deployment/update/publisher/publisher_de-DE.html9
-rwxr-xr-xdesktop/test/deployment/update/publisher/publisher_de.html9
-rwxr-xr-xdesktop/test/deployment/update/publisher/publisher_en-GB.html9
-rwxr-xr-xdesktop/test/deployment/update/publisher/publisher_en-US-region1.html9
-rwxr-xr-xdesktop/test/deployment/update/publisher/publisher_en-US-region2.html9
-rwxr-xr-xdesktop/test/deployment/update/publisher/publisher_en-US.html9
-rwxr-xr-xdesktop/test/deployment/update/publisher/publisher_en-region3.html9
-rwxr-xr-xdesktop/test/deployment/update/publisher/publisher_en.html9
-rwxr-xr-xdesktop/test/deployment/update/publisher/readme.txt212
-rwxr-xr-xdesktop/test/deployment/update/publisher/release-notes_de-DE-altmark.html8
-rwxr-xr-xdesktop/test/deployment/update/publisher/release-notes_de-DE.html8
-rwxr-xr-xdesktop/test/deployment/update/publisher/release-notes_de.html8
-rwxr-xr-xdesktop/test/deployment/update/publisher/release-notes_en-GB.html8
-rwxr-xr-xdesktop/test/deployment/update/publisher/release-notes_en-US-region1.html8
-rwxr-xr-xdesktop/test/deployment/update/publisher/release-notes_en-US-region2.html8
-rwxr-xr-xdesktop/test/deployment/update/publisher/release-notes_en-US.html8
-rwxr-xr-xdesktop/test/deployment/update/publisher/release-notes_en-region3.html8
-rwxr-xr-xdesktop/test/deployment/update/publisher/release-notes_en.html8
-rw-r--r--desktop/test/deployment/update/publisher/update/pub1.oxtbin0 -> 1885 bytes
-rwxr-xr-xdesktop/test/deployment/update/publisher/update/pub1.update.xml36
-rw-r--r--desktop/test/deployment/update/publisher/update/pub10.oxtbin0 -> 1744 bytes
-rw-r--r--desktop/test/deployment/update/publisher/update/pub11.oxtbin0 -> 1603 bytes
-rw-r--r--desktop/test/deployment/update/publisher/update/pub2.oxtbin0 -> 1871 bytes
-rwxr-xr-xdesktop/test/deployment/update/publisher/update/pub2.update.xml34
-rw-r--r--desktop/test/deployment/update/publisher/update/pub3.oxtbin0 -> 1833 bytes
-rwxr-xr-xdesktop/test/deployment/update/publisher/update/pub3.update.xml30
-rw-r--r--desktop/test/deployment/update/publisher/update/pub4.oxtbin0 -> 1815 bytes
-rwxr-xr-xdesktop/test/deployment/update/publisher/update/pub4.update.xml28
-rw-r--r--desktop/test/deployment/update/publisher/update/pub5.oxtbin0 -> 1774 bytes
-rwxr-xr-xdesktop/test/deployment/update/publisher/update/pub5.update.xml24
-rw-r--r--desktop/test/deployment/update/publisher/update/pub6.oxtbin0 -> 1816 bytes
-rwxr-xr-xdesktop/test/deployment/update/publisher/update/pub6.update.xml24
-rw-r--r--desktop/test/deployment/update/publisher/update/pub7.oxtbin0 -> 1771 bytes
-rwxr-xr-xdesktop/test/deployment/update/publisher/update/pub7.update.xml24
-rw-r--r--desktop/test/deployment/update/publisher/update/pub8.oxtbin0 -> 1855 bytes
-rw-r--r--desktop/test/deployment/update/publisher/update/pub9.oxtbin0 -> 1781 bytes
-rwxr-xr-xdesktop/test/deployment/update/readme.txt68
-rw-r--r--desktop/test/deployment/update/simple/plain1.oxtbin0 -> 1642 bytes
-rw-r--r--desktop/test/deployment/update/simple/plain2.oxtbin0 -> 1643 bytes
-rw-r--r--desktop/test/deployment/update/simple/plain3.oxtbin0 -> 1643 bytes
-rwxr-xr-xdesktop/test/deployment/update/simple/readme.txt31
-rw-r--r--desktop/test/deployment/update/simple/update/plain1.oxtbin0 -> 1645 bytes
-rwxr-xr-xdesktop/test/deployment/update/simple/update/plain1.update.xml10
-rw-r--r--desktop/test/deployment/update/simple/update/plain2.oxtbin0 -> 1645 bytes
-rwxr-xr-xdesktop/test/deployment/update/simple/update/plain2.update.xml10
-rw-r--r--desktop/test/deployment/update/simple/update/plain3.oxtbin0 -> 1645 bytes
-rwxr-xr-xdesktop/test/deployment/update/simple/update/plain3.update.xml10
-rw-r--r--desktop/test/deployment/update/updatefeed/feed1.oxtbin0 -> 2184 bytes
-rw-r--r--desktop/test/deployment/update/updatefeed/feed2.oxtbin0 -> 2184 bytes
-rw-r--r--desktop/test/deployment/update/updatefeed/update/feed1.oxtbin0 -> 2184 bytes
-rwxr-xr-xdesktop/test/deployment/update/updatefeed/update/feed1.update.xml10
-rwxr-xr-xdesktop/test/deployment/update/updatefeed/update/feed1.xml33
-rw-r--r--desktop/test/deployment/update/updatefeed/update/feed2.oxtbin0 -> 2184 bytes
-rwxr-xr-xdesktop/test/deployment/update/updatefeed/update/feed2.update.xml10
-rwxr-xr-xdesktop/test/deployment/update/updateinfocreation/build/MANIFEST.MF2
-rw-r--r--desktop/test/deployment/update/updateinfocreation/build/TestExtension.idl40
-rwxr-xr-xdesktop/test/deployment/update/updateinfocreation/build/TestExtension.java165
-rwxr-xr-xdesktop/test/deployment/update/updateinfocreation/build/delzip1
-rwxr-xr-xdesktop/test/deployment/update/updateinfocreation/build/description.xml13
-rwxr-xr-xdesktop/test/deployment/update/updateinfocreation/build/makefile.mk91
-rwxr-xr-xdesktop/test/deployment/update/updateinfocreation/build/manifest.xml5
-rwxr-xr-xdesktop/test/deployment/update/updateinfocreation/readme.txt38
-rw-r--r--desktop/test/deployment/update/updateinfocreation/update/updateinfo.oxtbin0 -> 4295 bytes
-rw-r--r--desktop/test/deployment/update/updateinfocreation/updateinfo.oxtbin0 -> 4295 bytes
-rwxr-xr-xdesktop/test/deployment/update/website_update/readme.txt133
-rw-r--r--desktop/test/deployment/update/website_update/update/web1.oxtbin0 -> 1695 bytes
-rwxr-xr-xdesktop/test/deployment/update/website_update/update/web1.update.xml20
-rwxr-xr-xdesktop/test/deployment/update/website_update/update/web1_de-DE-altmark.html18
-rwxr-xr-xdesktop/test/deployment/update/website_update/update/web1_de-DE.html18
-rwxr-xr-xdesktop/test/deployment/update/website_update/update/web1_de.html19
-rwxr-xr-xdesktop/test/deployment/update/website_update/update/web1_en-GB.html19
-rwxr-xr-xdesktop/test/deployment/update/website_update/update/web1_en-US-region1.html19
-rwxr-xr-xdesktop/test/deployment/update/website_update/update/web1_en-US-region2.html19
-rwxr-xr-xdesktop/test/deployment/update/website_update/update/web1_en-US.html20
-rwxr-xr-xdesktop/test/deployment/update/website_update/update/web1_en-region3.html19
-rwxr-xr-xdesktop/test/deployment/update/website_update/update/web1_en.html19
-rw-r--r--desktop/test/deployment/update/website_update/update/web2.oxtbin0 -> 1695 bytes
-rwxr-xr-xdesktop/test/deployment/update/website_update/update/web2.update.xml19
-rw-r--r--desktop/test/deployment/update/website_update/update/web3.oxtbin0 -> 1695 bytes
-rwxr-xr-xdesktop/test/deployment/update/website_update/update/web3.update.xml17
-rw-r--r--desktop/test/deployment/update/website_update/update/web4.oxtbin0 -> 1695 bytes
-rwxr-xr-xdesktop/test/deployment/update/website_update/update/web4.update.xml16
-rw-r--r--desktop/test/deployment/update/website_update/update/web5.oxtbin0 -> 1695 bytes
-rwxr-xr-xdesktop/test/deployment/update/website_update/update/web5.update.xml14
-rw-r--r--desktop/test/deployment/update/website_update/update/web6.oxtbin0 -> 1640 bytes
-rwxr-xr-xdesktop/test/deployment/update/website_update/update/web6/description.xml11
-rwxr-xr-xdesktop/test/deployment/update/website_update/update/web6/readme.txt5
-rw-r--r--desktop/test/deployment/update/website_update/update/web7.oxtbin0 -> 1897 bytes
-rwxr-xr-xdesktop/test/deployment/update/website_update/update/web7/description.xml36
-rwxr-xr-xdesktop/test/deployment/update/website_update/update/web7/readme.txt5
-rw-r--r--desktop/test/deployment/update/website_update/web1.oxtbin0 -> 1693 bytes
-rw-r--r--desktop/test/deployment/update/website_update/web2.oxtbin0 -> 1693 bytes
-rw-r--r--desktop/test/deployment/update/website_update/web3.oxtbin0 -> 1693 bytes
-rw-r--r--desktop/test/deployment/update/website_update/web4.oxtbin0 -> 1693 bytes
-rw-r--r--desktop/test/deployment/update/website_update/web5.oxtbin0 -> 1693 bytes
-rw-r--r--desktop/test/deployment/update/website_update/web6.oxtbin0 -> 1638 bytes
-rw-r--r--desktop/test/deployment/update/website_update/web7.oxtbin0 -> 1894 bytes
-rwxr-xr-xdesktop/test/deployment/update/wrong_url/readme.txt18
-rw-r--r--desktop/test/deployment/update/wrong_url/update/url1.oxtbin0 -> 2192 bytes
-rwxr-xr-xdesktop/test/deployment/update/wrong_url/update/url1.update.xml11
-rw-r--r--desktop/test/deployment/update/wrong_url/update/url2.oxtbin0 -> 2206 bytes
-rwxr-xr-xdesktop/test/deployment/update/wrong_url/update/url2.update.xml10
-rwxr-xr-xdesktop/test/deployment/update/wrong_url/update/wrongdownload1.update.xml11
-rwxr-xr-xdesktop/test/deployment/update/wrong_url/update/wrongdownload2.update.xml11
-rwxr-xr-xdesktop/test/deployment/update/wrong_url/update/wrongdownload3.update.xml11
-rw-r--r--desktop/test/deployment/update/wrong_url/url1.oxtbin0 -> 2190 bytes
-rw-r--r--desktop/test/deployment/update/wrong_url/url2.oxtbin0 -> 2205 bytes
-rw-r--r--desktop/test/deployment/update/wrong_url/url3.oxtbin0 -> 2204 bytes
-rw-r--r--desktop/test/deployment/update/wrong_url/wrongdownload1.oxtbin0 -> 2194 bytes
-rw-r--r--desktop/test/deployment/update/wrong_url/wrongdownload2.oxtbin0 -> 2194 bytes
-rw-r--r--desktop/test/deployment/update/wrong_url/wrongdownload3.oxtbin0 -> 2194 bytes
-rwxr-xr-xdesktop/test/deployment/version/readme.txt85
-rw-r--r--desktop/test/deployment/version/version_0.0/dependency.oxtbin0 -> 1657 bytes
-rw-r--r--desktop/test/deployment/version/version_0.0/license.oxtbin0 -> 1733 bytes
-rw-r--r--desktop/test/deployment/version/version_0.0/plain.oxtbin0 -> 1618 bytes
-rw-r--r--desktop/test/deployment/version/version_1.02.4.7.0/dependency.oxtbin0 -> 1662 bytes
-rw-r--r--desktop/test/deployment/version/version_1.02.4.7.0/license.oxtbin0 -> 1738 bytes
-rw-r--r--desktop/test/deployment/version/version_1.02.4.7.0/plain.oxtbin0 -> 1624 bytes
-rw-r--r--desktop/test/deployment/version/version_1.2.15.3/dependency.oxtbin0 -> 1662 bytes
-rw-r--r--desktop/test/deployment/version/version_1.2.15.3/license.oxtbin0 -> 1738 bytes
-rw-r--r--desktop/test/deployment/version/version_1.2.15.3/plain.oxtbin0 -> 1624 bytes
-rw-r--r--desktop/test/deployment/version/version_1.2.3/dependency.oxtbin0 -> 1659 bytes
-rw-r--r--desktop/test/deployment/version/version_1.2.3/license.oxtbin0 -> 1735 bytes
-rw-r--r--desktop/test/deployment/version/version_1.2.3/plain.oxtbin0 -> 1620 bytes
-rw-r--r--desktop/test/deployment/version/version_1.2.4.7/dependency.oxtbin0 -> 1661 bytes
-rw-r--r--desktop/test/deployment/version/version_1.2.4.7/license.oxtbin0 -> 1737 bytes
-rw-r--r--desktop/test/deployment/version/version_1.2.4.7/plain.oxtbin0 -> 1623 bytes
-rw-r--r--desktop/test/deployment/version/version_badelement/dependency.oxtbin0 -> 1654 bytes
-rw-r--r--desktop/test/deployment/version/version_badelement/license.oxtbin0 -> 1731 bytes
-rw-r--r--desktop/test/deployment/version/version_badelement/plain.oxtbin0 -> 1616 bytes
-rw-r--r--desktop/test/deployment/version/version_badvalue/dependency.oxtbin0 -> 1657 bytes
-rw-r--r--desktop/test/deployment/version/version_badvalue/license.oxtbin0 -> 1733 bytes
-rw-r--r--desktop/test/deployment/version/version_badvalue/plain.oxtbin0 -> 1618 bytes
-rw-r--r--desktop/test/deployment/version/version_nodependencies_0.0/dependency.oxtbin0 -> 1618 bytes
-rw-r--r--desktop/test/deployment/version/version_nodependencies_1.02.4.7.0/dependency.oxtbin0 -> 1624 bytes
-rw-r--r--desktop/test/deployment/version/version_nodependencies_1.2.15.3/dependency.oxtbin0 -> 1624 bytes
-rw-r--r--desktop/test/deployment/version/version_nodependencies_1.2.3/dependency.oxtbin0 -> 1620 bytes
-rw-r--r--desktop/test/deployment/version/version_nodependencies_1.2.4.7/dependency.oxtbin0 -> 1623 bytes
-rw-r--r--desktop/test/deployment/version/version_nodependencies_badelement/dependency.oxtbin0 -> 1616 bytes
-rw-r--r--desktop/test/deployment/version/version_nodependencies_badvalue/dependency.oxtbin0 -> 1618 bytes
-rw-r--r--desktop/test/deployment/version/version_nodependencies_none/dependency.oxtbin0 -> 1598 bytes
-rw-r--r--desktop/test/deployment/version/version_none/dependency.oxtbin0 -> 1645 bytes
-rw-r--r--desktop/test/deployment/version/version_none/license.oxtbin0 -> 1722 bytes
-rw-r--r--desktop/test/deployment/version/version_none/plain.oxtbin0 -> 1598 bytes
-rw-r--r--desktop/unx/source/args.c152
-rw-r--r--desktop/unx/source/args.h50
-rwxr-xr-xdesktop/unx/source/makefile.mk65
-rwxr-xr-xdesktop/unx/source/officeloader/makefile.mk47
-rw-r--r--desktop/unx/source/officeloader/officeloader.cxx113
-rwxr-xr-xdesktop/unx/source/splashx.c659
-rwxr-xr-xdesktop/unx/source/splashx.h65
-rwxr-xr-xdesktop/unx/source/start.c1012
-rwxr-xr-xdesktop/unx/splash/exports.map9
-rwxr-xr-xdesktop/unx/splash/makefile.mk76
-rwxr-xr-xdesktop/unx/splash/splash.component7
-rw-r--r--desktop/unx/splash/unxsplash.cxx196
-rw-r--r--desktop/unx/splash/unxsplash.hxx83
-rw-r--r--desktop/util/hidother.src54
-rwxr-xr-xdesktop/util/makefile.mk258
-rwxr-xr-xdesktop/util/ooverinfo.rc112
-rwxr-xr-xdesktop/util/ooverinfo2.rc76
-rw-r--r--desktop/util/soffice.icobin0 -> 4990 bytes
-rwxr-xr-xdesktop/util/template.manifest10
-rw-r--r--desktop/util/verinfo.rc116
-rwxr-xr-xdesktop/win32/source/QuickStart/OOQuickStart.rc130
-rwxr-xr-xdesktop/win32/source/QuickStart/QuickStart.cpp426
-rwxr-xr-xdesktop/win32/source/QuickStart/QuickStart.h15
-rwxr-xr-xdesktop/win32/source/QuickStart/StdAfx.h42
-rw-r--r--desktop/win32/source/QuickStart/makefile.mk74
-rwxr-xr-xdesktop/win32/source/QuickStart/resource.h35
-rwxr-xr-xdesktop/win32/source/QuickStart/so/QuickStart.rc130
-rwxr-xr-xdesktop/win32/source/QuickStart/so/makefile.mk77
-rw-r--r--desktop/win32/source/applauncher/launcher.cxx147
-rw-r--r--desktop/win32/source/applauncher/launcher.hxx24
-rwxr-xr-xdesktop/win32/source/applauncher/makefile.mk150
-rwxr-xr-xdesktop/win32/source/applauncher/ooo/makefile.mk130
-rwxr-xr-xdesktop/win32/source/applauncher/ooo/verinfo.rc71
-rw-r--r--desktop/win32/source/applauncher/sbase.cxx37
-rw-r--r--desktop/win32/source/applauncher/scalc.cxx37
-rw-r--r--desktop/win32/source/applauncher/sdraw.cxx37
-rw-r--r--desktop/win32/source/applauncher/simpress.cxx37
-rw-r--r--desktop/win32/source/applauncher/smath.cxx37
-rw-r--r--desktop/win32/source/applauncher/sweb.cxx37
-rw-r--r--desktop/win32/source/applauncher/swriter.cxx35
-rwxr-xr-xdesktop/win32/source/applauncher/verinfo.rc76
-rw-r--r--desktop/win32/source/extendloaderenvironment.cxx185
-rw-r--r--desktop/win32/source/extendloaderenvironment.hxx96
-rw-r--r--desktop/win32/source/guiloader/genericloader.cxx178
-rwxr-xr-xdesktop/win32/source/guiloader/makefile.mk66
-rw-r--r--desktop/win32/source/guistdio/guistdio.cxx33
-rwxr-xr-xdesktop/win32/source/guistdio/guistdio.inc454
-rwxr-xr-xdesktop/win32/source/guistdio/makefile.mk58
-rw-r--r--desktop/win32/source/guistdio/unopkgio.cxx34
-rw-r--r--desktop/win32/source/lwrapa.cxx35
-rw-r--r--desktop/win32/source/lwrapw.cxx36
-rwxr-xr-xdesktop/win32/source/main.h15
-rwxr-xr-xdesktop/win32/source/makefile.mk63
-rwxr-xr-xdesktop/win32/source/officeloader/makefile.mk45
-rw-r--r--desktop/win32/source/officeloader/officeloader.cxx430
-rwxr-xr-xdesktop/win32/source/rebase/Resource.h41
-rwxr-xr-xdesktop/win32/source/rebase/makefile.mk89
-rwxr-xr-xdesktop/win32/source/rebase/rcfooter.txt2
-rwxr-xr-xdesktop/win32/source/rebase/rcheader.txt39
-rwxr-xr-xdesktop/win32/source/rebase/rctmpl.txt9
-rw-r--r--desktop/win32/source/rebase/rebase.cxx191
-rw-r--r--desktop/win32/source/rebase/rebasegui.cxx200
-rwxr-xr-xdesktop/win32/source/rebase/rebasegui.ulf11
-rw-r--r--desktop/win32/source/rwrapa.cxx35
-rw-r--r--desktop/win32/source/rwrapw.cxx36
-rw-r--r--desktop/win32/source/setup/Resource.h82
-rw-r--r--desktop/win32/source/setup/makefile.mk90
-rw-r--r--desktop/win32/source/setup/rcfooter.txt2
-rw-r--r--desktop/win32/source/setup/rcheader.txt43
-rw-r--r--desktop/win32/source/setup/rctmpl.txt49
-rw-r--r--desktop/win32/source/setup/setup.cpp2063
-rw-r--r--desktop/win32/source/setup/setup.hxx157
-rw-r--r--desktop/win32/source/setup/setup.icobin0 -> 4710 bytes
-rw-r--r--desktop/win32/source/setup/setup.ulf162
-rw-r--r--desktop/win32/source/setup/setup_a.cxx34
-rw-r--r--desktop/win32/source/setup/setup_help.hxx49
-rw-r--r--desktop/win32/source/setup/setup_main.cxx142
-rw-r--r--desktop/win32/source/setup/setup_main.hxx74
-rw-r--r--desktop/win32/source/setup/setup_w.cxx37
-rw-r--r--desktop/win32/source/sowrapper.cxx50
-rw-r--r--desktop/win32/source/unoinfo.cxx151
-rwxr-xr-xdesktop/win32/source/wrapper.h175
-rw-r--r--desktop/win32/source/wrappera.cxx34
-rw-r--r--desktop/win32/source/wrapperw.cxx35
-rwxr-xr-xdesktop/zipintro/delzip1
-rwxr-xr-xdesktop/zipintro/makefile.mk104
737 files changed, 83273 insertions, 0 deletions
diff --git a/desktop/inc/app.hxx b/desktop/inc/app.hxx
new file mode 100644
index 000000000000..9872bbeefd58
--- /dev/null
+++ b/desktop/inc/app.hxx
@@ -0,0 +1,220 @@
+/* -*- 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_APP_HXX_
+#define _DESKTOP_APP_HXX_
+
+// stl includes first
+#include <map>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <vcl/svapp.hxx>
+#include <vcl/timer.hxx>
+#include <tools/resmgr.hxx>
+#include <unotools/bootstrap.hxx>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/task/XStatusIndicator.hpp>
+#include <com/sun/star/uno/Reference.h>
+#include <osl/mutex.hxx>
+
+using namespace com::sun::star::task;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+
+#define DESKTOP_SAVETASKS_MOD 0x1
+#define DESKTOP_SAVETASKS_UNMOD 0x2
+#define DESKTOP_SAVETASKS_ALL 0x3
+
+namespace desktop
+{
+
+/*--------------------------------------------------------------------
+ Description: Application-class
+ --------------------------------------------------------------------*/
+class CommandLineArgs;
+class Lockfile;
+class AcceptorMap : public std::map< rtl::OUString, Reference<XInitialization> > {};
+struct ConvertData;
+class Desktop : public Application
+{
+ friend class UserInstall;
+
+ int doShutdown();
+
+ public:
+ enum BootstrapError
+ {
+ BE_OK,
+ BE_UNO_SERVICEMANAGER,
+ BE_UNO_SERVICE_CONFIG_MISSING,
+ BE_PATHINFO_MISSING,
+ BE_USERINSTALL_FAILED,
+ BE_LANGUAGE_MISSING,
+ BE_USERINSTALL_NOTENOUGHDISKSPACE,
+ BE_USERINSTALL_NOWRITEACCESS,
+ BE_OFFICECONFIG_BROKEN
+ };
+ enum BootstrapStatus
+ {
+ BS_OK,
+ BS_TERMINATE
+ };
+
+ Desktop();
+ ~Desktop();
+ virtual int Main( );
+ virtual void Init();
+ virtual void InitFinished();
+ virtual void DeInit();
+ virtual sal_Bool QueryExit();
+ virtual sal_uInt16 Exception(sal_uInt16 nError);
+ virtual void SystemSettingsChanging( AllSettings& rSettings, Window* pFrame );
+ virtual void AppEvent( const ApplicationEvent& rAppEvent );
+
+ DECL_LINK( OpenClients_Impl, void* );
+
+ static void OpenClients();
+ static void OpenDefault();
+
+ DECL_LINK( EnableAcceptors_Impl, void*);
+
+ static void HandleAppEvent( const ApplicationEvent& rAppEvent );
+ static ResMgr* GetDesktopResManager();
+ static CommandLineArgs* GetCommandLineArgs();
+
+ void HandleBootstrapErrors( BootstrapError );
+ void SetBootstrapError( BootstrapError nError )
+ {
+ if ( m_aBootstrapError == BE_OK )
+ m_aBootstrapError = nError;
+ }
+ BootstrapError GetBootstrapError() const
+ {
+ return m_aBootstrapError;
+ }
+
+ void SetBootstrapStatus( BootstrapStatus nStatus )
+ {
+ m_aBootstrapStatus = nStatus;
+ }
+ BootstrapStatus GetBootstrapStatus() const
+ {
+ return m_aBootstrapStatus;
+ }
+
+ static sal_Bool CheckOEM();
+ static sal_Bool isCrashReporterEnabled();
+
+ // first-start (ever) related methods
+ static sal_Bool CheckExtensionDependencies();
+
+ static void DoRestartActionsIfNecessary( sal_Bool bQuickStart );
+ static void SetRestartState();
+
+ void SynchronizeExtensionRepositories();
+ void SetSplashScreenText( const ::rtl::OUString& rText );
+ void SetSplashScreenProgress( sal_Int32 );
+
+ void CreateProcessServiceFactory();
+
+ private:
+ // Bootstrap methods
+ ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > CreateApplicationServiceManager();
+
+ 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();
+
+ sal_Bool InitializeInstallation( const rtl::OUString& rAppFilename );
+ sal_Bool InitializeConfiguration();
+ void FlushConfiguration();
+ static sal_Bool shouldLaunchQuickstart();
+ sal_Bool InitializeQuickstartMode( com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >& rSMgr );
+
+ void HandleBootstrapPathErrors( ::utl::Bootstrap::Status, const ::rtl::OUString& aMsg );
+ void StartSetup( const ::rtl::OUString& aParameters );
+
+ // Get a resource message string securely e.g. if resource cannot be retrieved return aFaultBackMsg
+ ::rtl::OUString GetMsgString( sal_uInt16 nId, const ::rtl::OUString& aFaultBackMsg );
+
+ // Create a error message depending on bootstrap failure code and an optional file url
+ ::rtl::OUString CreateErrorMsgString( utl::Bootstrap::FailureCode nFailureCode,
+ const ::rtl::OUString& aFileURL );
+
+ static void PreloadModuleData( CommandLineArgs* );
+ static void PreloadConfigurationData();
+
+ Reference<XStatusIndicator> m_rSplashScreen;
+ void OpenSplashScreen();
+ void CloseSplashScreen();
+
+ void EnableOleAutomation();
+ DECL_LINK( ImplInitFilterHdl, ConvertData* );
+ DECL_LINK( AsyncInitFirstRun, void* );
+ /** checks if the office is run the first time
+ <p>If so, <method>DoFirstRunInitializations</method> is called (asynchronously and delayed) and the
+ respective flag in the configuration is reset.</p>
+ */
+ void CheckFirstRun( );
+
+ /// does initializations which are necessary for the first run of the office
+ void DoFirstRunInitializations();
+
+ static sal_Bool SaveTasks();
+ static sal_Bool _bTasksSaved;
+
+ static void retrieveCrashReporterState();
+ static sal_Bool isUIOnSessionShutdownAllowed();
+
+ // on-demand acceptors
+ static void createAcceptor(const rtl::OUString& aDescription);
+ static void enableAcceptors();
+ static void destroyAcceptor(const rtl::OUString& aDescription);
+
+ sal_Bool m_bMinimized;
+ sal_Bool m_bInvisible;
+ bool m_bServicesRegistered;
+ sal_uInt16 m_nAppEvents;
+ BootstrapError m_aBootstrapError;
+ BootstrapStatus m_aBootstrapStatus;
+
+ Lockfile *m_pLockfile;
+ Timer m_firstRunTimer;
+
+ static ResMgr* pResMgr;
+ static sal_Bool bSuppressOpenDefault;
+};
+
+}
+
+#endif // _DESKTOP_APP_HXX_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/inc/deployment.hrc b/desktop/inc/deployment.hrc
new file mode 100755
index 000000000000..22492cd8ae88
--- /dev/null
+++ b/desktop/inc/deployment.hrc
@@ -0,0 +1,78 @@
+/*************************************************************************
+ *
+ * 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_DEPLOYMENT_HRC
+#define INCLUDED_DEPLOYMENT_HRC
+
+#define MASKCOLOR MaskColor = \
+ Color { Red = 0xFFFF ; Green = 0x0000 ; Blue = 0xFFFF ; };
+
+#define RID_DEPLOYMENT_START 2000
+
+#define RID_DEPLOYMENT_GUI_START RID_DEPLOYMENT_START
+#define RID_DEPLOYMENT_MISC_START (RID_DEPLOYMENT_START+500)
+#define RID_DEPLOYMENT_MANAGER_START (RID_DEPLOYMENT_START+1000)
+#define RID_DEPLOYMENT_REGISTRY_START (RID_DEPLOYMENT_START+1500)
+
+#define RID_DEPLOYMENT_BUNDLE_START (RID_DEPLOYMENT_START+2000)
+#define RID_IMG_DEF_PACKAGE_BUNDLE RID_DEPLOYMENT_BUNDLE_START
+
+#define RID_DEPLOYMENT_SCRIPT_START (RID_DEPLOYMENT_START+2500)
+#define RID_IMG_SCRIPTLIB RID_DEPLOYMENT_SCRIPT_START
+#define RID_IMG_DIALOGLIB (RID_DEPLOYMENT_SCRIPT_START+2)
+
+#define RID_DEPLOYMENT_CONF_START (RID_DEPLOYMENT_START+3000)
+#define RID_IMG_CONF_XML RID_DEPLOYMENT_CONF_START
+
+#define RID_DEPLOYMENT_COMPONENT_START (RID_DEPLOYMENT_START+3500)
+#define RID_IMG_COMPONENT RID_DEPLOYMENT_COMPONENT_START
+#define RID_IMG_JAVA_COMPONENT (RID_DEPLOYMENT_COMPONENT_START+2)
+#define RID_IMG_TYPELIB (RID_DEPLOYMENT_COMPONENT_START+4)
+#define RID_IMG_JAVA_TYPELIB (RID_DEPLOYMENT_COMPONENT_START+6)
+
+#define RID_DEPLOYMENT_UNOPKG_START (RID_DEPLOYMENT_START+4000)
+#define RID_STR_UNOPKG_ACCEPT_LIC_1 (RID_DEPLOYMENT_UNOPKG_START+1)
+#define RID_STR_UNOPKG_ACCEPT_LIC_2 (RID_DEPLOYMENT_UNOPKG_START+2)
+#define RID_STR_UNOPKG_ACCEPT_LIC_3 (RID_DEPLOYMENT_UNOPKG_START+3)
+#define RID_STR_UNOPKG_ACCEPT_LIC_4 (RID_DEPLOYMENT_UNOPKG_START+4)
+#define RID_STR_UNOPKG_ACCEPT_LIC_YES (RID_DEPLOYMENT_UNOPKG_START+5)
+#define RID_STR_UNOPKG_ACCEPT_LIC_Y (RID_DEPLOYMENT_UNOPKG_START+6)
+#define RID_STR_UNOPKG_ACCEPT_LIC_NO (RID_DEPLOYMENT_UNOPKG_START+7)
+#define RID_STR_UNOPKG_ACCEPT_LIC_N (RID_DEPLOYMENT_UNOPKG_START+8)
+#define RID_STR_UNOPKG_ERROR (RID_DEPLOYMENT_UNOPKG_START+9)
+#define RID_STR_CONCURRENTINSTANCE (RID_DEPLOYMENT_UNOPKG_START+10)
+
+#define RID_DEPLOYMENT_DEPENDENCIES_START (RID_DEPLOYMENT_START + 4400)
+#define RID_DEPLYOMENT_DEPENDENCIES_UNKNOWN RID_DEPLOYMENT_DEPENDENCIES_START
+#define RID_DEPLYOMENT_DEPENDENCIES_MIN (RID_DEPLOYMENT_DEPENDENCIES_START+1)
+#define RID_DEPLYOMENT_DEPENDENCIES_MAX (RID_DEPLOYMENT_DEPENDENCIES_START+2)
+
+#define RID_DEPLOYMENT_LICENSE_START (RID_DEPLOYMENT_START+4500)
+
+#define RID_DEPLOYMENT_HELP_START (RID_DEPLOYMENT_START+5000)
+#define RID_IMG_HELP RID_DEPLOYMENT_HELP_START
+#endif
diff --git a/desktop/inc/makefile.mk b/desktop/inc/makefile.mk
new file mode 100755
index 000000000000..8715d814274f
--- /dev/null
+++ b/desktop/inc/makefile.mk
@@ -0,0 +1,47 @@
+#*************************************************************************
+#
+# 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=inc
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+# --- Targets -------------------------------------------------------
+
+.INCLUDE : target.mk
+
+.IF "$(ENABLE_PCH)"!=""
+ALLTAR : \
+ $(SLO)$/precompiled.pch \
+ $(SLO)$/precompiled_ex.pch
+
+.ENDIF # "$(ENABLE_PCH)"!=""
+
diff --git a/desktop/inc/migration.hxx b/desktop/inc/migration.hxx
new file mode 100644
index 000000000000..3319d8d7716f
--- /dev/null
+++ b/desktop/inc/migration.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_MIGRATION_HXX_
+#define _DESKTOP_MIGRATION_HXX_
+
+#include <sal/types.h>
+#include <rtl/ustring.hxx>
+
+namespace desktop {
+
+class Migration
+{
+public:
+ static void migrateSettingsIfNecessary();
+};
+}
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/inc/pch/precompiled_desktop.cxx b/desktop/inc/pch/precompiled_desktop.cxx
new file mode 100644
index 000000000000..24d7e45f222d
--- /dev/null
+++ b/desktop/inc/pch/precompiled_desktop.cxx
@@ -0,0 +1,31 @@
+/* -*- 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"
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/inc/pch/precompiled_desktop.hxx b/desktop/inc/pch/precompiled_desktop.hxx
new file mode 100644
index 000000000000..6baa50c69781
--- /dev/null
+++ b/desktop/inc/pch/precompiled_desktop.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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): Generated on 2006-09-01 17:49:39.170923
+
+#ifdef PRECOMPILED_HEADERS
+#include "com/sun/star/beans/XPropertySet.hpp"
+#include "com/sun/star/beans/NamedValue.hpp"
+#include "comphelper/processfactory.hxx"
+#include "osl/file.hxx"
+#include "rtl/bootstrap.hxx"
+#include "rtl/ustring.hxx"
+#include "tools/datetime.hxx"
+#include "tools/debug.hxx"
+#include "unotools/configmgr.hxx"
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/os2/source/applauncher/launcher.cxx b/desktop/os2/source/applauncher/launcher.cxx
new file mode 100644
index 000000000000..2a1a0e779b60
--- /dev/null
+++ b/desktop/os2/source/applauncher/launcher.cxx
@@ -0,0 +1,121 @@
+/* -*- 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 "launcher.hxx"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <malloc.h>
+#include <process.h>
+
+int main( int argc, char* argv[])
+{
+ PPIB pib;
+ APIRET rc;
+ RESULTCODES result = {0};
+ char szFail[ _MAX_PATH];
+
+ HAB hab = WinInitialize( 0);
+ HMQ hmq = WinCreateMsgQueue( hab, 0);
+ ERRORID erridErrorCode = 0;
+ erridErrorCode = WinGetLastError(hab);
+
+ // Calculate application name
+ CHAR szLibpath[_MAX_PATH*2];
+ CHAR szApplicationName[_MAX_PATH];
+ CHAR szDrive[_MAX_PATH];
+ CHAR szDir[_MAX_PATH];
+ CHAR szFileName[_MAX_PATH];
+ CHAR szExt[_MAX_PATH];
+
+ // get executable fullpath
+ DosGetInfoBlocks(NULL, &pib);
+ DosQueryModuleName(pib->pib_hmte, sizeof(szApplicationName), szApplicationName);
+
+ // adjust libpath
+ _splitpath( szApplicationName, szDrive, szDir, szFileName, szExt );
+ char* basedir = strstr( szDir, "\\PROGRAM\\");
+ if (basedir) *basedir = 0;
+ sprintf( szLibpath, "\"%s%s\\URE\\BIN\";\"%s%s\\BASIS\\PROGRAM\";%BeginLIBPATH%",
+ szDrive, szDir, szDrive, szDir);
+ DosSetExtLIBPATH( (PCSZ)szLibpath, BEGIN_LIBPATH);
+ // make sure we load DLL from our path only, so multiple instances/versions
+ // can be loaded.
+
+
+ // adjust exe name
+ _splitpath( szApplicationName, szDrive, szDir, szFileName, szExt );
+ _makepath( szApplicationName, szDrive, szDir, OFFICE_IMAGE_NAME, (".bin") );
+
+ // copy command line parameters
+ int i, len;
+ len = strlen(szApplicationName) + 1 + strlen( APPLICATION_SWITCH) + 1 + 1;
+ for( i=1; i<argc; i++)
+ len += strlen( argv[i]) + 1;
+
+ char* pszCommandLine, *pszArgs;
+ pszCommandLine = (char*) calloc( 1, len);
+ strcpy( pszCommandLine, szApplicationName);
+ pszArgs = pszCommandLine + strlen(szApplicationName) + 1;
+ strcat( pszArgs, APPLICATION_SWITCH);
+ strcat( pszArgs, " ");
+ for( i=1; i<argc; i++) {
+ // add quotes if argument has spaces!
+ if (strchr( argv[i], ' '))
+ strcat( pszArgs, "\"");
+ strcat( pszArgs, argv[i]);
+ if (strchr( argv[i], ' '))
+ strcat( pszArgs, "\"");
+ strcat( pszArgs, " ");
+ }
+ pszArgs[ strlen( pszArgs) + 0] = 0;
+
+ // execute
+ rc = DosExecPgm(szFail, sizeof(szFail),
+ EXEC_SYNC, (PCSZ)pszCommandLine, (PCSZ)NULL, &result,
+ (PCSZ)szApplicationName);
+ if (rc) {
+ char szMessage[ _MAX_PATH*2];
+ sprintf( szMessage, "Execution failed! Contact technical support.\n\nReturn code: %d\nFailing module:%s\n", rc, szFail);
+ rc = WinMessageBox( HWND_DESKTOP, HWND_DESKTOP,
+ (PSZ)szMessage,
+ (PSZ)"Unable to start OpenOffice.org!",
+ 0, MB_ERROR | MB_OK);
+ WinDestroyMsgQueue( hmq);
+ WinTerminate( hab);
+ exit(1);
+ }
+
+ WinDestroyMsgQueue( hmq);
+ WinTerminate( hab);
+
+ exit( result.codeResult);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/os2/source/applauncher/launcher.hxx b/desktop/os2/source/applauncher/launcher.hxx
new file mode 100644
index 000000000000..651098ef7382
--- /dev/null
+++ b/desktop/os2/source/applauncher/launcher.hxx
@@ -0,0 +1,11 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+
+#define INCL_DOS
+#define INCL_PM
+#include <os2.h>
+
+#define OFFICE_IMAGE_NAME ("soffice")
+
+extern CHAR APPLICATION_SWITCH[];
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/os2/source/applauncher/makefile.mk b/desktop/os2/source/applauncher/makefile.mk
new file mode 100755
index 000000000000..7eec8aee9c23
--- /dev/null
+++ b/desktop/os2/source/applauncher/makefile.mk
@@ -0,0 +1,121 @@
+#*************************************************************************
+#
+# 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=applauncher
+LIBTARGET=NO
+TARGETTYPE=GUI
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+OBJFILES= \
+ $(OBJ)$/launcher.obj \
+ $(OBJ)$/swriter.obj \
+ $(OBJ)$/scalc.obj \
+ $(OBJ)$/sdraw.obj \
+ $(OBJ)$/simpress.obj \
+ $(OBJ)$/sbase.obj \
+ $(OBJ)$/smath.obj \
+ $(OBJ)$/officeloader.obj \
+ $(OBJ)$/os2quickstart.obj
+
+APP1TARGET=swriter
+APP1NOSAL=TRUE
+APP1LINKRES=$(MISC)$/$(TARGET)1.res
+APP1ICON=$(SOLARRESDIR)$/icons$/ooo-writer-app.ico
+APP1OBJS = \
+ $(OBJ)$/launcher.obj\
+ $(OBJ)$/swriter.obj
+
+
+APP2TARGET=scalc
+APP2NOSAL=TRUE
+APP2LINKRES=$(MISC)$/$(TARGET)2.res
+APP2ICON=$(SOLARRESDIR)$/icons$/ooo-calc-app.ico
+APP2OBJS = \
+ $(OBJ)$/launcher.obj\
+ $(OBJ)$/scalc.obj
+
+APP3TARGET=sdraw
+APP3NOSAL=TRUE
+APP3LINKRES=$(MISC)$/$(TARGET)3.res
+APP3ICON=$(SOLARRESDIR)$/icons$/ooo-draw-app.ico
+APP3OBJS = \
+ $(OBJ)$/launcher.obj\
+ $(OBJ)$/sdraw.obj
+
+APP4TARGET=simpress
+APP4NOSAL=TRUE
+APP4LINKRES=$(MISC)$/$(TARGET)4.res
+APP4ICON=$(SOLARRESDIR)$/icons$/ooo-impress-app.ico
+APP4OBJS = \
+ $(OBJ)$/launcher.obj\
+ $(OBJ)$/simpress.obj
+
+APP5TARGET=sbase
+APP5NOSAL=TRUE
+APP5LINKRES=$(MISC)$/$(TARGET)5.res
+APP5ICON=$(SOLARRESDIR)$/icons$/ooo-base-app.ico
+APP5OBJS = \
+ $(OBJ)$/launcher.obj\
+ $(OBJ)$/sbase.obj
+
+APP6TARGET=smath
+APP6NOSAL=TRUE
+APP6LINKRES=$(MISC)$/$(TARGET)6.res
+APP6ICON=$(SOLARRESDIR)$/icons$/ooo-math-app.ico
+APP6OBJS = \
+ $(OBJ)$/launcher.obj\
+ $(OBJ)$/smath.obj
+
+APP7TARGET=officeloader
+APP7NOSAL=TRUE
+APP7LINKRES=$(MISC)$/$(TARGET)7.res
+APP7ICON=$(SOLARRESDIR)$/icons$/ooo-main-app.ico
+APP7OBJS = \
+ $(OBJ)$/launcher.obj\
+ $(OBJ)$/officeloader.obj
+
+APP8TARGET=os2quickstart
+APP8NOSAL=TRUE
+APP8LINKRES=$(MISC)$/$(TARGET)8.res
+APP8ICON=$(SOLARRESDIR)$/icons$/ooo-main-app.ico
+APP8OBJS = \
+ $(OBJ)$/launcher.obj\
+ $(OBJ)$/os2quickstart.obj
+
+# --- Targets ------------------------------------------------------
+
+
+.INCLUDE : target.mk
+
diff --git a/desktop/os2/source/applauncher/officeloader.cxx b/desktop/os2/source/applauncher/officeloader.cxx
new file mode 100644
index 000000000000..f3124acdcfeb
--- /dev/null
+++ b/desktop/os2/source/applauncher/officeloader.cxx
@@ -0,0 +1,6 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+#include "launcher.hxx"
+
+CHAR APPLICATION_SWITCH[] = ( "" );
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/os2/source/applauncher/os2quickstart.cxx b/desktop/os2/source/applauncher/os2quickstart.cxx
new file mode 100644
index 000000000000..b67389272f77
--- /dev/null
+++ b/desktop/os2/source/applauncher/os2quickstart.cxx
@@ -0,0 +1,6 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+#include "launcher.hxx"
+
+CHAR APPLICATION_SWITCH[] = ( "-quickstart" );
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/os2/source/applauncher/sbase.cxx b/desktop/os2/source/applauncher/sbase.cxx
new file mode 100644
index 000000000000..ed3e7cceb378
--- /dev/null
+++ b/desktop/os2/source/applauncher/sbase.cxx
@@ -0,0 +1,6 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+#include "launcher.hxx"
+
+CHAR APPLICATION_SWITCH[] = ( "-base" );
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/os2/source/applauncher/scalc.cxx b/desktop/os2/source/applauncher/scalc.cxx
new file mode 100644
index 000000000000..854f34e7f6c1
--- /dev/null
+++ b/desktop/os2/source/applauncher/scalc.cxx
@@ -0,0 +1,6 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+#include "launcher.hxx"
+
+CHAR APPLICATION_SWITCH[] = ( "-calc" );
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/os2/source/applauncher/sdraw.cxx b/desktop/os2/source/applauncher/sdraw.cxx
new file mode 100644
index 000000000000..b3f4bcff301a
--- /dev/null
+++ b/desktop/os2/source/applauncher/sdraw.cxx
@@ -0,0 +1,6 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+#include "launcher.hxx"
+
+CHAR APPLICATION_SWITCH[] = ( "-draw" );
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/os2/source/applauncher/simpress.cxx b/desktop/os2/source/applauncher/simpress.cxx
new file mode 100644
index 000000000000..f4cf9575eb7b
--- /dev/null
+++ b/desktop/os2/source/applauncher/simpress.cxx
@@ -0,0 +1,6 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+#include "launcher.hxx"
+
+CHAR APPLICATION_SWITCH[] = ( "-impress" );
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/os2/source/applauncher/smath.cxx b/desktop/os2/source/applauncher/smath.cxx
new file mode 100644
index 000000000000..d93b15d34519
--- /dev/null
+++ b/desktop/os2/source/applauncher/smath.cxx
@@ -0,0 +1,6 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+#include "launcher.hxx"
+
+CHAR APPLICATION_SWITCH[] = ( "-math" );
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/os2/source/applauncher/swriter.cxx b/desktop/os2/source/applauncher/swriter.cxx
new file mode 100644
index 000000000000..4fc857cf2e53
--- /dev/null
+++ b/desktop/os2/source/applauncher/swriter.cxx
@@ -0,0 +1,6 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+#include "launcher.hxx"
+
+CHAR APPLICATION_SWITCH[] = ( "-writer" );
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/prj/build.lst b/desktop/prj/build.lst
new file mode 100644
index 000000000000..0307d002282e
--- /dev/null
+++ b/desktop/prj/build.lst
@@ -0,0 +1,52 @@
+dt desktop : TRANSLATIONS:translations sfx2 stoc BERKELEYDB:berkeleydb sysui BOOST:boost svx xmlhelp sal unoil officecfg offuh filter LIBXSLT:libxslt NULL
+dt desktop usr1 - all dt_mkout NULL
+dt desktop\inc nmake - all dt_inc NULL
+dt desktop\prj get - all dt_prj NULL
+dt desktop\res get - all dt_res NULL
+dt desktop\source\app nmake - all dt_app dt_migr dt_inc dt_dp_misc NULL
+dt desktop\source\migration nmake - all dt_migr dt_inc NULL
+dt desktop\source\migration\services nmake - all dt_services dt_inc dt_dp_misc NULL
+dt desktop\source\so_comp nmake - all dt_so_comp dt_inc NULL
+dt desktop\source\offacc nmake - all dt_offac dt_inc NULL
+dt desktop\source\splash nmake - all dt_spl dt_migr dt_inc NULL
+dt desktop\win32\source nmake - w dt_wrapper dt_inc NULL
+dt desktop\win32\source\setup nmake - w dt_setup dt_inc NULL
+dt desktop\win32\source\officeloader nmake - w dt_officeloader dt_inc NULL
+dt desktop\win32\source\guiloader nmake - w dt_guiloader dt_wrapper.w dt_inc NULL
+dt desktop\win32\source\guistdio nmake - w dt_guistdio dt_inc NULL
+dt desktop\win32\source\applauncher nmake - w dt_applauncher dt_inc NULL
+dt desktop\win32\source\applauncher\ooo nmake - w dt_applauncher_ooo dt_applauncher.w dt_inc NULL
+dt desktop\win32\source\rebase nmake - w dt_rebase dt_inc NULL
+dt desktop\win32\source\QuickStart nmake - w dt_win32_quickstart NULL
+dt desktop\win32\source\QuickStart\so nmake - w dt_win32_quickstart_so dt_win32_quickstart.w NULL
+
+dt desktop\os2\source\applauncher nmake - p dt_applauncher dt_inc NULL
+dt desktop\unx\source\officeloader nmake - u dt_officeloader_unx dt_inc NULL
+dt desktop\unx\source nmake - u dt_uwrapper dt_pagein.u dt_inc NULL
+dt desktop\source\pagein nmake - u dt_pagein dt_inc NULL
+dt desktop\source\pkgchk\unopkg nmake - all dt_unopkg dt_dp_misc dt_app dt_inc dt_guiloader.w NULL
+dt desktop\unx\splash nmake - u dt_usplash dt_pagein.u dt_inc NULL
+dt desktop\source\deployment nmake - all dt_deployment dt_dp_manager dt_dp_registry dt_dp_registry_package dt_dp_registry_executable dt_dp_registry_help dt_dp_registry_script dt_dp_registry_sfwk dt_dp_registry_component dt_dp_registry_configuration dt_dp_unopkg dt_inc dt_dp_misc NULL
+dt desktop\source\deployment\misc nmake - all dt_dp_misc dt_inc NULL
+dt desktop\source\deployment\unopkg nmake - all dt_dp_unopkg dt_inc NULL
+dt desktop\source\deployment\gui nmake - all dt_dp_gui dt_dp_misc dt_inc NULL
+dt desktop\source\deployment\manager nmake - all dt_dp_manager dt_inc NULL
+dt desktop\source\deployment\registry nmake - all dt_dp_registry dt_inc NULL
+dt desktop\source\deployment\registry\package nmake - all dt_dp_registry_package dt_inc NULL
+dt desktop\source\deployment\registry\script nmake - all dt_dp_registry_script dt_inc NULL
+dt desktop\source\deployment\registry\sfwk nmake - all dt_dp_registry_sfwk dt_inc NULL
+dt desktop\source\deployment\registry\component nmake - all dt_dp_registry_component dt_inc NULL
+dt desktop\source\deployment\registry\configuration nmake - all dt_dp_registry_configuration dt_inc NULL
+dt desktop\source\deployment\registry\help nmake - all dt_dp_registry_help dt_inc NULL
+dt desktop\source\deployment\registry\executable nmake - all dt_dp_registry_executable dt_inc NULL
+dt desktop\scripts nmake - u dt_scripts dt_inc NULL
+dt desktop\util nmake - all dt_util dt_app dt_pagein.u dt_so_comp dt_spl dt_uwrapper.u dt_usplash.u dt_wrapper.w dt_officeloader.w dt_officeloader_unx.u dt_migr dt_rebase.w dt_win32_quickstart_so.w dt_zipintro NULL
+dt desktop\zipintro nmake - all dt_zipintro NULL
+dt desktop\registry\data\org\openoffice\Office nmake - all sn_regconfig NULL
+dt desktop\source\registration\com\sun\star\servicetag\resources get - all sn_svctagres NULL
+dt desktop\source\registration\com\sun\star\servicetag nmake - all sn_svctag NULL
+dt desktop\source\registration\com\sun\star\registration nmake - all sn_regjob sn_svctag NULL
+dt desktop\qa\deployment_misc nmake - all sn_qa_deployment_misc dt_dp_misc dt_inc NULL
+dt desktop\test\deployment\active nmake - all dt_test_deployment_active NULL
+dt desktop\test\deployment\boxt nmake - all dt_test_deployment_boxt NULL
+dt desktop\test\deployment\passive nmake - all dt_test_deployment_passive NULL
diff --git a/desktop/prj/d.lst b/desktop/prj/d.lst
new file mode 100644
index 000000000000..cb4fa0617293
--- /dev/null
+++ b/desktop/prj/d.lst
@@ -0,0 +1,152 @@
+mkdir: %COMMON_DEST%\bin%_EXT%\hid
+mkdir: %_DEST%\bin%_EXT%\so
+mkdir: %_DEST%\bin%_EXT%\c01
+mkdir: %_DEST%\bin%_EXT%\c05
+mkdir: %_DEST%\bin%_EXT%\c08
+mkdir: %_DEST%\bin%_EXT%\odf4ms
+
+..\%COMMON_OUTDIR%\misc\*.hid %COMMON_DEST%\bin%_EXT%\hid\*.hid
+..\%__SRC%\bin\soffice.bin %_DEST%\bin%_EXT%\soffice.bin
+..\%__SRC%\bin\officeloader.exe %_DEST%\bin%_EXT%\soffice.exe
+..\%__SRC%\bin\soffice %_DEST%\bin%_EXT%\soffice.bin
+..\%__SRC%\bin\soffice_mac %_DEST%\bin%_EXT%\soffice
+..\%__SRC%\bin\oosplash %_DEST%\bin%_EXT%\oosplash.bin
+..\%__SRC%\bin\so\soffice.bin %_DEST%\bin%_EXT%\so\soffice.bin
+..\%__SRC%\bin\so\officeloader.exe %_DEST%\bin%_EXT%\so\soffice.exe
+..\%__SRC%\bin\so\soffice %_DEST%\bin%_EXT%\so\soffice.bin
+..\%__SRC%\bin\so\soffice_mac %_DEST%\bin%_EXT%\so\soffice
+..\%__SRC%\bin\sofficea*.dll %_DEST%\bin%_EXT%\sofficea*.dll
+..\%__SRC%\lib\isofficeapp.lib %_DEST%\lib%_EXT%\isofficeapp.lib
+..\%__SRC%\lib\libsofficeapp.dylib %_DEST%\lib%_EXT%\libsofficeapp.dylib
+..\%__SRC%\lib\libsofficeapp.so %_DEST%\lib%_EXT%\libsofficeapp.so
+
+..\%__SRC%\bin\soffice_oo.exe %_DEST%\bin%_EXT%\soffice_oo.exe
+..\%__SRC%\bin\soffice_oo %_DEST%\bin%_EXT%\soffice_oo.bin
+..\%__SRC%\bin\so\soffice_so.exe %_DEST%\bin%_EXT%\so\soffice_so.exe
+..\%__SRC%\bin\so\soffice_so %_DEST%\bin%_EXT%\so\soffice_so.bin
+
+..\%__SRC%\bin\scalc.exe %_DEST%\bin%_EXT%\scalc.exe
+..\%__SRC%\bin\sdraw.exe %_DEST%\bin%_EXT%\sdraw.exe
+..\%__SRC%\bin\simpress.exe %_DEST%\bin%_EXT%\simpress.exe
+..\%__SRC%\bin\smath.exe %_DEST%\bin%_EXT%\smath.exe
+..\%__SRC%\bin\swriter.exe %_DEST%\bin%_EXT%\swriter.exe
+..\%__SRC%\bin\sbase.exe %_DEST%\bin%_EXT%\sbase.exe
+..\%__SRC%\bin\sweb.exe %_DEST%\bin%_EXT%\sweb.exe
+..\%__SRC%\bin\os2quickstart.exe %_DEST%\bin%_EXT%\quickstart.exe
+..\%__SRC%\bin\so\scalc.exe %_DEST%\bin%_EXT%\so\scalc.exe
+..\%__SRC%\bin\so\sdraw.exe %_DEST%\bin%_EXT%\so\sdraw.exe
+..\%__SRC%\bin\so\simpress.exe %_DEST%\bin%_EXT%\so\simpress.exe
+..\%__SRC%\bin\so\smath.exe %_DEST%\bin%_EXT%\so\smath.exe
+..\%__SRC%\bin\so\swriter.exe %_DEST%\bin%_EXT%\so\swriter.exe
+..\%__SRC%\bin\so\sbase.exe %_DEST%\bin%_EXT%\so\sbase.exe
+..\%__SRC%\bin\so\sweb.exe %_DEST%\bin%_EXT%\so\sweb.exe
+
+..\%__SRC%\bin\quickstart.exe %_DEST%\bin%_EXT%\quickstart.exe
+..\%__SRC%\bin\quickstart.exe %_DEST%\bin%_EXT%\install_quickstart.exe
+..\%__SRC%\bin\soquickstart.exe %_DEST%\bin%_EXT%\so\quickstart.exe
+..\%__SRC%\bin\soquickstart.exe %_DEST%\bin%_EXT%\so\install_quickstart.exe
+
+..\%__SRC%\misc\soffice.exe.manifest %_DEST%\bin%_EXT%\soffice.exe.manifest
+..\%__SRC%\misc\soffice.bin.manifest %_DEST%\bin%_EXT%\soffice.bin.manifest
+..\%__SRC%\bin\wrp*.dll %_DEST%\bin%_EXT%\wrp*.dll
+..\%__SRC%\bin\spl*.dll %_DEST%\bin%_EXT%\spl*.dll
+..\%__SRC%\bin\socomp.dll %_DEST%\bin%_EXT%\socomp.dll
+..\%__SRC%\obj\officeloader.obj %_DEST%\lib%_EXT%\officeloader.obj
+..\%__SRC%\obj\extendloaderenvironment.obj %_DEST%\lib%_EXT%\extendloaderenvironment.obj
+..\%__SRC%\obj\copyright_ascii_sun.obj %_DEST%\lib%_EXT%\copyright_ascii_sun.obj
+..\%__SRC%\obj\main.obj %_DEST%\lib%_EXT%\main.obj
+..\%__SRC%\lib\libwrp*.so %_DEST%\lib%_EXT%\libwrp*.so
+..\%__SRC%\lib\libwrp*.dylib %_DEST%\lib%_EXT%\libwrp*.dylib
+..\%__SRC%\lib\libspl*.so %_DEST%\lib%_EXT%\libspl*.so
+..\%__SRC%\lib\libspl*.dylib %_DEST%\lib%_EXT%\libspl*.dylib
+..\%__SRC%\lib\libsocomp.so %_DEST%\lib%_EXT%\libsocomp.so
+..\%__SRC%\lib\libsocomp.dylib %_DEST%\lib%_EXT%\libsocomp.dylib
+..\%__SRC%\bin\offacc*.dll %_DEST%\bin%_EXT%\offacc*.dll
+..\%__SRC%\lib\liboffacc*.so %_DEST%\lib%_EXT%\liboffacc*.so
+..\%__SRC%\lib\liboffacc*.dylib %_DEST%\lib%_EXT%\liboffacc*.dylib
+..\%__SRC%\bin\migratio*.dll %_DEST%\bin%_EXT%\migratio*.dll
+..\%__SRC%\lib\migratio*.uno.so %_DEST%\lib%_EXT%\migratio*.uno.so
+..\%__SRC%\lib\migratio*.uno.dylib %_DEST%\lib%_EXT%\migratio*.uno.dylib
+
+..\%__SRC%\bin\sweb %_DEST%\bin%_EXT%\sweb.bin
+
+..\%__SRC%\bin\loader2.ex? %_DEST%\bin%_EXT%\loader2.ex?
+
+..\%__SRC%\bin\depl*.dll %_DEST%\bin%_EXT%\depl*.dll
+..\%__SRC%\lib\deployment*.uno.so %_DEST%\lib%_EXT%\deployment*.uno.so
+..\%__SRC%\lib\deployment*.uno.dylib %_DEST%\lib%_EXT%\deployment*.uno.dylib
+..\%__SRC%\bin\deploymentmisc*.dll %_DEST%\bin%_EXT%\deploymentmisc*.dll
+..\%__SRC%\lib\libdeploymentmisc*.so %_DEST%\lib%_EXT%\libdeploymentmisc*.so
+..\%__SRC%\lib\libdeploymentmisc*.dylib %_DEST%\lib%_EXT%\libdeploymentmisc*.dylib
+..\%__SRC%\bin\guiloader.exe %_DEST%\bin%_EXT%\unopkg.exe
+..\%__SRC%\bin\so\guiloader.exe %_DEST%\bin%_EXT%\so\unopkg.exe
+..\%__SRC%\bin\unopkg %_DEST%\bin%_EXT%\unopkg.bin
+..\%__SRC%\bin\so\unopkg %_DEST%\bin%_EXT%\so\unopkg.bin
+..\%__SRC%\bin\unopkg.exe %_DEST%\bin%_EXT%\unopkg.bin
+..\%__SRC%\bin\so\unopkg.exe %_DEST%\bin%_EXT%\so\unopkg.bin
+..\%__SRC%\misc\unopkg.sh %_DEST%\bin%_EXT%\unopkg
+..\%__SRC%\bin\unopkga*.dll %_DEST%\bin%_EXT%\unopkga*.dll
+..\%__SRC%\lib\libunopkgapp.dylib %_DEST%\lib%_EXT%\libunopkgapp.dylib
+..\%__SRC%\lib\libunopkgapp.so %_DEST%\lib%_EXT%\libunopkgapp.so
+..\%__SRC%\bin\rebasegui.exe %_DEST%\bin%_EXT%\rebasegui.exe
+..\%__SRC%\bin\rebaseoo.exe %_DEST%\bin%_EXT%\rebaseoo.exe
+
+..\%__SRC%\bin\pagein %_DEST%\bin%_EXT%\pagein
+..\%__SRC%\misc\pagein-* %_DEST%\bin%_EXT%\pagein-*
+
+..\%__SRC%\bin\unoinfo.exe %_DEST%\bin%_EXT%\unoinfo.exe
+..\%__SRC%\misc\unoinfo.sh %_DEST%\bin%_EXT%\unoinfo
+
+..\%__SRC%\bin\*.res %_DEST%\bin%_EXT%\*.res
+
+..\%__SRC%\misc\soffice.sh-expanded %_DEST%\bin%_EXT%\soffice
+..\%__SRC%\misc\sbase.sh %_DEST%\bin%_EXT%\sbase
+..\%__SRC%\misc\scalc.sh %_DEST%\bin%_EXT%\scalc
+..\%__SRC%\misc\sdraw.sh %_DEST%\bin%_EXT%\sdraw
+..\%__SRC%\misc\simpress.sh %_DEST%\bin%_EXT%\simpress
+..\%__SRC%\misc\smaster.sh %_DEST%\bin%_EXT%\smaster
+..\%__SRC%\misc\smath.sh %_DEST%\bin%_EXT%\smath
+..\%__SRC%\misc\sweb.sh %_DEST%\bin%_EXT%\sweb
+..\%__SRC%\misc\swriter.sh %_DEST%\bin%_EXT%\swriter
+..\%__SRC%\misc\nswrapper.sh %_DEST%\bin%_EXT%\nswrapper
+..\%__SRC%\misc\mozwrapper.sh %_DEST%\bin%_EXT%\mozwrapper
+
+mkdir: %COMMON_DEST%\pck%_EXT%\brand
+mkdir: %COMMON_DEST%\pck%_EXT%\brand_dev
+
+..\%__SRC%\bin\intro.zip %COMMON_DEST%\pck%_EXT%\intro.zip
+..\%__SRC%\bin\brand\intro.zip %COMMON_DEST%\pck%_EXT%\brand\intro.zip
+..\%__SRC%\bin\brand_dev\intro.zip %COMMON_DEST%\pck%_EXT%\brand_dev\intro.zip
+..\%__SRC%\bin\shell\shell.zip %COMMON_DEST%\pck%_EXT%\shell.zip
+
+..\%__SRC%\bin\guiloader.exe %_DEST%\bin%_EXT%\testtool.exe
+
+..\%__SRC%\bin\guistdio.exe %_DEST%\bin%_EXT%\guistdio.com
+..\%__SRC%\bin\guistdio.exe %_DEST%\bin%_EXT%\crashrep.com
+..\%__SRC%\bin\unopkgio.exe %_DEST%\bin%_EXT%\unopkg.com
+
+..\scripts\ure-link %_DEST%\bin%_EXT%\ure-link
+..\scripts\basis-link %_DEST%\bin%_EXT%\basis-link
+..\scripts\basis-link %_DEST%\bin%_EXT%\c01\basis-link
+..\scripts\basis-link %_DEST%\bin%_EXT%\c05\basis-link
+..\scripts\basis-link %_DEST%\bin%_EXT%\c08\basis-link
+..\scripts\so-basis-link %_DEST%\bin%_EXT%\so\basis-link
+..\scripts\odf-basis-link %_DEST%\bin%_EXT%\odf4ms\basis-link
+
+mkdir: %_DEST%\xml%_EXT%\registry\spool
+mkdir: %_DEST%\xml%_EXT%\registry\spool\org
+mkdir: %_DEST%\xml%_EXT%\registry\spool\org\openoffice
+mkdir: %_DEST%\xml%_EXT%\registry\spool\org\openoffice\Office
+mkdir: %_DEST%\xml%_EXT%\registry\spool\org\openoffice\Office\Jobs
+
+..\%__SRC%\class\*.jar %_DEST%\bin%_EXT%\*.jar
+..\%__SRC%\misc\registry\spool\org\openoffice\Office\Jobs\*.xcu %_DEST%\xml%_EXT%\registry\spool\org\openoffice\Office\Jobs
+..\%__SRC%\misc\deployment.component %_DEST%\xml%_EXT%\deployment.component
+..\%__SRC%\misc\deploymentgui.component %_DEST%\xml%_EXT%\deploymentgui.component
+..\%__SRC%\misc\migrationoo2.component %_DEST%\xml%_EXT%\migrationoo2.component
+..\%__SRC%\misc\migrationoo3.component %_DEST%\xml%_EXT%\migrationoo3.component
+..\%__SRC%\misc\offacc.component %_DEST%\xml%_EXT%\offacc.component
+..\%__SRC%\misc\productregistration.jar.component %_DEST%\xml%_EXT%\productregistration.jar.component
+..\%__SRC%\misc\socomp.component %_DEST%\xml%_EXT%\socomp.component
+..\%__SRC%\misc\spl.component %_DEST%\xml%_EXT%\spl.component
+..\%__SRC%\misc\splash.component %_DEST%\xml%_EXT%\splash.component
diff --git a/desktop/qa/deployment_misc/makefile.mk b/desktop/qa/deployment_misc/makefile.mk
new file mode 100755
index 000000000000..16223914e740
--- /dev/null
+++ b/desktop/qa/deployment_misc/makefile.mk
@@ -0,0 +1,56 @@
+#*************************************************************************
+#
+# 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 := qa_deployment_misc
+
+ENABLE_EXCEPTIONS := TRUE
+
+.INCLUDE: settings.mk
+.INCLUDE: $(PRJ)$/source$/deployment$/inc$/dp_misc.mk
+
+CFLAGSCXX += $(CPPUNIT_CFLAGS)
+
+# TODO: On Windows, test_dp_version.cxx fails due to BOOL redefinition between
+# windef.h and tools/solar.h caused by including "precompiled_desktop.hxx"; this
+# hack to temporarily disable PCH will become unnecessary with the fix for issue
+# 112600:
+CFLAGSCXX += -DDISABLE_PCH_HACK
+
+SHL1TARGET = $(TARGET)
+SHL1OBJS = $(SLO)$/test_dp_version.obj
+SHL1STDLIBS = $(CPPUNITLIB) $(DEPLOYMENTMISCLIB) $(SALLIB)
+SHL1VERSIONMAP = version.map
+SHL1RPATH = NONE
+SHL1IMPLIB = i$(SHL1TARGET)
+DEF1NAME = $(SHL1TARGET)
+
+SLOFILES = $(SHL1OBJS)
+
+.INCLUDE: target.mk
+.INCLUDE : _cppunit.mk
diff --git a/desktop/qa/deployment_misc/test_dp_version.cxx b/desktop/qa/deployment_misc/test_dp_version.cxx
new file mode 100644
index 000000000000..480172bb5abe
--- /dev/null
+++ b/desktop/qa/deployment_misc/test_dp_version.cxx
@@ -0,0 +1,96 @@
+/* -*- 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 "cppunit/TestAssert.h"
+#include "cppunit/TestFixture.h"
+#include "cppunit/extensions/HelperMacros.h"
+#include "cppunit/plugin/TestPlugIn.h"
+#include "rtl/ustring.h"
+#include "rtl/ustring.hxx"
+
+#include "../../source/deployment/inc/dp_version.hxx"
+
+namespace {
+
+class Test: public ::CppUnit::TestFixture {
+public:
+ void test();
+
+ CPPUNIT_TEST_SUITE(Test);
+ CPPUNIT_TEST(test);
+ CPPUNIT_TEST_SUITE_END();
+};
+
+void Test::test() {
+ struct Data {
+ rtl::OUString version1;
+ rtl::OUString version2;
+ ::dp_misc::Order order;
+ };
+ static Data const data[] = {
+ { rtl::OUString(),
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("0.0000.00.0")),
+ ::dp_misc::EQUAL },
+ { rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".01")),
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("0.1")),
+ ::dp_misc::EQUAL },
+ { rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("10")),
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("2")),
+ ::dp_misc::GREATER },
+ { rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("9223372036854775808")),
+ // 2^63
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("9223372036854775807")),
+ ::dp_misc::GREATER }
+ };
+ for (::std::size_t i = 0; i < sizeof data / sizeof (Data); ++i) {
+ CPPUNIT_ASSERT_EQUAL(
+ data[i].order,
+ ::dp_misc::compareVersions(data[i].version1, data[i].version2));
+ static ::dp_misc::Order const reverse[3] = {
+ ::dp_misc::GREATER, ::dp_misc::EQUAL, ::dp_misc::LESS
+ };
+ CPPUNIT_ASSERT_EQUAL(
+ reverse[data[i].order],
+ ::dp_misc::compareVersions(data[i].version2, data[i].version1));
+ }
+}
+
+CPPUNIT_TEST_SUITE_REGISTRATION(Test);
+
+}
+
+CPPUNIT_PLUGIN_IMPLEMENT();
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/qa/deployment_misc/version.map b/desktop/qa/deployment_misc/version.map
new file mode 100755
index 000000000000..3308588ef6f8
--- /dev/null
+++ b/desktop/qa/deployment_misc/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:
+ cppunitTestPlugIn;
+
+ local:
+ *;
+};
diff --git a/desktop/registry/data/org/openoffice/Office/Jobs.xcu b/desktop/registry/data/org/openoffice/Office/Jobs.xcu
new file mode 100644
index 000000000000..0572d96a2a63
--- /dev/null
+++ b/desktop/registry/data/org/openoffice/Office/Jobs.xcu
@@ -0,0 +1,74 @@
+<?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.
+ *
+ ************************************************************************ -->
+<oor:component-data oor:name="Jobs" oor:package="org.openoffice.Office" xmlns:oor="http://openoffice.org/2001/registry" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <node oor:name="Jobs">
+ <node oor:name="ProductRegistration" oor:op="replace">
+ <prop oor:name="Service">
+ <value>com.sun.star.comp.framework.DoRegistrationJob</value>
+ </prop>
+ <node oor:name="Arguments">
+ <prop oor:name="ProductName" oor:op="replace" oor:type="xs:string">
+ <value>${SERVICETAG_PRODUCTNAME}</value>
+ </prop>
+ <prop oor:name="ProductVersion" oor:op="replace" oor:type="xs:string">
+ <value>${SERVICETAG_PRODUCTVERSION}</value>
+ </prop>
+ <prop oor:name="ProductURN" oor:op="replace" oor:type="xs:string">
+ <value>${SERVICETAG_URN}</value>
+ </prop>
+ <prop oor:name="ProductSource" oor:op="replace" oor:type="xs:string">
+ <value>${SERVICETAG_SOURCE}</value>
+ </prop>
+ <prop oor:name="ProductParent" oor:op="replace" oor:type="xs:string">
+ <value>${SERVICETAG_PARENTNAME}</value>
+ </prop>
+ <prop oor:name="Vendor" oor:op="replace" oor:type="xs:string">
+ <value>Sun Microsystems, Inc.</value>
+ </prop>
+ <prop oor:name="RegistrationData" oor:op="replace" oor:type="xs:string">
+ <value>$(user)/registration.xml</value>
+ </prop>
+ <prop oor:name="RegistrationURL" oor:op="replace" oor:type="xs:string">
+ <value>${REGISTRATION_HOST}/register/${registry_urn}?product=${REGISTRATION_PRODUCT}&amp;locale=${locale}&amp;cid=${REGISTRATION_CID}</value>
+ </prop>
+ </node>
+ </node>
+ </node>
+ <node oor:name="Events">
+ <node oor:name="onRegisterNow" oor:op="fuse">
+ <node oor:name="JobList">
+ <node oor:name="ProductRegistration" oor:op="replace"/>
+ </node>
+ </node>
+ <node oor:name="onRegisterLater" oor:op="fuse">
+ <node oor:name="JobList">
+ <node oor:name="ProductRegistration" oor:op="replace"/>
+ </node>
+ </node>
+ </node>
+</oor:component-data>
diff --git a/desktop/registry/data/org/openoffice/Office/makefile.mk b/desktop/registry/data/org/openoffice/Office/makefile.mk
new file mode 100755
index 000000000000..2ad8441ea3d3
--- /dev/null
+++ b/desktop/registry/data/org/openoffice/Office/makefile.mk
@@ -0,0 +1,77 @@
+#*************************************************************************
+#
+# 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=setup_native
+TARGET=data_registration
+PACKAGE=org.openoffice.Office
+
+ABSXCSROOT=$(SOLARXMLDIR)
+XCSROOT=..
+DTDDIR=$(ABSXCSROOT)
+XSLDIR=$(ABSXCSROOT)$/processing
+PROCESSOUT=$(MISC)$/$(TARGET)
+PROCESSORDIR=$(SOLARBINDIR)
+
+.INCLUDE : settings.mk
+.IF "$(L10N_framework)"==""
+
+# --- Files -------------------------------------------------------
+
+.IF "$(BUILD_SPECIAL)"!=""
+
+XCUFILES= \
+ Jobs.xcu
+
+MODULEFILES=
+
+LOCALIZEDFILES=
+
+PACKAGEDIR=$(subst,.,$/ $(PACKAGE))
+SPOOLDIR=$(MISC)$/registry$/spool
+
+MYXCUFILES= \
+ $(SPOOLDIR)$/$(PACKAGEDIR)$/Jobs$/Jobs-registration.xcu
+
+.ELSE # "$(BUILD_SPECIAL)"!=""
+
+dummy:
+ @echo "Nothing to build"
+
+.ENDIF # "$(BUILD_SPECIAL)"!=""
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
+.ENDIF # L10N_framework
+ALLTAR : $(MYXCUFILES)
+
+$(SPOOLDIR)$/$(PACKAGEDIR)$/Jobs$/Jobs-registration.xcu : $(PROCESSOUT)$/registry$/data$/$/$(PACKAGEDIR)$/Jobs.xcu
+ @-$(MKDIRHIER) $(@:d)
+ @$(COPY) $< $@
+
diff --git a/desktop/scripts/basis-link b/desktop/scripts/basis-link
new file mode 100755
index 000000000000..3af84201e04f
--- /dev/null
+++ b/desktop/scripts/basis-link
@@ -0,0 +1 @@
+Basis \ No newline at end of file
diff --git a/desktop/scripts/makefile.mk b/desktop/scripts/makefile.mk
new file mode 100755
index 000000000000..5c412f818702
--- /dev/null
+++ b/desktop/scripts/makefile.mk
@@ -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.
+#
+#*************************************************************************
+
+PRJ=..
+
+PRJNAME=desktop
+TARGET=scripts
+
+# --- Settings -----------------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Targets -------------------------------------------------------------
+
+UNIXTEXT= \
+ $(MISC)$/sbase.sh \
+ $(MISC)$/scalc.sh \
+ $(MISC)$/sdraw.sh \
+ $(MISC)$/simpress.sh \
+ $(MISC)$/smaster.sh \
+ $(MISC)$/smath.sh \
+ $(MISC)$/sweb.sh \
+ $(MISC)$/swriter.sh \
+ $(MISC)$/mozwrapper.sh \
+ $(MISC)$/unoinfo.sh \
+ $(MISC)$/unopkg.sh
+
+.IF "$(OS)" != "MACOSX"
+
+ALLTAR: $(MISC)$/soffice.sh-expanded
+
+$(MISC)/soffice.sh-expanded: $(MISC)/soffice.sh
+.IF "$(OS)" == "LINUX" && "$(CPUNAME)" == "POWERPC"
+ $(SED) 's/^#@# //' $< > $@
+.ELSE
+ $(COPY) $< $@
+.ENDIF
+
+UNIXTEXT+= $(MISC)$/soffice.sh
+
+.ENDIF
+
+.INCLUDE : target.mk
diff --git a/desktop/scripts/mozwrapper.sh b/desktop/scripts/mozwrapper.sh
new file mode 100755
index 000000000000..89b6415358be
--- /dev/null
+++ b/desktop/scripts/mozwrapper.sh
@@ -0,0 +1,8 @@
+#!/bin/sh
+
+# if mozilla is not found, specify full path here
+MOZILLA=mozilla
+
+if ${MOZILLA} -remote "openURL($1,new-window)" 2>&1 | egrep -si "not running on display"; then
+ ${MOZILLA} $1
+fi
diff --git a/desktop/scripts/odf-basis-link b/desktop/scripts/odf-basis-link
new file mode 100755
index 000000000000..3af84201e04f
--- /dev/null
+++ b/desktop/scripts/odf-basis-link
@@ -0,0 +1 @@
+Basis \ No newline at end of file
diff --git a/desktop/scripts/sbase.sh b/desktop/scripts/sbase.sh
new file mode 100755
index 000000000000..e3a8ed07d5c0
--- /dev/null
+++ b/desktop/scripts/sbase.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+cmd=`dirname "$0"`/soffice
+exec "$cmd" --base "$@"
diff --git a/desktop/scripts/scalc.sh b/desktop/scripts/scalc.sh
new file mode 100755
index 000000000000..c9c3cde39e49
--- /dev/null
+++ b/desktop/scripts/scalc.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+cmd=`dirname "$0"`/soffice
+exec "$cmd" --calc "$@"
diff --git a/desktop/scripts/sdraw.sh b/desktop/scripts/sdraw.sh
new file mode 100755
index 000000000000..4131a2505f48
--- /dev/null
+++ b/desktop/scripts/sdraw.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+cmd=`dirname "$0"`/soffice
+exec "$cmd" --draw "$@"
diff --git a/desktop/scripts/simpress.sh b/desktop/scripts/simpress.sh
new file mode 100755
index 000000000000..d78ea14207c0
--- /dev/null
+++ b/desktop/scripts/simpress.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+cmd=`dirname "$0"`/soffice
+exec "$cmd" --impress "$@"
diff --git a/desktop/scripts/smaster.sh b/desktop/scripts/smaster.sh
new file mode 100755
index 000000000000..ed9b09d51279
--- /dev/null
+++ b/desktop/scripts/smaster.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+cmd=`dirname "$0"`/soffice
+exec "$cmd" --global "$@"
diff --git a/desktop/scripts/smath.sh b/desktop/scripts/smath.sh
new file mode 100755
index 000000000000..454fa135ff8e
--- /dev/null
+++ b/desktop/scripts/smath.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+cmd=`dirname "$0"`/soffice
+exec "$cmd" --math "$@"
diff --git a/desktop/scripts/so-basis-link b/desktop/scripts/so-basis-link
new file mode 100755
index 000000000000..3af84201e04f
--- /dev/null
+++ b/desktop/scripts/so-basis-link
@@ -0,0 +1 @@
+Basis \ No newline at end of file
diff --git a/desktop/scripts/soffice.sh b/desktop/scripts/soffice.sh
new file mode 100755
index 000000000000..ef1f2dc135b0
--- /dev/null
+++ b/desktop/scripts/soffice.sh
@@ -0,0 +1,101 @@
+#!/bin/sh
+#*************************************************************************
+#
+# 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.
+#
+#*************************************************************************
+
+#
+# STAR_PROFILE_LOCKING_DISABLED=1
+# export STAR_PROFILE_LOCKING_DISABLED
+#
+
+# file locking now enabled by default
+SAL_ENABLE_FILE_LOCKING=1
+export SAL_ENABLE_FILE_LOCKING
+
+# Uncomment the line below if you suspect that OpenGL is not
+# working on your system.
+# SAL_NOOPENGL=true; export SAL_NOOPENGL
+
+unset XENVIRONMENT
+
+# uncomment line below to disable anti aliasing of fonts
+# SAL_ANTIALIAS_DISABLE=true; export SAL_ANTIALIAS_DISABLE
+
+# uncomment line below if you encounter problems starting soffice on your system
+# SAL_NO_XINITTHREADS=true; export SAL_NO_XINITTHREADS
+
+# read database entries for Adabas D
+if [ -f /etc/adabasrc ]; then
+ . /etc/adabasrc
+fi
+
+# The following is needed on Linux PPC with IBM j2sdk142:
+#@# export JITC_PROCESSOR_TYPE=6
+
+# resolve installation directory
+sd_cwd=`pwd`
+sd_res=$0
+while [ -h "$sd_res" ] ; do
+ cd "`dirname "$sd_res"`"
+ sd_basename=`basename "$sd_res"`
+ sd_res=`ls -l "$sd_basename" | sed "s/.*$sd_basename -> //g"`
+done
+cd "`dirname "$sd_res"`"
+sd_prog=`pwd`
+cd "$sd_cwd"
+
+# linked build needs additional settings
+if [ -e $sd_prog/ooenv ] ; then
+ . $sd_prog/ooenv
+fi
+
+if [ "$VALGRIND" != "" ]; then
+ VALGRINDCHECK="valgrind --tool=$VALGRIND --trace-children=yes --trace-children-skip=*/java --error-exitcode=101"
+ export VALGRINDCHECK
+ G_SLICE=always-malloc
+ export G_SLICE
+fi
+
+case "`uname -s`" in
+NetBSD|OpenBSD|FreeBSD|DragonFly)
+# this is a temporary hack until we can live with the default search paths
+ sd_prog1="$sd_prog/../basis-link/program"
+ sd_prog2="$sd_prog/../basis-link/ure-link/lib"
+ LD_LIBRARY_PATH=$sd_prog1:$sd_prog2${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}
+ JAVA_HOME=$(javaPathHelper -h libreoffice-java 2> /dev/null)
+ export LD_LIBRARY_PATH
+ if [ -n "${JAVA_HOME}" ]; then
+ export JAVA_HOME
+ fi
+ ;;
+AIX)
+ LIBPATH=$sd_prog:$sd_prog/../basis-link/program:$sd_prog/../basis-link/ure-link/lib${LIBPATH:+:$LIBPATH}
+ export LIBPATH
+ ;;
+esac
+
+# oosplash does the rest: forcing pages in, javaldx etc. are
+exec $VALGRINDCHECK "$sd_prog/oosplash.bin" "$@"
diff --git a/desktop/scripts/sweb.sh b/desktop/scripts/sweb.sh
new file mode 100755
index 000000000000..a365392584b6
--- /dev/null
+++ b/desktop/scripts/sweb.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+cmd=`dirname "$0"`/soffice
+exec "$cmd" --web "$@"
diff --git a/desktop/scripts/swriter.sh b/desktop/scripts/swriter.sh
new file mode 100755
index 000000000000..3fa48c0d3eba
--- /dev/null
+++ b/desktop/scripts/swriter.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+cmd=`dirname "$0"`/soffice
+exec "$cmd" --writer "$@"
diff --git a/desktop/scripts/unoinfo.sh b/desktop/scripts/unoinfo.sh
new file mode 100755
index 000000000000..a7566155aa0d
--- /dev/null
+++ b/desktop/scripts/unoinfo.sh
@@ -0,0 +1,55 @@
+#!/bin/sh
+#*************************************************************************
+#
+# 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.
+#
+#*************************************************************************
+
+set -e
+
+# resolve installation directory
+sd_res=$0
+while [ -h "$sd_res" ] ; do
+ cd "`dirname "$sd_res"`"
+ sd_basename=`basename "$sd_res"`
+ sd_res=`ls -l "$sd_basename" | sed "s/.*$sd_basename -> //g"`
+done
+cd "`dirname "$sd_res"`"
+sd_prog=`pwd`
+
+case $1 in
+c++)
+ printf '%s' "$sd_prog/../basis-link/ure-link/lib"
+ ;;
+java)
+ printf '0%s\0%s\0%s\0%s\0%s' \
+ "$sd_prog/../basis-link/ure-link/share/java/ridl.jar" \
+ "$sd_prog/../basis-link/ure-link/share/java/jurt.jar" \
+ "$sd_prog/../basis-link/ure-link/share/java/juh.jar" \
+ "$sd_prog/../basis-link/program/classes/unoil.jar" "$sd_prog"
+ ;;
+*)
+ exit 1
+ ;;
+esac
diff --git a/desktop/scripts/unopkg.sh b/desktop/scripts/unopkg.sh
new file mode 100755
index 000000000000..4419ea077e98
--- /dev/null
+++ b/desktop/scripts/unopkg.sh
@@ -0,0 +1,115 @@
+#!/bin/sh
+#*************************************************************************
+#
+# 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.
+#
+#*************************************************************************
+
+# enable file locking
+SAL_ENABLE_FILE_LOCKING=1
+export SAL_ENABLE_FILE_LOCKING
+
+# resolve installation directory
+sd_cwd=`pwd`
+sd_res=$0
+while [ -h "$sd_res" ] ; do
+ cd "`dirname "$sd_res"`"
+ sd_basename=`basename "$sd_res"`
+ sd_res=`ls -l "$sd_basename" | sed "s/.*$sd_basename -> //g"`
+done
+cd "`dirname "$sd_res"`"
+sd_prog=`pwd`
+cd "$sd_cwd"
+
+# this is a temporary hack until we can live with the default search paths
+case "`uname -s`" in
+NetBSD|OpenBSD|FreeBSD|DragonFly)
+ sd_prog1="$sd_prog/../basis-link/program"
+ sd_prog2="$sd_prog/../basis-link/ure-link/lib"
+ LD_LIBRARY_PATH=$sd_prog1:$sd_prog2${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}
+ JAVA_HOME=$(javaPathHelper -h libreoffice-java 2> /dev/null)
+ export LD_LIBRARY_PATH
+ if [ -n "${JAVA_HOME}" ]; then
+ export JAVA_HOME
+ fi
+ ;;
+AIX)
+ sd_prog1="$sd_prog/../basis-link/program"
+ sd_prog2="$sd_prog/../basis-link/ure-link/lib"
+ LIBPATH=$sd_prog1:$sd_prog2${LIBPATH:+:${LIBPATH}}
+ export LIBPATH
+ ;;
+esac
+
+#collect all bootstrap variables specified on the command line
+#so that they can be passed as arguments to javaldx later on
+#Recognize the "sync" option. sync must be applied without any other
+#options except bootstrap variables or the verbose option
+for arg in $@
+do
+ case "$arg" in
+ -env:*) BOOTSTRAPVARS=$BOOTSTRAPVARS" ""$arg";;
+ sync) OPTSYNC=true;;
+ -v) VERBOSE=true;;
+ --verbose) VERBOSE=true;;
+ *) OPTOTHER=$arg;;
+ esac
+done
+
+if [ "$OPTSYNC" = "true" ] && [ -z "$OPTOTHER" ]
+then
+ JVMFWKPARAMS='-env:UNO_JAVA_JFW_INSTALL_DATA=$OOO_BASE_DIR/share/config/javasettingsunopkginstall.xml -env:JFW_PLUGIN_DO_NOT_CHECK_ACCESSIBILITY=1'
+fi
+
+# extend the ld_library_path for java: javaldx checks the sofficerc for us
+if [ -x "$sd_prog/../basis-link/ure-link/bin/javaldx" ] ; then
+ my_path=`"$sd_prog/../basis-link/ure-link/bin/javaldx" $BOOTSTRAPVARS $JVMFWKPARAMS \
+ "-env:INIFILENAME=vnd.sun.star.pathname:$sd_prog/redirectrc"`
+ if [ -n "$my_path" ] ; then
+ sd_platform=`uname -s`
+ case $sd_platform in
+ AIX)
+ LIBPATH=$my_path${LIBPATH:+:$LIBPATH}
+ export LIBPATH
+ ;;
+ *)
+ LD_LIBRARY_PATH=$my_path${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}
+ export LD_LIBRARY_PATH
+ ;;
+ esac
+ fi
+fi
+
+unset XENVIRONMENT
+
+# uncomment line below to disable anti aliasing of fonts
+# SAL_ANTIALIAS_DISABLE=true; export SAL_ANTIALIAS_DISABLE
+
+# uncomment line below if you encounter problems starting soffice on your system
+# SAL_NO_XINITTHREADS=true; export SAL_NO_XINITTHREADS
+
+# execute binary
+exec "$sd_prog/unopkg.bin" "$@" "$JVMFWKPARAMS" \
+ "-env:INIFILENAME=vnd.sun.star.pathname:$sd_prog/redirectrc"
+
diff --git a/desktop/scripts/ure-link b/desktop/scripts/ure-link
new file mode 100755
index 000000000000..dd0ecb6115e8
--- /dev/null
+++ b/desktop/scripts/ure-link
@@ -0,0 +1 @@
+..\URE \ No newline at end of file
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: */
diff --git a/desktop/test/deployment/active/Addons.xcu b/desktop/test/deployment/active/Addons.xcu
new file mode 100644
index 000000000000..cc75f2ab8f64
--- /dev/null
+++ b/desktop/test/deployment/active/Addons.xcu
@@ -0,0 +1,67 @@
+<?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.
+*
+**********************************************************************-->
+
+<o:component-data xmlns:o="http://openoffice.org/2001/registry"
+ o:package="org.openoffice.Office" o:name="Addons">
+ <node o:name="AddonUI">
+ <node o:name="OfficeMenuBar">
+ <node o:name="org.openoffice.test.desktop.deployment.active"
+ o:op="replace">
+ <prop o:name="Title" xml:lang="en-US">
+ <value>active</value>
+ </prop>
+ <node o:name="Submenu">
+ <node o:name="1" o:op="replace">
+ <prop o:name="URL">
+ <value>vnd.org.openoffice.test.desktop.deployment.active_native:</value>
+ </prop>
+ <prop o:name="Title" xml:lang="en-US">
+ <value>native</value>
+ </prop>
+ </node>
+ <node o:name="2" o:op="replace">
+ <prop o:name="URL">
+ <value>vnd.org.openoffice.test.desktop.deployment.active_java:</value>
+ </prop>
+ <prop o:name="Title" xml:lang="en-US">
+ <value>java</value>
+ </prop>
+ </node>
+ <node o:name="3" o:op="replace">
+ <prop o:name="URL">
+ <value>vnd.org.openoffice.test.desktop.deployment.active_python:</value>
+ </prop>
+ <prop o:name="Title" xml:lang="en-US">
+ <value>python</value>
+ </prop>
+ </node>
+ </node>
+ </node>
+ </node>
+ </node>
+</o:component-data>
diff --git a/desktop/test/deployment/active/Dispatch.java b/desktop/test/deployment/active/Dispatch.java
new file mode 100755
index 000000000000..25443f96e092
--- /dev/null
+++ b/desktop/test/deployment/active/Dispatch.java
@@ -0,0 +1,101 @@
+/*************************************************************************
+* 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.comp.test.deployment.active_java;
+
+import com.sun.star.awt.MessageBoxButtons;
+import com.sun.star.awt.Rectangle;
+import com.sun.star.awt.XMessageBox;
+import com.sun.star.awt.XMessageBoxFactory;
+import com.sun.star.awt.XWindowPeer;
+import com.sun.star.beans.PropertyValue;
+import com.sun.star.frame.DispatchDescriptor;
+import com.sun.star.frame.XDesktop;
+import com.sun.star.frame.XDispatch;
+import com.sun.star.frame.XStatusListener;
+import com.sun.star.lang.WrappedTargetRuntimeException;
+import com.sun.star.lang.XComponent;
+import com.sun.star.lang.XMultiComponentFactory;
+import com.sun.star.lang.XServiceInfo;
+import com.sun.star.lib.uno.helper.WeakBase;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XComponentContext;
+import com.sun.star.util.URL;
+
+public final class Dispatch extends WeakBase implements XServiceInfo, XDispatch
+{
+ public Dispatch(XComponentContext context) {
+ this.context = context;
+ }
+
+ public String getImplementationName() { return implementationName; }
+
+ public boolean supportsService(String ServiceName) {
+ return false; //TODO
+ }
+
+ public String[] getSupportedServiceNames() {
+ return serviceNames;
+ }
+
+ public void dispatch(URL URL, PropertyValue[] Arguments) {
+ try {
+ XMultiComponentFactory smgr = UnoRuntime.queryInterface(
+ XMultiComponentFactory.class, context.getServiceManager());
+ XMessageBox box = UnoRuntime.queryInterface(
+ XMessageBoxFactory.class,
+ smgr.createInstanceWithContext(
+ "com.sun.star.awt.Toolkit", context)).
+ createMessageBox(
+ UnoRuntime.queryInterface(
+ XWindowPeer.class,
+ (UnoRuntime.queryInterface(
+ XDesktop.class,
+ smgr.createInstanceWithContext(
+ "com.sun.star.frame.Desktop", context)).
+ getCurrentFrame().getComponentWindow())),
+ new Rectangle(), "infobox", MessageBoxButtons.BUTTONS_OK,
+ "active", "java");
+ box.execute();
+ UnoRuntime.queryInterface(XComponent.class, box).dispose();
+ } catch (com.sun.star.uno.RuntimeException e) {
+ throw e;
+ } catch (com.sun.star.uno.Exception e) {
+ throw new WrappedTargetRuntimeException(
+ "wrapped: " + e.getMessage(), this, e);
+ }
+ }
+
+ public void addStatusListener(XStatusListener Control, URL URL) {}
+
+ public void removeStatusListener(XStatusListener Control, URL URL) {}
+
+ private final XComponentContext context;
+
+ static final String implementationName =
+ "com.sun.star.comp.test.deployment.active_java_singleton";
+
+ static final String[] serviceNames = new String[0];
+}
diff --git a/desktop/test/deployment/active/MANIFEST.MF b/desktop/test/deployment/active/MANIFEST.MF
new file mode 100755
index 000000000000..63480874dd55
--- /dev/null
+++ b/desktop/test/deployment/active/MANIFEST.MF
@@ -0,0 +1,3 @@
+Sealed: true
+RegistrationClassName: com.sun.star.comp.test.deployment.active_java.Services
+UNO-Type-Path:
diff --git a/desktop/test/deployment/active/ProtocolHandler.xcu b/desktop/test/deployment/active/ProtocolHandler.xcu
new file mode 100644
index 000000000000..017bdea72bea
--- /dev/null
+++ b/desktop/test/deployment/active/ProtocolHandler.xcu
@@ -0,0 +1,48 @@
+<?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.
+*
+**********************************************************************-->
+
+<o:component-data xmlns:o="http://openoffice.org/2001/registry"
+ o:package="org.openoffice.Office" o:name="ProtocolHandler">
+ <node o:name="HandlerSet">
+ <node o:name="com.sun.star.test.deployment.active_native" o:op="replace">
+ <prop o:name="Protocols">
+ <value>vnd.org.openoffice.test.desktop.deployment.active_native:*</value>
+ </prop>
+ </node>
+ <node o:name="com.sun.star.test.deployment.active_java" o:op="replace">
+ <prop o:name="Protocols">
+ <value>vnd.org.openoffice.test.desktop.deployment.active_java:*</value>
+ </prop>
+ </node>
+ <node o:name="com.sun.star.test.deployment.active_python" o:op="replace">
+ <prop o:name="Protocols">
+ <value>vnd.org.openoffice.test.desktop.deployment.active_python:*</value>
+ </prop>
+ </node>
+ </node>
+</o:component-data>
diff --git a/desktop/test/deployment/active/Provider.java b/desktop/test/deployment/active/Provider.java
new file mode 100755
index 000000000000..df31979f4b9d
--- /dev/null
+++ b/desktop/test/deployment/active/Provider.java
@@ -0,0 +1,81 @@
+/*************************************************************************
+* 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.comp.test.deployment.active_java;
+
+import com.sun.star.frame.DispatchDescriptor;
+import com.sun.star.frame.XDispatch;
+import com.sun.star.frame.XDispatchProvider;
+import com.sun.star.lang.XServiceInfo;
+import com.sun.star.lib.uno.helper.WeakBase;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XComponentContext;
+import com.sun.star.util.URL;
+
+public final class Provider extends WeakBase
+ implements XServiceInfo, XDispatchProvider
+{
+ public Provider(XComponentContext context) {
+ this.context = context;
+ }
+
+ public String getImplementationName() { return implementationName; }
+
+ public boolean supportsService(String ServiceName) {
+ return ServiceName.equals(getSupportedServiceNames()[0]); //TODO
+ }
+
+ public String[] getSupportedServiceNames() {
+ return serviceNames;
+ }
+
+ public XDispatch queryDispatch(
+ URL URL, String TargetFrameName, int SearchFlags)
+ {
+ return UnoRuntime.queryInterface(
+ XDispatch.class,
+ context.getValueByName(
+ "/singletons/" +
+ "com.sun.star.test.deployment.active_java_singleton"));
+ }
+
+ public XDispatch[] queryDispatches(DispatchDescriptor[] Requests) {
+ XDispatch[] s = new XDispatch[Requests.length];
+ for (int i = 0; i < s.length; ++i) {
+ s[i] = queryDispatch(
+ Requests[i].FeatureURL, Requests[i].FrameName,
+ Requests[i].SearchFlags);
+ }
+ return s;
+ }
+
+ private final XComponentContext context;
+
+ static final String implementationName =
+ "com.sun.star.comp.test.deployment.active_java";
+
+ static final String[] serviceNames = new String[] {
+ "com.sun.star.test.deployment.active_java" };
+}
diff --git a/desktop/test/deployment/active/Services.java b/desktop/test/deployment/active/Services.java
new file mode 100755
index 000000000000..4ea19f4b7a71
--- /dev/null
+++ b/desktop/test/deployment/active/Services.java
@@ -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.
+************************************************************************/
+
+package com.sun.star.comp.test.deployment.active_java;
+
+import com.sun.star.lang.XSingleComponentFactory;
+import com.sun.star.lib.uno.helper.Factory;
+import com.sun.star.registry.InvalidRegistryException;
+import com.sun.star.registry.XRegistryKey;
+
+public final class Services {
+ private Services() {}
+
+ public static XSingleComponentFactory __getComponentFactory(
+ String implementation)
+ {
+ if (implementation.equals(Dispatch.implementationName)) {
+ return Factory.createComponentFactory(
+ Dispatch.class, Dispatch.implementationName,
+ Dispatch.serviceNames);
+ } else if (implementation.equals(Provider.implementationName)) {
+ return Factory.createComponentFactory(
+ Provider.class, Provider.implementationName,
+ Provider.serviceNames);
+ } else {
+ return null;
+ }
+ }
+
+ public static boolean __writeRegistryServiceInfo(XRegistryKey key) {
+ if (!(Factory.writeRegistryServiceInfo(
+ Dispatch.implementationName, Dispatch.serviceNames, key) &&
+ Factory.writeRegistryServiceInfo(
+ Provider.implementationName, Provider.serviceNames, key)))
+ {
+ return false;
+ }
+ try {
+ key.
+ createKey(
+ "/" + Dispatch.implementationName +
+ "/UNO/SINGLETONS/" +
+ "com.sun.star.test.deployment.active_java_singleton").
+ setStringValue(Dispatch.implementationName);
+ } catch (InvalidRegistryException e) {
+ return false;
+ }
+ return true;
+ }
+}
diff --git a/desktop/test/deployment/active/active_native.cxx b/desktop/test/deployment/active/active_native.cxx
new file mode 100644
index 000000000000..a34d8de88a61
--- /dev/null
+++ b/desktop/test/deployment/active/active_native.cxx
@@ -0,0 +1,320 @@
+/*************************************************************************
+*
+* 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 "boost/noncopyable.hpp"
+#include "com/sun/star/awt/MessageBoxButtons.hpp"
+#include "com/sun/star/awt/Rectangle.hpp"
+#include "com/sun/star/awt/XMessageBox.hpp"
+#include "com/sun/star/awt/XMessageBoxFactory.hpp"
+#include "com/sun/star/awt/XWindowPeer.hpp"
+#include "com/sun/star/beans/PropertyValue.hpp"
+#include "com/sun/star/frame/DispatchDescriptor.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/frame/XFrame.hpp"
+#include "com/sun/star/frame/XStatusListener.hpp"
+#include "com/sun/star/lang/XComponent.hpp"
+#include "com/sun/star/lang/XMultiComponentFactory.hpp"
+#include "com/sun/star/lang/XServiceInfo.hpp"
+#include "com/sun/star/registry/XRegistryKey.hpp"
+#include "com/sun/star/uno/DeploymentException.hpp"
+#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/XComponentContext.hpp"
+#include "com/sun/star/uno/XInterface.hpp"
+#include "com/sun/star/util/URL.hpp"
+#include "cppuhelper/factory.hxx"
+#include "cppuhelper/implbase2.hxx"
+#include "cppuhelper/implementationentry.hxx"
+#include "cppuhelper/weak.hxx"
+#include "osl/diagnose.h"
+#include "rtl/textenc.h"
+#include "rtl/ustring.h"
+#include "rtl/ustring.hxx"
+#include "sal/types.h"
+#include "uno/lbnames.h"
+
+namespace {
+
+namespace css = com::sun::star;
+
+class Provider:
+ public cppu::WeakImplHelper2<
+ css::lang::XServiceInfo, css::frame::XDispatchProvider >,
+ private boost::noncopyable
+{
+public:
+ static css::uno::Reference< css::uno::XInterface > SAL_CALL static_create(
+ css::uno::Reference< css::uno::XComponentContext > const & xContext)
+ SAL_THROW((css::uno::Exception))
+ { return static_cast< cppu::OWeakObject * >(new Provider(xContext)); }
+
+ static rtl::OUString SAL_CALL static_getImplementationName();
+
+ static css::uno::Sequence< rtl::OUString > SAL_CALL
+ static_getSupportedServiceNames();
+
+private:
+ Provider(
+ css::uno::Reference< css::uno::XComponentContext > const & context):
+ context_(context) { OSL_ASSERT(context.is()); }
+
+ virtual ~Provider() {}
+
+ virtual rtl::OUString SAL_CALL getImplementationName()
+ throw (css::uno::RuntimeException)
+ { return static_getImplementationName(); }
+
+ virtual sal_Bool SAL_CALL supportsService(rtl::OUString const & ServiceName)
+ throw (css::uno::RuntimeException)
+ { return ServiceName == getSupportedServiceNames()[0]; } //TODO
+
+ virtual css::uno::Sequence< rtl::OUString > SAL_CALL
+ getSupportedServiceNames() throw (css::uno::RuntimeException)
+ { return static_getSupportedServiceNames(); }
+
+ virtual css::uno::Reference< css::frame::XDispatch > SAL_CALL queryDispatch(
+ css::util::URL const &, rtl::OUString const &, sal_Int32)
+ throw (css::uno::RuntimeException);
+
+ virtual css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > >
+ SAL_CALL queryDispatches(
+ css::uno::Sequence< css::frame::DispatchDescriptor > const & Requests)
+ throw (css::uno::RuntimeException);
+
+ css::uno::Reference< css::uno::XComponentContext > context_;
+};
+
+rtl::OUString Provider::static_getImplementationName() {
+ return rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.comp.test.deployment.active_native"));
+}
+
+css::uno::Sequence< rtl::OUString > Provider::static_getSupportedServiceNames()
+{
+ rtl::OUString name(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.test.deployment.active_native"));
+ return css::uno::Sequence< rtl::OUString >(&name, 1);
+}
+
+css::uno::Reference< css::frame::XDispatch > Provider::queryDispatch(
+ css::util::URL const &, rtl::OUString const &, sal_Int32)
+ throw (css::uno::RuntimeException)
+{
+ css::uno::Reference< css::frame::XDispatch > dispatch;
+ if (!(context_->getValueByName(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "/singletons/com.sun.star.test.deployment."
+ "active_native_singleton"))) >>=
+ dispatch) ||
+ !dispatch.is())
+ {
+ throw css::uno::DeploymentException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "component context fails to supply singleton"
+ " com.sun.star.test.deployment.active_native_singleton of"
+ " type com.sun.star.frame.XDispatch")),
+ context_);
+ }
+ return dispatch;
+}
+
+css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > >
+Provider::queryDispatches(
+ css::uno::Sequence< css::frame::DispatchDescriptor > const & Requests)
+ throw (css::uno::RuntimeException)
+{
+ css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > > s(
+ Requests.getLength());
+ for (sal_Int32 i = 0; i < s.getLength(); ++i) {
+ s[i] = queryDispatch(
+ Requests[i].FeatureURL, Requests[i].FrameName,
+ Requests[i].SearchFlags);
+ }
+ return s;
+}
+
+class Dispatch:
+ public cppu::WeakImplHelper2<
+ css::lang::XServiceInfo, css::frame::XDispatch >,
+ private boost::noncopyable
+{
+public:
+ static css::uno::Reference< css::uno::XInterface > SAL_CALL static_create(
+ css::uno::Reference< css::uno::XComponentContext > const & xContext)
+ SAL_THROW((css::uno::Exception))
+ { return static_cast< cppu::OWeakObject * >(new Dispatch(xContext)); }
+
+ static rtl::OUString SAL_CALL static_getImplementationName();
+
+ static css::uno::Sequence< rtl::OUString > SAL_CALL
+ static_getSupportedServiceNames()
+ { return css::uno::Sequence< rtl::OUString >(); }
+
+private:
+ Dispatch(
+ css::uno::Reference< css::uno::XComponentContext > const & context):
+ context_(context) { OSL_ASSERT(context.is()); }
+
+ virtual ~Dispatch() {}
+
+ virtual rtl::OUString SAL_CALL getImplementationName()
+ throw (css::uno::RuntimeException)
+ { return static_getImplementationName(); }
+
+ virtual sal_Bool SAL_CALL supportsService(rtl::OUString const &)
+ throw (css::uno::RuntimeException)
+ { return false; } //TODO
+
+ virtual css::uno::Sequence< rtl::OUString > SAL_CALL
+ getSupportedServiceNames() throw (css::uno::RuntimeException)
+ { return static_getSupportedServiceNames(); }
+
+ virtual void SAL_CALL dispatch(
+ css::util::URL const &,
+ css::uno::Sequence< css::beans::PropertyValue > const &)
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL addStatusListener(
+ css::uno::Reference< css::frame::XStatusListener > const &,
+ css::util::URL const &)
+ throw (css::uno::RuntimeException)
+ {}
+
+ virtual void SAL_CALL removeStatusListener(
+ css::uno::Reference< css::frame::XStatusListener > const &,
+ css::util::URL const &)
+ throw (css::uno::RuntimeException)
+ {}
+
+ css::uno::Reference< css::uno::XComponentContext > context_;
+};
+
+rtl::OUString Dispatch::static_getImplementationName() {
+ return rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.comp.test.deployment.active_native_singleton"));
+}
+
+void Dispatch::dispatch(
+ css::util::URL const &,
+ css::uno::Sequence< css::beans::PropertyValue > const &)
+ throw (css::uno::RuntimeException)
+{
+ css::uno::Reference< css::lang::XMultiComponentFactory > smgr(
+ context_->getServiceManager(), css::uno::UNO_SET_THROW);
+ css::uno::Reference< css::awt::XMessageBox > box(
+ css::uno::Reference< css::awt::XMessageBoxFactory >(
+ smgr->createInstanceWithContext(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.awt.Toolkit")), context_),
+ css::uno::UNO_QUERY_THROW)->createMessageBox(
+ css::uno::Reference< css::awt::XWindowPeer >(
+ css::uno::Reference< css::frame::XFrame >(
+ css::uno::Reference< css::frame::XDesktop >(
+ smgr->createInstanceWithContext(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.frame.Desktop")),
+ context_),
+ css::uno::UNO_QUERY_THROW)->getCurrentFrame(),
+ css::uno::UNO_SET_THROW)->getComponentWindow(),
+ css::uno::UNO_QUERY_THROW),
+ css::awt::Rectangle(),
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("infobox")),
+ css::awt::MessageBoxButtons::BUTTONS_OK,
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("active")),
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("native"))),
+ css::uno::UNO_SET_THROW);
+ box->execute();
+ css::uno::Reference< css::lang::XComponent >(
+ box, css::uno::UNO_QUERY_THROW)->dispose();
+}
+
+static cppu::ImplementationEntry const services[] = {
+ { &Provider::static_create, &Provider::static_getImplementationName,
+ &Provider::static_getSupportedServiceNames,
+ &cppu::createSingleComponentFactory, 0, 0 },
+ { &Dispatch::static_create, &Dispatch::static_getImplementationName,
+ &Dispatch::static_getSupportedServiceNames,
+ &cppu::createSingleComponentFactory, 0, 0 },
+ { 0, 0, 0, 0, 0, 0 }
+};
+
+}
+
+extern "C" void * SAL_CALL component_getFactory(
+ char const * pImplName, void * pServiceManager, void * pRegistryKey)
+{
+ return cppu::component_getFactoryHelper(
+ pImplName, pServiceManager, pRegistryKey, services);
+}
+
+extern "C" void SAL_CALL component_getImplementationEnvironment(
+ char const ** ppEnvTypeName, uno_Environment **)
+{
+ *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
+}
+
+extern "C" sal_Bool SAL_CALL component_writeInfo(
+ void * pServiceManager, void * pRegistryKey)
+{
+ if (!component_writeInfoHelper(pServiceManager, pRegistryKey, services)) {
+ return false;
+ }
+ try {
+ css::uno::Reference< css::registry::XRegistryKey >(
+ (css::uno::Reference< css::registry::XRegistryKey >(
+ static_cast< css::registry::XRegistryKey * >(pRegistryKey))->
+ createKey(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/")) +
+ Dispatch::static_getImplementationName() +
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "/UNO/SINGLETONS/com.sun.star.test.deployment."
+ "active_native_singleton")))),
+ css::uno::UNO_SET_THROW)->
+ setStringValue(Dispatch::static_getImplementationName());
+ } catch (css::uno::Exception & e) {
+ (void) e;
+ OSL_TRACE(
+ "active_native component_writeInfo exception: %s",
+ rtl::OUStringToOString(e.Message, RTL_TEXTENCODING_UTF8).getStr());
+ return false;
+ }
+ return true;
+}
diff --git a/desktop/test/deployment/active/active_python.py b/desktop/test/deployment/active/active_python.py
new file mode 100755
index 000000000000..8ba0947b6bf8
--- /dev/null
+++ b/desktop/test/deployment/active/active_python.py
@@ -0,0 +1,120 @@
+#*************************************************************************
+#
+# 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.
+#
+#***********************************************************************/
+
+import uno
+import unohelper
+
+from com.sun.star.awt import Rectangle
+from com.sun.star.awt.MessageBoxButtons import BUTTONS_OK
+from com.sun.star.frame import XDispatch, XDispatchProvider
+from com.sun.star.lang import XServiceInfo
+from com.sun.star.registry import InvalidRegistryException
+
+class Provider(unohelper.Base, XServiceInfo, XDispatchProvider):
+ implementationName = "com.sun.star.comp.test.deployment.active_python"
+
+ serviceNames = ("com.sun.star.test.deployment.active_python",)
+
+ def __init__(self, context):
+ self.context = context
+
+ def getImplementationName(self):
+ return self.implementationName
+
+ def supportsService(self, ServiceName):
+ return ServiceName in self.serviceNames
+
+ def getSupportedServiceNames(self):
+ return self.serviceNames
+
+ def queryDispatch(self, URL, TargetFrame, SearchFlags):
+ return self.context.getValueByName( \
+ "/singletons/com.sun.star.test.deployment.active_python_singleton")
+
+ def queryDispatches(self, Requests):
+ tuple( \
+ self.queryDispatch(i.FeatureURL, i.FrameName, i.SearchFlags) \
+ for i in Requests)
+
+class Dispatch(unohelper.Base, XServiceInfo, XDispatch):
+ implementationName = \
+ "com.sun.star.comp.test.deployment.active_python_singleton"
+
+ serviceNames = ()
+
+ def __init__(self, context):
+ self.context = context
+
+ def getImplementationName(self):
+ return self.implementationName
+
+ def supportsService(self, ServiceName):
+ return ServiceName in self.serviceNames
+
+ def getSupportedServiceNames(self):
+ return self.serviceNames
+
+ def dispatch(self, URL, Arguments):
+ smgr = self.context.getServiceManager()
+ box = smgr.createInstanceWithContext( \
+ "com.sun.star.awt.Toolkit", self.context).createMessageBox( \
+ smgr.createInstanceWithContext( \
+ "com.sun.star.frame.Desktop", self.context). \
+ getCurrentFrame().getComponentWindow(), \
+ Rectangle(), "infobox", BUTTONS_OK, "active", "python")
+ box.execute();
+ box.dispose();
+
+ def addStatusListener(self, Control, URL):
+ pass
+
+ def removeStatusListener(self, Control, URL):
+ pass
+
+def getComponentFactory(implementationName, smgr, regKey):
+ if implementationName == Provider.implementationName:
+ return unohelper.createSingleServiceFactory( \
+ Provider, Provider.implementationName, Provider.serviceNames)
+ elif implementationName == Dispatch.implementationName:
+ return unohelper.createSingleServiceFactory( \
+ Dispatch, Dispatch.implementationName, Dispatch.serviceNames)
+ else:
+ return None
+
+def writeRegistryInfo(smgr, regKey):
+ try:
+ for i in (Provider, Dispatch):
+ key = regKey.createKey("/" + i.implementationName + "/UNO")
+ for j in i.serviceNames:
+ key.createKey("/SERVICES/" + j);
+ regKey.createKey( \
+ "/" + Dispatch.implementationName + "/UNO/SINGLETONS/" \
+ "com.sun.star.test.deployment.active_python_singleton"). \
+ setStringValue(Dispatch.implementationName)
+ except InvalidRegistryException:
+ return False
+ return True
diff --git a/desktop/test/deployment/active/description.xml b/desktop/test/deployment/active/description.xml
new file mode 100755
index 000000000000..fd7049e0cc3d
--- /dev/null
+++ b/desktop/test/deployment/active/description.xml
@@ -0,0 +1,36 @@
+<?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.
+*
+**********************************************************************-->
+
+<d:description xmlns:d="http://openoffice.org/extensions/description/2006">
+ <d:identifier
+ value="org.openoffice/framework/desktop/test/deployment/active"/>
+ <d:version value="1"/>
+ <d:dependencies>
+ <d:OpenOffice.org-minimal-version d:name="OpenOffice.org 3.4" value="3.4"/>
+ </d:dependencies>
+</d:description>
diff --git a/desktop/test/deployment/active/makefile.mk b/desktop/test/deployment/active/makefile.mk
new file mode 100755
index 000000000000..05c19eb236e3
--- /dev/null
+++ b/desktop/test/deployment/active/makefile.mk
@@ -0,0 +1,87 @@
+#*************************************************************************
+#
+# 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 = test_deployment_active
+
+ENABLE_EXCEPTIONS = TRUE
+
+PACKAGE = com/sun/star/comp/test/deployment/active_java
+JAVAFILES = Dispatch.java Provider.java Services.java
+JARFILES = juh.jar ridl.jar unoil.jar
+
+.INCLUDE: settings.mk
+
+DLLPRE =
+
+SLOFILES = $(SHL1OBJS)
+
+SHL1TARGET = active_native.uno
+SHL1OBJS = $(SLO)/active_native.obj
+SHL1RPATH = OXT
+SHL1STDLIBS = $(CPPUHELPERLIB) $(CPPULIB) $(SALLIB)
+SHL1VERSIONMAP = $(SOLARENV)/src/reg-component.map
+DEF1NAME = $(SHL1TARGET)
+
+.INCLUDE: target.mk
+
+.IF "$(SOLAR_JAVA)" != ""
+
+ALLTAR : $(MISC)/active.oxt
+
+$(MISC)/active.oxt : manifest.xml description.xml Addons.xcu \
+ ProtocolHandler.xcu $(SHL1TARGETN) $(MISC)/$(TARGET)/active_java.jar \
+ active_python.py
+ $(RM) $@
+ $(RM) -r $(MISC)/$(TARGET)/active.oxt-zip
+ $(MKDIR) $(MISC)/$(TARGET)/active.oxt-zip
+ $(MKDIRHIER) $(MISC)/$(TARGET)/active.oxt-zip/META-INF
+ $(SED) -e 's|@PATH@|$(SHL1TARGETN:f)|g' \
+ -e 's|@PLATFORM@|$(RTL_OS:l)_$(RTL_ARCH:l)|g' < manifest.xml \
+ > $(MISC)/$(TARGET)/active.oxt-zip/META-INF/manifest.xml
+ $(COPY) description.xml Addons.xcu ProtocolHandler.xcu $(SHL1TARGETN) \
+ $(MISC)/$(TARGET)/active_java.jar active_python.py \
+ $(MISC)/$(TARGET)/active.oxt-zip/
+ cd $(MISC)/$(TARGET)/active.oxt-zip && zip ../../active.oxt \
+ META-INF/manifest.xml description.xml Addons.xcu ProtocolHandler.xcu \
+ $(SHL1TARGETN:f) active_java.jar active_python.py
+
+$(MISC)/$(TARGET)/active_java.jar : MANIFEST.MF $(JAVATARGET)
+ $(MKDIRHIER) $(@:d)
+ $(RM) $@
+ $(RM) -r $(MISC)/$(TARGET)/active_java.jar-zip
+ $(MKDIR) $(MISC)/$(TARGET)/active_java.jar-zip
+ $(MKDIRHIER) $(MISC)/$(TARGET)/active_java.jar-zip/META-INF \
+ $(MISC)/$(TARGET)/active_java.jar-zip/$(PACKAGE)
+ $(COPY) MANIFEST.MF $(MISC)/$(TARGET)/active_java.jar-zip/META-INF/
+ $(COPY) $(foreach,i,$(JAVAFILES:b) $(CLASSDIR)/$(PACKAGE)/$i.class) \
+ $(MISC)/$(TARGET)/active_java.jar-zip/$(PACKAGE)/
+ cd $(MISC)/$(TARGET)/active_java.jar-zip && zip ../active_java.jar \
+ META-INF/MANIFEST.MF $(foreach,i,$(JAVAFILES:b) $(PACKAGE)/$i.class)
+
+.ENDIF
diff --git a/desktop/test/deployment/active/manifest.xml b/desktop/test/deployment/active/manifest.xml
new file mode 100755
index 000000000000..4f076696663b
--- /dev/null
+++ b/desktop/test/deployment/active/manifest.xml
@@ -0,0 +1,43 @@
+<?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.
+*
+**********************************************************************-->
+
+<m:manifest xmlns:m="http://openoffice.org/2001/manifest">
+ <m:file-entry m:media-type="application/vnd.sun.star.configuration-data"
+ m:full-path="Addons.xcu"/>
+ <m:file-entry m:media-type="application/vnd.sun.star.configuration-data"
+ m:full-path="ProtocolHandler.xcu"/>
+ <m:file-entry
+ m:media-type="application/vnd.sun.star.uno-component;type=native;platform=@PLATFORM@"
+ m:full-path="@PATH@"/>
+ <m:file-entry
+ m:media-type="application/vnd.sun.star.uno-component;type=Java"
+ m:full-path="active_java.jar"/>
+ <m:file-entry
+ m:media-type="application/vnd.sun.star.uno-component;type=Python"
+ m:full-path="active_python.py"/>
+</m:manifest>
diff --git a/desktop/test/deployment/boxt/Addons.xcu b/desktop/test/deployment/boxt/Addons.xcu
new file mode 100644
index 000000000000..3df7e2de274c
--- /dev/null
+++ b/desktop/test/deployment/boxt/Addons.xcu
@@ -0,0 +1,50 @@
+<?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.
+*
+**********************************************************************-->
+
+<o:component-data xmlns:o="http://openoffice.org/2001/registry"
+ o:package="org.openoffice.Office" o:name="Addons">
+ <node o:name="AddonUI">
+ <node o:name="OfficeMenuBar">
+ <node o:name="org.openoffice.test.desktop.deployment.boxt" o:op="replace">
+ <prop o:name="Title" xml:lang="en-US">
+ <value>boxt</value>
+ </prop>
+ <node o:name="Submenu">
+ <node o:name="1" o:op="replace">
+ <prop o:name="URL">
+ <value>vnd.org.openoffice.test.desktop.deployment.boxt:</value>
+ </prop>
+ <prop o:name="Title" xml:lang="en-US">
+ <value>boxt</value>
+ </prop>
+ </node>
+ </node>
+ </node>
+ </node>
+ </node>
+</o:component-data>
diff --git a/desktop/test/deployment/boxt/ProtocolHandler.xcu b/desktop/test/deployment/boxt/ProtocolHandler.xcu
new file mode 100644
index 000000000000..fe448aedbe17
--- /dev/null
+++ b/desktop/test/deployment/boxt/ProtocolHandler.xcu
@@ -0,0 +1,38 @@
+<?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.
+*
+**********************************************************************-->
+
+<o:component-data xmlns:o="http://openoffice.org/2001/registry"
+ o:package="org.openoffice.Office" o:name="ProtocolHandler">
+ <node o:name="HandlerSet">
+ <node o:name="com.sun.star.test.deployment.boxt" o:op="replace">
+ <prop o:name="Protocols">
+ <value>vnd.org.openoffice.test.desktop.deployment.boxt:*</value>
+ </prop>
+ </node>
+ </node>
+</o:component-data>
diff --git a/desktop/test/deployment/boxt/boxt.cxx b/desktop/test/deployment/boxt/boxt.cxx
new file mode 100644
index 000000000000..f0b706bc647a
--- /dev/null
+++ b/desktop/test/deployment/boxt/boxt.cxx
@@ -0,0 +1,190 @@
+/* -*- 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 "boost/noncopyable.hpp"
+#include "com/sun/star/beans/PropertyValue.hpp"
+#include "com/sun/star/frame/DispatchDescriptor.hpp"
+#include "com/sun/star/frame/XDispatch.hpp"
+#include "com/sun/star/frame/XDispatchProvider.hpp"
+#include "com/sun/star/frame/XStatusListener.hpp"
+#include "com/sun/star/lang/XServiceInfo.hpp"
+#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/XComponentContext.hpp"
+#include "com/sun/star/uno/XInterface.hpp"
+#include "com/sun/star/util/URL.hpp"
+#include "cppuhelper/factory.hxx"
+#include "cppuhelper/implbase3.hxx"
+#include "cppuhelper/implementationentry.hxx"
+#include "cppuhelper/weak.hxx"
+#include "filter/msfilter/countryid.hxx"
+#include "osl/diagnose.h"
+#include "rtl/ustring.h"
+#include "rtl/ustring.hxx"
+#include "sal/types.h"
+#include "uno/lbnames.h"
+#include "vcl/svapp.hxx"
+
+namespace {
+
+namespace css = com::sun::star;
+
+class Service:
+ public cppu::WeakImplHelper3<
+ css::lang::XServiceInfo, css::frame::XDispatchProvider,
+ css::frame::XDispatch >,
+ private boost::noncopyable
+{
+public:
+ static css::uno::Reference< css::uno::XInterface > SAL_CALL static_create(
+ css::uno::Reference< css::uno::XComponentContext > const &)
+ SAL_THROW((css::uno::Exception))
+ { return static_cast< cppu::OWeakObject * >(new Service); }
+
+ static rtl::OUString SAL_CALL static_getImplementationName();
+
+ static css::uno::Sequence< rtl::OUString > SAL_CALL
+ static_getSupportedServiceNames();
+
+private:
+ Service() {}
+
+ virtual ~Service() {}
+
+ virtual rtl::OUString SAL_CALL getImplementationName()
+ throw (css::uno::RuntimeException)
+ { return static_getImplementationName(); }
+
+ virtual sal_Bool SAL_CALL supportsService(rtl::OUString const & ServiceName)
+ throw (css::uno::RuntimeException)
+ { return ServiceName == getSupportedServiceNames()[0]; } //TODO
+
+ virtual css::uno::Sequence< rtl::OUString > SAL_CALL
+ getSupportedServiceNames() throw (css::uno::RuntimeException)
+ { return static_getSupportedServiceNames(); }
+
+ virtual css::uno::Reference< css::frame::XDispatch > SAL_CALL queryDispatch(
+ css::util::URL const &, rtl::OUString const &, sal_Int32)
+ throw (css::uno::RuntimeException)
+ { return this; }
+
+ virtual css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > >
+ SAL_CALL queryDispatches(
+ css::uno::Sequence< css::frame::DispatchDescriptor > const & Requests)
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL dispatch(
+ css::util::URL const &,
+ css::uno::Sequence< css::beans::PropertyValue > const &)
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL addStatusListener(
+ css::uno::Reference< css::frame::XStatusListener > const &,
+ css::util::URL const &)
+ throw (css::uno::RuntimeException)
+ {}
+
+ virtual void SAL_CALL removeStatusListener(
+ css::uno::Reference< css::frame::XStatusListener > const &,
+ css::util::URL const &)
+ throw (css::uno::RuntimeException)
+ {}
+};
+
+rtl::OUString Service::static_getImplementationName() {
+ return rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.test.deployment.boxt"));
+}
+
+css::uno::Sequence< rtl::OUString > Service::static_getSupportedServiceNames() {
+ rtl::OUString name(
+ RTL_CONSTASCII_USTRINGPARAM("com.sun.star.test.deployment.boxt"));
+ return css::uno::Sequence< rtl::OUString >(&name, 1);
+}
+
+css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > >
+Service::queryDispatches(
+ css::uno::Sequence< css::frame::DispatchDescriptor > const & Requests)
+ throw (css::uno::RuntimeException)
+{
+ css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > > s(
+ Requests.getLength());
+ for (sal_Int32 i = 0; i < s.getLength(); ++i) {
+ s[i] = queryDispatch(
+ Requests[i].FeatureURL, Requests[i].FrameName,
+ Requests[i].SearchFlags);
+ }
+ return s;
+}
+
+void Service::dispatch(
+ css::util::URL const &,
+ css::uno::Sequence< css::beans::PropertyValue > const &)
+ throw (css::uno::RuntimeException)
+{
+ msfilter::ConvertCountryToLanguage(msfilter::COUNTRY_DONTKNOW);
+ // link against some obscure library that is unlikely already loaded
+ Application::ShowNativeErrorBox(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("boxt")),
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("test")));
+}
+
+static cppu::ImplementationEntry const services[] = {
+ { &Service::static_create, &Service::static_getImplementationName,
+ &Service::static_getSupportedServiceNames,
+ &cppu::createSingleComponentFactory, 0, 0 },
+ { 0, 0, 0, 0, 0, 0 }
+};
+
+}
+
+extern "C" void * SAL_CALL component_getFactory(
+ char const * pImplName, void * pServiceManager, void * pRegistryKey)
+{
+ return cppu::component_getFactoryHelper(
+ pImplName, pServiceManager, pRegistryKey, services);
+}
+
+extern "C" void SAL_CALL component_getImplementationEnvironment(
+ char const ** ppEnvTypeName, uno_Environment **)
+{
+ *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
+}
+
+extern "C" sal_Bool SAL_CALL component_writeInfo(
+ void * pServiceManager, void * pRegistryKey)
+{
+ return component_writeInfoHelper(pServiceManager, pRegistryKey, services);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/test/deployment/boxt/description.xml b/desktop/test/deployment/boxt/description.xml
new file mode 100755
index 000000000000..5a67bf3e949f
--- /dev/null
+++ b/desktop/test/deployment/boxt/description.xml
@@ -0,0 +1,39 @@
+<?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.
+*
+**********************************************************************-->
+
+<d:description xmlns:d="http://openoffice.org/extensions/description/2006">
+ <d:identifier value="org.openoffice/framework/desktop/test/deployment/boxt"/>
+ <d:version value="@VERSION@"/>
+ <d:platform value="@PLATFORM@"/>
+ <d:dependencies>
+ <d:OpenOffice.org-minimal-version d:name="OpenOffice.org @VERSION@"
+ value="@VERSION@"/>
+ <d:OpenOffice.org-maximal-version d:name="OpenOffice.org @VERSION@ or older"
+ d:OpenOffice.org-minimal-version="2.3" value="@VERSION@"/>
+ </d:dependencies>
+</d:description>
diff --git a/desktop/test/deployment/boxt/makefile.mk b/desktop/test/deployment/boxt/makefile.mk
new file mode 100755
index 000000000000..88e72aef4ab8
--- /dev/null
+++ b/desktop/test/deployment/boxt/makefile.mk
@@ -0,0 +1,68 @@
+#*************************************************************************
+#
+# 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 = test_deployment_boxt
+
+ENABLE_EXCEPTIONS = TRUE
+
+.INCLUDE: settings.mk
+.INCLUDE: rtlbootstrap.mk
+.INCLUDE: versionlist.mk
+
+my_version = $(OOOBASEVERSIONMAJOR).$(OOOBASEVERSIONMINOR)
+
+DLLPRE =
+
+SLOFILES = $(SHL1OBJS)
+
+SHL1TARGET = boxt.uno
+SHL1OBJS = $(SLO)/boxt.obj
+SHL1RPATH = BOXT
+SHL1STDLIBS = \
+ $(CPPUHELPERLIB) $(CPPULIB) $(MSFILTERLIB) $(SALLIB) $(TOOLSLIB) $(VCLLIB)
+SHL1VERSIONMAP = $(SOLARENV)/src/reg-component.map
+DEF1NAME = $(SHL1TARGET)
+
+.INCLUDE: target.mk
+
+ALLTAR : $(MISC)/boxt.oxt
+
+$(MISC)/boxt.oxt .ERRREMOVE : manifest.xml description.xml Addons.xcu \
+ ProtocolHandler.xcu $(SHL1TARGETN)
+ $(RM) -r $@ $(MISC)/$(TARGET).zip
+ $(MKDIR) $(MISC)/$(TARGET).zip
+ $(MKDIR) $(MISC)/$(TARGET).zip/META-INF
+ $(SED) -e 's|@PATH@|$(SHL1TARGETN:f)|g' < manifest.xml \
+ > $(MISC)/$(TARGET).zip/META-INF/manifest.xml
+ $(SED) -e 's|@PLATFORM@|$(RTL_OS:l)_$(RTL_ARCH:l)|g' \
+ -e 's|@VERSION@|$(my_version)|g' < description.xml \
+ > $(MISC)/$(TARGET).zip/description.xml
+ $(COPY) Addons.xcu ProtocolHandler.xcu $(SHL1TARGETN) $(MISC)/$(TARGET).zip
+ cd $(MISC)/$(TARGET).zip && zip ../boxt.oxt META-INF/manifest.xml \
+ description.xml Addons.xcu ProtocolHandler.xcu $(SHL1TARGETN:f)
diff --git a/desktop/test/deployment/boxt/manifest.xml b/desktop/test/deployment/boxt/manifest.xml
new file mode 100755
index 000000000000..73ebfc306e30
--- /dev/null
+++ b/desktop/test/deployment/boxt/manifest.xml
@@ -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.
+*
+**********************************************************************-->
+
+<m:manifest xmlns:m="http://openoffice.org/2001/manifest">
+ <m:file-entry m:media-type="application/vnd.sun.star.configuration-data"
+ m:full-path="Addons.xcu"/>
+ <m:file-entry m:media-type="application/vnd.sun.star.configuration-data"
+ m:full-path="ProtocolHandler.xcu"/>
+ <m:file-entry
+ m:media-type="application/vnd.sun.star.uno-component;type=native"
+ m:full-path="@PATH@"/>
+</m:manifest>
diff --git a/desktop/test/deployment/dependencies/broken-dependency.oxt b/desktop/test/deployment/dependencies/broken-dependency.oxt
new file mode 100644
index 000000000000..11bab0a95092
--- /dev/null
+++ b/desktop/test/deployment/dependencies/broken-dependency.oxt
Binary files differ
diff --git a/desktop/test/deployment/dependencies/double-dependencies.oxt b/desktop/test/deployment/dependencies/double-dependencies.oxt
new file mode 100644
index 000000000000..055c27ea53ba
--- /dev/null
+++ b/desktop/test/deployment/dependencies/double-dependencies.oxt
Binary files differ
diff --git a/desktop/test/deployment/dependencies/empty-dependencies.oxt b/desktop/test/deployment/dependencies/empty-dependencies.oxt
new file mode 100644
index 000000000000..ebb18dcbf51b
--- /dev/null
+++ b/desktop/test/deployment/dependencies/empty-dependencies.oxt
Binary files differ
diff --git a/desktop/test/deployment/dependencies/funny-dependency.oxt b/desktop/test/deployment/dependencies/funny-dependency.oxt
new file mode 100644
index 000000000000..9b683e6d1e4b
--- /dev/null
+++ b/desktop/test/deployment/dependencies/funny-dependency.oxt
Binary files differ
diff --git a/desktop/test/deployment/dependencies/license-dependency.oxt b/desktop/test/deployment/dependencies/license-dependency.oxt
new file mode 100644
index 000000000000..b01da4b5ca8a
--- /dev/null
+++ b/desktop/test/deployment/dependencies/license-dependency.oxt
Binary files differ
diff --git a/desktop/test/deployment/dependencies/many-dependencies.oxt b/desktop/test/deployment/dependencies/many-dependencies.oxt
new file mode 100644
index 000000000000..367568143778
--- /dev/null
+++ b/desktop/test/deployment/dependencies/many-dependencies.oxt
Binary files differ
diff --git a/desktop/test/deployment/dependencies/minattr22.oxt b/desktop/test/deployment/dependencies/minattr22.oxt
new file mode 100644
index 000000000000..a6c8e3758cf4
--- /dev/null
+++ b/desktop/test/deployment/dependencies/minattr22.oxt
Binary files differ
diff --git a/desktop/test/deployment/dependencies/minattr23.oxt b/desktop/test/deployment/dependencies/minattr23.oxt
new file mode 100644
index 000000000000..83d17938c425
--- /dev/null
+++ b/desktop/test/deployment/dependencies/minattr23.oxt
Binary files differ
diff --git a/desktop/test/deployment/dependencies/minattr24.oxt b/desktop/test/deployment/dependencies/minattr24.oxt
new file mode 100644
index 000000000000..00f053f487ec
--- /dev/null
+++ b/desktop/test/deployment/dependencies/minattr24.oxt
Binary files differ
diff --git a/desktop/test/deployment/dependencies/no-dependencies.oxt b/desktop/test/deployment/dependencies/no-dependencies.oxt
new file mode 100644
index 000000000000..6487eb66ae14
--- /dev/null
+++ b/desktop/test/deployment/dependencies/no-dependencies.oxt
Binary files differ
diff --git a/desktop/test/deployment/dependencies/no-description.oxt b/desktop/test/deployment/dependencies/no-description.oxt
new file mode 100644
index 000000000000..1e6579cd7dd4
--- /dev/null
+++ b/desktop/test/deployment/dependencies/no-description.oxt
Binary files differ
diff --git a/desktop/test/deployment/dependencies/readme.txt b/desktop/test/deployment/dependencies/readme.txt
new file mode 100755
index 000000000000..a99fade00225
--- /dev/null
+++ b/desktop/test/deployment/dependencies/readme.txt
@@ -0,0 +1,82 @@
+#*************************************************************************
+#
+# 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.
+#
+#*************************************************************************
+
+no-description.oxt, no-dependencies.oxt, empty-dependencies.oxt effectively have
+no dependencies and should thus install successfully.
+
+broken-dependencies.oxt contains a malformed description.xml and should thus
+display an error and not install.
+
+double-dependencies.oxt contains a description.xml with two dependencies
+elements. This is not allowed by the spec but behaviour is unspecified. In the
+current implementation, it combines the two elements, and thus finds two
+unsatisfied dependencies, displays the Unsatisfied Dependencies dialog and does
+not install.
+
+version21.oxt contains a dependency on OOo 2.1 (and should thus only install in
+OOo 2.1 or later); version21ns.oxt is the same, but with a different way of
+using XML namespaces; version21other.oxt additionally contains an unsatisfied
+dependency (and should thus not install in any OOo version). version22.oxt
+contains a dependency on OOo 2.2 (and should thus only install in OOo 2.2 or
+later). version23.oxt contains a dependency on OOo 2.3 (and should thus only
+install in OOo 2.3 or later). version10000.oxt contains a dependency on the
+hypothetical OOo version 10000 (and should thus not install in any OOo version).
+versionempty.oxt contains an empty value attribute and versionnone.oxt lacks the
+value attribute; neither is allowed by the spec, but the current implementation
+treats both as pre OOo 2.1 versions (and the extensions should thus install in
+OOo 2.1 or later).
+
+maxversion30.oxt contains a maximal version dependency on OOo 3.0 (and should
+thus only install in OOo 3.0 or earlier, back to OOo 2.3, thanks to the
+additionally specified OpenOffice.org-minimal-version attribute).
+maxversion10000.oxt contains a maximal version dependency on the hypothetical
+OOo version 10000 (and should thus install in any OOo version 3.1 or later;
+OpenOffice.org-maximal-version was introduced in OOo 3.1, and no OpenOffice.org-
+minimal-version attribute is specified). bad-minmaxversion.oxt contains a
+minimal version dependency on OOo 3.2 and a maximal version dependency on
+OOo 3.1 (and should thus not install in any OOo version).
+
+minattr22.oxt contains a (hypothetical, most probably never satisfied)
+UNSATISFIED dependency with an OpenOffice.org-minimal-version attribute of
+"2.2" (and should thus install in OOo 2.3 or later); minattr23.oxt is similar,
+but with an OpenOffice.org-minimal-version attribute of "2.3" (and should thus
+also install in OOo 2.3 or later); minattr24.oxt is similar, but with an
+OpenOffice.org-minimal-version attribute of "2.4" (and should thus only install
+in OOo 2.4 or later).
+
+All of the following testcases should result in the Unsatisfied Dependencies
+dialog being displayed and the extension not being installed:
+
+unknown-dependency.oxt contains a dependency without a name attribute, and
+should thus display "Unknown" (localized).
+
+funny-dependency.oxt, many-dependencies.oxt contain somewhat extreme input.
+
+license-dependency.oxt contains both a license to be accepted by the user and
+dependencies. What is important here is that the Unsatisfied Dependencies
+dialog is displayed, but not the license (as installation aborts as soon as
+unsatisfied dependencies are found).
diff --git a/desktop/test/deployment/dependencies/unknown-dependency.oxt b/desktop/test/deployment/dependencies/unknown-dependency.oxt
new file mode 100644
index 000000000000..7c2a22c6d5da
--- /dev/null
+++ b/desktop/test/deployment/dependencies/unknown-dependency.oxt
Binary files differ
diff --git a/desktop/test/deployment/dependencies/version10000.oxt b/desktop/test/deployment/dependencies/version10000.oxt
new file mode 100644
index 000000000000..c15b7a117c8c
--- /dev/null
+++ b/desktop/test/deployment/dependencies/version10000.oxt
Binary files differ
diff --git a/desktop/test/deployment/dependencies/version21.oxt b/desktop/test/deployment/dependencies/version21.oxt
new file mode 100644
index 000000000000..922b2795555c
--- /dev/null
+++ b/desktop/test/deployment/dependencies/version21.oxt
Binary files differ
diff --git a/desktop/test/deployment/dependencies/version21ns.oxt b/desktop/test/deployment/dependencies/version21ns.oxt
new file mode 100644
index 000000000000..5efb2ed90220
--- /dev/null
+++ b/desktop/test/deployment/dependencies/version21ns.oxt
Binary files differ
diff --git a/desktop/test/deployment/dependencies/version21other.oxt b/desktop/test/deployment/dependencies/version21other.oxt
new file mode 100644
index 000000000000..d88a8155af65
--- /dev/null
+++ b/desktop/test/deployment/dependencies/version21other.oxt
Binary files differ
diff --git a/desktop/test/deployment/dependencies/version22.oxt b/desktop/test/deployment/dependencies/version22.oxt
new file mode 100644
index 000000000000..4c8a207b68ba
--- /dev/null
+++ b/desktop/test/deployment/dependencies/version22.oxt
Binary files differ
diff --git a/desktop/test/deployment/dependencies/version23.oxt b/desktop/test/deployment/dependencies/version23.oxt
new file mode 100644
index 000000000000..6c08d2949ced
--- /dev/null
+++ b/desktop/test/deployment/dependencies/version23.oxt
Binary files differ
diff --git a/desktop/test/deployment/dependencies/versionempty.oxt b/desktop/test/deployment/dependencies/versionempty.oxt
new file mode 100644
index 000000000000..a06bb01294f4
--- /dev/null
+++ b/desktop/test/deployment/dependencies/versionempty.oxt
Binary files differ
diff --git a/desktop/test/deployment/dependencies/versionnone.oxt b/desktop/test/deployment/dependencies/versionnone.oxt
new file mode 100644
index 000000000000..ace2a11651ff
--- /dev/null
+++ b/desktop/test/deployment/dependencies/versionnone.oxt
Binary files differ
diff --git a/desktop/test/deployment/description/desc1.oxt b/desktop/test/deployment/description/desc1.oxt
new file mode 100644
index 000000000000..e447fd6eae78
--- /dev/null
+++ b/desktop/test/deployment/description/desc1.oxt
Binary files differ
diff --git a/desktop/test/deployment/description/desc2.oxt b/desktop/test/deployment/description/desc2.oxt
new file mode 100644
index 000000000000..8df2f33fa6de
--- /dev/null
+++ b/desktop/test/deployment/description/desc2.oxt
Binary files differ
diff --git a/desktop/test/deployment/description/desc3.oxt b/desktop/test/deployment/description/desc3.oxt
new file mode 100644
index 000000000000..fbd1136b039a
--- /dev/null
+++ b/desktop/test/deployment/description/desc3.oxt
Binary files differ
diff --git a/desktop/test/deployment/description/desc4.oxt b/desktop/test/deployment/description/desc4.oxt
new file mode 100644
index 000000000000..0c97f5fd4426
--- /dev/null
+++ b/desktop/test/deployment/description/desc4.oxt
Binary files differ
diff --git a/desktop/test/deployment/description/desc5.oxt b/desktop/test/deployment/description/desc5.oxt
new file mode 100644
index 000000000000..8110073499ca
--- /dev/null
+++ b/desktop/test/deployment/description/desc5.oxt
Binary files differ
diff --git a/desktop/test/deployment/description/readme.txt b/desktop/test/deployment/description/readme.txt
new file mode 100755
index 000000000000..bb133ba516ce
--- /dev/null
+++ b/desktop/test/deployment/description/readme.txt
@@ -0,0 +1,23 @@
+The folder contains extensions which use in the description.xml the following:
+-The <extension-description> element The element contains localized child
+elements.
+
+The following table shows what localized item is used, when the Office the locale
+en-US uses. The displayed extension description contains the locale.
+
+
+Localization:
+
+Installed office: en-US
+ | locale
+=========================
+desc1.oxt | en-US
+-------------------------
+desc2.oxt | en-US-region1
+--------------------------
+desc3.oxt | en
+--------------------------
+desc4.oxt | en-GB
+--------------------------
+desc5.oxt | de
+
diff --git a/desktop/test/deployment/display_name/name1.oxt b/desktop/test/deployment/display_name/name1.oxt
new file mode 100644
index 000000000000..5a53690d6935
--- /dev/null
+++ b/desktop/test/deployment/display_name/name1.oxt
Binary files differ
diff --git a/desktop/test/deployment/display_name/name2.oxt b/desktop/test/deployment/display_name/name2.oxt
new file mode 100644
index 000000000000..f6cbcae3bcbd
--- /dev/null
+++ b/desktop/test/deployment/display_name/name2.oxt
Binary files differ
diff --git a/desktop/test/deployment/display_name/name3.oxt b/desktop/test/deployment/display_name/name3.oxt
new file mode 100644
index 000000000000..8df750ce62a5
--- /dev/null
+++ b/desktop/test/deployment/display_name/name3.oxt
Binary files differ
diff --git a/desktop/test/deployment/display_name/name4.oxt b/desktop/test/deployment/display_name/name4.oxt
new file mode 100644
index 000000000000..6ce4822e3701
--- /dev/null
+++ b/desktop/test/deployment/display_name/name4.oxt
Binary files differ
diff --git a/desktop/test/deployment/display_name/name5.oxt b/desktop/test/deployment/display_name/name5.oxt
new file mode 100644
index 000000000000..56973be7817b
--- /dev/null
+++ b/desktop/test/deployment/display_name/name5.oxt
Binary files differ
diff --git a/desktop/test/deployment/display_name/readme.txt b/desktop/test/deployment/display_name/readme.txt
new file mode 100755
index 000000000000..23173bde63dd
--- /dev/null
+++ b/desktop/test/deployment/display_name/readme.txt
@@ -0,0 +1,26 @@
+The folder contains extensions which use in the description.xml the following:
+-The <display-name> element
+The element contains localized child elements.
+
+To test the display name in the update dialog use the extensions in
+desktop/test/deployment/update/simple
+
+
+The following table shows what localized item is used, when the Office the locale
+en-US uses.
+
+
+Localization:
+
+Installed office: en-US
+ | publisher | release notes
+=============================================
+name1.oxt | en-US | en-US
+---------------------------------------------
+name2.oxt | en-US-region1 | en-US-region1
+---------------------------------------------
+name3.oxt | en | en
+---------------------------------------------
+name4.oxt | en-GB | en-GB
+---------------------------------------------
+name5.oxt | de | de
diff --git a/desktop/test/deployment/executable_content/build/hello.c b/desktop/test/deployment/executable_content/build/hello.c
new file mode 100755
index 000000000000..4af0b02ff888
--- /dev/null
+++ b/desktop/test/deployment/executable_content/build/hello.c
@@ -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 <stdio.h>
+
+int main(int argc , char** argv, char** envp)
+{
+ //prevent warning about unused parameters
+ //we need to provide parameter names in C
+ (void)argc;
+ (void)argv;
+ (void)envp;
+
+ fprintf(stdout,"Hello world!\n");
+ return 0;
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/test/deployment/executable_content/build/makefile.mk b/desktop/test/deployment/executable_content/build/makefile.mk
new file mode 100755
index 000000000000..038051c97499
--- /dev/null
+++ b/desktop/test/deployment/executable_content/build/makefile.mk
@@ -0,0 +1,51 @@
+#*************************************************************************
+#
+# 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 = hello
+LIBTARGET=NO
+NO_DEFAULT_STL=TRUE
+LIBSALCPPRT=
+
+.INCLUDE : settings.mk
+
+
+APP1NOSAL = TRUE
+APP1OBJS = \
+ $(OBJ)$/hello.obj
+
+
+APP1TARGET = $(TARGET)
+
+DEPOBJFILES = \
+ $(OBJ)$/hello.obj
+
+
+.INCLUDE : target.mk
+
diff --git a/desktop/test/deployment/executable_content/build/readme.txt b/desktop/test/deployment/executable_content/build/readme.txt
new file mode 100755
index 000000000000..4f956e573e07
--- /dev/null
+++ b/desktop/test/deployment/executable_content/build/readme.txt
@@ -0,0 +1,2 @@
+This folder contains the sources to build the hello executable which is contained
+in the hello.oxt.
diff --git a/desktop/test/deployment/executable_content/hello.oxt b/desktop/test/deployment/executable_content/hello.oxt
new file mode 100644
index 000000000000..97d6d14a3128
--- /dev/null
+++ b/desktop/test/deployment/executable_content/hello.oxt
Binary files differ
diff --git a/desktop/test/deployment/executable_content/readme.txt b/desktop/test/deployment/executable_content/readme.txt
new file mode 100755
index 000000000000..ad3c01097e14
--- /dev/null
+++ b/desktop/test/deployment/executable_content/readme.txt
@@ -0,0 +1,12 @@
+When the executable is installed try to execute the executable "hello". The executable
+file attribute (not on Windows) should be set.
+
+CD into the extension directory in /user|share)/uno_packages/cache/uno_packages/xyz_
+Then there are the directories for different platforms:
+
+windows,
+solaris,
+linux
+
+Each directory contains a hello executable. On linux one should execute it in a
+shell with an build environment, so that the c++ runtime is found.
diff --git a/desktop/test/deployment/identifier/explicit/identifier.oxt b/desktop/test/deployment/identifier/explicit/identifier.oxt
new file mode 100644
index 000000000000..3851e291c970
--- /dev/null
+++ b/desktop/test/deployment/identifier/explicit/identifier.oxt
Binary files differ
diff --git a/desktop/test/deployment/identifier/legacy/identifier.oxt b/desktop/test/deployment/identifier/legacy/identifier.oxt
new file mode 100644
index 000000000000..df8bb8449241
--- /dev/null
+++ b/desktop/test/deployment/identifier/legacy/identifier.oxt
Binary files differ
diff --git a/desktop/test/deployment/identifier/readme.txt b/desktop/test/deployment/identifier/readme.txt
new file mode 100755
index 000000000000..8a791c586a78
--- /dev/null
+++ b/desktop/test/deployment/identifier/readme.txt
@@ -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.
+#
+#*************************************************************************
+
+legacy/identifier.oxt and explicit/identifier.oxt are two different extensions
+that happen to have the same file name. legacy/identifier.oxt does not have an
+explicit extension identifier, so it gets the implicit one "org.openoffice.
+legacy.identifier.oxt". explicit/identifier.oxt has the
+explicit extension identifier "org.openoffice/framework/desktop/test/deployment/
+identifier/explicit/identifier.oxt".
diff --git a/desktop/test/deployment/locationtest/LocationTest.idl b/desktop/test/deployment/locationtest/LocationTest.idl
new file mode 100644
index 000000000000..2bcc6818c168
--- /dev/null
+++ b/desktop/test/deployment/locationtest/LocationTest.idl
@@ -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.
+ *
+ *************************************************************************/
+
+#ifndef _com_sun_star_comp_smoketest_LocationTest_idl_
+#define _com_sun_star_comp_smoketest_LocationTest_idl_
+
+#include <com/sun/star/lang/XServiceInfo.idl>
+
+
+module com { module sun { module star { module comp { module smoketest {
+ // example service, XServiceInfo is implemented here for demonstration
+ // issues. XServiceInfo must be implemented by all components.
+ service TestExtension: ::com::sun::star::lang::XServiceInfo;
+};};};};};
+
+#endif
diff --git a/desktop/test/deployment/locationtest/LocationTest.java b/desktop/test/deployment/locationtest/LocationTest.java
new file mode 100755
index 000000000000..c5d24f4b0ecc
--- /dev/null
+++ b/desktop/test/deployment/locationtest/LocationTest.java
@@ -0,0 +1,165 @@
+/*************************************************************************
+ *
+ * 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.comp.smoketest;
+
+import com.sun.star.lib.uno.helper.Factory;
+import com.sun.star.lang.XMultiComponentFactory;
+import com.sun.star.lang.XSingleComponentFactory;
+import com.sun.star.lib.uno.helper.WeakBase;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XComponentContext;
+import com.sun.star.registry.XRegistryKey;
+import com.sun.star.lang.XInitialization;
+import com.sun.star.lang.XTypeProvider;
+import com.sun.star.lang.XServiceInfo;
+import com.sun.star.uno.Type;
+
+/** This class capsulates the class, that implements the minimal component, a
+ * factory for creating the service (<CODE>__getComponentFactory</CODE>) and a
+ * method, that writes the information into the given registry key
+ * (<CODE>__writeRegistryServiceInfo</CODE>).
+ */
+public class LocationTest {
+ /** This class implements the component. At least the interfaces XServiceInfo,
+ * XTypeProvider, and XInitialization should be provided by the service.
+ */
+ public static class _LocationTest extends WeakBase
+ implements XServiceInfo {
+ /** The service name, that must be used to get an instance of this service.
+ */
+ static private final String __serviceName =
+ "com.sun.star.comp.smoketest.LocationTest";
+
+ /** The initial component contextr, that gives access to
+ * the service manager, supported singletons, ...
+ * It's often later used
+ */
+ private XComponentContext m_cmpCtx;
+
+ /** The service manager, that gives access to all registered services.
+ * It's often later used
+ */
+ private XMultiComponentFactory m_xMCF;
+
+ /** The constructor of the inner class has a XMultiServiceFactory parameter.
+ * @param xmultiservicefactoryInitialization A special service factory
+ * could be introduced while initializing.
+ */
+ public _LocationTest(XComponentContext xCompContext) {
+ try {
+ m_cmpCtx = xCompContext;
+ m_xMCF = m_cmpCtx.getServiceManager();
+ }
+ catch( Exception e ) {
+ e.printStackTrace();
+ }
+ }
+
+ /** This method returns an array of all supported service names.
+ * @return Array of supported service names.
+ */
+ public String[] getSupportedServiceNames() {
+ return getServiceNames();
+ }
+
+ /** This method is a simple helper function to used in the
+ * static component initialisation functions as well as in
+ * getSupportedServiceNames.
+ */
+ public static String[] getServiceNames() {
+ String[] sSupportedServiceNames = { __serviceName };
+ return sSupportedServiceNames;
+ }
+
+ /** This method returns true, if the given service will be
+ * supported by the component.
+ * @param sServiceName Service name.
+ * @return True, if the given service name will be supported.
+ */
+ public boolean supportsService( String sServiceName ) {
+ return sServiceName.equals( __serviceName );
+ }
+
+ /** Return the class name of the component.
+ * @return Class name of the component.
+ */
+ public String getImplementationName() {
+ return _LocationTest.class.getName();
+ }
+ }
+
+
+ /**
+ * Gives a factory for creating the service.
+ * This method is called by the <code>JavaLoader</code>
+ * <p>
+ * @return returns a <code>XSingleComponentFactory</code> for creating
+ * the component
+ * @param sImplName the name of the implementation for which a
+ * service is desired
+ * @see com.sun.star.comp.loader.JavaLoader
+ */
+ public static XSingleComponentFactory __getComponentFactory(String sImplName)
+ {
+ XSingleComponentFactory xFactory = null;
+
+ if ( sImplName.equals( _LocationTest.class.getName() ) )
+ xFactory = Factory.createComponentFactory(_LocationTest.class,
+ _LocationTest.getServiceNames());
+
+ return xFactory;
+ }
+
+ /**
+ * Writes the service information into the given registry key.
+ * This method is called by the <code>JavaLoader</code>
+ * <p>
+ * @return returns true if the operation succeeded
+ * @param regKey the registryKey
+ * @see com.sun.star.comp.loader.JavaLoader
+ */
+ public static boolean __writeRegistryServiceInfo(XRegistryKey regKey) {
+ return Factory.writeRegistryServiceInfo(_LocationTest.class.getName(),
+ _LocationTest.getServiceNames(),
+ regKey);
+ }
+
+ /** This method is a member of the interface for initializing an object
+ * directly after its creation.
+ * @param object This array of arbitrary objects will be passed to the
+ * component after its creation.
+ * @throws Exception Every exception will not be handled, but will be
+ * passed to the caller.
+ */
+ public void initialize( Object[] object )
+ throws com.sun.star.uno.Exception {
+ /* The component describes what arguments its expected and in which
+ * order!At this point you can read the objects and can intialize
+ * your component using these objects.
+ */
+ }
+}
diff --git a/desktop/test/deployment/locationtest/LocationTest.odt b/desktop/test/deployment/locationtest/LocationTest.odt
new file mode 100644
index 000000000000..8e1aa70078db
--- /dev/null
+++ b/desktop/test/deployment/locationtest/LocationTest.odt
Binary files differ
diff --git a/desktop/test/deployment/locationtest/MANIFEST.MF b/desktop/test/deployment/locationtest/MANIFEST.MF
new file mode 100755
index 000000000000..a2fa8c34b7f9
--- /dev/null
+++ b/desktop/test/deployment/locationtest/MANIFEST.MF
@@ -0,0 +1,2 @@
+RegistrationClassName: com.sun.star.comp.smoketest.LocationTest
+
diff --git a/desktop/test/deployment/locationtest/delzip b/desktop/test/deployment/locationtest/delzip
new file mode 100755
index 000000000000..636fda90bfcb
--- /dev/null
+++ b/desktop/test/deployment/locationtest/delzip
@@ -0,0 +1 @@
+ECHO is OFF
diff --git a/desktop/test/deployment/locationtest/description.xml b/desktop/test/deployment/locationtest/description.xml
new file mode 100755
index 000000000000..b8874dd4da85
--- /dev/null
+++ b/desktop/test/deployment/locationtest/description.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<description xmlns="http://openoffice.org/extensions/description/2006"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:d="http://openoffice.org/extensions/description/2006" >
+ <identifier value="org.openoffice.extensions.testarea.desktop.location"/>
+ <version value="1.0" />
+ <dependencies >
+ <OpenOffice.org-minimal-version value="2.2" d:name="OpenOffice.org 2.2"/>
+ </dependencies>
+ <update-information>
+ <src xlink:href="http://update.services.openoffice.org/ProductUpdateService/check.Update?product=extension&amp;extensionid=org.openoffice.extensions.testarea.desktop.updateinfo&amp;refresh=true"/>
+ </update-information>
+</description>
diff --git a/desktop/test/deployment/locationtest/makefile.mk b/desktop/test/deployment/locationtest/makefile.mk
new file mode 100755
index 000000000000..24be56c28d7e
--- /dev/null
+++ b/desktop/test/deployment/locationtest/makefile.mk
@@ -0,0 +1,87 @@
+#*************************************************************************
+#
+# 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 = location_test
+PACKAGE = com$/sun$/star$/comp$/smoketest
+TARGET = com_sun_star_comp_smoketest
+
+no_common_build_zip:=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+JARFILES = ridl.jar jurt.jar unoil.jar juh.jar
+
+JARTARGET = LocationTest.jar
+JARCOMPRESS = TRUE
+CUSTOMMANIFESTFILE = MANIFEST.MF
+
+ZIP1TARGET=locationtest
+ZIP1LIST=*
+ZIPFLAGS=-r
+ZIP1DIR=$(MISC)$/$(TARGET)
+ZIP1EXT=.oxt
+
+# --- Files --------------------------------------------------------
+
+COPY_OXT_MANIFEST:= $(MISC)$/$(TARGET)$/META-INF$/manifest.xml
+JAVAFILES = LocationTest.java
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
+$(JARTARGETN) : $(MISC)$/$(TARGET).javamaker.done
+
+$(JAVACLASSFILES) : $(MISC)$/$(TARGET).javamaker.done
+
+$(MISC)$/$(TARGET).javamaker.done: $(BIN)$/LocationTest.rdb
+ $(JAVAMAKER) -O$(CLASSDIR) -BUCR -nD -X$(SOLARBINDIR)/types.rdb $<
+ $(TOUCH) $@
+
+$(BIN)$/LocationTest.rdb: LocationTest.idl
+ $(IDLC) -O$(MISC) -I$(SOLARIDLDIR) -cid -we $<
+ +-$(RM) $@
+ $(REGMERGE) $@ /UCR $(MISC)$/LocationTest.urd
+
+$(MISC)$/$(ZIP1TARGET).createdir :
+ +$(MKDIRHIER) $(MISC)$/$(TARGET)$/META-INF >& $(NULLDEV) && $(TOUCH) $@
+
+$(MISC)$/$(TARGET)_resort : manifest.xml $(JARTARGETN) $(MISC)$/$(ZIP1TARGET).createdir $(BIN)$/LocationTest.rdb description.xml
+ $(COPY) manifest.xml $(MISC)$/$(TARGET)$/META-INF$/manifest.xml
+ $(COPY) $(JARTARGETN) $(MISC)$/$(TARGET)$/$(JARTARGET)
+ $(COPY) $(BIN)$/LocationTest.rdb $(MISC)$/$(TARGET)$/LocationTest.rdb
+ $(COPY) description.xml $(MISC)$/$(TARGET)$/description.xml
+ $(TOUCH) $@
+
+.IF "$(ZIP1TARGETN)"!=""
+$(ZIP1TARGETN) : $(MISC)$/$(TARGET)_resort $(MISC)$/$(ZIP1TARGET).createdir
+
+.ENDIF # "$(ZIP1TARGETN)"!=""
+
diff --git a/desktop/test/deployment/locationtest/manifest.xml b/desktop/test/deployment/locationtest/manifest.xml
new file mode 100755
index 000000000000..3dd6460faffa
--- /dev/null
+++ b/desktop/test/deployment/locationtest/manifest.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<manifest:manifest xmlns:manifest="http://openoffice.org/2001/manifest">
+ <manifest:file-entry manifest:full-path="LocationTest.jar" manifest:media-type="application/vnd.sun.star.uno-component;type=Java"/>
+ <manifest:file-entry manifest:full-path="LocationTest.rdb" manifest:media-type="application/vnd.sun.star.uno-typelibrary;type=RDB"/>
+</manifest:manifest>
diff --git a/desktop/test/deployment/options/handler/com/sun/star/comp/extensionoptions/MANIFEST.MF b/desktop/test/deployment/options/handler/com/sun/star/comp/extensionoptions/MANIFEST.MF
new file mode 100755
index 000000000000..fba55a6e0d5a
--- /dev/null
+++ b/desktop/test/deployment/options/handler/com/sun/star/comp/extensionoptions/MANIFEST.MF
@@ -0,0 +1,2 @@
+RegistrationClassName: com.sun.star.comp.extensionoptions.OptionsEventHandler
+
diff --git a/desktop/test/deployment/options/handler/com/sun/star/comp/extensionoptions/OptionsEventHandler.java b/desktop/test/deployment/options/handler/com/sun/star/comp/extensionoptions/OptionsEventHandler.java
new file mode 100755
index 000000000000..bb38108e5eea
--- /dev/null
+++ b/desktop/test/deployment/options/handler/com/sun/star/comp/extensionoptions/OptionsEventHandler.java
@@ -0,0 +1,449 @@
+*************************************************************************
+ *
+ * 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.comp.extensionoptions;
+
+import com.sun.star.lib.uno.helper.Factory;
+import com.sun.star.lib.uno.helper.WeakBase;
+import com.sun.star.lang.XMultiComponentFactory;
+import com.sun.star.lang.XSingleComponentFactory;
+import com.sun.star.lang.XMultiServiceFactory;
+import com.sun.star.lang.WrappedTargetException;
+import com.sun.star.lang.IllegalArgumentException;
+import com.sun.star.lang.XInitialization;
+import com.sun.star.lang.XTypeProvider;
+import com.sun.star.lang.XServiceInfo;
+import com.sun.star.lang.WrappedTargetException;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.Any;
+import com.sun.star.uno.AnyConverter;
+import com.sun.star.uno.XComponentContext;
+import com.sun.star.uno.Exception;
+import com.sun.star.registry.XRegistryKey;
+import com.sun.star.awt.XContainerWindowEventHandler;
+import com.sun.star.awt.XControl;
+import com.sun.star.awt.XControlModel;
+import com.sun.star.awt.XControlContainer;
+import com.sun.star.container.XNameAccess;
+import com.sun.star.container.NoSuchElementException;
+import com.sun.star.beans.PropertyValue;
+import com.sun.star.beans.PropertyState;
+import com.sun.star.beans.XPropertySet;
+import com.sun.star.beans.UnknownPropertyException;
+import com.sun.star.beans.PropertyVetoException;
+import com.sun.star.util.XChangesBatch;
+
+/** A handler which supports multiple options pages which all
+ * have the same controls.
+ */
+public class OptionsEventHandler {
+
+ public static class _OptionsEventHandler extends WeakBase
+ implements XServiceInfo, XContainerWindowEventHandler {
+
+ static private final String __serviceName =
+ "com.sun.star.comp.extensionoptions.OptionsEventHandler";
+
+ private XComponentContext m_cmpCtx;
+
+ private XMultiComponentFactory m_xMCF;
+
+ private XNameAccess m_xAccessLeaves;
+
+ /**Names of supported options pages.
+ */
+ private String[] m_arWindowNames = {
+ "Writer1", "Writer2", "Writer3", "Calc1", "Calc2", "Calc3",
+ "Draw1", "Draw2", "Draw3", "Node1_1", "Node1_2", "Node1_3",
+ "Node2_1", "Node2_2", "Node2_3", "Node3_1", "Node3_2", "Node3_3"};
+
+ /**Names of the controls which are supported by this handler. All these
+ *controls must have a "Text" property.
+ */
+ private String[] m_arStringControls = {
+ "String0", "String1", "String2", "String3", "String4"};
+
+ public _OptionsEventHandler(XComponentContext xCompContext) {
+ m_cmpCtx = xCompContext;
+ m_xMCF = m_cmpCtx.getServiceManager();
+
+ //Create the com.sun.star.configuration.ConfigurationUpdateAccess
+ //for the registry node which contains the data for our option
+ //pages.
+ XMultiServiceFactory xConfig;
+ try {
+ xConfig = (XMultiServiceFactory) UnoRuntime.queryInterface(
+ XMultiServiceFactory.class,
+ m_cmpCtx.getServiceManager().createInstanceWithContext(
+ "com.sun.star.configuration.ConfigurationProvider", m_cmpCtx));
+ } catch (com.sun.star.uno.Exception e) {
+ e.printStackTrace();
+ return;
+ }
+
+ //One argument for creating the ConfigurationUpdateAccess is the "nodepath".
+ //Our nodepath point to the node of which the direct subnodes represent the
+ //different options pages.
+ Object[] args = new Object[1];
+ args[0] = new PropertyValue(
+ "nodepath", 0, "/org.openoffice.desktop.deployment.options.ExtensionData/Leaves",
+ PropertyState.DIRECT_VALUE);
+
+ //We get the com.sun.star.container.XNameAccess from the instance of
+ //ConfigurationUpdateAccess and save it for later use.
+ try {
+ m_xAccessLeaves = (XNameAccess) UnoRuntime.queryInterface(
+ XNameAccess.class, xConfig.createInstanceWithArguments(
+ "com.sun.star.configuration.ConfigurationUpdateAccess", args));
+
+ } catch (com.sun.star.uno.Exception e) {
+ e.printStackTrace();
+ return;
+ }
+ }
+
+ /** This method returns an array of all supported service names.
+ * @return Array of supported service names.
+ */
+ public String[] getSupportedServiceNames() {
+ return getServiceNames();
+ }
+
+ /** This method is a simple helper function to used in the
+ * static component initialisation functions as well as in
+ * getSupportedServiceNames.
+ */
+ public static String[] getServiceNames() {
+ String[] sSupportedServiceNames = { __serviceName };
+ return sSupportedServiceNames;
+ }
+
+ /** This method returns true, if the given service will be
+ * supported by the component.
+ * @param sServiceName Service name.
+ * @return True, if the given service name will be supported.
+ */
+ public boolean supportsService( String sServiceName ) {
+ return sServiceName.equals( __serviceName );
+ }
+
+ /** Return the class name of the component.
+ * @return Class name of the component.
+ */
+ public String getImplementationName() {
+ return _OptionsEventHandler.class.getName();
+ }
+
+ //XContainerWindowEventHandler
+ public boolean callHandlerMethod(com.sun.star.awt.XWindow aWindow,
+ Object aEventObject, String sMethod)
+ throws WrappedTargetException {
+ if (sMethod.equals("external_event") ){
+ try {
+ return handleExternalEvent(aWindow, aEventObject);
+ } catch (com.sun.star.uno.RuntimeException re) {
+ throw re;
+ } catch (com.sun.star.uno.Exception e) {
+ throw new WrappedTargetException(sMethod, this, e);
+ }
+ }
+
+ return true;
+ }
+
+ //XContainerWindowEventHandler
+ public String[] getSupportedMethodNames() {
+ return new String[] {"external_event"};
+ }
+
+ private boolean handleExternalEvent(com.sun.star.awt.XWindow aWindow, Object aEventObject)
+ throws com.sun.star.uno.Exception {
+ try {
+ String sMethod = AnyConverter.toString(aEventObject);
+ if (sMethod.equals("ok")) {
+ saveData(aWindow);
+ } else if (sMethod.equals("back") || sMethod.equals("initialize")) {
+ loadData(aWindow);
+ }
+ } catch (com.sun.star.lang.IllegalArgumentException e) {
+ throw new com.sun.star.lang.IllegalArgumentException(
+ "Method external_event requires a string in the event object argument.",
+ this, (short) -1);
+ }
+
+ return true;
+ }
+
+ private void saveData(com.sun.star.awt.XWindow aWindow)
+ throws com.sun.star.lang.IllegalArgumentException,
+ com.sun.star.uno.Exception {
+
+ //Determine the name of the options page. This serves two purposes. First, if this
+ //options page is supported by this handler and second we use the name two locate
+ //the corresponding data in the registry.
+ String sWindowName = getWindowName(aWindow);
+ if (sWindowName == null)
+ throw new com.sun.star.lang.IllegalArgumentException(
+ "This window is not supported by this handler", this, (short) -1);
+
+ //To access the separate controls of the window we need to obtain the
+ //XControlContainer from the window implementation
+ XControlContainer xContainer = (XControlContainer) UnoRuntime.queryInterface(
+ XControlContainer.class, aWindow);
+ if (xContainer == null)
+ throw new com.sun.star.uno.Exception(
+ "Could not get XControlContainer from window.", this);
+
+ //This is an implementation which will be used for several options pages
+ //which all have the same controls. m_arStringControls is an array which
+ //contains the names.
+ for (int i = 0; i < m_arStringControls.length; i++) {
+
+ //To obtain the data from the controls we need to get their model.
+ //First get the respective control from the XControlContainer.
+ XControl xControl = xContainer.getControl(m_arStringControls[i]);
+
+ //This generic handler and the corresponding registry schema support
+ //up to five text controls. However, if a options page does not use all
+ //five controls then we will not complain here.
+ if (xControl == null)
+ continue;
+
+ //From the control we get the model, which in turn supports the
+ //XPropertySet interface, which we finally use to get the data from
+ //the control.
+ XPropertySet xProp = (XPropertySet) UnoRuntime.queryInterface(
+ XPropertySet.class, xControl.getModel());
+
+ if (xProp == null)
+ throw new com.sun.star.uno.Exception(
+ "Could not get XPropertySet from control.", this);
+ //Get the "Text" property.
+ Object aText = xProp.getPropertyValue("Text");
+ String sValue = null;
+
+ //The value is still contained in a com.sun.star.uno.Any - so convert it.
+ try {
+ sValue = AnyConverter.toString(aText);
+ } catch (com.sun.star.lang.IllegalArgumentException e) {
+ throw new com.sun.star.lang.IllegalArgumentException(
+ "Wrong property type.", this, (short) -1);
+ }
+
+ //Now we have the actual string value of the control. What we need now is
+ //the XPropertySet of the respective property in the registry, so that we
+ //can store the value.
+ //To access the registry we have previously created a service instance
+ //of com.sun.star.configuration.ConfigurationUpdateAccess which supports
+ //com.sun.star.container.XNameAccess. The XNameAccess is used to get the
+ //particular registry node which represents this options page.
+ //Fortunately the name of the window is the same as the registry node.
+ XPropertySet xLeaf = (XPropertySet) UnoRuntime.queryInterface(
+ XPropertySet.class, m_xAccessLeaves.getByName(sWindowName));
+ if (xLeaf == null)
+ throw new com.sun.star.uno.Exception(
+ "XPropertySet not supported.", this);
+
+ //Finally we can set the value
+ xLeaf.setPropertyValue(m_arStringControls[i], sValue);
+ }
+
+ //Committing the changes will cause or changes to be written to the registry.
+ XChangesBatch xUpdateCommit =
+ (XChangesBatch) UnoRuntime.queryInterface(XChangesBatch.class, m_xAccessLeaves);
+ xUpdateCommit.commitChanges();
+ }
+
+ private void loadData(com.sun.star.awt.XWindow aWindow)
+ throws com.sun.star.uno.Exception {
+
+ //Determine the name of the window. This serves two purposes. First, if this
+ //window is supported by this handler and second we use the name two locate
+ //the corresponding data in the registry.
+ String sWindowName = getWindowName(aWindow);
+ if (sWindowName == null)
+ throw new com.sun.star.lang.IllegalArgumentException(
+ "The window is not supported by this handler", this, (short) -1);
+
+ //To acces the separate controls of the window we need to obtain the
+ //XControlContainer from window implementation
+ XControlContainer xContainer = (XControlContainer) UnoRuntime.queryInterface(
+ XControlContainer.class, aWindow);
+ if (xContainer == null)
+ throw new com.sun.star.uno.Exception(
+ "Could not get XControlContainer from window.", this);
+
+ //This is an implementation which will be used for several options pages
+ //which all have the same controls. m_arStringControls is an array which
+ //contains the names.
+ for (int i = 0; i < m_arStringControls.length; i++) {
+
+ //load the values from the registry
+ //To access the registry we have previously created a service instance
+ //of com.sun.star.configuration.ConfigurationUpdateAccess which supports
+ //com.sun.star.container.XNameAccess. We obtain now the section
+ //of the registry which is assigned to this options page.
+ XPropertySet xLeaf = (XPropertySet) UnoRuntime.queryInterface(
+ XPropertySet.class, m_xAccessLeaves.getByName(sWindowName));
+ if (xLeaf == null)
+ throw new com.sun.star.uno.Exception(
+ "XPropertySet not supported.", this);
+
+ //The properties in the registry have the same name as the respective
+ //controls. We use the names now to obtain the property values.
+ Object aValue = xLeaf.getPropertyValue(m_arStringControls[i]);
+
+ //Now that we have the value we need to set it at the corresponding
+ //control in the window. The XControlContainer, which we obtained earlier
+ //is the means to get hold of all the controls.
+ XControl xControl = xContainer.getControl(m_arStringControls[i]);
+
+ //This generic handler and the corresponding registry schema support
+ //up to five text controls. However, if a options page does not use all
+ //five controls then we will not complain here.
+ if (xControl == null)
+ continue;
+
+ //From the control we get the model, which in turn supports the
+ //XPropertySet interface, which we finally use to set the data at the
+ //control
+ XPropertySet xProp = (XPropertySet) UnoRuntime.queryInterface(
+ XPropertySet.class, xControl.getModel());
+
+ if (xProp == null)
+ throw new com.sun.star.uno.Exception(
+ "Could not get XPropertySet from control.", this);
+
+ //This handler supports only text controls, which are named "Pattern Field"
+ //in the dialog editor. We set the "Text" property.
+ xProp.setPropertyValue("Text", aValue);
+ }
+ }
+
+ //Checks if the name property of the window is one of the supported names and returns
+ //always a valid string or null
+ private String getWindowName(com.sun.star.awt.XWindow aWindow)
+ throws com.sun.star.uno.Exception {
+
+ if (aWindow == null)
+ new com.sun.star.lang.IllegalArgumentException(
+ "Method external_event requires that a window is passed as argument",
+ this, (short) -1);
+
+ //We need to get the control model of the window. Therefore the first step is
+ //to query for it.
+ XControl xControlDlg = (XControl) UnoRuntime.queryInterface(
+ XControl.class, aWindow);
+
+ if (xControlDlg == null)
+ throw new com.sun.star.uno.Exception(
+ "Cannot obtain XControl from XWindow in method external_event.");
+ //Now get model
+ XControlModel xModelDlg = xControlDlg.getModel();
+
+ if (xModelDlg == null)
+ throw new com.sun.star.uno.Exception(
+ "Cannot obtain XControlModel from XWindow in method external_event.", this);
+ //The model itself does not provide any information except that its
+ //implementation supports XPropertySet which is used to access the data.
+ XPropertySet xPropDlg = (XPropertySet) UnoRuntime.queryInterface(
+ XPropertySet.class, xModelDlg);
+ if (xPropDlg == null)
+ throw new com.sun.star.uno.Exception(
+ "Cannot obtain XPropertySet from window in method external_event.", this);
+
+ //Get the "Name" property of the window
+ Object aWindowName = xPropDlg.getPropertyValue("Name");
+
+ //Get the string from the returned com.sun.star.uno.Any
+ String sName = null;
+ try {
+ sName = AnyConverter.toString(aWindowName);
+ } catch (com.sun.star.lang.IllegalArgumentException e) {
+ throw new com.sun.star.uno.Exception(
+ "Name - property of window is not a string.", this);
+ }
+
+ //Eventually we can check if we this handler can "handle" this options page.
+ //The class has a member m_arWindowNames which contains all names of windows
+ //for which it is intended
+ for (int i = 0; i < m_arWindowNames.length; i++) {
+ if (m_arWindowNames[i].equals(sName)) {
+ return sName;
+ }
+ }
+ return null;
+ }
+ }
+
+
+ /**
+ * Gives a factory for creating the service.
+ * This method is called by the <code>JavaLoader</code>
+ * <p>
+ * @return returns a <code>XSingleComponentFactory</code> for creating
+ * the component
+ * @param sImplName the name of the implementation for which a
+ * service is desired
+ * @see com.sun.star.comp.loader.JavaLoader
+ */
+ public static XSingleComponentFactory __getComponentFactory(String sImplName)
+ {
+ XSingleComponentFactory xFactory = null;
+
+ if ( sImplName.equals( _OptionsEventHandler.class.getName() ) )
+ xFactory = Factory.createComponentFactory(_OptionsEventHandler.class,
+ _OptionsEventHandler.getServiceNames());
+
+ return xFactory;
+ }
+
+ /**
+ * Writes the service information into the given registry key.
+ * This method is called by the <code>JavaLoader</code>
+ * <p>
+ * @return returns true if the operation succeeded
+ * @param regKey the registryKey
+ * @see com.sun.star.comp.loader.JavaLoader
+ */
+ public static boolean __writeRegistryServiceInfo(XRegistryKey regKey) {
+ return Factory.writeRegistryServiceInfo(_OptionsEventHandler.class.getName(),
+ _OptionsEventHandler.getServiceNames(),
+ regKey);
+ }
+
+ /** This method is a member of the interface for initializing an object
+ * directly after its creation.
+ * @param object This array of arbitrary objects will be passed to the
+ * component after its creation.
+ * @throws Exception Every exception will not be handled, but will be
+ * passed to the caller.
+ */
+ public void initialize( Object[] object )
+ throws com.sun.star.uno.Exception {
+ }
+
+}
diff --git a/desktop/test/deployment/options/handler/com/sun/star/comp/extensionoptions/makefile.mk b/desktop/test/deployment/options/handler/com/sun/star/comp/extensionoptions/makefile.mk
new file mode 100755
index 000000000000..662fffce407c
--- /dev/null
+++ b/desktop/test/deployment/options/handler/com/sun/star/comp/extensionoptions/makefile.mk
@@ -0,0 +1,53 @@
+#*************************************************************************
+#
+# 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
+PACKAGE = com$/sun$/star$/comp$/extensionoptions
+TARGET = options
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+JARFILES = ridl.jar jurt.jar unoil.jar juh.jar
+
+
+JARTARGET = extensionoptions.jar
+JARCOMPRESS = TRUE
+CUSTOMMANIFESTFILE = MANIFEST.MF
+JARCLASSDIRS=com
+
+
+# --- Files --------------------------------------------------------
+
+JAVAFILES = OptionsEventHandler.java
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/desktop/test/deployment/options/leaf1.oxt b/desktop/test/deployment/options/leaf1.oxt
new file mode 100644
index 000000000000..9c3ff86985b6
--- /dev/null
+++ b/desktop/test/deployment/options/leaf1.oxt
Binary files differ
diff --git a/desktop/test/deployment/options/leaf1mod.oxt b/desktop/test/deployment/options/leaf1mod.oxt
new file mode 100644
index 000000000000..d5d9fe6896f8
--- /dev/null
+++ b/desktop/test/deployment/options/leaf1mod.oxt
Binary files differ
diff --git a/desktop/test/deployment/options/leaf2.oxt b/desktop/test/deployment/options/leaf2.oxt
new file mode 100644
index 000000000000..b95628900c40
--- /dev/null
+++ b/desktop/test/deployment/options/leaf2.oxt
Binary files differ
diff --git a/desktop/test/deployment/options/leaves1.oxt b/desktop/test/deployment/options/leaves1.oxt
new file mode 100644
index 000000000000..037389a018b8
--- /dev/null
+++ b/desktop/test/deployment/options/leaves1.oxt
Binary files differ
diff --git a/desktop/test/deployment/options/leaves2.oxt b/desktop/test/deployment/options/leaves2.oxt
new file mode 100644
index 000000000000..531b38566352
--- /dev/null
+++ b/desktop/test/deployment/options/leaves2.oxt
Binary files differ
diff --git a/desktop/test/deployment/options/leaves3.oxt b/desktop/test/deployment/options/leaves3.oxt
new file mode 100644
index 000000000000..f5bb0f226239
--- /dev/null
+++ b/desktop/test/deployment/options/leaves3.oxt
Binary files differ
diff --git a/desktop/test/deployment/options/modules1.oxt b/desktop/test/deployment/options/modules1.oxt
new file mode 100644
index 000000000000..bae652ffbc39
--- /dev/null
+++ b/desktop/test/deployment/options/modules1.oxt
Binary files differ
diff --git a/desktop/test/deployment/options/modules2.oxt b/desktop/test/deployment/options/modules2.oxt
new file mode 100644
index 000000000000..d6d7956d459c
--- /dev/null
+++ b/desktop/test/deployment/options/modules2.oxt
Binary files differ
diff --git a/desktop/test/deployment/options/nodes1.oxt b/desktop/test/deployment/options/nodes1.oxt
new file mode 100644
index 000000000000..b1dfa18d3efa
--- /dev/null
+++ b/desktop/test/deployment/options/nodes1.oxt
Binary files differ
diff --git a/desktop/test/deployment/options/nodes2.oxt b/desktop/test/deployment/options/nodes2.oxt
new file mode 100644
index 000000000000..a35cfaba9dc8
--- /dev/null
+++ b/desktop/test/deployment/options/nodes2.oxt
Binary files differ
diff --git a/desktop/test/deployment/options/nodes3.oxt b/desktop/test/deployment/options/nodes3.oxt
new file mode 100644
index 000000000000..db0bc49da522
--- /dev/null
+++ b/desktop/test/deployment/options/nodes3.oxt
Binary files differ
diff --git a/desktop/test/deployment/options/nodes4.oxt b/desktop/test/deployment/options/nodes4.oxt
new file mode 100644
index 000000000000..fe0550fdc655
--- /dev/null
+++ b/desktop/test/deployment/options/nodes4.oxt
Binary files differ
diff --git a/desktop/test/deployment/options/nodes5.oxt b/desktop/test/deployment/options/nodes5.oxt
new file mode 100644
index 000000000000..893e9ee3e216
--- /dev/null
+++ b/desktop/test/deployment/options/nodes5.oxt
Binary files differ
diff --git a/desktop/test/deployment/options/readme.txt b/desktop/test/deployment/options/readme.txt
new file mode 100755
index 000000000000..9879a72ceffa
--- /dev/null
+++ b/desktop/test/deployment/options/readme.txt
@@ -0,0 +1,200 @@
+Important: The hander component extensionoptions.jar in the extensions may not
+contain exactly the same sources as the one build in the handler directory. To
+make sure that debugging works build the handler directory and put the
+extensionoptions.jar into the extension.
+
+
+
+leaf1.oxt: Defines a leaf under the node WriterNode
+================================================================================
+
+leaf1mod.oxt: Defines a leaf under the node WriterNode
+
+It has a douplicate entry in the manifest.xml (OptionsDialog.xcu). This would cause a DisposedException when uninstalling on OOo 3.0 and prevent the extension from being uninstalled. This is actually a bug of the extensions. However, the error is difficult to investigate. Therefore this was fixed to make OOo more robust (i96690).
+================================================================================
+
+leaf2.oxt: Defines a leaf under a node that has a name which requires special
+"xml encoding". The name is "My Writer's & Settings". The node is not assigned
+to a Module and the Node/AllModules property is not true. This is a typical
+scenario when a Node had been added to an existing Module and later the Module
+was removed. This is a situation which actually should not occur. In this case
+DO NOT show the Node in the OOo's options dialog, because it shows only nodes
+for a particular module and in this case the Module for the Node is unknown.
+In the Extension Manager's
+options dialog this Node can be shown because the Module is irrelevant.
+See also nodes5.oxt.
+================================================================================
+
+leaves1.oxt: multiple ordered leaves under available nodes. The leaves Lables are
+localized for en-US and de. The following leaves should appear:
+
+Writer:
+-leaves1 Writer 1 en-US
+-leaves1 Writer 2 en-US
+-leaves1 Writer 3 en-US
+
+Calc:
+-leaves1 Calc 3 en-US
+-leaves1 Calc 3 en-US
+-leaves1 Calc 3 en-US
+
+Draw:
+-leaves1 Draw 3 en-US
+-leaves1 Draw 3 en-US
+-leaves1 Draw 3 en-US
+
+If a german office is used then the strings contain "de" instead of "en-US".
+================================================================================
+
+leaves2.oxt: Same as leaves1.oxt. Use together with leaves1.oxt to test the
+grouping of leaves.
+================================================================================
+
+leaves3.oxt: Same as leaves1.oxt, but the leaves are not ordered.
+================================================================================
+
+nodes1.oxt: Defines one node which has AllModules set and which has
+no children. Therefore this node should not be displayed.
+================================================================================
+
+nodes2.oxt: Defines 3 nodes which use AllModules and which form an
+ordered group. Every node defines also 3 nodes which have a determined order.
+
+-nodes2 node 1 en-US
+ -nodes2 node 1 leaf 1 en-US
+ -nodes2 node 1 leaf 2 en-US
+ -nodes2 node 1 leaf 3 en-US
+
+-nodes2 node 2 en-US
+ -nodes2 node 2 leaf 1 en-US
+ -nodes2 node 2 leaf 2 en-US
+ -nodes2 node 2 leaf 3 en-US
+
+-nodes2 node 3 en-US
+ -nodes2 node 3 leaf 1 en-US
+ -nodes2 node 3 leaf 2 en-US
+ -nodes2 node 3 leaf 3 en-US
+
+================================================================================
+
+nodes3.oxt: Defines 3 nodes which are placed under different existing Modules.
+The nodes and there leaves are ordered.
+
+Context Writer:
+- nodes3 node 1
+ nodes3 node 1 leaf 1 en-US
+ nodes3 node 1 leaf 2 en-US
+ nodes3 node 1 leaf 3 en-US
+
+- nodes3 node 2
+ nodes3 node 2 leaf 1 en-US
+ nodes3 node 2 leaf 2 en-US
+ nodes3 node 2 leaf 3 en-US
+
+- nodes3 node 3
+ nodes3 node 3 leaf 1 en-US
+ nodes3 node 3 leaf 2 en-US
+ nodes3 node 3 leaf 3 en-US
+
+Context Calc:
+- nodes3 node 1
+ nodes3 node 1 leaf 1 en-US
+ nodes3 node 1 leaf 2 en-US
+ nodes3 node 1 leaf 3 en-US
+
+- nodes3 node 3
+ nodes3 node 3 leaf 1 en-US
+ nodes3 node 3 leaf 2 en-US
+ nodes3 node 3 leaf 3 en-US
+
+Context Draw:
+- nodes3 node 2
+ nodes3 node 2 leaf 1 en-US
+ nodes3 node 2 leaf 2 en-US
+ nodes3 node 2 leaf 3 en-US
+
+================================================================================
+
+nodes4.oxt: Same as nodes3.oxt. Use together with nodes3.txt to test the
+grouping of nodes.
+================================================================================
+
+nodes5.oxt: Defines a node which in turn defines 3 leaves. The Node
+is not assigned to a Module and the AllModule property is false (which is the
+default).This may happen when a node
+had been added to an already existing Module and then this Module was removed. For
+example, an extension adds a node to the "Writer Module" and the
+next office update removes the "Writer Module" (which is rather inconceivable).
+Then the node and its leaves MUST NOT be displayed in OOo's options dialog,
+because the Module is not known. However, it can be displayed in the
+options dialog of the Extension Manager. See also the description for leaf2.oxt.
+================================================================================
+
+modules1.oxt: Defines two Modules and three Nodes. The Nodes may not
+be displayed in OOo's options dialog because there is currently no application
+which uses this Module. However the Nodes are displayed in the options dialog
+of the Extension Manager.
+There are three Nodes defined. The relation ship is this:
+
+-module1
+ -node 1
+ -leaf 1
+ -leaf 2
+ -leaf 3
+ -node 2
+ -leaf 1
+ -leaf 2
+ -leaf 3
+ -node 3
+ -leaf 1
+ -leaf 2
+ -leaf 3
+
+-module2
+ -node1
+ -leaf 1
+ -leaf 2
+ -leaf 3
+ -node3
+ -leaf 1
+ -leaf 2
+ -leaf 3
+
+The options dialog of the Extension Manager shall display only three nodes:
+
+ -node 1
+ -leaf 1
+ -leaf 2
+ -leaf 3
+ -node 2
+ -leaf 1
+ -leaf 2
+ -leaf 3
+ -node 3
+ -leaf 1
+ -leaf 2
+ -leaf 3
+
+or
+
+ -node 1
+ -leaf 1
+ -leaf 2
+ -leaf 3
+ -node 3
+ -leaf 1
+ -leaf 2
+ -leaf 3
+ -node 2
+ -leaf 1
+ -leaf 2
+ -leaf 3
+
+Since the order of Module|s is not defined, the dialog may display first the
+Nodes from module2 and then from module1. If a node is already displayed then
+it is not shown again.
+
+================================================================================
+
+modules2.oxt: Same as modules1, except that the order of nodes and leaves
+is not defined.
diff --git a/desktop/test/deployment/passive/Addons.xcu b/desktop/test/deployment/passive/Addons.xcu
new file mode 100644
index 000000000000..61578d7426e9
--- /dev/null
+++ b/desktop/test/deployment/passive/Addons.xcu
@@ -0,0 +1,67 @@
+<?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.
+*
+**********************************************************************-->
+
+<o:component-data xmlns:o="http://openoffice.org/2001/registry"
+ o:package="org.openoffice.Office" o:name="Addons">
+ <node o:name="AddonUI">
+ <node o:name="OfficeMenuBar">
+ <node o:name="org.openoffice.test.desktop.deployment.passive"
+ o:op="replace">
+ <prop o:name="Title" xml:lang="en-US">
+ <value>passive</value>
+ </prop>
+ <node o:name="Submenu">
+ <node o:name="1" o:op="replace">
+ <prop o:name="URL">
+ <value>vnd.org.openoffice.test.desktop.deployment.passive_native:</value>
+ </prop>
+ <prop o:name="Title" xml:lang="en-US">
+ <value>native</value>
+ </prop>
+ </node>
+ <node o:name="2" o:op="replace">
+ <prop o:name="URL">
+ <value>vnd.org.openoffice.test.desktop.deployment.passive_java:</value>
+ </prop>
+ <prop o:name="Title" xml:lang="en-US">
+ <value>java</value>
+ </prop>
+ </node>
+ <node o:name="3" o:op="replace">
+ <prop o:name="URL">
+ <value>vnd.org.openoffice.test.desktop.deployment.passive_python:</value>
+ </prop>
+ <prop o:name="Title" xml:lang="en-US">
+ <value>python</value>
+ </prop>
+ </node>
+ </node>
+ </node>
+ </node>
+ </node>
+</o:component-data>
diff --git a/desktop/test/deployment/passive/Dispatch.java b/desktop/test/deployment/passive/Dispatch.java
new file mode 100755
index 000000000000..295f34d599da
--- /dev/null
+++ b/desktop/test/deployment/passive/Dispatch.java
@@ -0,0 +1,101 @@
+/*************************************************************************
+* 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.comp.test.deployment.passive_java;
+
+import com.sun.star.awt.MessageBoxButtons;
+import com.sun.star.awt.Rectangle;
+import com.sun.star.awt.XMessageBox;
+import com.sun.star.awt.XMessageBoxFactory;
+import com.sun.star.awt.XWindowPeer;
+import com.sun.star.beans.PropertyValue;
+import com.sun.star.frame.DispatchDescriptor;
+import com.sun.star.frame.XDesktop;
+import com.sun.star.frame.XDispatch;
+import com.sun.star.frame.XStatusListener;
+import com.sun.star.lang.WrappedTargetRuntimeException;
+import com.sun.star.lang.XComponent;
+import com.sun.star.lang.XMultiComponentFactory;
+import com.sun.star.lang.XServiceInfo;
+import com.sun.star.lib.uno.helper.WeakBase;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XComponentContext;
+import com.sun.star.util.URL;
+
+public final class Dispatch extends WeakBase implements XServiceInfo, XDispatch
+{
+ public Dispatch(XComponentContext context) {
+ this.context = context;
+ }
+
+ public String getImplementationName() { return implementationName; }
+
+ public boolean supportsService(String ServiceName) {
+ return false; //TODO
+ }
+
+ public String[] getSupportedServiceNames() {
+ return serviceNames;
+ }
+
+ public void dispatch(URL URL, PropertyValue[] Arguments) {
+ try {
+ XMultiComponentFactory smgr = UnoRuntime.queryInterface(
+ XMultiComponentFactory.class, context.getServiceManager());
+ XMessageBox box = UnoRuntime.queryInterface(
+ XMessageBoxFactory.class,
+ smgr.createInstanceWithContext(
+ "com.sun.star.awt.Toolkit", context)).
+ createMessageBox(
+ UnoRuntime.queryInterface(
+ XWindowPeer.class,
+ (UnoRuntime.queryInterface(
+ XDesktop.class,
+ smgr.createInstanceWithContext(
+ "com.sun.star.frame.Desktop", context)).
+ getCurrentFrame().getComponentWindow())),
+ new Rectangle(), "infobox", MessageBoxButtons.BUTTONS_OK,
+ "passive", "java");
+ box.execute();
+ UnoRuntime.queryInterface(XComponent.class, box).dispose();
+ } catch (com.sun.star.uno.RuntimeException e) {
+ throw e;
+ } catch (com.sun.star.uno.Exception e) {
+ throw new WrappedTargetRuntimeException(
+ "wrapped: " + e.getMessage(), this, e);
+ }
+ }
+
+ public void addStatusListener(XStatusListener Control, URL URL) {}
+
+ public void removeStatusListener(XStatusListener Control, URL URL) {}
+
+ private final XComponentContext context;
+
+ static final String implementationName =
+ "com.sun.star.comp.test.deployment.passive_java_singleton";
+
+ static final String[] serviceNames = new String[0];
+}
diff --git a/desktop/test/deployment/passive/MANIFEST.MF b/desktop/test/deployment/passive/MANIFEST.MF
new file mode 100755
index 000000000000..45a04bf263dc
--- /dev/null
+++ b/desktop/test/deployment/passive/MANIFEST.MF
@@ -0,0 +1,3 @@
+Sealed: true
+RegistrationClassName: com.sun.star.comp.test.deployment.passive_java.Services
+UNO-Type-Path:
diff --git a/desktop/test/deployment/passive/ProtocolHandler.xcu b/desktop/test/deployment/passive/ProtocolHandler.xcu
new file mode 100644
index 000000000000..bc0355be41df
--- /dev/null
+++ b/desktop/test/deployment/passive/ProtocolHandler.xcu
@@ -0,0 +1,48 @@
+<?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.
+*
+**********************************************************************-->
+
+<o:component-data xmlns:o="http://openoffice.org/2001/registry"
+ o:package="org.openoffice.Office" o:name="ProtocolHandler">
+ <node o:name="HandlerSet">
+ <node o:name="com.sun.star.test.deployment.passive_native" o:op="replace">
+ <prop o:name="Protocols">
+ <value>vnd.org.openoffice.test.desktop.deployment.passive_native:*</value>
+ </prop>
+ </node>
+ <node o:name="com.sun.star.test.deployment.passive_java" o:op="replace">
+ <prop o:name="Protocols">
+ <value>vnd.org.openoffice.test.desktop.deployment.passive_java:*</value>
+ </prop>
+ </node>
+ <node o:name="com.sun.star.test.deployment.passive_python" o:op="replace">
+ <prop o:name="Protocols">
+ <value>vnd.org.openoffice.test.desktop.deployment.passive_python:*</value>
+ </prop>
+ </node>
+ </node>
+</o:component-data>
diff --git a/desktop/test/deployment/passive/Provider.java b/desktop/test/deployment/passive/Provider.java
new file mode 100755
index 000000000000..6f74ed9eb89e
--- /dev/null
+++ b/desktop/test/deployment/passive/Provider.java
@@ -0,0 +1,81 @@
+/*************************************************************************
+* 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.comp.test.deployment.passive_java;
+
+import com.sun.star.frame.DispatchDescriptor;
+import com.sun.star.frame.XDispatch;
+import com.sun.star.frame.XDispatchProvider;
+import com.sun.star.lang.XServiceInfo;
+import com.sun.star.lib.uno.helper.WeakBase;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XComponentContext;
+import com.sun.star.util.URL;
+
+public final class Provider extends WeakBase
+ implements XServiceInfo, XDispatchProvider
+{
+ public Provider(XComponentContext context) {
+ this.context = context;
+ }
+
+ public String getImplementationName() { return implementationName; }
+
+ public boolean supportsService(String ServiceName) {
+ return ServiceName.equals(getSupportedServiceNames()[0]); //TODO
+ }
+
+ public String[] getSupportedServiceNames() {
+ return serviceNames;
+ }
+
+ public XDispatch queryDispatch(
+ URL URL, String TargetFrameName, int SearchFlags)
+ {
+ return UnoRuntime.queryInterface(
+ XDispatch.class,
+ context.getValueByName(
+ "/singletons/" +
+ "com.sun.star.test.deployment.passive_java_singleton"));
+ }
+
+ public XDispatch[] queryDispatches(DispatchDescriptor[] Requests) {
+ XDispatch[] s = new XDispatch[Requests.length];
+ for (int i = 0; i < s.length; ++i) {
+ s[i] = queryDispatch(
+ Requests[i].FeatureURL, Requests[i].FrameName,
+ Requests[i].SearchFlags);
+ }
+ return s;
+ }
+
+ private final XComponentContext context;
+
+ static final String implementationName =
+ "com.sun.star.comp.test.deployment.passive_java";
+
+ static final String[] serviceNames = new String[] {
+ "com.sun.star.test.deployment.passive_java" };
+}
diff --git a/desktop/test/deployment/passive/Services.java b/desktop/test/deployment/passive/Services.java
new file mode 100755
index 000000000000..799df3e70222
--- /dev/null
+++ b/desktop/test/deployment/passive/Services.java
@@ -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.
+************************************************************************/
+
+package com.sun.star.comp.test.deployment.passive_java;
+
+import com.sun.star.lang.XSingleComponentFactory;
+import com.sun.star.lib.uno.helper.Factory;
+
+public final class Services {
+ private Services() {}
+
+ public static XSingleComponentFactory __getComponentFactory(
+ String implementation)
+ {
+ if (implementation.equals(Dispatch.implementationName)) {
+ return Factory.createComponentFactory(
+ Dispatch.class, Dispatch.implementationName,
+ Dispatch.serviceNames);
+ } else if (implementation.equals(Provider.implementationName)) {
+ return Factory.createComponentFactory(
+ Provider.class, Provider.implementationName,
+ Provider.serviceNames);
+ } else {
+ return null;
+ }
+ }
+}
diff --git a/desktop/test/deployment/passive/description.xml b/desktop/test/deployment/passive/description.xml
new file mode 100755
index 000000000000..468dfa065fb1
--- /dev/null
+++ b/desktop/test/deployment/passive/description.xml
@@ -0,0 +1,36 @@
+<?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.
+*
+**********************************************************************-->
+
+<d:description xmlns:d="http://openoffice.org/extensions/description/2006">
+ <d:identifier
+ value="org.openoffice/framework/desktop/test/deployment/passive"/>
+ <d:version value="1"/>
+ <d:dependencies>
+ <d:OpenOffice.org-minimal-version d:name="OpenOffice.org 3.4" value="3.4"/>
+ </d:dependencies>
+</d:description>
diff --git a/desktop/test/deployment/passive/makefile.mk b/desktop/test/deployment/passive/makefile.mk
new file mode 100755
index 000000000000..05defbe6d16e
--- /dev/null
+++ b/desktop/test/deployment/passive/makefile.mk
@@ -0,0 +1,141 @@
+#*************************************************************************
+#
+# 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 = test_deployment_passive
+
+ENABLE_EXCEPTIONS = TRUE
+
+PACKAGE = com/sun/star/comp/test/deployment/passive_java
+JAVAFILES = Dispatch.java Provider.java Services.java
+JARFILES = juh.jar ridl.jar unoil.jar
+
+my_platform_components = passive_native
+my_generic_components = passive_java passive_python
+
+.INCLUDE: settings.mk
+
+
+DLLPRE =
+
+SLOFILES = $(SHL1OBJS)
+
+SHL1TARGET = passive_native.uno
+SHL1OBJS = $(SLO)/passive_native.obj
+SHL1RPATH = OXT
+SHL1STDLIBS = $(CPPUHELPERLIB) $(CPPULIB) $(SALLIB)
+SHL1VERSIONMAP = $(SOLARENV)/src/component.map
+DEF1NAME = $(SHL1TARGET)
+
+.INCLUDE: target.mk
+
+.IF "$(SOLAR_JAVA)" != ""
+
+ALLTAR : $(MISC)/passive.oxt
+
+$(MISC)/passive.oxt : manifest.xml description.xml Addons.xcu \
+ ProtocolHandler.xcu $(MISC)/$(TARGET)/platform.components \
+ $(MISC)/$(TARGET)/generic.components $(SHL1TARGETN) \
+ $(MISC)/$(TARGET)/passive_java.jar passive_python.py
+ $(RM) $@
+ $(RM) -r $(MISC)/$(TARGET)/passive.oxt-zip
+ $(MKDIR) $(MISC)/$(TARGET)/passive.oxt-zip
+ $(MKDIRHIER) $(MISC)/$(TARGET)/passive.oxt-zip/META-INF
+ $(SED) -e 's|@PLATFORM@|$(RTL_OS:l)_$(RTL_ARCH:l)|g' < manifest.xml \
+ > $(MISC)/$(TARGET)/passive.oxt-zip/META-INF/manifest.xml
+ $(COPY) description.xml Addons.xcu ProtocolHandler.xcu \
+ $(MISC)/$(TARGET)/platform.components \
+ $(MISC)/$(TARGET)/generic.components $(SHL1TARGETN) \
+ $(MISC)/$(TARGET)/passive_java.jar passive_python.py \
+ $(MISC)/$(TARGET)/passive.oxt-zip/
+ cd $(MISC)/$(TARGET)/passive.oxt-zip && zip ../../passive.oxt \
+ META-INF/manifest.xml description.xml Addons.xcu ProtocolHandler.xcu \
+ platform.components generic.components $(SHL1TARGETN:f) \
+ passive_java.jar passive_python.py
+
+$(MISC)/$(TARGET)/platform.components : $(SOLARENV)/bin/packcomponents.xslt \
+ $(MISC)/$(TARGET)/platform.components.input \
+ $(my_platform_components:^"$(MISC)/$(TARGET)/":+".component")
+ $(XSLTPROC) --nonet --stringparam prefix $(PWD)/$(MISC)/$(TARGET)/ -o $@ \
+ $(SOLARENV)/bin/packcomponents.xslt \
+ $(MISC)/$(TARGET)/platform.components.input
+
+$(MISC)/$(TARGET)/platform.components.input :
+ $(MKDIRHIER) $(@:d)
+ echo '<list>' \
+ '$(my_platform_components:^"<filename>":+".component</filename>")' \
+ '</list>' > $@
+
+$(MISC)/$(TARGET)/generic.components : $(SOLARENV)/bin/packcomponents.xslt \
+ $(MISC)/$(TARGET)/generic.components.input \
+ $(my_generic_components:^"$(MISC)/$(TARGET)/":+".component")
+ $(XSLTPROC) --nonet --stringparam prefix $(PWD)/$(MISC)/$(TARGET)/ -o $@ \
+ $(SOLARENV)/bin/packcomponents.xslt \
+ $(MISC)/$(TARGET)/generic.components.input
+
+$(MISC)/$(TARGET)/generic.components.input :
+ $(MKDIRHIER) $(@:d)
+ echo '<list>' \
+ '$(my_generic_components:^"<filename>":+".component</filename>")' \
+ '</list>' > $@
+
+$(MISC)/$(TARGET)/passive_native.component : \
+ $(SOLARENV)/bin/createcomponent.xslt passive_native.component
+ $(MKDIRHIER) $(@:d)
+ $(XSLTPROC) --nonet --stringparam uri \
+ '$(COMPONENTPREFIX_EXTENSION)$(SHL1TARGETN:f)' -o $@ \
+ $(SOLARENV)/bin/createcomponent.xslt passive_native.component
+
+$(MISC)/$(TARGET)/passive_java.component : \
+ $(SOLARENV)/bin/createcomponent.xslt passive_java.component
+ $(MKDIRHIER) $(@:d)
+ $(XSLTPROC) --nonet --stringparam uri \
+ '$(COMPONENTPREFIX_EXTENSION)passive_java.jar' -o $@ \
+ $(SOLARENV)/bin/createcomponent.xslt passive_java.component
+
+$(MISC)/$(TARGET)/passive_python.component : \
+ $(SOLARENV)/bin/createcomponent.xslt passive_python.component
+ $(MKDIRHIER) $(@:d)
+ $(XSLTPROC) --nonet --stringparam uri \
+ '$(COMPONENTPREFIX_EXTENSION)passive_python.py' -o $@ \
+ $(SOLARENV)/bin/createcomponent.xslt passive_python.component
+
+$(MISC)/$(TARGET)/passive_java.jar : MANIFEST.MF $(JAVATARGET)
+ $(MKDIRHIER) $(@:d)
+ $(RM) $@
+ $(RM) -r $(MISC)/$(TARGET)/passive_java.jar-zip
+ $(MKDIR) $(MISC)/$(TARGET)/passive_java.jar-zip
+ $(MKDIRHIER) $(MISC)/$(TARGET)/passive_java.jar-zip/META-INF \
+ $(MISC)/$(TARGET)/passive_java.jar-zip/$(PACKAGE)
+ $(COPY) MANIFEST.MF $(MISC)/$(TARGET)/passive_java.jar-zip/META-INF/
+ $(COPY) $(foreach,i,$(JAVAFILES:b) $(CLASSDIR)/$(PACKAGE)/$i.class) \
+ $(MISC)/$(TARGET)/passive_java.jar-zip/$(PACKAGE)/
+ cd $(MISC)/$(TARGET)/passive_java.jar-zip && zip ../passive_java.jar \
+ META-INF/MANIFEST.MF $(foreach,i,$(JAVAFILES:b) $(PACKAGE)/$i.class)
+
+.ENDIF
diff --git a/desktop/test/deployment/passive/manifest.xml b/desktop/test/deployment/passive/manifest.xml
new file mode 100755
index 000000000000..5b8ac8419bb9
--- /dev/null
+++ b/desktop/test/deployment/passive/manifest.xml
@@ -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.
+*
+**********************************************************************-->
+
+<m:manifest xmlns:m="http://openoffice.org/2001/manifest">
+ <m:file-entry m:media-type="application/vnd.sun.star.configuration-data"
+ m:full-path="Addons.xcu"/>
+ <m:file-entry m:media-type="application/vnd.sun.star.configuration-data"
+ m:full-path="ProtocolHandler.xcu"/>
+ <m:file-entry
+ m:media-type="application/vnd.sun.star.uno-components;platform=@PLATFORM@"
+ m:full-path="platform.components"/>
+ <m:file-entry
+ m:media-type="application/vnd.sun.star.uno-components"
+ m:full-path="generic.components"/>
+</m:manifest>
diff --git a/desktop/test/deployment/passive/passive_java.component b/desktop/test/deployment/passive/passive_java.component
new file mode 100755
index 000000000000..74be57177dfe
--- /dev/null
+++ b/desktop/test/deployment/passive/passive_java.component
@@ -0,0 +1,38 @@
+<?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.comp.test.deployment.passive_java">
+ <service name="com.sun.star.test.deployment.passive_java"/>
+ </implementation>
+ <implementation
+ name="com.sun.star.comp.test.deployment.passive_java_singleton">
+ <singleton name="com.sun.star.test.deployment.passive_java_singleton"/>
+ </implementation>
+</component>
diff --git a/desktop/test/deployment/passive/passive_native.component b/desktop/test/deployment/passive/passive_native.component
new file mode 100755
index 000000000000..c14fd7ff0062
--- /dev/null
+++ b/desktop/test/deployment/passive/passive_native.component
@@ -0,0 +1,38 @@
+<?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.test.deployment.passive_native">
+ <service name="com.sun.star.test.deployment.passive_native"/>
+ </implementation>
+ <implementation
+ name="com.sun.star.comp.test.deployment.passive_native_singleton">
+ <singleton name="com.sun.star.test.deployment.passive_native_singleton"/>
+ </implementation>
+</component>
diff --git a/desktop/test/deployment/passive/passive_native.cxx b/desktop/test/deployment/passive/passive_native.cxx
new file mode 100644
index 000000000000..39101257ad67
--- /dev/null
+++ b/desktop/test/deployment/passive/passive_native.cxx
@@ -0,0 +1,289 @@
+/*************************************************************************
+*
+* 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 "boost/noncopyable.hpp"
+#include "com/sun/star/awt/MessageBoxButtons.hpp"
+#include "com/sun/star/awt/Rectangle.hpp"
+#include "com/sun/star/awt/XMessageBox.hpp"
+#include "com/sun/star/awt/XMessageBoxFactory.hpp"
+#include "com/sun/star/awt/XWindowPeer.hpp"
+#include "com/sun/star/beans/PropertyValue.hpp"
+#include "com/sun/star/frame/DispatchDescriptor.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/frame/XFrame.hpp"
+#include "com/sun/star/frame/XStatusListener.hpp"
+#include "com/sun/star/lang/XComponent.hpp"
+#include "com/sun/star/lang/XMultiComponentFactory.hpp"
+#include "com/sun/star/lang/XServiceInfo.hpp"
+#include "com/sun/star/uno/DeploymentException.hpp"
+#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/XComponentContext.hpp"
+#include "com/sun/star/uno/XInterface.hpp"
+#include "com/sun/star/util/URL.hpp"
+#include "cppuhelper/factory.hxx"
+#include "cppuhelper/implbase2.hxx"
+#include "cppuhelper/implementationentry.hxx"
+#include "cppuhelper/weak.hxx"
+#include "osl/diagnose.h"
+#include "rtl/ustring.h"
+#include "rtl/ustring.hxx"
+#include "sal/types.h"
+#include "uno/lbnames.h"
+
+namespace {
+
+namespace css = com::sun::star;
+
+class Provider:
+ public cppu::WeakImplHelper2<
+ css::lang::XServiceInfo, css::frame::XDispatchProvider >,
+ private boost::noncopyable
+{
+public:
+ static css::uno::Reference< css::uno::XInterface > SAL_CALL static_create(
+ css::uno::Reference< css::uno::XComponentContext > const & xContext)
+ SAL_THROW((css::uno::Exception))
+ { return static_cast< cppu::OWeakObject * >(new Provider(xContext)); }
+
+ static rtl::OUString SAL_CALL static_getImplementationName();
+
+ static css::uno::Sequence< rtl::OUString > SAL_CALL
+ static_getSupportedServiceNames();
+
+private:
+ Provider(
+ css::uno::Reference< css::uno::XComponentContext > const & context):
+ context_(context) { OSL_ASSERT(context.is()); }
+
+ virtual ~Provider() {}
+
+ virtual rtl::OUString SAL_CALL getImplementationName()
+ throw (css::uno::RuntimeException)
+ { return static_getImplementationName(); }
+
+ virtual sal_Bool SAL_CALL supportsService(rtl::OUString const & ServiceName)
+ throw (css::uno::RuntimeException)
+ { return ServiceName == getSupportedServiceNames()[0]; } //TODO
+
+ virtual css::uno::Sequence< rtl::OUString > SAL_CALL
+ getSupportedServiceNames() throw (css::uno::RuntimeException)
+ { return static_getSupportedServiceNames(); }
+
+ virtual css::uno::Reference< css::frame::XDispatch > SAL_CALL queryDispatch(
+ css::util::URL const &, rtl::OUString const &, sal_Int32)
+ throw (css::uno::RuntimeException);
+
+ virtual css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > >
+ SAL_CALL queryDispatches(
+ css::uno::Sequence< css::frame::DispatchDescriptor > const & Requests)
+ throw (css::uno::RuntimeException);
+
+ css::uno::Reference< css::uno::XComponentContext > context_;
+};
+
+rtl::OUString Provider::static_getImplementationName() {
+ return rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.comp.test.deployment.passive_native"));
+}
+
+css::uno::Sequence< rtl::OUString > Provider::static_getSupportedServiceNames()
+{
+ rtl::OUString name(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.test.deployment.passive_native"));
+ return css::uno::Sequence< rtl::OUString >(&name, 1);
+}
+
+css::uno::Reference< css::frame::XDispatch > Provider::queryDispatch(
+ css::util::URL const &, rtl::OUString const &, sal_Int32)
+ throw (css::uno::RuntimeException)
+{
+ css::uno::Reference< css::frame::XDispatch > dispatch;
+ if (!(context_->getValueByName(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "/singletons/com.sun.star.test.deployment."
+ "passive_native_singleton"))) >>=
+ dispatch) ||
+ !dispatch.is())
+ {
+ throw css::uno::DeploymentException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "component context fails to supply singleton"
+ " com.sun.star.test.deployment.passive_native_singleton of"
+ " type com.sun.star.frame.XDispatch")),
+ context_);
+ }
+ return dispatch;
+}
+
+css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > >
+Provider::queryDispatches(
+ css::uno::Sequence< css::frame::DispatchDescriptor > const & Requests)
+ throw (css::uno::RuntimeException)
+{
+ css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > > s(
+ Requests.getLength());
+ for (sal_Int32 i = 0; i < s.getLength(); ++i) {
+ s[i] = queryDispatch(
+ Requests[i].FeatureURL, Requests[i].FrameName,
+ Requests[i].SearchFlags);
+ }
+ return s;
+}
+
+class Dispatch:
+ public cppu::WeakImplHelper2<
+ css::lang::XServiceInfo, css::frame::XDispatch >,
+ private boost::noncopyable
+{
+public:
+ static css::uno::Reference< css::uno::XInterface > SAL_CALL static_create(
+ css::uno::Reference< css::uno::XComponentContext > const & xContext)
+ SAL_THROW((css::uno::Exception))
+ { return static_cast< cppu::OWeakObject * >(new Dispatch(xContext)); }
+
+ static rtl::OUString SAL_CALL static_getImplementationName();
+
+ static css::uno::Sequence< rtl::OUString > SAL_CALL
+ static_getSupportedServiceNames()
+ { return css::uno::Sequence< rtl::OUString >(); }
+
+private:
+ Dispatch(
+ css::uno::Reference< css::uno::XComponentContext > const & context):
+ context_(context) { OSL_ASSERT(context.is()); }
+
+ virtual ~Dispatch() {}
+
+ virtual rtl::OUString SAL_CALL getImplementationName()
+ throw (css::uno::RuntimeException)
+ { return static_getImplementationName(); }
+
+ virtual sal_Bool SAL_CALL supportsService(rtl::OUString const &)
+ throw (css::uno::RuntimeException)
+ { return false; } //TODO
+
+ virtual css::uno::Sequence< rtl::OUString > SAL_CALL
+ getSupportedServiceNames() throw (css::uno::RuntimeException)
+ { return static_getSupportedServiceNames(); }
+
+ virtual void SAL_CALL dispatch(
+ css::util::URL const &,
+ css::uno::Sequence< css::beans::PropertyValue > const &)
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL addStatusListener(
+ css::uno::Reference< css::frame::XStatusListener > const &,
+ css::util::URL const &)
+ throw (css::uno::RuntimeException)
+ {}
+
+ virtual void SAL_CALL removeStatusListener(
+ css::uno::Reference< css::frame::XStatusListener > const &,
+ css::util::URL const &)
+ throw (css::uno::RuntimeException)
+ {}
+
+ css::uno::Reference< css::uno::XComponentContext > context_;
+};
+
+rtl::OUString Dispatch::static_getImplementationName() {
+ return rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.comp.test.deployment.passive_native_singleton"));
+}
+
+void Dispatch::dispatch(
+ css::util::URL const &,
+ css::uno::Sequence< css::beans::PropertyValue > const &)
+ throw (css::uno::RuntimeException)
+{
+ css::uno::Reference< css::lang::XMultiComponentFactory > smgr(
+ context_->getServiceManager(), css::uno::UNO_SET_THROW);
+ css::uno::Reference< css::awt::XMessageBox > box(
+ css::uno::Reference< css::awt::XMessageBoxFactory >(
+ smgr->createInstanceWithContext(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.awt.Toolkit")), context_),
+ css::uno::UNO_QUERY_THROW)->createMessageBox(
+ css::uno::Reference< css::awt::XWindowPeer >(
+ css::uno::Reference< css::frame::XFrame >(
+ css::uno::Reference< css::frame::XDesktop >(
+ smgr->createInstanceWithContext(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.frame.Desktop")),
+ context_),
+ css::uno::UNO_QUERY_THROW)->getCurrentFrame(),
+ css::uno::UNO_SET_THROW)->getComponentWindow(),
+ css::uno::UNO_QUERY_THROW),
+ css::awt::Rectangle(),
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("infobox")),
+ css::awt::MessageBoxButtons::BUTTONS_OK,
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("passive")),
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("native"))),
+ css::uno::UNO_SET_THROW);
+ box->execute();
+ css::uno::Reference< css::lang::XComponent >(
+ box, css::uno::UNO_QUERY_THROW)->dispose();
+}
+
+static cppu::ImplementationEntry const services[] = {
+ { &Provider::static_create, &Provider::static_getImplementationName,
+ &Provider::static_getSupportedServiceNames,
+ &cppu::createSingleComponentFactory, 0, 0 },
+ { &Dispatch::static_create, &Dispatch::static_getImplementationName,
+ &Dispatch::static_getSupportedServiceNames,
+ &cppu::createSingleComponentFactory, 0, 0 },
+ { 0, 0, 0, 0, 0, 0 }
+};
+
+}
+
+extern "C" void * SAL_CALL component_getFactory(
+ char const * pImplName, void * pServiceManager, void * pRegistryKey)
+{
+ return cppu::component_getFactoryHelper(
+ pImplName, pServiceManager, pRegistryKey, services);
+}
+
+extern "C" void SAL_CALL component_getImplementationEnvironment(
+ char const ** ppEnvTypeName, uno_Environment **)
+{
+ *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
+}
diff --git a/desktop/test/deployment/passive/passive_python.component b/desktop/test/deployment/passive/passive_python.component
new file mode 100755
index 000000000000..ea7a1992b534
--- /dev/null
+++ b/desktop/test/deployment/passive/passive_python.component
@@ -0,0 +1,38 @@
+<?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.Python"
+ xmlns="http://openoffice.org/2010/uno-components">
+ <implementation name="com.sun.star.comp.test.deployment.passive_python">
+ <service name="com.sun.star.test.deployment.passive_python"/>
+ </implementation>
+ <implementation
+ name="com.sun.star.comp.test.deployment.passive_python_singleton">
+ <singleton name="com.sun.star.test.deployment.passive_python_singleton"/>
+ </implementation>
+</component>
diff --git a/desktop/test/deployment/passive/passive_python.py b/desktop/test/deployment/passive/passive_python.py
new file mode 100755
index 000000000000..dda68cccdb2f
--- /dev/null
+++ b/desktop/test/deployment/passive/passive_python.py
@@ -0,0 +1,101 @@
+#*************************************************************************
+#
+# 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.
+#
+#***********************************************************************/
+
+import uno
+import unohelper
+
+from com.sun.star.awt import Rectangle
+from com.sun.star.awt.MessageBoxButtons import BUTTONS_OK
+from com.sun.star.frame import XDispatch, XDispatchProvider
+from com.sun.star.lang import XServiceInfo
+
+class Provider(unohelper.Base, XServiceInfo, XDispatchProvider):
+ implementationName = "com.sun.star.comp.test.deployment.passive_python"
+
+ serviceNames = ("com.sun.star.test.deployment.passive_python",)
+
+ def __init__(self, context):
+ self.context = context
+
+ def getImplementationName(self):
+ return self.implementationName
+
+ def supportsService(self, ServiceName):
+ return ServiceName in self.serviceNames
+
+ def getSupportedServiceNames(self):
+ return self.serviceNames
+
+ def queryDispatch(self, URL, TargetFrame, SearchFlags):
+ return self.context.getValueByName( \
+ "/singletons/com.sun.star.test.deployment.passive_python_singleton")
+
+ def queryDispatches(self, Requests):
+ tuple( \
+ self.queryDispatch(i.FeatureURL, i.FrameName, i.SearchFlags) \
+ for i in Requests)
+
+class Dispatch(unohelper.Base, XServiceInfo, XDispatch):
+ implementationName = \
+ "com.sun.star.comp.test.deployment.passive_python_singleton"
+
+ serviceNames = ()
+
+ def __init__(self, context):
+ self.context = context
+
+ def getImplementationName(self):
+ return self.implementationName
+
+ def supportsService(self, ServiceName):
+ return ServiceName in self.serviceNames
+
+ def getSupportedServiceNames(self):
+ return self.serviceNames
+
+ def dispatch(self, URL, Arguments):
+ smgr = self.context.getServiceManager()
+ box = smgr.createInstanceWithContext( \
+ "com.sun.star.awt.Toolkit", self.context).createMessageBox( \
+ smgr.createInstanceWithContext( \
+ "com.sun.star.frame.Desktop", self.context). \
+ getCurrentFrame().getComponentWindow(), \
+ Rectangle(), "infobox", BUTTONS_OK, "passive", "python")
+ box.execute();
+ box.dispose();
+
+ def addStatusListener(self, Control, URL):
+ pass
+
+ def removeStatusListener(self, Control, URL):
+ pass
+
+g_ImplementationHelper = unohelper.ImplementationHelper()
+g_ImplementationHelper.addImplementation( \
+ Provider, Provider.implementationName, Provider.serviceNames)
+g_ImplementationHelper.addImplementation( \
+ Dispatch, Dispatch.implementationName, Dispatch.serviceNames)
diff --git a/desktop/test/deployment/simple_license/BadDesc.oxt b/desktop/test/deployment/simple_license/BadDesc.oxt
new file mode 100644
index 000000000000..436778d54dd4
--- /dev/null
+++ b/desktop/test/deployment/simple_license/BadDesc.oxt
Binary files differ
diff --git a/desktop/test/deployment/simple_license/BadNamespace.oxt b/desktop/test/deployment/simple_license/BadNamespace.oxt
new file mode 100644
index 000000000000..e439c9e171de
--- /dev/null
+++ b/desktop/test/deployment/simple_license/BadNamespace.oxt
Binary files differ
diff --git a/desktop/test/deployment/simple_license/BadRoot.oxt b/desktop/test/deployment/simple_license/BadRoot.oxt
new file mode 100644
index 000000000000..1f6c60c992ba
--- /dev/null
+++ b/desktop/test/deployment/simple_license/BadRoot.oxt
Binary files differ
diff --git a/desktop/test/deployment/simple_license/Locale1.oxt b/desktop/test/deployment/simple_license/Locale1.oxt
new file mode 100644
index 000000000000..51ecb5c75c6c
--- /dev/null
+++ b/desktop/test/deployment/simple_license/Locale1.oxt
Binary files differ
diff --git a/desktop/test/deployment/simple_license/Locale2.oxt b/desktop/test/deployment/simple_license/Locale2.oxt
new file mode 100644
index 000000000000..bb6b236a5d07
--- /dev/null
+++ b/desktop/test/deployment/simple_license/Locale2.oxt
Binary files differ
diff --git a/desktop/test/deployment/simple_license/Locale3.oxt b/desktop/test/deployment/simple_license/Locale3.oxt
new file mode 100644
index 000000000000..56bfedc24025
--- /dev/null
+++ b/desktop/test/deployment/simple_license/Locale3.oxt
Binary files differ
diff --git a/desktop/test/deployment/simple_license/Locale4.oxt b/desktop/test/deployment/simple_license/Locale4.oxt
new file mode 100644
index 000000000000..9a465bc7cff3
--- /dev/null
+++ b/desktop/test/deployment/simple_license/Locale4.oxt
Binary files differ
diff --git a/desktop/test/deployment/simple_license/Locale5.oxt b/desktop/test/deployment/simple_license/Locale5.oxt
new file mode 100644
index 000000000000..ce16830c13fa
--- /dev/null
+++ b/desktop/test/deployment/simple_license/Locale5.oxt
Binary files differ
diff --git a/desktop/test/deployment/simple_license/Locale6.oxt b/desktop/test/deployment/simple_license/Locale6.oxt
new file mode 100644
index 000000000000..770d32506ee3
--- /dev/null
+++ b/desktop/test/deployment/simple_license/Locale6.oxt
Binary files differ
diff --git a/desktop/test/deployment/simple_license/LongLic.oxt b/desktop/test/deployment/simple_license/LongLic.oxt
new file mode 100644
index 000000000000..a0a49daebacf
--- /dev/null
+++ b/desktop/test/deployment/simple_license/LongLic.oxt
Binary files differ
diff --git a/desktop/test/deployment/simple_license/MissingLic.oxt b/desktop/test/deployment/simple_license/MissingLic.oxt
new file mode 100644
index 000000000000..04d58fd117a2
--- /dev/null
+++ b/desktop/test/deployment/simple_license/MissingLic.oxt
Binary files differ
diff --git a/desktop/test/deployment/simple_license/MissingLicRef.oxt b/desktop/test/deployment/simple_license/MissingLicRef.oxt
new file mode 100644
index 000000000000..01c9d19a2833
--- /dev/null
+++ b/desktop/test/deployment/simple_license/MissingLicRef.oxt
Binary files differ
diff --git a/desktop/test/deployment/simple_license/NoDefLang.oxt b/desktop/test/deployment/simple_license/NoDefLang.oxt
new file mode 100644
index 000000000000..3eadd5254ccc
--- /dev/null
+++ b/desktop/test/deployment/simple_license/NoDefLang.oxt
Binary files differ
diff --git a/desktop/test/deployment/simple_license/NoDesc.oxt b/desktop/test/deployment/simple_license/NoDesc.oxt
new file mode 100644
index 000000000000..ac83dac97eba
--- /dev/null
+++ b/desktop/test/deployment/simple_license/NoDesc.oxt
Binary files differ
diff --git a/desktop/test/deployment/simple_license/NoLang.oxt b/desktop/test/deployment/simple_license/NoLang.oxt
new file mode 100644
index 000000000000..a4f3dd43a079
--- /dev/null
+++ b/desktop/test/deployment/simple_license/NoLang.oxt
Binary files differ
diff --git a/desktop/test/deployment/simple_license/Prefix.oxt b/desktop/test/deployment/simple_license/Prefix.oxt
new file mode 100644
index 000000000000..3e09b8d804e9
--- /dev/null
+++ b/desktop/test/deployment/simple_license/Prefix.oxt
Binary files differ
diff --git a/desktop/test/deployment/simple_license/ShortLicense.oxt b/desktop/test/deployment/simple_license/ShortLicense.oxt
new file mode 100644
index 000000000000..efcfdc98e125
--- /dev/null
+++ b/desktop/test/deployment/simple_license/ShortLicense.oxt
Binary files differ
diff --git a/desktop/test/deployment/simple_license/ShortLicenseShared.oxt b/desktop/test/deployment/simple_license/ShortLicenseShared.oxt
new file mode 100644
index 000000000000..775559a2c7a3
--- /dev/null
+++ b/desktop/test/deployment/simple_license/ShortLicenseShared.oxt
Binary files differ
diff --git a/desktop/test/deployment/simple_license/suppress_license.oxt b/desktop/test/deployment/simple_license/suppress_license.oxt
new file mode 100644
index 000000000000..2bacd6aa378b
--- /dev/null
+++ b/desktop/test/deployment/simple_license/suppress_license.oxt
Binary files differ
diff --git a/desktop/test/deployment/simple_license/tests_simple_license.odt b/desktop/test/deployment/simple_license/tests_simple_license.odt
new file mode 100644
index 000000000000..b0c86e11c69b
--- /dev/null
+++ b/desktop/test/deployment/simple_license/tests_simple_license.odt
Binary files differ
diff --git a/desktop/test/deployment/update/changing_display_name/change1.oxt b/desktop/test/deployment/update/changing_display_name/change1.oxt
new file mode 100644
index 000000000000..c919129ab6d7
--- /dev/null
+++ b/desktop/test/deployment/update/changing_display_name/change1.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/changing_display_name/change1_mod.oxt b/desktop/test/deployment/update/changing_display_name/change1_mod.oxt
new file mode 100644
index 000000000000..5ab99d7bf224
--- /dev/null
+++ b/desktop/test/deployment/update/changing_display_name/change1_mod.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/changing_display_name/readme.txt b/desktop/test/deployment/update/changing_display_name/readme.txt
new file mode 100755
index 000000000000..905f0be9a962
--- /dev/null
+++ b/desktop/test/deployment/update/changing_display_name/readme.txt
@@ -0,0 +1,13 @@
+
+The default display name, if nothing is provided by the extension, is the file name.
+The display name could be changed in different versions. There are three versions
+of change1.oxt available:
+
+v1: no display name
+v2: change1 de
+v3: change1 de - changed display name -
+
+change1_mod.oxt is the same as change1.oxt version 1 except that is has a display name.
+This situation should actually never arise, because the version should always be
+changed when the extension is changed - and be it only the display name.
+
diff --git a/desktop/test/deployment/update/changing_display_name/update1/change1.oxt b/desktop/test/deployment/update/changing_display_name/update1/change1.oxt
new file mode 100644
index 000000000000..ef034f94459f
--- /dev/null
+++ b/desktop/test/deployment/update/changing_display_name/update1/change1.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/changing_display_name/update1/change1.update.xml b/desktop/test/deployment/update/changing_display_name/update1/change1.update.xml
new file mode 100755
index 000000000000..a4fefb6d96ba
--- /dev/null
+++ b/desktop/test/deployment/update/changing_display_name/update1/change1.update.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<description xmlns="http://openoffice.org/extensions/update/2006"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+ <identifier value="org.openoffice/framework/desktop/changing_display_name/change1" />
+ <version value="2.0" />
+ <update-download>
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/changing_display_name/update1/change1.oxt" />
+ </update-download>
+</description>
+
diff --git a/desktop/test/deployment/update/changing_display_name/update2/change1.oxt b/desktop/test/deployment/update/changing_display_name/update2/change1.oxt
new file mode 100644
index 000000000000..551f5a3f48c3
--- /dev/null
+++ b/desktop/test/deployment/update/changing_display_name/update2/change1.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/changing_display_name/update2/change1.update.xml b/desktop/test/deployment/update/changing_display_name/update2/change1.update.xml
new file mode 100755
index 000000000000..8e52ce3c2b2d
--- /dev/null
+++ b/desktop/test/deployment/update/changing_display_name/update2/change1.update.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<description xmlns="http://openoffice.org/extensions/update/2006"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+ <identifier value="org.openoffice/framework/desktop/changing_display_name/change1" />
+ <version value="3.0" />
+ <update-download>
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/changing_display_name/update2/change1.oxt" />
+ </update-download>
+</description>
+
diff --git a/desktop/test/deployment/update/default_url/default1.oxt b/desktop/test/deployment/update/default_url/default1.oxt
new file mode 100644
index 000000000000..3fa8c9f08f8d
--- /dev/null
+++ b/desktop/test/deployment/update/default_url/default1.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/default_url/default2.oxt b/desktop/test/deployment/update/default_url/default2.oxt
new file mode 100644
index 000000000000..d54ce88c51d6
--- /dev/null
+++ b/desktop/test/deployment/update/default_url/default2.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/default_url/readme.txt b/desktop/test/deployment/update/default_url/readme.txt
new file mode 100755
index 000000000000..4ae7936bfc18
--- /dev/null
+++ b/desktop/test/deployment/update/default_url/readme.txt
@@ -0,0 +1,9 @@
+Tests for using the default URL for update information. This URL is currently contained in
+the version.ini (ExtensionUpdateURL) and is used to obtain update information for extensions which do not provide
+an URL themselves.
+
+The extensions default1.oxt and default2.oxt do not have a URL for update information.
+
+To test this one has to put this entry into the version.ini:
+
+ExtensionUpdateURL=http://extensions.openoffice.org/testarea/desktop/default_url/update/feed1.xml
diff --git a/desktop/test/deployment/update/default_url/update/default1.oxt b/desktop/test/deployment/update/default_url/update/default1.oxt
new file mode 100644
index 000000000000..198395c76e5d
--- /dev/null
+++ b/desktop/test/deployment/update/default_url/update/default1.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/default_url/update/default1.update.xml b/desktop/test/deployment/update/default_url/update/default1.update.xml
new file mode 100755
index 000000000000..b3d78e29e814
--- /dev/null
+++ b/desktop/test/deployment/update/default_url/update/default1.update.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<description xmlns="http://openoffice.org/extensions/update/2006"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+ <identifier value="org.openoffice.legacy.default1.oxt"/>
+ <version value="2.0" />
+ <update-download>
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/default_url/update/default1.oxt" />
+ </update-download>
+</description>
+
diff --git a/desktop/test/deployment/update/default_url/update/default2.oxt b/desktop/test/deployment/update/default_url/update/default2.oxt
new file mode 100644
index 000000000000..198395c76e5d
--- /dev/null
+++ b/desktop/test/deployment/update/default_url/update/default2.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/default_url/update/default2.update.xml b/desktop/test/deployment/update/default_url/update/default2.update.xml
new file mode 100755
index 000000000000..a5894a18b05b
--- /dev/null
+++ b/desktop/test/deployment/update/default_url/update/default2.update.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<description xmlns="http://openoffice.org/extensions/update/2006"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+ <identifier value="org.openoffice.legacy.default2.oxt"/>
+ <version value="2.0" />
+ <update-download>
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/default_url/update/default2.oxt" />
+ </update-download>
+</description>
+
diff --git a/desktop/test/deployment/update/default_url/update/feed1.xml b/desktop/test/deployment/update/default_url/update/feed1.xml
new file mode 100755
index 000000000000..b504b7b4b00c
--- /dev/null
+++ b/desktop/test/deployment/update/default_url/update/feed1.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-US">
+
+ <title>OpenOffice.org Update Feed</title>
+ <link rel="alternate" type="text/html" href="http://update.services.openoffice.org/ooo/snapshot.html"/>
+ <updated>2006-11-06T18:30:02Z</updated>
+ <author>
+ <name>The OpenOffice.org Project</name>
+ <uri>http://openoffice.org</uri>
+ <email>updatefeed@openoffice.org</email>
+ </author>
+ <id>urn:uuid:a4ccd383-1dd1-11b2-a95c-0003ba566e9d</id>
+ <entry>
+ <title>default1.oxt version 2.0 available</title>
+ <link rel="alternate" type="text/html"
+ href="http://extensions.openoffice.org"/>
+ <id>urn:uuid:a4ccd383-1dd1-11b2-a95c-0003ba566e9f</id>
+ <category term="org.openoffice.legacy.default1.oxt" label="default1.oxt" />
+ <updated>2006-11-06T18:30:02Z</updated>
+ <summary>Click here to go to the download page.</summary>
+ <content type="application/xml" src="http://extensions.openoffice.org/testarea/desktop/default_url/update/default1.update.xml" />
+ </entry>
+ <entry>
+ <title>default2.oxt version 2.0 available</title>
+ <link rel="alternate" type="text/html"
+ href="http://extensions.openoffice.org"/>
+ <id>urn:uuid:a4ccd383-1dd1-11b2-a95c-0003ba566eaf</id>
+ <category term="org.openoffice.legacy.default2.oxt" label="default2.oxt" />
+ <updated>2006-11-06T18:30:02Z</updated>
+ <summary>Click here to go to the download page.</summary>
+ <content type="application/xml" src="http://extensions.openoffice.org/testarea/desktop/default_url/update/default2.update.xml" />
+ </entry>
+</feed>
diff --git a/desktop/test/deployment/update/defect/fail1.oxt b/desktop/test/deployment/update/defect/fail1.oxt
new file mode 100644
index 000000000000..5b5cdba2cdbc
--- /dev/null
+++ b/desktop/test/deployment/update/defect/fail1.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/defect/fail2.oxt b/desktop/test/deployment/update/defect/fail2.oxt
new file mode 100644
index 000000000000..61b0306f0947
--- /dev/null
+++ b/desktop/test/deployment/update/defect/fail2.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/defect/fail3.oxt b/desktop/test/deployment/update/defect/fail3.oxt
new file mode 100644
index 000000000000..9da26d48a636
--- /dev/null
+++ b/desktop/test/deployment/update/defect/fail3.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/defect/fail4.oxt b/desktop/test/deployment/update/defect/fail4.oxt
new file mode 100644
index 000000000000..66b87caa14b7
--- /dev/null
+++ b/desktop/test/deployment/update/defect/fail4.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/defect/info1.oxt b/desktop/test/deployment/update/defect/info1.oxt
new file mode 100644
index 000000000000..9ffd373fa11f
--- /dev/null
+++ b/desktop/test/deployment/update/defect/info1.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/defect/info2.oxt b/desktop/test/deployment/update/defect/info2.oxt
new file mode 100644
index 000000000000..229a52c3bc69
--- /dev/null
+++ b/desktop/test/deployment/update/defect/info2.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/defect/info3.oxt b/desktop/test/deployment/update/defect/info3.oxt
new file mode 100644
index 000000000000..b702f3e00417
--- /dev/null
+++ b/desktop/test/deployment/update/defect/info3.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/defect/readme.txt b/desktop/test/deployment/update/defect/readme.txt
new file mode 100755
index 000000000000..5e8322f5cf26
--- /dev/null
+++ b/desktop/test/deployment/update/defect/readme.txt
@@ -0,0 +1,15 @@
+The updates, that is the newer versions, are defect. However, only fail2.oxt fails to install. The other extensions can be installed directly and through an update.
+
+fail1.oxt: in version2 the contained t.rdb was renamed so that it is not found (t.rdb is referenced in the manifest.xml).
+
+fail2.oxt: in version 2 the contained t.rdb is corrupted. It is a renamed .txt file which contains some text.
+
+fail3.oxt: in version 2 the contained t.rdb is corrupted. It is a renamed .txt file which does not contain any text.
+
+fail4.oxt: the version 2 references by fail4.update.xml is empty.
+
+info1.oxt: The update information file has length null.
+
+info2.oxt: The update information does not contain xml.
+
+info3.oxt: The update information contain an error: the tag update information contains two opening brackets (<<update-information>) \ No newline at end of file
diff --git a/desktop/test/deployment/update/defect/update/fail1.oxt b/desktop/test/deployment/update/defect/update/fail1.oxt
new file mode 100644
index 000000000000..dbcc7cd73eb9
--- /dev/null
+++ b/desktop/test/deployment/update/defect/update/fail1.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/defect/update/fail1.update.xml b/desktop/test/deployment/update/defect/update/fail1.update.xml
new file mode 100755
index 000000000000..40f2d1c7df9f
--- /dev/null
+++ b/desktop/test/deployment/update/defect/update/fail1.update.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<description xmlns="http://openoffice.org/extensions/update/2006"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+ <identifier value="org.openoffice.legacy.fail1.oxt"/>
+ <version value="2.0" />
+ <update-download>
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/defect/update/fail1.oxt" />
+ </update-download>
+</description>
+
diff --git a/desktop/test/deployment/update/defect/update/fail2.oxt b/desktop/test/deployment/update/defect/update/fail2.oxt
new file mode 100644
index 000000000000..6df0c3cf9977
--- /dev/null
+++ b/desktop/test/deployment/update/defect/update/fail2.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/defect/update/fail2.update.xml b/desktop/test/deployment/update/defect/update/fail2.update.xml
new file mode 100755
index 000000000000..d6bdaccb30e9
--- /dev/null
+++ b/desktop/test/deployment/update/defect/update/fail2.update.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<description xmlns="http://openoffice.org/extensions/update/2006"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+ <identifier value="org.openoffice.legacy.fail2.oxt"/>
+ <version value="2.0" />
+ <update-download>
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/defect/update/fail2.oxt" />
+ </update-download>
+</description>
+
diff --git a/desktop/test/deployment/update/defect/update/fail3.oxt b/desktop/test/deployment/update/defect/update/fail3.oxt
new file mode 100644
index 000000000000..2d340f41443b
--- /dev/null
+++ b/desktop/test/deployment/update/defect/update/fail3.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/defect/update/fail3.update.xml b/desktop/test/deployment/update/defect/update/fail3.update.xml
new file mode 100755
index 000000000000..e7f2606d604c
--- /dev/null
+++ b/desktop/test/deployment/update/defect/update/fail3.update.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<description xmlns="http://openoffice.org/extensions/update/2006"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+ <identifier value="org.openoffice.legacy.fail3.oxt"/>
+ <version value="2.0" />
+ <update-download>
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/defect/update/fail3.oxt" />
+ </update-download>
+</description>
+
diff --git a/desktop/test/deployment/update/defect/update/fail4.oxt b/desktop/test/deployment/update/defect/update/fail4.oxt
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/desktop/test/deployment/update/defect/update/fail4.oxt
diff --git a/desktop/test/deployment/update/defect/update/fail4.update.xml b/desktop/test/deployment/update/defect/update/fail4.update.xml
new file mode 100755
index 000000000000..4b293f28e034
--- /dev/null
+++ b/desktop/test/deployment/update/defect/update/fail4.update.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<description xmlns="http://openoffice.org/extensions/update/2006"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+ <identifier value="org.openoffice.legacy.fail4.oxt"/>
+ <version value="2.0" />
+ <update-download>
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/defect/update/fail4.oxt" />
+ </update-download>
+</description>
+
diff --git a/desktop/test/deployment/update/defect/update/info1.update.xml b/desktop/test/deployment/update/defect/update/info1.update.xml
new file mode 100755
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/desktop/test/deployment/update/defect/update/info1.update.xml
diff --git a/desktop/test/deployment/update/defect/update/info2.update.xml b/desktop/test/deployment/update/defect/update/info2.update.xml
new file mode 100755
index 000000000000..1446608022f0
--- /dev/null
+++ b/desktop/test/deployment/update/defect/update/info2.update.xml
@@ -0,0 +1 @@
+This is a invalid update information file!!!
diff --git a/desktop/test/deployment/update/defect/update/info3.oxt b/desktop/test/deployment/update/defect/update/info3.oxt
new file mode 100644
index 000000000000..60debac57c4e
--- /dev/null
+++ b/desktop/test/deployment/update/defect/update/info3.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/defect/update/info3.update.xml b/desktop/test/deployment/update/defect/update/info3.update.xml
new file mode 100755
index 000000000000..62306e55b693
--- /dev/null
+++ b/desktop/test/deployment/update/defect/update/info3.update.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<description xmlns="http://openoffice.org/extensions/update/2006"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+ <identifier value="org.openoffice.legacy.info3.oxt"/>
+ <version value="2.0" />
+ <<update-download>
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/defect/update/info3.oxt" />
+ </update-download>
+</description>
+
diff --git a/desktop/test/deployment/update/dependencies/publisher_en.html b/desktop/test/deployment/update/dependencies/publisher_en.html
new file mode 100755
index 000000000000..37dbc2b9d6ce
--- /dev/null
+++ b/desktop/test/deployment/update/dependencies/publisher_en.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+</HEAD>
+<BODY>
+<H1>My Extension Company</H1>
+</BODY>
+</HTML>
+
diff --git a/desktop/test/deployment/update/dependencies/readme.txt b/desktop/test/deployment/update/dependencies/readme.txt
new file mode 100755
index 000000000000..3c71da24884d
--- /dev/null
+++ b/desktop/test/deployment/update/dependencies/readme.txt
@@ -0,0 +1,32 @@
+#*************************************************************************
+#
+# 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.
+#
+#*************************************************************************
+
+update-dependencies.oxt is an extension that itself has no dependencies, but
+whose update has unsatisfied dependencies (and also uses update-website).
+
+The update information contain also publisher and release notes information,
+which should be displayed in the update dialog.
diff --git a/desktop/test/deployment/update/dependencies/release-notes_en.html b/desktop/test/deployment/update/dependencies/release-notes_en.html
new file mode 100755
index 000000000000..0971f78d1484
--- /dev/null
+++ b/desktop/test/deployment/update/dependencies/release-notes_en.html
@@ -0,0 +1,8 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+</HEAD>
+<BODY>
+<H1>Release Notes</H1>
+</BODY>
+</HTML>
diff --git a/desktop/test/deployment/update/dependencies/update-dependencies.oxt b/desktop/test/deployment/update/dependencies/update-dependencies.oxt
new file mode 100644
index 000000000000..513b25d20763
--- /dev/null
+++ b/desktop/test/deployment/update/dependencies/update-dependencies.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/dependencies/update/update-dependencies.update.xml b/desktop/test/deployment/update/dependencies/update/update-dependencies.update.xml
new file mode 100755
index 000000000000..bf8a399da116
--- /dev/null
+++ b/desktop/test/deployment/update/dependencies/update/update-dependencies.update.xml
@@ -0,0 +1,71 @@
+<?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.
+
+ ************************************************************************ -->
+<description xmlns="http://openoffice.org/extensions/update/2006"
+ xmlns:d="http://openoffice.org/extensions/description/2006"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+ <identifier value="org.openoffice/framework/desktop/test/deployment/update/dependencies/update-dependencies.oxt"/>
+ <version value="2.0"/>
+ <dependencies>
+ <dependency d:name="&amp; &lt; &gt; &apos; &quot; > ' tab&#x9;. crlf&#xD;&#xA;. em-dash&#x2014;. line-separator&#x2028;. paragraph-separator&#x2029;. xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"/>
+ <dependency d:name="Dependency 1"/>
+ <dependency d:name="Dependency 2"/>
+ <dependency d:name="Dependency 3"/>
+ <dependency d:name="Dependency 4"/>
+ <dependency d:name="Dependency 5"/>
+ <dependency d:name="Dependency 6"/>
+ <dependency d:name="Dependency 7"/>
+ <dependency d:name="Dependency 8"/>
+ <dependency d:name="Dependency 9"/>
+ <dependency d:name="Dependency 10"/>
+ <dependency d:name="Dependency 11"/>
+ <dependency d:name="Dependency 12"/>
+ <dependency d:name="Dependency 13"/>
+ <dependency d:name="Dependency 14"/>
+ <dependency d:name="Dependency 15"/>
+ <dependency d:name="Dependency 16"/>
+ <dependency d:name="Dependency 17"/>
+ <dependency d:name="Dependency 18"/>
+ <dependency d:name="Dependency 19"/>
+ <dependency d:name="Dependency 20"/>
+ <dependency/>
+ <d:OpenOffice.org-minimal-version value="2.1" d:name="OpenOffice.org 2.1"/>
+ </dependencies>
+ <update-website>
+ <src xlink:href="http://nowhere.openoffice.org"/>
+ <src xlink:href="http://nowhere.openoffice.org/2"/>
+ </update-website>
+
+ <publisher>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/dependencies/publisher_en.html" lang="en">My Extension Company</name>
+ </publisher>
+
+ <release-notes>
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/dependencies/release-notes_en.html" lang="en" />
+ </release-notes>
+
+</description>
diff --git a/desktop/test/deployment/update/license/lic1.oxt b/desktop/test/deployment/update/license/lic1.oxt
new file mode 100644
index 000000000000..43bfe3b77b2d
--- /dev/null
+++ b/desktop/test/deployment/update/license/lic1.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/license/lic2.oxt b/desktop/test/deployment/update/license/lic2.oxt
new file mode 100644
index 000000000000..266a45e9a857
--- /dev/null
+++ b/desktop/test/deployment/update/license/lic2.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/license/lic3.oxt b/desktop/test/deployment/update/license/lic3.oxt
new file mode 100644
index 000000000000..3f1b98960043
--- /dev/null
+++ b/desktop/test/deployment/update/license/lic3.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/license/readme.txt b/desktop/test/deployment/update/license/readme.txt
new file mode 100755
index 000000000000..03123d2c5812
--- /dev/null
+++ b/desktop/test/deployment/update/license/readme.txt
@@ -0,0 +1,9 @@
+The extensions contain a license which is displayed during installaion. If a the license is displayed during a update can be determined by the attribute
+/description/registration/simple-license/@suppress-on-update
+
+The default value is false, which means that the attribute is not set, then the license is displayed during an update.
+
+lic1.oxt: attribute not set
+lic2.oxt: attribute set to false
+lic3.oxt: attribute set to true
+
diff --git a/desktop/test/deployment/update/license/update/lic1.oxt b/desktop/test/deployment/update/license/update/lic1.oxt
new file mode 100644
index 000000000000..cc91e1ff16fe
--- /dev/null
+++ b/desktop/test/deployment/update/license/update/lic1.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/license/update/lic1.update.xml b/desktop/test/deployment/update/license/update/lic1.update.xml
new file mode 100755
index 000000000000..6b23b97890fc
--- /dev/null
+++ b/desktop/test/deployment/update/license/update/lic1.update.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<description xmlns="http://openoffice.org/extensions/update/2006"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+ <identifier value="org.openoffice.legacy.lic1.oxt"/>
+ <version value="2.0" />
+ <update-download>
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/license/update/lic1.oxt" />
+ </update-download>
+</description>
+
diff --git a/desktop/test/deployment/update/license/update/lic2.oxt b/desktop/test/deployment/update/license/update/lic2.oxt
new file mode 100644
index 000000000000..351000792487
--- /dev/null
+++ b/desktop/test/deployment/update/license/update/lic2.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/license/update/lic2.update.xml b/desktop/test/deployment/update/license/update/lic2.update.xml
new file mode 100755
index 000000000000..40f3fa47bc99
--- /dev/null
+++ b/desktop/test/deployment/update/license/update/lic2.update.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<description xmlns="http://openoffice.org/extensions/update/2006"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+ <identifier value="org.openoffice.legacy.lic2.oxt"/>
+ <version value="2.0" />
+ <update-download>
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/license/update/lic2.oxt" />
+ </update-download>
+</description>
+
diff --git a/desktop/test/deployment/update/license/update/lic3.oxt b/desktop/test/deployment/update/license/update/lic3.oxt
new file mode 100644
index 000000000000..6ac6e0fd0fd1
--- /dev/null
+++ b/desktop/test/deployment/update/license/update/lic3.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/license/update/lic3.update.xml b/desktop/test/deployment/update/license/update/lic3.update.xml
new file mode 100755
index 000000000000..a9c2a7995d7c
--- /dev/null
+++ b/desktop/test/deployment/update/license/update/lic3.update.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<description xmlns="http://openoffice.org/extensions/update/2006"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+ <identifier value="org.openoffice.legacy.lic3.oxt"/>
+ <version value="2.0" />
+ <update-download>
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/license/update/lic3.oxt" />
+ </update-download>
+</description>
+
diff --git a/desktop/test/deployment/update/platform/all1.oxt b/desktop/test/deployment/update/platform/all1.oxt
new file mode 100644
index 000000000000..ad9662a7c226
--- /dev/null
+++ b/desktop/test/deployment/update/platform/all1.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/platform/all2.oxt b/desktop/test/deployment/update/platform/all2.oxt
new file mode 100644
index 000000000000..632d11b42938
--- /dev/null
+++ b/desktop/test/deployment/update/platform/all2.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/platform/all3.oxt b/desktop/test/deployment/update/platform/all3.oxt
new file mode 100644
index 000000000000..ab781552a5aa
--- /dev/null
+++ b/desktop/test/deployment/update/platform/all3.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/platform/freebsd_x86.oxt b/desktop/test/deployment/update/platform/freebsd_x86.oxt
new file mode 100644
index 000000000000..338f5761deb1
--- /dev/null
+++ b/desktop/test/deployment/update/platform/freebsd_x86.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/platform/freebsd_x86_64.oxt b/desktop/test/deployment/update/platform/freebsd_x86_64.oxt
new file mode 100644
index 000000000000..39fee6de1a77
--- /dev/null
+++ b/desktop/test/deployment/update/platform/freebsd_x86_64.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/platform/invalid1.oxt b/desktop/test/deployment/update/platform/invalid1.oxt
new file mode 100644
index 000000000000..13d709f438fc
--- /dev/null
+++ b/desktop/test/deployment/update/platform/invalid1.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/platform/invalid2.oxt b/desktop/test/deployment/update/platform/invalid2.oxt
new file mode 100644
index 000000000000..f14257191b81
--- /dev/null
+++ b/desktop/test/deployment/update/platform/invalid2.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/platform/invalid3.oxt b/desktop/test/deployment/update/platform/invalid3.oxt
new file mode 100644
index 000000000000..cadffa4f2ac1
--- /dev/null
+++ b/desktop/test/deployment/update/platform/invalid3.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/platform/linux_arm_eabi.oxt b/desktop/test/deployment/update/platform/linux_arm_eabi.oxt
new file mode 100644
index 000000000000..9c504e841b98
--- /dev/null
+++ b/desktop/test/deployment/update/platform/linux_arm_eabi.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/platform/linux_arm_oabi.oxt b/desktop/test/deployment/update/platform/linux_arm_oabi.oxt
new file mode 100644
index 000000000000..f2c987f645a7
--- /dev/null
+++ b/desktop/test/deployment/update/platform/linux_arm_oabi.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/platform/linux_ia64.oxt b/desktop/test/deployment/update/platform/linux_ia64.oxt
new file mode 100644
index 000000000000..f579a18ab90d
--- /dev/null
+++ b/desktop/test/deployment/update/platform/linux_ia64.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/platform/linux_mips_eb.oxt b/desktop/test/deployment/update/platform/linux_mips_eb.oxt
new file mode 100644
index 000000000000..bf0bd942332b
--- /dev/null
+++ b/desktop/test/deployment/update/platform/linux_mips_eb.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/platform/linux_mips_el.oxt b/desktop/test/deployment/update/platform/linux_mips_el.oxt
new file mode 100644
index 000000000000..6bd56446831b
--- /dev/null
+++ b/desktop/test/deployment/update/platform/linux_mips_el.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/platform/linux_powerpc.oxt b/desktop/test/deployment/update/platform/linux_powerpc.oxt
new file mode 100644
index 000000000000..e301a3fb3ad1
--- /dev/null
+++ b/desktop/test/deployment/update/platform/linux_powerpc.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/platform/linux_powerpc64.oxt b/desktop/test/deployment/update/platform/linux_powerpc64.oxt
new file mode 100644
index 000000000000..e5f3ae063923
--- /dev/null
+++ b/desktop/test/deployment/update/platform/linux_powerpc64.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/platform/linux_s390.oxt b/desktop/test/deployment/update/platform/linux_s390.oxt
new file mode 100644
index 000000000000..199702ebf056
--- /dev/null
+++ b/desktop/test/deployment/update/platform/linux_s390.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/platform/linux_s390x.oxt b/desktop/test/deployment/update/platform/linux_s390x.oxt
new file mode 100644
index 000000000000..2ed250833fb1
--- /dev/null
+++ b/desktop/test/deployment/update/platform/linux_s390x.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/platform/linux_sparc.oxt b/desktop/test/deployment/update/platform/linux_sparc.oxt
new file mode 100644
index 000000000000..53dfc71e0c4e
--- /dev/null
+++ b/desktop/test/deployment/update/platform/linux_sparc.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/platform/linux_x86.oxt b/desktop/test/deployment/update/platform/linux_x86.oxt
new file mode 100644
index 000000000000..8379539cad34
--- /dev/null
+++ b/desktop/test/deployment/update/platform/linux_x86.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/platform/linux_x86_64.oxt b/desktop/test/deployment/update/platform/linux_x86_64.oxt
new file mode 100644
index 000000000000..0fb18227522f
--- /dev/null
+++ b/desktop/test/deployment/update/platform/linux_x86_64.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/platform/macosx_powerpc.oxt b/desktop/test/deployment/update/platform/macosx_powerpc.oxt
new file mode 100644
index 000000000000..7c146347127a
--- /dev/null
+++ b/desktop/test/deployment/update/platform/macosx_powerpc.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/platform/macosx_x86.oxt b/desktop/test/deployment/update/platform/macosx_x86.oxt
new file mode 100644
index 000000000000..a20aadfefffd
--- /dev/null
+++ b/desktop/test/deployment/update/platform/macosx_x86.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/platform/mul1.oxt b/desktop/test/deployment/update/platform/mul1.oxt
new file mode 100644
index 000000000000..b3b555969bdf
--- /dev/null
+++ b/desktop/test/deployment/update/platform/mul1.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/platform/os2_x86.oxt b/desktop/test/deployment/update/platform/os2_x86.oxt
new file mode 100644
index 000000000000..1c7fd40bef9f
--- /dev/null
+++ b/desktop/test/deployment/update/platform/os2_x86.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/platform/readme.txt b/desktop/test/deployment/update/platform/readme.txt
new file mode 100755
index 000000000000..2ab102a27d3c
--- /dev/null
+++ b/desktop/test/deployment/update/platform/readme.txt
@@ -0,0 +1,49 @@
+Extension which only support one platform
+========================================================
+
+freebsd_x86.oxt: freebsd_x86
+freebsd_x86_86.oxt: freebsd_x86_64
+linux_arm_eabi.oxt: linux_arm_eabi
+linux_arm_oabi.oxt: linux_arm_oabi
+linux_ia64.oxt: linux_ia64
+linux_mips_eb.oxt: linux_mips_eb
+linux_mips_el.oxt: linux_mips_el
+linux_powerpc64.oxt: linux_powerpc64
+linux_powerpc.oxt: linux_powerpc
+linux_s390.oxt: linux_s390
+linux_s390x.oxt: linux_s390x
+linux_sparc.oxt: linux_sparc
+linux_x86.oxt: linux_x86
+linux_x86_64.oxt: linux_x86_64
+macos_powerpc.oxt: macos_powerpc
+macos_x86.oxt: macos_x86
+solaris_sparc.oxt: solaris_sparc
+solaris_x86.oxt: solaris_x86
+windows_x86.oxt: windows_x86
+os2_x86.oxt: os/2_x86
+
+Extensions which support multiple platforms
+=======================================================
+mul1.oxt: windows_x86, linux_x86, solaris_x86
+
+
+All platforms
+=========================================================
+all1.oxt: all, The <platform> element is missing. Default is "all".
+
+all2.oxt: all, <platform value="all" />
+
+all3.oxt: all, no description.xml
+
+
+
+Invalid platforms
+=========================================================
+The following extensions cannot be installed because the platform element
+is not correct. We assume that no valid platform is defined.
+
+invalid1.oxt: <platform />
+
+invalid2.oxt: <platform value=""/>
+
+invalid3.oxt: <platform value="," />
diff --git a/desktop/test/deployment/update/platform/solaris_sparc.oxt b/desktop/test/deployment/update/platform/solaris_sparc.oxt
new file mode 100644
index 000000000000..a61f81f43942
--- /dev/null
+++ b/desktop/test/deployment/update/platform/solaris_sparc.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/platform/solaris_x86.oxt b/desktop/test/deployment/update/platform/solaris_x86.oxt
new file mode 100644
index 000000000000..44d43df69184
--- /dev/null
+++ b/desktop/test/deployment/update/platform/solaris_x86.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/platform/windows_x86.oxt b/desktop/test/deployment/update/platform/windows_x86.oxt
new file mode 100644
index 000000000000..c66a9b1418fa
--- /dev/null
+++ b/desktop/test/deployment/update/platform/windows_x86.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/publisher/pub1.oxt b/desktop/test/deployment/update/publisher/pub1.oxt
new file mode 100644
index 000000000000..c44ee9f3bc56
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/pub1.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/publisher/pub10.oxt b/desktop/test/deployment/update/publisher/pub10.oxt
new file mode 100644
index 000000000000..1e7410ec1b2e
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/pub10.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/publisher/pub11.oxt b/desktop/test/deployment/update/publisher/pub11.oxt
new file mode 100644
index 000000000000..ef7fbca5e63a
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/pub11.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/publisher/pub2.oxt b/desktop/test/deployment/update/publisher/pub2.oxt
new file mode 100644
index 000000000000..438bcae830a3
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/pub2.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/publisher/pub3.oxt b/desktop/test/deployment/update/publisher/pub3.oxt
new file mode 100644
index 000000000000..62fd69f5595a
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/pub3.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/publisher/pub4.oxt b/desktop/test/deployment/update/publisher/pub4.oxt
new file mode 100644
index 000000000000..4f6224f780cd
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/pub4.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/publisher/pub5.oxt b/desktop/test/deployment/update/publisher/pub5.oxt
new file mode 100644
index 000000000000..1774e6cd35c3
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/pub5.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/publisher/pub6.oxt b/desktop/test/deployment/update/publisher/pub6.oxt
new file mode 100644
index 000000000000..791a37f8e710
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/pub6.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/publisher/pub7.oxt b/desktop/test/deployment/update/publisher/pub7.oxt
new file mode 100644
index 000000000000..96e96887d0b1
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/pub7.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/publisher/pub8.oxt b/desktop/test/deployment/update/publisher/pub8.oxt
new file mode 100644
index 000000000000..dc9f0ce34d95
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/pub8.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/publisher/pub9.oxt b/desktop/test/deployment/update/publisher/pub9.oxt
new file mode 100644
index 000000000000..5e8ba9ebc154
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/pub9.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/publisher/publisher_de-DE-altmark.html b/desktop/test/deployment/update/publisher/publisher_de-DE-altmark.html
new file mode 100755
index 000000000000..c770b914ad78
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/publisher_de-DE-altmark.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+</HEAD>
+<BODY>
+<H1>My OpenOffice en-DE-altmark</H1>
+</BODY>
+</HTML>
+
diff --git a/desktop/test/deployment/update/publisher/publisher_de-DE.html b/desktop/test/deployment/update/publisher/publisher_de-DE.html
new file mode 100755
index 000000000000..b06ed7088f08
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/publisher_de-DE.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+</HEAD>
+<BODY>
+<H1>My OpenOffice de-DE</H1>
+</BODY>
+</HTML>
+
diff --git a/desktop/test/deployment/update/publisher/publisher_de.html b/desktop/test/deployment/update/publisher/publisher_de.html
new file mode 100755
index 000000000000..4cba9f423d5b
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/publisher_de.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+</HEAD>
+<BODY>
+<H1>My OpenOffice de</H1>
+</BODY>
+</HTML>
+
diff --git a/desktop/test/deployment/update/publisher/publisher_en-GB.html b/desktop/test/deployment/update/publisher/publisher_en-GB.html
new file mode 100755
index 000000000000..c73cf6219b78
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/publisher_en-GB.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+</HEAD>
+<BODY>
+<H1>My OpenOffice en-GB</H1>
+</BODY>
+</HTML>
+
diff --git a/desktop/test/deployment/update/publisher/publisher_en-US-region1.html b/desktop/test/deployment/update/publisher/publisher_en-US-region1.html
new file mode 100755
index 000000000000..68beac724894
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/publisher_en-US-region1.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+</HEAD>
+<BODY>
+<H1>My OpenOffice en-US-region1</H1>
+</BODY>
+</HTML>
+
diff --git a/desktop/test/deployment/update/publisher/publisher_en-US-region2.html b/desktop/test/deployment/update/publisher/publisher_en-US-region2.html
new file mode 100755
index 000000000000..501adb659664
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/publisher_en-US-region2.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+</HEAD>
+<BODY>
+<H1>My OpenOffice en-US-region2</H1>
+</BODY>
+</HTML>
+
diff --git a/desktop/test/deployment/update/publisher/publisher_en-US.html b/desktop/test/deployment/update/publisher/publisher_en-US.html
new file mode 100755
index 000000000000..fd2575150315
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/publisher_en-US.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+</HEAD>
+<BODY>
+<H1>My OpenOffice en-US</H1>
+</BODY>
+</HTML>
+
diff --git a/desktop/test/deployment/update/publisher/publisher_en-region3.html b/desktop/test/deployment/update/publisher/publisher_en-region3.html
new file mode 100755
index 000000000000..b9fdc9d657b4
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/publisher_en-region3.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+</HEAD>
+<BODY>
+<H1>My OpenOffice en-region3</H1>
+</BODY>
+</HTML>
+
diff --git a/desktop/test/deployment/update/publisher/publisher_en.html b/desktop/test/deployment/update/publisher/publisher_en.html
new file mode 100755
index 000000000000..416ab8124314
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/publisher_en.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+</HEAD>
+<BODY>
+<H1>My OpenOffice en</H1>
+</BODY>
+</HTML>
+
diff --git a/desktop/test/deployment/update/publisher/readme.txt b/desktop/test/deployment/update/publisher/readme.txt
new file mode 100755
index 000000000000..1a659d8e875d
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/readme.txt
@@ -0,0 +1,212 @@
+--The folder contains extensions which use in the description.xml the following:
+
+-The <publisher> element
+-The <release-notes> element
+
+Both element contain localized child elements.
+
+The following table shows what localized item is used, when the Office the locale
+en-US uses.
+
+
+Localization:
+
+Installed office en-US
+ | publisher | release notes
+=============================================
+pub1.oxt | en-US | en-US
+---------------------------------------------
+pub2.oxt | en-US-region1 | en-US-region1
+---------------------------------------------
+pub3.oxt | en | en
+---------------------------------------------
+pub4.oxt | en-GB | en-GB
+---------------------------------------------
+pub5.oxt | de | de
+
+
+================================================================================
+pub6.oxt
+================================================================================
+like pub1 but without release notes.
+
+
+================================================================================
+pub7.oxt
+================================================================================
+like pub1 but without publisher name.
+
+================================================================================
+pub8.oxt
+================================================================================
+Need not be committed in extensions/www/testarea/desktop.
+
+pub8.oxt is intended for tests with extensions.services.openoffice.org.
+It does not contain <update-information>. That is, the Extension Manager will obtain
+the update information from the repository as feed:
+
+http://updateext.services.openoffice.org/ProductUpdateService/check.Update
+
+pub8.oxt provides <publisher> and <release-notes>. These information should be transferred
+in the update feed and not those entered in the repository.
+
+Test
+----
+Repository:
+
+-Create the new extension in the repository.
+-Provide a company name and a URL to the company website. This setting should be ignored
+ when generating the udpate feed. Instead the publisher name from the extension is used.
+ Enter "Publisher Title" : some arbitrary company
+ "Publisher URL": any arbitrary URL but not:
+ http://extensions.openoffice.org/testarea/desktop/publisher/publisher_en-US.html
+
+-Create a new release for the extension. Upload the version 2.0 (update/pub8.oxt).
+ Provide release notes. These release notes should later not be seen when clicking on
+ the release notes link.
+
+
+Office:
+-Install version 1.0 of the extension:
+ desktop/test/deployment/update/publisher/pub8.oxt
+
+-Run the update in the Extension Manager
+
+
+Result:
+The Update Dialog should show the publisher name as provided in the description.xml. For example,
+when lang=en-US was selected: My OpenOffice en-US
+
+A release notes link is displayed with an URL to the release notes as provided in
+the description.xml. For example, when lang=en-US was selected:
+"http://extensions.openoffice.org/testarea/desktop/publisher/publisher_en-US.html
+
+
+================================================================================
+pub9.oxt
+================================================================================
+Need not be committed in extensions/www/testarea/desktop.
+
+pub9.oxt is intended for tests with extensions.services.openoffice.org.
+It does not contain <update-information>. That is, the Extension Manager will obtain
+the update information from the repository as feed:
+
+http://updateext.services.openoffice.org/ProductUpdateService/check.Update
+
+pub9.oxt provides <publisher>. That means the update feed should
+contain the <publisher> as provided by the extension and the release notes as entered
+in the repository.
+
+Test
+----
+Repository:
+
+-Create the new extension in the repository.
+-Provide a company name and a URL to the company website. This setting should be ignored
+ when generating the udpate feed. Instead the publisher name from the extension is used.
+ Enter "Publisher Title" : some arbitrary company name
+ "Publisher URL": any arbitrary URL but not:
+ http://extensions.openoffice.org/testarea/desktop/publisher/publisher_en-US.html
+
+-Create a new release for the extension. Upload the version 2.0 (update/pub9.oxt).
+ Provide release notes. These release notes should later be displayed when clicking on
+ the release notes link.
+
+
+Office:
+-Install version 1.0 of the extension:
+ desktop/test/deployment/update/publisher/pub9.oxt
+
+-Run the update in the Extension Manager
+
+
+Result:
+The Update Dialog should show the publisher name as provided in the description.xml. For example,
+when lang=en-US was selected: My OpenOffice en-US
+
+A release notes link is displayed with an URL to the release notes as provided in the release notes
+field on the edit page for the extension in the repository.
+
+================================================================================
+pub10.oxt
+================================================================================
+Need not be committed in extensions/www/testarea/desktop.
+
+pub10.oxt is intended for tests with extensions.services.openoffice.org.
+It does not contain <update-information>. That is, the Extension Manager will obtain
+the update information from the repository as feed:
+
+http://updateext.services.openoffice.org/ProductUpdateService/check.Update
+
+pub10.oxt provides <release-notes>. That means the update feed should
+contain the <release-notes> as provided by the extension and the publisher name/URLs as entered
+in the repository.
+
+Test
+----
+Repository:
+
+-Create the new extension in the repository.
+-Provide a company name and a URL to the company website. They should then be in the udpate
+ feed.
+
+-Create a new release for the extension. Upload the version 2.0 (update/pub10.oxt).
+ Provide release notes. These release notes should NOT be displayed when clicking on
+ the release notes link. Instead the release notes provided by pub10.oxt should be displayed.
+
+
+Office:
+-Install version 1.0 of the extension:
+ desktop/test/deployment/update/publisher/pub10.oxt
+
+-Run the update in the Extension Manager
+
+
+Result:
+The Update Dialog should show the publisher name as provided in the repository.
+
+A release notes link is displayed with an URL to the release notes as provided in the
+pub10.oxt. For example, when the locale of the office is en-US then this page will be
+displayed:
+For example,
+when lang=en-US was selected: My OpenOffice en-US
+
+================================================================================
+pub11.oxt
+================================================================================
+Need not be committed in extensions/www/testarea/desktop.
+
+pub11.oxt is intended for tests with extensions.services.openoffice.org.
+It does not contain <update-information>. That is, the Extension Manager will obtain
+the update information from the repository as feed:
+
+http://updateext.services.openoffice.org/ProductUpdateService/check.Update
+
+pub10.oxt neither provides <release-notes> nor <publisher>. That means the update feed should
+contain these data as provided by the user on the repository web site.
+
+Test
+----
+Repository:
+
+-Create the new extension in the repository.
+-Provide a company name and a URL to the company website. They should then be in the udpate
+ feed.
+
+-Create a new release for the extension. Upload the version 2.0 (update/pub11.oxt).
+ Provide release notes. These release notes should be displayed when clicking on
+ the release notes link.
+
+
+Office:
+-Install version 1.0 of the extension:
+ desktop/test/deployment/update/publisher/pub11.oxt
+
+-Run the update in the Extension Manager
+
+
+Result:
+The Update Dialog should show the publisher name as provided in the repository.
+
+A release notes link is displayed which leads to the release notes kept in the repository.
+
diff --git a/desktop/test/deployment/update/publisher/release-notes_de-DE-altmark.html b/desktop/test/deployment/update/publisher/release-notes_de-DE-altmark.html
new file mode 100755
index 000000000000..81b38a9f5b44
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/release-notes_de-DE-altmark.html
@@ -0,0 +1,8 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+</HEAD>
+<BODY>
+<H1>Release Notes de-DE-altmark</H1>
+</BODY>
+</HTML>
diff --git a/desktop/test/deployment/update/publisher/release-notes_de-DE.html b/desktop/test/deployment/update/publisher/release-notes_de-DE.html
new file mode 100755
index 000000000000..f8f0121f0215
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/release-notes_de-DE.html
@@ -0,0 +1,8 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+</HEAD>
+<BODY>
+<H1>Release Notes de-DE</H1>
+</BODY>
+</HTML>
diff --git a/desktop/test/deployment/update/publisher/release-notes_de.html b/desktop/test/deployment/update/publisher/release-notes_de.html
new file mode 100755
index 000000000000..a9e1dc3647eb
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/release-notes_de.html
@@ -0,0 +1,8 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+</HEAD>
+<BODY>
+<H1>Release Notes de</H1>
+</BODY>
+</HTML>
diff --git a/desktop/test/deployment/update/publisher/release-notes_en-GB.html b/desktop/test/deployment/update/publisher/release-notes_en-GB.html
new file mode 100755
index 000000000000..ca72ec1b9c6e
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/release-notes_en-GB.html
@@ -0,0 +1,8 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+</HEAD>
+<BODY>
+<H1>Release Notes en-GB</H1>
+</BODY>
+</HTML>
diff --git a/desktop/test/deployment/update/publisher/release-notes_en-US-region1.html b/desktop/test/deployment/update/publisher/release-notes_en-US-region1.html
new file mode 100755
index 000000000000..0e6f99ce4c35
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/release-notes_en-US-region1.html
@@ -0,0 +1,8 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+</HEAD>
+<BODY>
+<H1>Release Notes en-US-region1</H1>
+</BODY>
+</HTML>
diff --git a/desktop/test/deployment/update/publisher/release-notes_en-US-region2.html b/desktop/test/deployment/update/publisher/release-notes_en-US-region2.html
new file mode 100755
index 000000000000..597bca0ebeef
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/release-notes_en-US-region2.html
@@ -0,0 +1,8 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+</HEAD>
+<BODY>
+<H1>Release Notes en-US-region2</H1>
+</BODY>
+</HTML>
diff --git a/desktop/test/deployment/update/publisher/release-notes_en-US.html b/desktop/test/deployment/update/publisher/release-notes_en-US.html
new file mode 100755
index 000000000000..7f9d73e338f8
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/release-notes_en-US.html
@@ -0,0 +1,8 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+</HEAD>
+<BODY>
+<H1>Release Notes en-US</H1>
+</BODY>
+</HTML>
diff --git a/desktop/test/deployment/update/publisher/release-notes_en-region3.html b/desktop/test/deployment/update/publisher/release-notes_en-region3.html
new file mode 100755
index 000000000000..5d62c7bcb4cf
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/release-notes_en-region3.html
@@ -0,0 +1,8 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+</HEAD>
+<BODY>
+<H1>Release Notes en-region3</H1>
+</BODY>
+</HTML>
diff --git a/desktop/test/deployment/update/publisher/release-notes_en.html b/desktop/test/deployment/update/publisher/release-notes_en.html
new file mode 100755
index 000000000000..d02e4f3330ee
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/release-notes_en.html
@@ -0,0 +1,8 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+</HEAD>
+<BODY>
+<H1>Release Notes en</H1>
+</BODY>
+</HTML>
diff --git a/desktop/test/deployment/update/publisher/update/pub1.oxt b/desktop/test/deployment/update/publisher/update/pub1.oxt
new file mode 100644
index 000000000000..cd04a58d5585
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/update/pub1.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/publisher/update/pub1.update.xml b/desktop/test/deployment/update/publisher/update/pub1.update.xml
new file mode 100755
index 000000000000..db25b56a8847
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/update/pub1.update.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<description xmlns="http://openoffice.org/extensions/update/2006"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+ <version value="2.0" />
+
+ <identifier value="org.openoffice/framework/desktop/test/deployment/update/publisher/pub1"/>
+
+ <publisher>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_de.html" lang="de">My OpenOffice de</name>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_en.html" lang="en">My OpenOffice en</name>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_de-DE.html" lang="de-DE">My OpenOffice de-DE</name>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_de-DE-altmark.html" lang="de-DE-altmark">My OpenOffice de-DE-altmark</name>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_en-GB.html" lang="en-GB">My OpenOffice en-GB</name>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_en-US.html" lang="en-US">My OpenOffice en-US</name>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_en-US-region1.html" lang="en-US-region1">My OpenOffice en-US-region1</name>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_en-US-region2.html" lang="en-US-region2">My OpenOffice en-US-region2</name>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_en-region3.html" lang="en-region3">My OpenOffice en-region3</name>
+ </publisher>
+
+ <release-notes>
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_de.html" lang="de" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_en.html" lang="en" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_de-DE.html" lang="de-DE" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_de-DE-altmark.html" lang="de-DE-altmark" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_en-GB.html" lang="en-GB" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_en-US.html" lang="en-US" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_en-US-region1.html" lang="en-US-region1" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_en-US-region2.html" lang="en-US-region2" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_en-region3.html" lang="en-region3" />
+ </release-notes>
+
+ <update-download>
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/update/pub1.oxt" />
+ </update-download>
+</description>
+
diff --git a/desktop/test/deployment/update/publisher/update/pub10.oxt b/desktop/test/deployment/update/publisher/update/pub10.oxt
new file mode 100644
index 000000000000..501a843381a8
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/update/pub10.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/publisher/update/pub11.oxt b/desktop/test/deployment/update/publisher/update/pub11.oxt
new file mode 100644
index 000000000000..692c0401f4a5
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/update/pub11.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/publisher/update/pub2.oxt b/desktop/test/deployment/update/publisher/update/pub2.oxt
new file mode 100644
index 000000000000..2a0bd6c21fed
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/update/pub2.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/publisher/update/pub2.update.xml b/desktop/test/deployment/update/publisher/update/pub2.update.xml
new file mode 100755
index 000000000000..d856348df87f
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/update/pub2.update.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<description xmlns="http://openoffice.org/extensions/update/2006"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+ <version value="2.0" />
+
+ <identifier value="org.openoffice/framework/desktop/test/deployment/update/publisher/pub2"/>
+
+ <publisher>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_de.html" lang="de">My OpenOffice de</name>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_en.html" lang="en">My OpenOffice en</name>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_de-DE.html" lang="de-DE">My OpenOffice de-DE</name>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_de-DE-altmark.html" lang="de-DE-altmark">My OpenOffice de-DE-altmark</name>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_en-GB.html" lang="en-GB">My OpenOffice en-GB</name>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_en-US-region1.html" lang="en-US-region1">My OpenOffice en-US-region1</name>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_en-US-region2.html" lang="en-US-region2">My OpenOffice en-US-region2</name>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_en-region3.html" lang="en-region3">My OpenOffice en-region3</name>
+ </publisher>
+
+ <release-notes>
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_de.html" lang="de" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_en.html" lang="en" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_de-DE.html" lang="de-DE" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_de-DE-altmark.html" lang="de-DE-altmark" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_en-GB.html" lang="en-GB" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_en-US-region1.html" lang="en-US-region1" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_en-US-region2.html" lang="en-US-region2" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_en-region3.html" lang="en-region3" />
+ </release-notes>
+
+ <update-download>
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/update/pub2.oxt" />
+ </update-download>
+</description>
+
diff --git a/desktop/test/deployment/update/publisher/update/pub3.oxt b/desktop/test/deployment/update/publisher/update/pub3.oxt
new file mode 100644
index 000000000000..60675fc4d21e
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/update/pub3.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/publisher/update/pub3.update.xml b/desktop/test/deployment/update/publisher/update/pub3.update.xml
new file mode 100755
index 000000000000..29a8e16b2ce4
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/update/pub3.update.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<description xmlns="http://openoffice.org/extensions/update/2006"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+ <version value="2.0" />
+
+ <identifier value="org.openoffice/framework/desktop/test/deployment/update/publisher/pub3"/>
+
+ <publisher>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_de.html" lang="de">My OpenOffice de</name>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_en.html" lang="en">My OpenOffice en</name>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_de-DE.html" lang="de-DE">My OpenOffice de-DE</name>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_de-DE-altmark.html" lang="de-DE-altmark">My OpenOffice de-DE-altmark</name>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_en-GB.html" lang="en-GB">My OpenOffice en-GB</name>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_en-region3.html" lang="en-region3">My OpenOffice en-region3</name>
+ </publisher>
+
+ <release-notes>
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_de.html" lang="de" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_en.html" lang="en" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_de-DE.html" lang="de-DE" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_de-DE-altmark.html" lang="de-DE-altmark" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_en-GB.html" lang="en-GB" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_en-region3.html" lang="en-region3" />
+ </release-notes>
+
+ <update-download>
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/update/pub3.oxt" />
+ </update-download>
+</description>
+
diff --git a/desktop/test/deployment/update/publisher/update/pub4.oxt b/desktop/test/deployment/update/publisher/update/pub4.oxt
new file mode 100644
index 000000000000..19f7b7991bd4
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/update/pub4.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/publisher/update/pub4.update.xml b/desktop/test/deployment/update/publisher/update/pub4.update.xml
new file mode 100755
index 000000000000..67b79f782412
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/update/pub4.update.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<description xmlns="http://openoffice.org/extensions/update/2006"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+ <version value="2.0" />
+
+ <identifier value="org.openoffice/framework/desktop/test/deployment/update/publisher/pub4"/>
+
+ <publisher>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_de.html" lang="de">My OpenOffice de</name>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_de-DE.html" lang="de-DE">My OpenOffice de-DE</name>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_de-DE-altmark.html" lang="de-DE-altmark">My OpenOffice de-DE-altmark</name>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_en-GB.html" lang="en-GB">My OpenOffice en-GB</name>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_en-region3.html" lang="en-region3">My OpenOffice en-region3</name>
+ </publisher>
+
+ <release-notes>
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_de.html" lang="de" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_de-DE.html" lang="de-DE" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_de-DE-altmark.html" lang="de-DE-altmark" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_en-GB.html" lang="en-GB" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_en-region3.html" lang="en-region3" />
+ </release-notes>
+
+ <update-download>
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/update/pub4.oxt" />
+ </update-download>
+</description>
+
diff --git a/desktop/test/deployment/update/publisher/update/pub5.oxt b/desktop/test/deployment/update/publisher/update/pub5.oxt
new file mode 100644
index 000000000000..afc632d570f1
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/update/pub5.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/publisher/update/pub5.update.xml b/desktop/test/deployment/update/publisher/update/pub5.update.xml
new file mode 100755
index 000000000000..3a58b298b549
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/update/pub5.update.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<description xmlns="http://openoffice.org/extensions/update/2006"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+ <version value="2.0" />
+
+ <identifier value="org.openoffice/framework/desktop/test/deployment/update/publisher/pub5"/>
+
+ <publisher>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_de.html" lang="de">My OpenOffice de</name>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_de-DE.html" lang="de-DE">My OpenOffice de-DE</name>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_de-DE-altmark.html" lang="de-DE-altmark">My OpenOffice de-DE-altmark</name>
+ </publisher>
+
+ <release-notes>
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_de.html" lang="de" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_de-DE.html" lang="de-DE" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_de-DE-altmark.html" lang="de-DE-altmark" />
+ </release-notes>
+
+ <update-download>
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/update/pub5.oxt" />
+ </update-download>
+</description>
+
diff --git a/desktop/test/deployment/update/publisher/update/pub6.oxt b/desktop/test/deployment/update/publisher/update/pub6.oxt
new file mode 100644
index 000000000000..a68b445b8a1a
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/update/pub6.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/publisher/update/pub6.update.xml b/desktop/test/deployment/update/publisher/update/pub6.update.xml
new file mode 100755
index 000000000000..ef187ce6cb5a
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/update/pub6.update.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<description xmlns="http://openoffice.org/extensions/update/2006"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+ <version value="2.0" />
+
+ <identifier value="org.openoffice/framework/desktop/test/deployment/update/publisher/pub6"/>
+
+ <publisher>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_de.html" lang="de">My OpenOffice de</name>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_en.html" lang="en">My OpenOffice en</name>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_de-DE.html" lang="de-DE">My OpenOffice de-DE</name>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_de-DE-altmark.html" lang="de-DE-altmark">My OpenOffice de-DE-altmark</name>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_en-GB.html" lang="en-GB">My OpenOffice en-GB</name>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_en-US.html" lang="en-US">My OpenOffice en-US</name>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_en-US-region1.html" lang="en-US-region1">My OpenOffice en-US-region1</name>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_en-US-region2.html" lang="en-US-region2">My OpenOffice en-US-region2</name>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_en-region3.html" lang="en-region3">My OpenOffice en-region3</name>
+ </publisher>
+
+ <update-download>
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/update/pub6.oxt" />
+ </update-download>
+</description>
+
diff --git a/desktop/test/deployment/update/publisher/update/pub7.oxt b/desktop/test/deployment/update/publisher/update/pub7.oxt
new file mode 100644
index 000000000000..1b4bee0442bb
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/update/pub7.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/publisher/update/pub7.update.xml b/desktop/test/deployment/update/publisher/update/pub7.update.xml
new file mode 100755
index 000000000000..10984e08d72f
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/update/pub7.update.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<description xmlns="http://openoffice.org/extensions/update/2006"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+ <version value="2.0" />
+
+ <identifier value="org.openoffice/framework/desktop/test/deployment/update/publisher/pub7"/>
+
+ <release-notes>
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_de.html" lang="de" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_en.html" lang="en" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_de-DE.html" lang="de-DE" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_de-DE-altmark.html" lang="de-DE-altmark" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_en-GB.html" lang="en-GB" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_en-US.html" lang="en-US" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_en-US-region1.html" lang="en-US-region1" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_en-US-region2.html" lang="en-US-region2" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_en-region3.html" lang="en-region3" />
+ </release-notes>
+
+ <update-download>
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/update/pub7.oxt" />
+ </update-download>
+</description>
+
diff --git a/desktop/test/deployment/update/publisher/update/pub8.oxt b/desktop/test/deployment/update/publisher/update/pub8.oxt
new file mode 100644
index 000000000000..5688ab9d24f5
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/update/pub8.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/publisher/update/pub9.oxt b/desktop/test/deployment/update/publisher/update/pub9.oxt
new file mode 100644
index 000000000000..752cfbbcf0b0
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/update/pub9.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/readme.txt b/desktop/test/deployment/update/readme.txt
new file mode 100755
index 000000000000..b3fd9126cae3
--- /dev/null
+++ b/desktop/test/deployment/update/readme.txt
@@ -0,0 +1,68 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+
+The extensions in the subdirectories of the update folder are used for
+testing the online update feature of extensions. The folder such as
+simple,
+license,
+defect, etc. contain extensions which can be installed in OOo. The
+corresponding update information file and the update are located on
+the extensions.openoffice.org website (cvs: extensions/www/testarea). For example:
+
+desktop/test/deployment/update/simple/plain1.oxt
+
+is version 1 of this extension and it references
+
+http://extensions.openoffice.org/testarea/desktop/simple/update/plain1.update.xml
+
+which in turn references version 2 at
+
+http://extensions.openoffice.org/testarea/desktop/simple/update/plain1.oxt
+
+
+To have all in one place the update information file and the update are also contained
+in the desktop project. They are in the update subfolder of the different test folders.
+For example
+
+.../update/simple/update
+.../update/license/update
+.../update/updatefeed/udpate
+
+
+The different test folders for the update are also commited in project extensions/www
+so that the files can be obtain via an URL. The structure and the contents is about the
+same as the content
+of desktop/test/deployment/udpate
+For example in
+
+extensions/www/testarea/desktop
+
+are the subfolder defect, simple, updatefeed, wrong_url, etc.
+they contain the extensions which are installed directly by the Extension Manager.
+These folders contain also the update subfolder which contains the update information
+and the actual updates.
diff --git a/desktop/test/deployment/update/simple/plain1.oxt b/desktop/test/deployment/update/simple/plain1.oxt
new file mode 100644
index 000000000000..6256f99d5e9c
--- /dev/null
+++ b/desktop/test/deployment/update/simple/plain1.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/simple/plain2.oxt b/desktop/test/deployment/update/simple/plain2.oxt
new file mode 100644
index 000000000000..03249c27774c
--- /dev/null
+++ b/desktop/test/deployment/update/simple/plain2.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/simple/plain3.oxt b/desktop/test/deployment/update/simple/plain3.oxt
new file mode 100644
index 000000000000..64838932d1ae
--- /dev/null
+++ b/desktop/test/deployment/update/simple/plain3.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/simple/readme.txt b/desktop/test/deployment/update/simple/readme.txt
new file mode 100755
index 000000000000..34ad6bedabf9
--- /dev/null
+++ b/desktop/test/deployment/update/simple/readme.txt
@@ -0,0 +1,31 @@
+The folder contains only simple extension. That is, they only contain
+- META-INF
+-t.rdb
+-description.xml
+
+The description.xml contains a version, a display name, and one URL to the update data
+
+For example:
+
+
+<?xml version="1.0" encoding="UTF-8"?>
+<description xmlns="http://openoffice.org/extensions/description/2006"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+ <version value="1.0" />
+
+ <display-name>
+ <name lang="de">plain1 de</name>
+ </display-name>
+
+ <update-information>
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/simple/plain1.update.xml" />
+ </update-information>
+</description>
+
+There is only one language as display name available, which will therefore always be displayed.
+
+The update information which is referenced in the update-information and the update is committed in the extensions/www project. To modify them get the project:
+
+cvs co extensions/wwww
+
+the files can be found under extensions/www/testarea/desktop
diff --git a/desktop/test/deployment/update/simple/update/plain1.oxt b/desktop/test/deployment/update/simple/update/plain1.oxt
new file mode 100644
index 000000000000..d73362e873bc
--- /dev/null
+++ b/desktop/test/deployment/update/simple/update/plain1.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/simple/update/plain1.update.xml b/desktop/test/deployment/update/simple/update/plain1.update.xml
new file mode 100755
index 000000000000..c9eb679cdba0
--- /dev/null
+++ b/desktop/test/deployment/update/simple/update/plain1.update.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<description xmlns="http://openoffice.org/extensions/update/2006"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+ <identifier value="org.openoffice.legacy.plain1.oxt"/>
+ <version value="2.0" />
+ <update-download>
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/simple/update/plain1.oxt" />
+ </update-download>
+</description>
+
diff --git a/desktop/test/deployment/update/simple/update/plain2.oxt b/desktop/test/deployment/update/simple/update/plain2.oxt
new file mode 100644
index 000000000000..3dc02aa97aa4
--- /dev/null
+++ b/desktop/test/deployment/update/simple/update/plain2.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/simple/update/plain2.update.xml b/desktop/test/deployment/update/simple/update/plain2.update.xml
new file mode 100755
index 000000000000..5aeb8080446f
--- /dev/null
+++ b/desktop/test/deployment/update/simple/update/plain2.update.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<description xmlns="http://openoffice.org/extensions/update/2006"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+ <identifier value="org.openoffice.legacy.plain2.oxt"/>
+ <version value="2.0" />
+ <update-download>
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/simple/update/plain2.oxt" />
+ </update-download>
+</description>
+
diff --git a/desktop/test/deployment/update/simple/update/plain3.oxt b/desktop/test/deployment/update/simple/update/plain3.oxt
new file mode 100644
index 000000000000..575152403bfe
--- /dev/null
+++ b/desktop/test/deployment/update/simple/update/plain3.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/simple/update/plain3.update.xml b/desktop/test/deployment/update/simple/update/plain3.update.xml
new file mode 100755
index 000000000000..6c1241dbdede
--- /dev/null
+++ b/desktop/test/deployment/update/simple/update/plain3.update.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<description xmlns="http://openoffice.org/extensions/update/2006"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+ <identifier value="org.openoffice.legacy.plain3.oxt"/>
+ <version value="2.0" />
+ <update-download>
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/simple/update/plain3.oxt" />
+ </update-download>
+</description>
+
diff --git a/desktop/test/deployment/update/updatefeed/feed1.oxt b/desktop/test/deployment/update/updatefeed/feed1.oxt
new file mode 100644
index 000000000000..b1b11ecceabb
--- /dev/null
+++ b/desktop/test/deployment/update/updatefeed/feed1.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/updatefeed/feed2.oxt b/desktop/test/deployment/update/updatefeed/feed2.oxt
new file mode 100644
index 000000000000..47dca1676c6a
--- /dev/null
+++ b/desktop/test/deployment/update/updatefeed/feed2.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/updatefeed/update/feed1.oxt b/desktop/test/deployment/update/updatefeed/update/feed1.oxt
new file mode 100644
index 000000000000..82bb9665ae3d
--- /dev/null
+++ b/desktop/test/deployment/update/updatefeed/update/feed1.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/updatefeed/update/feed1.update.xml b/desktop/test/deployment/update/updatefeed/update/feed1.update.xml
new file mode 100755
index 000000000000..31d0cfa61d3b
--- /dev/null
+++ b/desktop/test/deployment/update/updatefeed/update/feed1.update.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<description xmlns="http://openoffice.org/extensions/update/2006"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+ <identifier value="org.openoffice.legacy.feed1.oxt"/>
+ <version value="2.0" />
+ <update-download>
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/updatefeed/update/feed1.oxt" />
+ </update-download>
+</description>
+
diff --git a/desktop/test/deployment/update/updatefeed/update/feed1.xml b/desktop/test/deployment/update/updatefeed/update/feed1.xml
new file mode 100755
index 000000000000..1c31851d8cfd
--- /dev/null
+++ b/desktop/test/deployment/update/updatefeed/update/feed1.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-US">
+
+ <title>OpenOffice.org Update Feed</title>
+ <link rel="alternate" type="text/html" href="http://update.services.openoffice.org/ooo/snapshot.html"/>
+ <updated>2006-11-06T18:30:02Z</updated>
+ <author>
+ <name>The OpenOffice.org Project</name>
+ <uri>http://openoffice.org</uri>
+ <email>updatefeed@openoffice.org</email>
+ </author>
+ <id>urn:uuid:a4ccd383-1dd1-11b2-a95c-0003ba566e9d</id>
+ <entry>
+ <title>feed1.oxt version 2.0 available</title>
+ <link rel="alternate" type="text/html"
+ href="http://extensions.openoffice.org"/>
+ <id>urn:uuid:a4ccd383-1dd1-11b2-a95c-0003ba566e9f</id>
+ <category term="org.openoffice.legacy.feed1.oxt" label="feed1.oxt" />
+ <updated>2006-11-06T18:30:02Z</updated>
+ <summary>Click here to go to the download page.</summary>
+ <content type="application/xml" src="http://extensions.openoffice.org/testarea/desktop/updatefeed/update/feed1.update.xml" />
+ </entry>
+ <entry>
+ <title>feed2.oxt version 2.0 available</title>
+ <link rel="alternate" type="text/html"
+ href="http://extensions.openoffice.org"/>
+ <id>urn:uuid:a4ccd383-1dd1-11b2-a95c-0003ba566eaf</id>
+ <category term="org.openoffice.legacy.feed2.oxt" label="feed2.oxt" />
+ <updated>2006-11-06T18:30:02Z</updated>
+ <summary>Click here to go to the download page.</summary>
+ <content type="application/xml" src="http://extensions.openoffice.org/testarea/desktop/updatefeed/update/feed2.update.xml" />
+ </entry>
+</feed>
diff --git a/desktop/test/deployment/update/updatefeed/update/feed2.oxt b/desktop/test/deployment/update/updatefeed/update/feed2.oxt
new file mode 100644
index 000000000000..9c867ae4a812
--- /dev/null
+++ b/desktop/test/deployment/update/updatefeed/update/feed2.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/updatefeed/update/feed2.update.xml b/desktop/test/deployment/update/updatefeed/update/feed2.update.xml
new file mode 100755
index 000000000000..8cbc5045fd5d
--- /dev/null
+++ b/desktop/test/deployment/update/updatefeed/update/feed2.update.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<description xmlns="http://openoffice.org/extensions/update/2006"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+ <identifier value="org.openoffice.legacy.feed2.oxt"/>
+ <version value="2.0" />
+ <update-download>
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/updatefeed/update/feed2.oxt" />
+ </update-download>
+</description>
+
diff --git a/desktop/test/deployment/update/updateinfocreation/build/MANIFEST.MF b/desktop/test/deployment/update/updateinfocreation/build/MANIFEST.MF
new file mode 100755
index 000000000000..09e2f42ca0f6
--- /dev/null
+++ b/desktop/test/deployment/update/updateinfocreation/build/MANIFEST.MF
@@ -0,0 +1,2 @@
+RegistrationClassName: com.sun.star.comp.smoketest.TestExtension
+
diff --git a/desktop/test/deployment/update/updateinfocreation/build/TestExtension.idl b/desktop/test/deployment/update/updateinfocreation/build/TestExtension.idl
new file mode 100644
index 000000000000..3f5fc3b53bbe
--- /dev/null
+++ b/desktop/test/deployment/update/updateinfocreation/build/TestExtension.idl
@@ -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.
+ *
+ *************************************************************************/
+
+#ifndef _com_sun_star_comp_smoketest_TestExtension_idl_
+#define _com_sun_star_comp_smoketest_TestExtension_idl_
+
+#include <com/sun/star/lang/XServiceInfo.idl>
+
+
+module com { module sun { module star { module comp { module smoketest {
+ // example service, XServiceInfo is implemented here for demonstration
+ // issues. XServiceInfo must be implemented by all components.
+ service TestExtension: ::com::sun::star::lang::XServiceInfo;
+};};};};};
+
+#endif
diff --git a/desktop/test/deployment/update/updateinfocreation/build/TestExtension.java b/desktop/test/deployment/update/updateinfocreation/build/TestExtension.java
new file mode 100755
index 000000000000..059715845c32
--- /dev/null
+++ b/desktop/test/deployment/update/updateinfocreation/build/TestExtension.java
@@ -0,0 +1,165 @@
+/*************************************************************************
+ *
+ * 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.comp.smoketest;
+
+import com.sun.star.lib.uno.helper.Factory;
+import com.sun.star.lang.XMultiComponentFactory;
+import com.sun.star.lang.XSingleComponentFactory;
+import com.sun.star.lib.uno.helper.WeakBase;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XComponentContext;
+import com.sun.star.registry.XRegistryKey;
+import com.sun.star.lang.XInitialization;
+import com.sun.star.lang.XTypeProvider;
+import com.sun.star.lang.XServiceInfo;
+import com.sun.star.uno.Type;
+
+/** This class capsulates the class, that implements the minimal component, a
+ * factory for creating the service (<CODE>__getComponentFactory</CODE>) and a
+ * method, that writes the information into the given registry key
+ * (<CODE>__writeRegistryServiceInfo</CODE>).
+ */
+public class TestExtension {
+ /** This class implements the component. At least the interfaces XServiceInfo,
+ * XTypeProvider, and XInitialization should be provided by the service.
+ */
+ public static class _TestExtension extends WeakBase
+ implements XServiceInfo {
+ /** The service name, that must be used to get an instance of this service.
+ */
+ static private final String __serviceName =
+ "com.sun.star.comp.smoketest.TestExtension";
+
+ /** The initial component contextr, that gives access to
+ * the service manager, supported singletons, ...
+ * It's often later used
+ */
+ private XComponentContext m_cmpCtx;
+
+ /** The service manager, that gives access to all registered services.
+ * It's often later used
+ */
+ private XMultiComponentFactory m_xMCF;
+
+ /** The constructor of the inner class has a XMultiServiceFactory parameter.
+ * @param xmultiservicefactoryInitialization A special service factory
+ * could be introduced while initializing.
+ */
+ public _TestExtension(XComponentContext xCompContext) {
+ try {
+ m_cmpCtx = xCompContext;
+ m_xMCF = m_cmpCtx.getServiceManager();
+ }
+ catch( Exception e ) {
+ e.printStackTrace();
+ }
+ }
+
+ /** This method returns an array of all supported service names.
+ * @return Array of supported service names.
+ */
+ public String[] getSupportedServiceNames() {
+ return getServiceNames();
+ }
+
+ /** This method is a simple helper function to used in the
+ * static component initialisation functions as well as in
+ * getSupportedServiceNames.
+ */
+ public static String[] getServiceNames() {
+ String[] sSupportedServiceNames = { __serviceName };
+ return sSupportedServiceNames;
+ }
+
+ /** This method returns true, if the given service will be
+ * supported by the component.
+ * @param sServiceName Service name.
+ * @return True, if the given service name will be supported.
+ */
+ public boolean supportsService( String sServiceName ) {
+ return sServiceName.equals( __serviceName );
+ }
+
+ /** Return the class name of the component.
+ * @return Class name of the component.
+ */
+ public String getImplementationName() {
+ return _TestExtension.class.getName();
+ }
+ }
+
+
+ /**
+ * Gives a factory for creating the service.
+ * This method is called by the <code>JavaLoader</code>
+ * <p>
+ * @return returns a <code>XSingleComponentFactory</code> for creating
+ * the component
+ * @param sImplName the name of the implementation for which a
+ * service is desired
+ * @see com.sun.star.comp.loader.JavaLoader
+ */
+ public static XSingleComponentFactory __getComponentFactory(String sImplName)
+ {
+ XSingleComponentFactory xFactory = null;
+
+ if ( sImplName.equals( _TestExtension.class.getName() ) )
+ xFactory = Factory.createComponentFactory(_TestExtension.class,
+ _TestExtension.getServiceNames());
+
+ return xFactory;
+ }
+
+ /**
+ * Writes the service information into the given registry key.
+ * This method is called by the <code>JavaLoader</code>
+ * <p>
+ * @return returns true if the operation succeeded
+ * @param regKey the registryKey
+ * @see com.sun.star.comp.loader.JavaLoader
+ */
+ public static boolean __writeRegistryServiceInfo(XRegistryKey regKey) {
+ return Factory.writeRegistryServiceInfo(_TestExtension.class.getName(),
+ _TestExtension.getServiceNames(),
+ regKey);
+ }
+ /** This method is a member of the interface for initializing an object
+ * directly after its creation.
+ * @param object This array of arbitrary objects will be passed to the
+ * component after its creation.
+ * @throws Exception Every exception will not be handled, but will be
+ * passed to the caller.
+ */
+ public void initialize( Object[] object )
+ throws com.sun.star.uno.Exception {
+ /* The component describes what arguments its expected and in which
+ * order!At this point you can read the objects and can intialize
+ * your component using these objects.
+ */
+ }
+
+}
diff --git a/desktop/test/deployment/update/updateinfocreation/build/delzip b/desktop/test/deployment/update/updateinfocreation/build/delzip
new file mode 100755
index 000000000000..636fda90bfcb
--- /dev/null
+++ b/desktop/test/deployment/update/updateinfocreation/build/delzip
@@ -0,0 +1 @@
+ECHO is OFF
diff --git a/desktop/test/deployment/update/updateinfocreation/build/description.xml b/desktop/test/deployment/update/updateinfocreation/build/description.xml
new file mode 100755
index 000000000000..257c48a79b79
--- /dev/null
+++ b/desktop/test/deployment/update/updateinfocreation/build/description.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<description xmlns="http://openoffice.org/extensions/description/2006"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:d="http://openoffice.org/extensions/description/2006" >
+ <identifier value="org.openoffice.extensions.testarea.desktop.updateinfo"/>
+ <version value="2.0" />
+ <dependencies >
+ <OpenOffice.org-minimal-version value="2.1" d:name="OpenOffice.org 2.1"/>
+ </dependencies>
+ <update-information>
+ <src xlink:href="http://update.services.openoffice.org/ProductUpdateService/check.Update?product=extension&amp;extensionid=org.openoffice.extensions.testarea.desktop.updateinfo&amp;refresh=true"/>
+ </update-information>
+</description>
diff --git a/desktop/test/deployment/update/updateinfocreation/build/makefile.mk b/desktop/test/deployment/update/updateinfocreation/build/makefile.mk
new file mode 100755
index 000000000000..b0479c942b4f
--- /dev/null
+++ b/desktop/test/deployment/update/updateinfocreation/build/makefile.mk
@@ -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.
+#
+#*************************************************************************
+
+PRJ = ..$/..$/..$/..$/..
+PRJNAME = updateinfo
+PACKAGE = com$/sun$/star$/comp$/smoketest
+TARGET = com_sun_star_comp_smoketest
+
+no_common_build_zip:=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+JARFILES = ridl.jar jurt.jar unoil.jar juh.jar
+
+
+JARTARGET = TestExtension.jar
+JARCOMPRESS = TRUE
+CUSTOMMANIFESTFILE = MANIFEST.MF
+
+ZIP1TARGET=updateinfo
+ZIP1LIST=*
+ZIPFLAGS=-r
+ZIP1DIR=$(MISC)$/$(TARGET)
+ZIP1EXT=.oxt
+
+EXTUPDATEINFO_NAME=org.openoffice.extensions.testarea.desktop.updateinfo.update.xml
+EXTUPDATEINFO_SOURCE=description.xml
+EXTUPDATEINFO_URLS = http://extensions.openoffice.org/testarea/desktop/updateinfocreation/update/updateinfo.oxt
+# --- Files --------------------------------------------------------
+
+COPY_OXT_MANIFEST:= $(MISC)$/$(TARGET)$/META-INF$/manifest.xml
+JAVAFILES = TestExtension.java
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
+$(JARTARGETN) : $(MISC)$/$(TARGET).javamaker.done
+
+$(JAVACLASSFILES) : $(MISC)$/$(TARGET).javamaker.done
+
+$(MISC)$/$(TARGET).javamaker.done: $(BIN)$/TestExtension.rdb
+ $(JAVAMAKER) -O$(CLASSDIR) -BUCR -nD -X$(SOLARBINDIR)/types.rdb $<
+ $(TOUCH) $@
+
+$(BIN)$/TestExtension.rdb: TestExtension.idl
+ $(IDLC) -O$(MISC) -I$(SOLARIDLDIR) -cid -we $<
+ +-$(RM) $@
+ $(REGMERGE) $@ /UCR $(MISC)$/TestExtension.urd
+
+$(MISC)$/$(ZIP1TARGET).createdir :
+ +$(MKDIRHIER) $(MISC)$/$(TARGET)$/META-INF >& $(NULLDEV) && $(TOUCH) $@
+
+$(MISC)$/$(TARGET)_resort : manifest.xml $(JARTARGETN) $(MISC)$/$(ZIP1TARGET).createdir $(BIN)$/TestExtension.rdb description.xml
+ $(GNUCOPY) -u manifest.xml $(MISC)$/$(TARGET)$/META-INF$/manifest.xml
+ $(GNUCOPY) -u $(JARTARGETN) $(MISC)$/$(TARGET)$/$(JARTARGET)
+ $(GNUCOPY) -u $(BIN)$/TestExtension.rdb $(MISC)$/$(TARGET)$/TestExtension.rdb
+ $(GNUCOPY) -u description.xml $(MISC)$/$(TARGET)$/description.xml
+ $(TOUCH) $@
+
+.IF "$(ZIP1TARGETN)"!=""
+$(ZIP1TARGETN) : $(MISC)$/$(TARGET)_resort $(MISC)$/$(ZIP1TARGET).createdir
+
+.ENDIF # "$(ZIP1TARGETN)"!=""
+
diff --git a/desktop/test/deployment/update/updateinfocreation/build/manifest.xml b/desktop/test/deployment/update/updateinfocreation/build/manifest.xml
new file mode 100755
index 000000000000..fcedabf96b4b
--- /dev/null
+++ b/desktop/test/deployment/update/updateinfocreation/build/manifest.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<manifest:manifest xmlns:manifest="http://openoffice.org/2001/manifest">
+ <manifest:file-entry manifest:full-path="TestExtension.jar" manifest:media-type="application/vnd.sun.star.uno-component;type=Java"/>
+ <manifest:file-entry manifest:full-path="TestExtension.rdb" manifest:media-type="application/vnd.sun.star.uno-typelibrary;type=RDB"/>
+</manifest:manifest>
diff --git a/desktop/test/deployment/update/updateinfocreation/readme.txt b/desktop/test/deployment/update/updateinfocreation/readme.txt
new file mode 100755
index 000000000000..c4fc059053e9
--- /dev/null
+++ b/desktop/test/deployment/update/updateinfocreation/readme.txt
@@ -0,0 +1,38 @@
+The extension build in this test uses an update information which is obtained
+through a http get request. That is the URL does not reference an update
+information file. Instead it invokes code on a webserver which returns the
+update information. The URL used in this example is:
+
+http://update.services.openoffice.org/ProductUpdateService/check.Update?product=extension&amp;extensionid=org.openoffice.extensions.testarea.desktop.updateinfo&amp;refresh=true
+
+The updateinfo.oxt in this directory has the version 1.0 and in the sub-directory "update is the version 2 of this extension. Version 1.0 is also available here
+/extensions/www/testarea/desktop/updateinfocreation/updateinfo.oxt
+and version 2.0 here
+/extensions/www/testarea/desktop/updateinfocreation/update/updateinfo.oxt
+
+Therefore they can be accessed through
+
+http://extensions.openoffice.org/testarea/desktop/updateinfocreation/updateinfo.oxt
+and
+http://extensions.openoffice.org/testarea/desktop/updateinfocreation/update/updateinfo.oxt
+
+The latter location (version 2.0) will also be referenced by the update information
+which are returned by the webserver.
+
+The build sub-directory contains the code of the extension (version 2.0) and can
+be build by calling dmake in this directory. The makefile uses the special macros:
+
+EXTUPDATEINFO_NAME=org.openoffice.extensions.testarea.desktop.updateinfo.update.xml
+EXTUPDATEINFO_SOURCE=description.xml
+EXTUPDATEINFO_URLS = http://extensions.openoffice.org/testarea/desktop/updateinfocreation/update/updateinfo.oxt
+
+This causes the generation of the update information file. This file could be
+directly references by the URL in the <update-information> of the description.xml.
+See also the Wiki entry at:
+http://wiki.services.openoffice.org/wiki/Creating_update_information_for_extensions
+This generated update information file can then be used by the webserver, when it
+sends back the requested update information. The update information file will be
+generated in the misc diretory of the output directory.
+
+The update information file needs to be copied into common.pro/pus.mxyz directory.
+The project mwsfinish will process the files in the pus directory.
diff --git a/desktop/test/deployment/update/updateinfocreation/update/updateinfo.oxt b/desktop/test/deployment/update/updateinfocreation/update/updateinfo.oxt
new file mode 100644
index 000000000000..52ddd3158e31
--- /dev/null
+++ b/desktop/test/deployment/update/updateinfocreation/update/updateinfo.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/updateinfocreation/updateinfo.oxt b/desktop/test/deployment/update/updateinfocreation/updateinfo.oxt
new file mode 100644
index 000000000000..43ac7003bc59
--- /dev/null
+++ b/desktop/test/deployment/update/updateinfocreation/updateinfo.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/website_update/readme.txt b/desktop/test/deployment/update/website_update/readme.txt
new file mode 100755
index 000000000000..4ae5ddd9182f
--- /dev/null
+++ b/desktop/test/deployment/update/website_update/readme.txt
@@ -0,0 +1,133 @@
+The folder contains extensions which need to be updated through a web site.
+The "Updates dialog" of the Extension Manager will mark the updates for these
+extensions as "browser based update". The Extension Manager will open a browser
+for each of the extensions and navigate to the respective website.
+
+================================================================================
+web1.oxt - web5.oxt:
+================================================================================
+They contain <update-information>. That is they reference directly the respective
+webX.update.xml (for example, web1.update.xml) files which are available at
+http://extensions.openoffice.org/testarea/desktop/website_update/update/...
+For example:
+http://extensions.openoffice.org/testarea/desktop/website_update/update/web2.update.xml
+
+The update information contain multiple URLs to "localized" web sites. Each URL is
+assigned to a particular local. For example:
+
+<src xlink:href="http://extensions.openoffice.org/testarea/desktop/website_update/update/web1_de.html" lang="de"/>
+
+The Extension Manager will choose the URLs where the lang attribute matches most
+closely the locale of the office.
+
+The following table shows what localized web site is used, when the office uses the locale
+en-US. The web page will display the locale used. See update/web1_de.html, etc.
+
+
+Localization:
+
+Installed office en-US
+ | publisher | release notes
+=============================================
+web1.oxt | en-US | en-US
+---------------------------------------------
+web2.oxt | en-US-region1 | en-US-region1
+---------------------------------------------
+web3.oxt | en | en
+---------------------------------------------
+web4.oxt | en-GB | en-GB
+---------------------------------------------
+web5.oxt | de | de
+
+
+================================================================================
+web6.oxt
+================================================================================
+Need not be committed in extensions/www/testarea/desktop.
+
+web6.oxt is intended for tests with extensions.services.openoffice.org.
+It does not contain <update-information>. That is, the Extension Manager will obtain
+the update information from the repository as feed:
+
+http://updateext.services.openoffice.org/ProductUpdateService/check.Update
+
+Test
+----
+Repository:
+
+-Create the new extension in the repository.
+-Provide a company name and a URL to the company website. In our case this should be
+ http://extensions.openoffice.org/testarea/desktop/website_update/update/web1_en-US.html
+
+-Create a new release for the extension. Upload the description.xml of version 2.0
+(update/web6/description.xml). Provide a download URL for the web site (field
+ "Download from page / Open follow up page URL", which should be
+ http://extensions.openoffice.org/testarea/desktop/website_update/update/web1_en-US.html
+ Provide release notes.
+
+
+Office:
+-Install version 1.0 of the extension:
+ desktop/test/deployment/update/website_update/web6.oxt
+
+-Run the update in the Extension Manager
+
+
+Result:
+The Update Dialog should show the publisher name as provided in "Provider URL" field
+of the extension edit page (not release).
+
+A release notes link is displayed with an URL to the release notes as provided in
+the "Provider Title" field of the extension release edit page.
+
+When running the update then the web browser should navigate to
+http://extensions.openoffice.org/testarea/desktop/website_update/update/web1_en-US.html
+
+
+================================================================================
+web7.oxt
+================================================================================
+Need not be committed in extensions/www/testarea/desktop
+
+web7.oxt is intended for tests with extensions.services.openoffice.org.
+It does not contain <update-information>. That is, the Extension Manager will obtain
+the update information from the repository as feed:
+
+http://updateext.services.openoffice.org/ProductUpdateService/check.Update
+
+The description.xml which will be uploaded contains URLs for release notes and publisher
+names/ URLs. That is, these information are not generated from the information of the
+repository web site.
+
+Test
+-----------
+Repository:
+
+-Create the new extension in the repository.
+-Provide a company name and a URL to the company website. In our case these should be different
+ to those provided in the description.xml. These should NOT go into the update feed.
+ Choose for example as "Provider Title": FOO and as "Provider URL" some valid URL but NOT
+ http://extensions.openoffice.org/testarea/desktop/website_update/update/web1_en-US.html
+
+-Create a new release for the extension. Upload the description.xml of version 2.0
+(update/web7/description.xml). Provide a download URL for the web site (field
+ "Download from page / Open follow up page URL", which should be
+ http://extensions.openoffice.org/testarea/desktop/website_update/update/web1_en-US.html
+ Provide release notes.
+
+Office:
+-Install version 1.0 of the extension:
+ desktop/test/deployment/update/website_update/web7.oxt
+
+-Run the update in the Extension Manager
+
+Result:
+The Update Dialog should show the publisher name as provided in the description.xml.
+That is: My OpenOffice en-US and NOT "FOO".
+
+A release notes link is displayed with an URL to the release notes as provided in
+the description.xml. That is:
+http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_xxx.html
+
+When running the update then the web browser should navigate to
+http://extensions.openoffice.org/testarea/desktop/website_update/update/web1_en-US.html
diff --git a/desktop/test/deployment/update/website_update/update/web1.oxt b/desktop/test/deployment/update/website_update/update/web1.oxt
new file mode 100644
index 000000000000..157d5d952c60
--- /dev/null
+++ b/desktop/test/deployment/update/website_update/update/web1.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/website_update/update/web1.update.xml b/desktop/test/deployment/update/website_update/update/web1.update.xml
new file mode 100755
index 000000000000..ad2379dd43ca
--- /dev/null
+++ b/desktop/test/deployment/update/website_update/update/web1.update.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<description xmlns="http://openoffice.org/extensions/update/2006"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+ <version value="2.0" />
+
+ <identifier value="org.openoffice/framework/desktop/test/deployment/update/website_update/web1"/>
+
+ <update-website>
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/website_update/update/web1_de.html" lang="de" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/website_update/update/web1_en.html" lang="en" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/website_update/update/web1_de-DE.html" lang="de-DE" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/website_update/update/web1_de-DE-altmark.html" lang="de-DE-altmark" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/website_update/update/web1_en-GB.html" lang="en-GB" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/website_update/update/web1_en-US.html" lang="en-US" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/website_update/update/web1_en-US-region1.html" lang="en-US-region1" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/website_update/update/web1_en-US-region2.html" lang="en-US-region2" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/website_update/update/web1_en-region3.html" lang="en-region3" />
+ </update-website>
+</description>
+
diff --git a/desktop/test/deployment/update/website_update/update/web1_de-DE-altmark.html b/desktop/test/deployment/update/website_update/update/web1_de-DE-altmark.html
new file mode 100755
index 000000000000..ffed5a52e892
--- /dev/null
+++ b/desktop/test/deployment/update/website_update/update/web1_de-DE-altmark.html
@@ -0,0 +1,18 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+</HEAD>
+<BODY>
+<H1>Update Extensions</H1>
+<H1>de-DE-altmark</H1>
+<p><a href="web1.oxt">web1.oxt</a></p>
+<p><a href="web2.oxt">web2.oxt</a></p>
+<p><a href="web3.oxt">web3.oxt</a></p>
+<p><a href="web4.oxt">web4.oxt</a></p>
+<p><a href="web5.oxt">web5.oxt</a></p>
+<p><a href="web6.oxt">web6.oxt</a></p>
+<p><a href="web7.oxt">web7.oxt</a></p>
+
+</BODY>
+</HTML>
+
diff --git a/desktop/test/deployment/update/website_update/update/web1_de-DE.html b/desktop/test/deployment/update/website_update/update/web1_de-DE.html
new file mode 100755
index 000000000000..33fb7f2ec8bc
--- /dev/null
+++ b/desktop/test/deployment/update/website_update/update/web1_de-DE.html
@@ -0,0 +1,18 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+</HEAD>
+<BODY>
+<H1>Update Extensions</H1>
+<H1>de-DE</H1>
+<p><a href="web1.oxt">web1.oxt</a></p>
+<p><a href="web2.oxt">web2.oxt</a></p>
+<p><a href="web3.oxt">web3.oxt</a></p>
+<p><a href="web4.oxt">web4.oxt</a></p>
+<p><a href="web5.oxt">web5.oxt</a></p>
+<p><a href="web6.oxt">web6.oxt</a></p>
+<p><a href="web7.oxt">web7.oxt</a></p>
+
+</BODY>
+</HTML>
+
diff --git a/desktop/test/deployment/update/website_update/update/web1_de.html b/desktop/test/deployment/update/website_update/update/web1_de.html
new file mode 100755
index 000000000000..31a53b91dbe4
--- /dev/null
+++ b/desktop/test/deployment/update/website_update/update/web1_de.html
@@ -0,0 +1,19 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+</HEAD>
+<BODY>
+<H1>Update Extensions</H1>
+<H1>de</H1>
+<p><a href="web1.oxt">web1.oxt</a></p>
+<p><a href="web2.oxt">web2.oxt</a></p>
+<p><a href="web3.oxt">web3.oxt</a></p>
+<p><a href="web4.oxt">web4.oxt</a></p>
+<p><a href="web5.oxt">web5.oxt</a></p>
+<p><a href="web6.oxt">web6.oxt</a></p>
+<p><a href="web7.oxt">web7.oxt</a></p>
+
+
+</BODY>
+</HTML>
+
diff --git a/desktop/test/deployment/update/website_update/update/web1_en-GB.html b/desktop/test/deployment/update/website_update/update/web1_en-GB.html
new file mode 100755
index 000000000000..c46328a82145
--- /dev/null
+++ b/desktop/test/deployment/update/website_update/update/web1_en-GB.html
@@ -0,0 +1,19 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+</HEAD>
+<BODY>
+<H1>Update Extensions</H1>
+<H1>en-GB</H1>
+<p><a href="web1.oxt">web1.oxt</a></p>
+<p><a href="web2.oxt">web2.oxt</a></p>
+<p><a href="web3.oxt">web3.oxt</a></p>
+<p><a href="web4.oxt">web4.oxt</a></p>
+<p><a href="web5.oxt">web5.oxt</a></p>
+<p><a href="web6.oxt">web6.oxt</a></p>
+<p><a href="web7.oxt">web7.oxt</a></p>
+
+
+</BODY>
+</HTML>
+
diff --git a/desktop/test/deployment/update/website_update/update/web1_en-US-region1.html b/desktop/test/deployment/update/website_update/update/web1_en-US-region1.html
new file mode 100755
index 000000000000..80b41823b70f
--- /dev/null
+++ b/desktop/test/deployment/update/website_update/update/web1_en-US-region1.html
@@ -0,0 +1,19 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+</HEAD>
+<BODY>
+<H1>Update Extensions</H1>
+<H1>en-US-region1</H1>
+<p><a href="web1.oxt">web1.oxt</a></p>
+<p><a href="web2.oxt">web2.oxt</a></p>
+<p><a href="web3.oxt">web3.oxt</a></p>
+<p><a href="web4.oxt">web4.oxt</a></p>
+<p><a href="web5.oxt">web5.oxt</a></p>
+<p><a href="web6.oxt">web6.oxt</a></p>
+<p><a href="web7.oxt">web7.oxt</a></p>
+
+
+</BODY>
+</HTML>
+
diff --git a/desktop/test/deployment/update/website_update/update/web1_en-US-region2.html b/desktop/test/deployment/update/website_update/update/web1_en-US-region2.html
new file mode 100755
index 000000000000..1a501f520d85
--- /dev/null
+++ b/desktop/test/deployment/update/website_update/update/web1_en-US-region2.html
@@ -0,0 +1,19 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+</HEAD>
+<BODY>
+<H1>Update Extensions</H1>
+<H1>en-US-region2</H1>
+<p><a href="web1.oxt">web1.oxt</a></p>
+<p><a href="web2.oxt">web2.oxt</a></p>
+<p><a href="web3.oxt">web3.oxt</a></p>
+<p><a href="web4.oxt">web4.oxt</a></p>
+<p><a href="web5.oxt">web5.oxt</a></p>
+<p><a href="web6.oxt">web6.oxt</a></p>
+<p><a href="web7.oxt">web7.oxt</a></p>
+
+
+</BODY>
+</HTML>
+
diff --git a/desktop/test/deployment/update/website_update/update/web1_en-US.html b/desktop/test/deployment/update/website_update/update/web1_en-US.html
new file mode 100755
index 000000000000..f861b09c0162
--- /dev/null
+++ b/desktop/test/deployment/update/website_update/update/web1_en-US.html
@@ -0,0 +1,20 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+</HEAD>
+<BODY>
+<H1>Update Extensions</H1>
+<H1>en-US</H1>
+<p><a href="web1.oxt">web1.oxt</a></p>
+<p><a href="web2.oxt">web2.oxt</a></p>
+<p><a href="web3.oxt">web3.oxt</a></p>
+<p><a href="web4.oxt">web4.oxt</a></p>
+<p><a href="web5.oxt">web5.oxt</a></p>
+<p><a href="web6.oxt">web6.oxt</a></p>
+<p><a href="web7.oxt">web7.oxt</a></p>
+
+
+
+</BODY>
+</HTML>
+
diff --git a/desktop/test/deployment/update/website_update/update/web1_en-region3.html b/desktop/test/deployment/update/website_update/update/web1_en-region3.html
new file mode 100755
index 000000000000..f55bcbe38135
--- /dev/null
+++ b/desktop/test/deployment/update/website_update/update/web1_en-region3.html
@@ -0,0 +1,19 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+</HEAD>
+<BODY>
+<H1>Update Extensions</H1>
+<H1>en-region3</H1>
+<p><a href="web1.oxt">web1.oxt</a></p>
+<p><a href="web2.oxt">web2.oxt</a></p>
+<p><a href="web3.oxt">web3.oxt</a></p>
+<p><a href="web4.oxt">web4.oxt</a></p>
+<p><a href="web5.oxt">web5.oxt</a></p>
+<p><a href="web6.oxt">web6.oxt</a></p>
+<p><a href="web7.oxt">web7.oxt</a></p>
+
+
+</BODY>
+</HTML>
+
diff --git a/desktop/test/deployment/update/website_update/update/web1_en.html b/desktop/test/deployment/update/website_update/update/web1_en.html
new file mode 100755
index 000000000000..a0b422ebf20e
--- /dev/null
+++ b/desktop/test/deployment/update/website_update/update/web1_en.html
@@ -0,0 +1,19 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+</HEAD>
+<BODY>
+<H1>Update Extensions</H1>
+<H1>en</H1>
+<p><a href="web1.oxt">web1.oxt</a></p>
+<p><a href="web2.oxt">web2.oxt</a></p>
+<p><a href="web3.oxt">web3.oxt</a></p>
+<p><a href="web4.oxt">web4.oxt</a></p>
+<p><a href="web5.oxt">web5.oxt</a></p>
+<p><a href="web6.oxt">web6.oxt</a></p>
+<p><a href="web7.oxt">web7.oxt</a></p>
+
+
+</BODY>
+</HTML>
+
diff --git a/desktop/test/deployment/update/website_update/update/web2.oxt b/desktop/test/deployment/update/website_update/update/web2.oxt
new file mode 100644
index 000000000000..3a13e8114314
--- /dev/null
+++ b/desktop/test/deployment/update/website_update/update/web2.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/website_update/update/web2.update.xml b/desktop/test/deployment/update/website_update/update/web2.update.xml
new file mode 100755
index 000000000000..afdcdf078edf
--- /dev/null
+++ b/desktop/test/deployment/update/website_update/update/web2.update.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<description xmlns="http://openoffice.org/extensions/update/2006"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+ <version value="2.0" />
+
+ <identifier value="org.openoffice/framework/desktop/test/deployment/update/website_update/web2"/>
+
+ <update-website>
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/website_update/update/web1_de.html" lang="de" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/website_update/update/web1_en.html" lang="en" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/website_update/update/web1_de-DE.html" lang="de-DE" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/website_update/update/web1_de-DE-altmark.html" lang="de-DE-altmark" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/website_update/update/web1_en-GB.html" lang="en-GB" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/website_update/update/web1_en-US-region1.html" lang="en-US-region1" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/website_update/update/web1_en-US-region2.html" lang="en-US-region2" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/website_update/update/web1_en-region3.html" lang="en-region3" />
+ </update-website>
+</description>
+
diff --git a/desktop/test/deployment/update/website_update/update/web3.oxt b/desktop/test/deployment/update/website_update/update/web3.oxt
new file mode 100644
index 000000000000..b3214a4e693f
--- /dev/null
+++ b/desktop/test/deployment/update/website_update/update/web3.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/website_update/update/web3.update.xml b/desktop/test/deployment/update/website_update/update/web3.update.xml
new file mode 100755
index 000000000000..ce6263656120
--- /dev/null
+++ b/desktop/test/deployment/update/website_update/update/web3.update.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<description xmlns="http://openoffice.org/extensions/update/2006"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+ <version value="2.0" />
+
+ <identifier value="org.openoffice/framework/desktop/test/deployment/update/website_update/web3"/>
+
+ <update-website>
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/website_update/update/web1_de.html" lang="de" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/website_update/update/web1_en.html" lang="en" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/website_update/update/web1_de-DE.html" lang="de-DE" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/website_update/update/web1_de-DE-altmark.html" lang="de-DE-altmark" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/website_update/update/web1_en-GB.html" lang="en-GB" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/website_update/update/web1_en-region3.html" lang="en-region3" />
+ </update-website>
+</description>
+
diff --git a/desktop/test/deployment/update/website_update/update/web4.oxt b/desktop/test/deployment/update/website_update/update/web4.oxt
new file mode 100644
index 000000000000..93766fd44faf
--- /dev/null
+++ b/desktop/test/deployment/update/website_update/update/web4.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/website_update/update/web4.update.xml b/desktop/test/deployment/update/website_update/update/web4.update.xml
new file mode 100755
index 000000000000..d07f1dec149e
--- /dev/null
+++ b/desktop/test/deployment/update/website_update/update/web4.update.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<description xmlns="http://openoffice.org/extensions/update/2006"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+ <version value="2.0" />
+
+ <identifier value="org.openoffice/framework/desktop/test/deployment/update/website_update/web4"/>
+
+ <update-website>
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/website_update/update/web1_de.html" lang="de" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/website_update/update/web1_de-DE.html" lang="de-DE" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/website_update/update/web1_de-DE-altmark.html" lang="de-DE-altmark" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/website_update/update/web1_en-GB.html" lang="en-GB" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/website_update/update/web1_en-region3.html" lang="en-region3" />
+ </update-website>
+</description>
+
diff --git a/desktop/test/deployment/update/website_update/update/web5.oxt b/desktop/test/deployment/update/website_update/update/web5.oxt
new file mode 100644
index 000000000000..1ae8f01b19cb
--- /dev/null
+++ b/desktop/test/deployment/update/website_update/update/web5.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/website_update/update/web5.update.xml b/desktop/test/deployment/update/website_update/update/web5.update.xml
new file mode 100755
index 000000000000..a392466c5785
--- /dev/null
+++ b/desktop/test/deployment/update/website_update/update/web5.update.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<description xmlns="http://openoffice.org/extensions/update/2006"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+ <version value="2.0" />
+
+ <identifier value="org.openoffice/framework/desktop/test/deployment/update/website_update/web5"/>
+
+ <update-website>
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/website_update/update/web1_de.html" lang="de" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/website_update/update/web1_de-DE.html" lang="de-DE" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/website_update/update/web1_de-DE-altmark.html" lang="de-DE-altmark" />
+ </update-website>
+</description>
+
diff --git a/desktop/test/deployment/update/website_update/update/web6.oxt b/desktop/test/deployment/update/website_update/update/web6.oxt
new file mode 100644
index 000000000000..8bc16fb2c73a
--- /dev/null
+++ b/desktop/test/deployment/update/website_update/update/web6.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/website_update/update/web6/description.xml b/desktop/test/deployment/update/website_update/update/web6/description.xml
new file mode 100755
index 000000000000..243c1d8ff962
--- /dev/null
+++ b/desktop/test/deployment/update/website_update/update/web6/description.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<description xmlns="http://openoffice.org/extensions/description/2006"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+ <version value="2.0" />
+ <identifier value="org.openoffice/framework/desktop/test/deployment/update/website_update/web6"/>
+ <display-name>
+ <name lang="en">web-based update test 1</name>
+ </display-name>
+
+</description>
+
diff --git a/desktop/test/deployment/update/website_update/update/web6/readme.txt b/desktop/test/deployment/update/website_update/update/web6/readme.txt
new file mode 100755
index 000000000000..7a1ba06efaa3
--- /dev/null
+++ b/desktop/test/deployment/update/website_update/update/web6/readme.txt
@@ -0,0 +1,5 @@
+This folder contains the description.xml from update/web6.oxt
+When creating the release 2.0 on the repository then this description.xml can be uploaded.
+
+
+This folder is not needed on extensions.openoffice.org/testarea/desktop/....
diff --git a/desktop/test/deployment/update/website_update/update/web7.oxt b/desktop/test/deployment/update/website_update/update/web7.oxt
new file mode 100644
index 000000000000..4d6220a48af2
--- /dev/null
+++ b/desktop/test/deployment/update/website_update/update/web7.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/website_update/update/web7/description.xml b/desktop/test/deployment/update/website_update/update/web7/description.xml
new file mode 100755
index 000000000000..5b03e12ad436
--- /dev/null
+++ b/desktop/test/deployment/update/website_update/update/web7/description.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<description xmlns="http://openoffice.org/extensions/description/2006"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+ <version value="2.0" />
+ <identifier value="org.openoffice/framework/desktop/test/deployment/update/website_update/web7"/>
+ <display-name>
+ <name lang="en">web-based update test 1</name>
+ </display-name>
+
+ <publisher>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_de.html" lang="de">My OpenOffice de</name>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_en.html" lang="en">My OpenOffice en</name>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_de-DE.html" lang="de-DE">My OpenOffice de-DE</name>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_de-DE-altmark.html" lang="de-DE-altmark">My OpenOffice de-DE-altmark</name>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_en-GB.html" lang="en-GB">My OpenOffice en-GB</name>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_en-US.html" lang="en-US">My OpenOffice en-US</name>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_en-US-region1.html" lang="en-US-region1">My OpenOffice en-US-region1</name>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_en-US-region2.html" lang="en-US-region2">My OpenOffice en-US-region2</name>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_en-region3.html" lang="en-region3">My OpenOffice en-region3</name>
+ </publisher>
+
+ <release-notes>
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_de.html" lang="de" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_en.html" lang="en" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_de-DE.html" lang="de-DE" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_de-DE-altmark.html" lang="de-DE-altmark" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_en-GB.html" lang="en-GB" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_en-US.html" lang="en-US" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_en-US-region1.html" lang="en-US-region1" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_en-US-region2.html" lang="en-US-region2" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_en-region3.html" lang="en-region3" />
+ </release-notes>
+
+
+</description>
+
diff --git a/desktop/test/deployment/update/website_update/update/web7/readme.txt b/desktop/test/deployment/update/website_update/update/web7/readme.txt
new file mode 100755
index 000000000000..8a6721b8e85c
--- /dev/null
+++ b/desktop/test/deployment/update/website_update/update/web7/readme.txt
@@ -0,0 +1,5 @@
+This folder contains the description.xml from update/web7.oxt
+When creating the release 2.0 on the repository then this description.xml can be uploaded.
+
+
+This folder is not needed on extensions.openoffice.org/testarea/desktop/....
diff --git a/desktop/test/deployment/update/website_update/web1.oxt b/desktop/test/deployment/update/website_update/web1.oxt
new file mode 100644
index 000000000000..7c17586e0454
--- /dev/null
+++ b/desktop/test/deployment/update/website_update/web1.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/website_update/web2.oxt b/desktop/test/deployment/update/website_update/web2.oxt
new file mode 100644
index 000000000000..705e70a7533f
--- /dev/null
+++ b/desktop/test/deployment/update/website_update/web2.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/website_update/web3.oxt b/desktop/test/deployment/update/website_update/web3.oxt
new file mode 100644
index 000000000000..4e63a75f0cbf
--- /dev/null
+++ b/desktop/test/deployment/update/website_update/web3.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/website_update/web4.oxt b/desktop/test/deployment/update/website_update/web4.oxt
new file mode 100644
index 000000000000..e66513e68384
--- /dev/null
+++ b/desktop/test/deployment/update/website_update/web4.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/website_update/web5.oxt b/desktop/test/deployment/update/website_update/web5.oxt
new file mode 100644
index 000000000000..65b02db9347d
--- /dev/null
+++ b/desktop/test/deployment/update/website_update/web5.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/website_update/web6.oxt b/desktop/test/deployment/update/website_update/web6.oxt
new file mode 100644
index 000000000000..98416edfa583
--- /dev/null
+++ b/desktop/test/deployment/update/website_update/web6.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/website_update/web7.oxt b/desktop/test/deployment/update/website_update/web7.oxt
new file mode 100644
index 000000000000..31ba45f032d5
--- /dev/null
+++ b/desktop/test/deployment/update/website_update/web7.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/wrong_url/readme.txt b/desktop/test/deployment/update/wrong_url/readme.txt
new file mode 100755
index 000000000000..cc2459763ca9
--- /dev/null
+++ b/desktop/test/deployment/update/wrong_url/readme.txt
@@ -0,0 +1,18 @@
+The extensions use either multiple urls to the update information file, or the update information file contains multiple urls. Some of those URLs point to locations which do not exist.
+
+url1.oxt: The corresponding url1.update.xml contains two download urls. The first Url points to a location that is not available. The second points to the new version.
+
+url2.oxt: Contains to URLs to update information files. The first URL in url2.oxt is wrong and the second is
+correct.
+
+url3.oxt: contains to URLs to update information files which point to locations which do not exist.
+
+wrongdownload1.oxt: The corresponding wrongdownload1.update.xml contains two download URLs which point to locations which are not available.
+
+wrongdownload2.oxt: same as wrongdownload1.oxt
+
+wrongdownload3.oxt: same as wrongdownload1.oxt
+
+
+Use the wrongdownload extensions to check the automatic scolling of the text area that contains the results.
+
diff --git a/desktop/test/deployment/update/wrong_url/update/url1.oxt b/desktop/test/deployment/update/wrong_url/update/url1.oxt
new file mode 100644
index 000000000000..479b546c84dd
--- /dev/null
+++ b/desktop/test/deployment/update/wrong_url/update/url1.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/wrong_url/update/url1.update.xml b/desktop/test/deployment/update/wrong_url/update/url1.update.xml
new file mode 100755
index 000000000000..5ff3bce7bb2f
--- /dev/null
+++ b/desktop/test/deployment/update/wrong_url/update/url1.update.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<description xmlns="http://openoffice.org/extensions/update/2006"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+ <identifier value="org.openoffice.legacy.url1.oxt"/>
+ <version value="2.0" />
+ <update-download>
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/wrong_url/notavailable/url1.oxt" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/wrong_url/update/url1.oxt" />
+ </update-download>
+</description>
+
diff --git a/desktop/test/deployment/update/wrong_url/update/url2.oxt b/desktop/test/deployment/update/wrong_url/update/url2.oxt
new file mode 100644
index 000000000000..ec2c5c6528cd
--- /dev/null
+++ b/desktop/test/deployment/update/wrong_url/update/url2.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/wrong_url/update/url2.update.xml b/desktop/test/deployment/update/wrong_url/update/url2.update.xml
new file mode 100755
index 000000000000..4bf79eb39425
--- /dev/null
+++ b/desktop/test/deployment/update/wrong_url/update/url2.update.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<description xmlns="http://openoffice.org/extensions/update/2006"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+ <identifier value="org.openoffice.legacy.url2.oxt"/>
+ <version value="2.0" />
+ <update-download>
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/wrong_url/update/url2.oxt" />
+ </update-download>
+</description>
+
diff --git a/desktop/test/deployment/update/wrong_url/update/wrongdownload1.update.xml b/desktop/test/deployment/update/wrong_url/update/wrongdownload1.update.xml
new file mode 100755
index 000000000000..0fd5bee55346
--- /dev/null
+++ b/desktop/test/deployment/update/wrong_url/update/wrongdownload1.update.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<description xmlns="http://openoffice.org/extensions/update/2006"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+ <identifier value="org.openoffice.legacy.wrongdownload1.oxt"/>
+ <version value="2.0" />
+ <update-download>
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/wrong_url/notavailable/wrongdownload1.oxt" />
+ <src xlink:href="http://extensions.openoffice.org/notavailable/" />
+ </update-download>
+</description>
+
diff --git a/desktop/test/deployment/update/wrong_url/update/wrongdownload2.update.xml b/desktop/test/deployment/update/wrong_url/update/wrongdownload2.update.xml
new file mode 100755
index 000000000000..124331215215
--- /dev/null
+++ b/desktop/test/deployment/update/wrong_url/update/wrongdownload2.update.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<description xmlns="http://openoffice.org/extensions/update/2006"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+ <identifier value="org.openoffice.legacy.wrongdownload2.oxt"/>
+ <version value="2.0" />
+ <update-download>
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/wrong_url/notavailable/wrongdownload2.oxt" />
+ <src xlink:href="http://extensions.openoffice.org/notavailable/" />
+ </update-download>
+</description>
+
diff --git a/desktop/test/deployment/update/wrong_url/update/wrongdownload3.update.xml b/desktop/test/deployment/update/wrong_url/update/wrongdownload3.update.xml
new file mode 100755
index 000000000000..051d33ec4ba4
--- /dev/null
+++ b/desktop/test/deployment/update/wrong_url/update/wrongdownload3.update.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<description xmlns="http://openoffice.org/extensions/update/2006"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+ <identifier value="org.openoffice.legacy.wrongdownload3.oxt"/>
+ <version value="2.0" />
+ <update-download>
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/wrong_url/notavailable/wrongdownload3.oxt" />
+ <src xlink:href="http://extensions.openoffice.org/notavailable/" />
+ </update-download>
+</description>
+
diff --git a/desktop/test/deployment/update/wrong_url/url1.oxt b/desktop/test/deployment/update/wrong_url/url1.oxt
new file mode 100644
index 000000000000..41d8522fbbce
--- /dev/null
+++ b/desktop/test/deployment/update/wrong_url/url1.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/wrong_url/url2.oxt b/desktop/test/deployment/update/wrong_url/url2.oxt
new file mode 100644
index 000000000000..d68e45e5e55f
--- /dev/null
+++ b/desktop/test/deployment/update/wrong_url/url2.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/wrong_url/url3.oxt b/desktop/test/deployment/update/wrong_url/url3.oxt
new file mode 100644
index 000000000000..80f93b74d11f
--- /dev/null
+++ b/desktop/test/deployment/update/wrong_url/url3.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/wrong_url/wrongdownload1.oxt b/desktop/test/deployment/update/wrong_url/wrongdownload1.oxt
new file mode 100644
index 000000000000..535ae331a9af
--- /dev/null
+++ b/desktop/test/deployment/update/wrong_url/wrongdownload1.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/wrong_url/wrongdownload2.oxt b/desktop/test/deployment/update/wrong_url/wrongdownload2.oxt
new file mode 100644
index 000000000000..aafe2c24672b
--- /dev/null
+++ b/desktop/test/deployment/update/wrong_url/wrongdownload2.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/wrong_url/wrongdownload3.oxt b/desktop/test/deployment/update/wrong_url/wrongdownload3.oxt
new file mode 100644
index 000000000000..fbdac925a257
--- /dev/null
+++ b/desktop/test/deployment/update/wrong_url/wrongdownload3.oxt
Binary files differ
diff --git a/desktop/test/deployment/version/readme.txt b/desktop/test/deployment/version/readme.txt
new file mode 100755
index 000000000000..c2ba28afd916
--- /dev/null
+++ b/desktop/test/deployment/version/readme.txt
@@ -0,0 +1,85 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+There are three extensions in various versions:
+
+1 version_XXX/plain.oxt has no dependencies and no license.
+2a version_XXX/dependency.oxt has an unsatisfied dependency and no license.
+2b version_nodependencies_XXX/dependency.oxt is identical to 2a but without the
+ dependency.
+3 version_XXX/license.oxt has no dependencies and a license.
+
+The different versions are:
+
+A version_none contains no version element (treated as version "0").
+B version_badelement contains a bad <version val="1"/> (not allowed by the
+ specification, but treated by the current implementation as version "0").
+C version_badvalue contains a bad <version value="1.a"/> (not allowed by the
+ specification, but treated by the current implementation as version "1").
+D version_0.0 contains <version value="0.0"/> (same as version "0").
+E version_1.2.3 contains <version value="1.2.3"/>.
+F version_1.2.4.7 contains <version value="1.2.4.7"/>.
+G version_1.02.4.7.0 contains <version value="1.02.4.7.0"/> (same as version
+ "1.2.4.7").
+H version_1.2.15.3 contains <version value="1.2.15.3"/>.
+
+The total order among the various versions is thus
+
+ A = B = D < C < E < F = G < H.
+
+Things to watch for:
+
+- If version y of extension e is to be installed and version x < y of
+ extension e is already installed, then
+ unopkg add e
+ will replace x with y.
+
+- If version y of extension e is to be installed and version x >= y of
+ extension e is already installed, then
+ unopkg add e
+ will fail with an error message.
+
+- If version y of extension e is to be installed and any version x of
+ extension e is already installed, then
+ unopkg add -f e
+ will replace x with y.
+
+- If version y of extension e is to be installed and any version x of
+ extension e is already installed, then
+ unopkg gui "Add..."
+ and
+ soffice "Tools - Package Manager... - Add..."
+ will query with a dialog whether to replace x with y. The dialog will have
+ "OK" (replace) preselected if x < y, and "Cancel" otherwise.
+
+- If replacing an installed version x of an extension e with a version y fails
+ because y has unsatisfied dependencies, or because y has a license to wich the
+ user does not agree, version x is left installed afterwards.
+
+- Checking for already installed versions of an extension is only done within a
+ single layer (unopkg versus unopkg --shared; "My Packages" versus
+ "OpenOffice Packages" in unopkg gui/soffice), not across layers.
diff --git a/desktop/test/deployment/version/version_0.0/dependency.oxt b/desktop/test/deployment/version/version_0.0/dependency.oxt
new file mode 100644
index 000000000000..30c8432251a5
--- /dev/null
+++ b/desktop/test/deployment/version/version_0.0/dependency.oxt
Binary files differ
diff --git a/desktop/test/deployment/version/version_0.0/license.oxt b/desktop/test/deployment/version/version_0.0/license.oxt
new file mode 100644
index 000000000000..b994ff71b732
--- /dev/null
+++ b/desktop/test/deployment/version/version_0.0/license.oxt
Binary files differ
diff --git a/desktop/test/deployment/version/version_0.0/plain.oxt b/desktop/test/deployment/version/version_0.0/plain.oxt
new file mode 100644
index 000000000000..f156014eb8c3
--- /dev/null
+++ b/desktop/test/deployment/version/version_0.0/plain.oxt
Binary files differ
diff --git a/desktop/test/deployment/version/version_1.02.4.7.0/dependency.oxt b/desktop/test/deployment/version/version_1.02.4.7.0/dependency.oxt
new file mode 100644
index 000000000000..4d75f7076234
--- /dev/null
+++ b/desktop/test/deployment/version/version_1.02.4.7.0/dependency.oxt
Binary files differ
diff --git a/desktop/test/deployment/version/version_1.02.4.7.0/license.oxt b/desktop/test/deployment/version/version_1.02.4.7.0/license.oxt
new file mode 100644
index 000000000000..40938b7543db
--- /dev/null
+++ b/desktop/test/deployment/version/version_1.02.4.7.0/license.oxt
Binary files differ
diff --git a/desktop/test/deployment/version/version_1.02.4.7.0/plain.oxt b/desktop/test/deployment/version/version_1.02.4.7.0/plain.oxt
new file mode 100644
index 000000000000..521a2b6c77a8
--- /dev/null
+++ b/desktop/test/deployment/version/version_1.02.4.7.0/plain.oxt
Binary files differ
diff --git a/desktop/test/deployment/version/version_1.2.15.3/dependency.oxt b/desktop/test/deployment/version/version_1.2.15.3/dependency.oxt
new file mode 100644
index 000000000000..6f2a301f3bb3
--- /dev/null
+++ b/desktop/test/deployment/version/version_1.2.15.3/dependency.oxt
Binary files differ
diff --git a/desktop/test/deployment/version/version_1.2.15.3/license.oxt b/desktop/test/deployment/version/version_1.2.15.3/license.oxt
new file mode 100644
index 000000000000..2e2a87575047
--- /dev/null
+++ b/desktop/test/deployment/version/version_1.2.15.3/license.oxt
Binary files differ
diff --git a/desktop/test/deployment/version/version_1.2.15.3/plain.oxt b/desktop/test/deployment/version/version_1.2.15.3/plain.oxt
new file mode 100644
index 000000000000..000f3a144fbd
--- /dev/null
+++ b/desktop/test/deployment/version/version_1.2.15.3/plain.oxt
Binary files differ
diff --git a/desktop/test/deployment/version/version_1.2.3/dependency.oxt b/desktop/test/deployment/version/version_1.2.3/dependency.oxt
new file mode 100644
index 000000000000..c2966345872d
--- /dev/null
+++ b/desktop/test/deployment/version/version_1.2.3/dependency.oxt
Binary files differ
diff --git a/desktop/test/deployment/version/version_1.2.3/license.oxt b/desktop/test/deployment/version/version_1.2.3/license.oxt
new file mode 100644
index 000000000000..9cd80e9911b4
--- /dev/null
+++ b/desktop/test/deployment/version/version_1.2.3/license.oxt
Binary files differ
diff --git a/desktop/test/deployment/version/version_1.2.3/plain.oxt b/desktop/test/deployment/version/version_1.2.3/plain.oxt
new file mode 100644
index 000000000000..e34264591c58
--- /dev/null
+++ b/desktop/test/deployment/version/version_1.2.3/plain.oxt
Binary files differ
diff --git a/desktop/test/deployment/version/version_1.2.4.7/dependency.oxt b/desktop/test/deployment/version/version_1.2.4.7/dependency.oxt
new file mode 100644
index 000000000000..53089e76b07e
--- /dev/null
+++ b/desktop/test/deployment/version/version_1.2.4.7/dependency.oxt
Binary files differ
diff --git a/desktop/test/deployment/version/version_1.2.4.7/license.oxt b/desktop/test/deployment/version/version_1.2.4.7/license.oxt
new file mode 100644
index 000000000000..e283508d3492
--- /dev/null
+++ b/desktop/test/deployment/version/version_1.2.4.7/license.oxt
Binary files differ
diff --git a/desktop/test/deployment/version/version_1.2.4.7/plain.oxt b/desktop/test/deployment/version/version_1.2.4.7/plain.oxt
new file mode 100644
index 000000000000..d63c79a734b6
--- /dev/null
+++ b/desktop/test/deployment/version/version_1.2.4.7/plain.oxt
Binary files differ
diff --git a/desktop/test/deployment/version/version_badelement/dependency.oxt b/desktop/test/deployment/version/version_badelement/dependency.oxt
new file mode 100644
index 000000000000..3cb8faa2e7b6
--- /dev/null
+++ b/desktop/test/deployment/version/version_badelement/dependency.oxt
Binary files differ
diff --git a/desktop/test/deployment/version/version_badelement/license.oxt b/desktop/test/deployment/version/version_badelement/license.oxt
new file mode 100644
index 000000000000..7b2b7730eced
--- /dev/null
+++ b/desktop/test/deployment/version/version_badelement/license.oxt
Binary files differ
diff --git a/desktop/test/deployment/version/version_badelement/plain.oxt b/desktop/test/deployment/version/version_badelement/plain.oxt
new file mode 100644
index 000000000000..62267c212fdc
--- /dev/null
+++ b/desktop/test/deployment/version/version_badelement/plain.oxt
Binary files differ
diff --git a/desktop/test/deployment/version/version_badvalue/dependency.oxt b/desktop/test/deployment/version/version_badvalue/dependency.oxt
new file mode 100644
index 000000000000..7d8103365452
--- /dev/null
+++ b/desktop/test/deployment/version/version_badvalue/dependency.oxt
Binary files differ
diff --git a/desktop/test/deployment/version/version_badvalue/license.oxt b/desktop/test/deployment/version/version_badvalue/license.oxt
new file mode 100644
index 000000000000..b97723ebb0bc
--- /dev/null
+++ b/desktop/test/deployment/version/version_badvalue/license.oxt
Binary files differ
diff --git a/desktop/test/deployment/version/version_badvalue/plain.oxt b/desktop/test/deployment/version/version_badvalue/plain.oxt
new file mode 100644
index 000000000000..f9964ed8f070
--- /dev/null
+++ b/desktop/test/deployment/version/version_badvalue/plain.oxt
Binary files differ
diff --git a/desktop/test/deployment/version/version_nodependencies_0.0/dependency.oxt b/desktop/test/deployment/version/version_nodependencies_0.0/dependency.oxt
new file mode 100644
index 000000000000..f156014eb8c3
--- /dev/null
+++ b/desktop/test/deployment/version/version_nodependencies_0.0/dependency.oxt
Binary files differ
diff --git a/desktop/test/deployment/version/version_nodependencies_1.02.4.7.0/dependency.oxt b/desktop/test/deployment/version/version_nodependencies_1.02.4.7.0/dependency.oxt
new file mode 100644
index 000000000000..521a2b6c77a8
--- /dev/null
+++ b/desktop/test/deployment/version/version_nodependencies_1.02.4.7.0/dependency.oxt
Binary files differ
diff --git a/desktop/test/deployment/version/version_nodependencies_1.2.15.3/dependency.oxt b/desktop/test/deployment/version/version_nodependencies_1.2.15.3/dependency.oxt
new file mode 100644
index 000000000000..000f3a144fbd
--- /dev/null
+++ b/desktop/test/deployment/version/version_nodependencies_1.2.15.3/dependency.oxt
Binary files differ
diff --git a/desktop/test/deployment/version/version_nodependencies_1.2.3/dependency.oxt b/desktop/test/deployment/version/version_nodependencies_1.2.3/dependency.oxt
new file mode 100644
index 000000000000..e34264591c58
--- /dev/null
+++ b/desktop/test/deployment/version/version_nodependencies_1.2.3/dependency.oxt
Binary files differ
diff --git a/desktop/test/deployment/version/version_nodependencies_1.2.4.7/dependency.oxt b/desktop/test/deployment/version/version_nodependencies_1.2.4.7/dependency.oxt
new file mode 100644
index 000000000000..d63c79a734b6
--- /dev/null
+++ b/desktop/test/deployment/version/version_nodependencies_1.2.4.7/dependency.oxt
Binary files differ
diff --git a/desktop/test/deployment/version/version_nodependencies_badelement/dependency.oxt b/desktop/test/deployment/version/version_nodependencies_badelement/dependency.oxt
new file mode 100644
index 000000000000..62267c212fdc
--- /dev/null
+++ b/desktop/test/deployment/version/version_nodependencies_badelement/dependency.oxt
Binary files differ
diff --git a/desktop/test/deployment/version/version_nodependencies_badvalue/dependency.oxt b/desktop/test/deployment/version/version_nodependencies_badvalue/dependency.oxt
new file mode 100644
index 000000000000..f9964ed8f070
--- /dev/null
+++ b/desktop/test/deployment/version/version_nodependencies_badvalue/dependency.oxt
Binary files differ
diff --git a/desktop/test/deployment/version/version_nodependencies_none/dependency.oxt b/desktop/test/deployment/version/version_nodependencies_none/dependency.oxt
new file mode 100644
index 000000000000..fc227b099ec8
--- /dev/null
+++ b/desktop/test/deployment/version/version_nodependencies_none/dependency.oxt
Binary files differ
diff --git a/desktop/test/deployment/version/version_none/dependency.oxt b/desktop/test/deployment/version/version_none/dependency.oxt
new file mode 100644
index 000000000000..36a1854bf59b
--- /dev/null
+++ b/desktop/test/deployment/version/version_none/dependency.oxt
Binary files differ
diff --git a/desktop/test/deployment/version/version_none/license.oxt b/desktop/test/deployment/version/version_none/license.oxt
new file mode 100644
index 000000000000..1564c089b0a7
--- /dev/null
+++ b/desktop/test/deployment/version/version_none/license.oxt
Binary files differ
diff --git a/desktop/test/deployment/version/version_none/plain.oxt b/desktop/test/deployment/version/version_none/plain.oxt
new file mode 100644
index 000000000000..fc227b099ec8
--- /dev/null
+++ b/desktop/test/deployment/version/version_none/plain.oxt
Binary files differ
diff --git a/desktop/unx/source/args.c b/desktop/unx/source/args.c
new file mode 100644
index 000000000000..0f47f791d5eb
--- /dev/null
+++ b/desktop/unx/source/args.c
@@ -0,0 +1,152 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Version: MPL 1.1 / GPLv3+ / LGPLv3+
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License or as specified alternatively below. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Initial Developer of the Original Code is
+ * Novell, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 2010 the
+ * Initial Developer. All Rights Reserved.
+ *
+ * Major Contributor(s):
+ * Michael Meeks <michael.meeks@novell.com>
+ * Portions created by the Ted are Copyright (C) 2010 Ted. All Rights Reserved.
+ *
+ * For minor contributions see the git repository.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
+ * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
+ * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
+ * instead of those above.
+ */
+#include <stdlib.h>
+#include <string.h>
+#include <osl/process.h>
+
+#include "args.h"
+
+/* do we start -env: */
+static int
+is_env_arg (rtl_uString *str)
+{
+ return !rtl_ustr_ascii_compare_WithLength (str->buffer, 5, "-env:");
+}
+
+static struct {
+ const char *name;
+ unsigned int bTwoArgs : 1;
+ unsigned int bInhibitSplash : 1;
+ unsigned int bInhibitPagein : 1;
+ unsigned int bInhibitJavaLdx : 1;
+ const char *pPageinType;
+} pArgDescr[] = {
+ /* have a trailing argument */
+ { "pt", 1, 0, 0, 0, NULL },
+ { "display", 1, 0, 0, 0, NULL },
+
+ /* no splash */
+ { "nologo", 0, 1, 0, 0, NULL },
+ { "headless", 0, 1, 0, 0, NULL },
+ { "invisible", 0, 1, 0, 0, NULL },
+ { "minimized", 0, 1, 0, 0, NULL },
+
+ /* pagein bits */
+ { "writer", 0, 0, 0, 0, "@pagein-writer" },
+ { "calc", 0, 0, 0, 0, "@pagein-calc" },
+ { "draw", 0, 0, 0, 0, "@pagein-draw" },
+ { "impress", 0, 0, 0, 0, "@pagein-impress" },
+
+ /* nothing much */
+ { "version", 0, 1, 1, 1, NULL },
+ { "help", 0, 1, 1, 1, NULL },
+ { "h", 0, 1, 1, 1, NULL },
+ { "?", 0, 1, 1, 1, NULL },
+};
+
+Args *args_parse (void)
+{
+ Args *args;
+ sal_uInt32 nArgs, i, j;
+
+ nArgs = osl_getCommandArgCount();
+ i = sizeof (Args) + sizeof (rtl_uString *) * nArgs;
+ args = malloc (i);
+ memset (args, 0, i);
+ args->nArgsTotal = nArgs;
+
+ j = 0;
+
+ /* sort the -env: args to the front */
+ for ( i = 0; i < nArgs; ++i )
+ {
+ rtl_uString *pTmp = NULL;
+ osl_getCommandArg( i, &pTmp );
+ if (is_env_arg (pTmp))
+ args->ppArgs[j++] = pTmp;
+ else
+ rtl_uString_release (pTmp);
+ }
+ args->nArgsEnv = j;
+
+ /* Then the other args */
+ for ( i = 0; i < nArgs; ++i )
+ {
+ rtl_uString *pTmp = NULL;
+
+ osl_getCommandArg( i, &pTmp );
+ if (!is_env_arg (pTmp))
+ args->ppArgs[j++] = pTmp;
+ else
+ rtl_uString_release (pTmp);
+ }
+
+ for ( i = args->nArgsEnv; i < args->nArgsTotal; i++ )
+ {
+ sal_uInt32 j;
+ const sal_Unicode *arg = args->ppArgs[i]->buffer;
+ sal_Int32 length = args->ppArgs[i]->length;
+
+ /* grok only parameters */
+ if (arg[0] != '-')
+ continue;
+
+ while (length > 2 && arg[0] == '-') {
+ arg++;
+ length--;
+ }
+
+ for ( j = 0; j < SAL_N_ELEMENTS (pArgDescr); ++j ) {
+ if (!rtl_ustr_indexOfAscii_WithLength
+ (arg, length, pArgDescr[j].name, strlen (pArgDescr[j].name))) {
+
+ args->bInhibitSplash |= pArgDescr[j].bInhibitSplash;
+ args->bInhibitPagein |= pArgDescr[j].bInhibitPagein;
+ args->bInhibitJavaLdx |= pArgDescr[j].bInhibitJavaLdx;
+ if (pArgDescr[j].pPageinType)
+ args->pPageinType = pArgDescr[j].pPageinType;
+ }
+ }
+ }
+
+ return args;
+}
+
+void
+args_free (Args *args)
+{
+ /* FIXME: free ppArgs */
+ rtl_uString_release( args->pAppPath );
+ free (args);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/unx/source/args.h b/desktop/unx/source/args.h
new file mode 100644
index 000000000000..4a0cb55ffcde
--- /dev/null
+++ b/desktop/unx/source/args.h
@@ -0,0 +1,50 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Version: MPL 1.1 / GPLv3+ / LGPLv3+
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License or as specified alternatively below. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Initial Developer of the Original Code is
+ * Novell, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 2010 the
+ * Initial Developer. All Rights Reserved.
+ *
+ * Major Contributor(s):
+ * Michael Meeks <michael.meeks@novell.com>
+ * Portions created by the Ted are Copyright (C) 2010 Ted. All Rights Reserved.
+ *
+ * For minor contributions see the git repository.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
+ * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
+ * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
+ * instead of those above.
+ */
+#include <sal/types.h>
+#include <rtl/ustring.h>
+
+typedef struct {
+ rtl_uString *pAppPath;
+ const char *pPageinType; // @pagein-writer for - writer etc. else NULL
+ sal_Bool bInhibitSplash; // should we show a splash screen
+ sal_Bool bInhibitPagein; // should we run pagein ?
+ sal_Bool bInhibitJavaLdx; // should we run javaldx ?
+
+ sal_uInt32 nArgsEnv; // number of -env: style args
+ sal_uInt32 nArgsTotal; // number of -env: as well as -writer style args
+ rtl_uString *ppArgs[1]; // sorted argument array
+} Args;
+
+Args *args_parse (void);
+void args_free (Args *args);
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/unx/source/makefile.mk b/desktop/unx/source/makefile.mk
new file mode 100755
index 000000000000..5c5c8f3e9e88
--- /dev/null
+++ b/desktop/unx/source/makefile.mk
@@ -0,0 +1,65 @@
+#
+# Version: MPL 1.1 / GPLv3+ / LGPLv3+
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Initial Developer of the Original Code is
+# Novell, Inc.
+# Portions created by the Initial Developer are Copyright (C) 2010 the
+# Initial Developer. All Rights Reserved.
+#
+# Contributor(s): Jan Holesovsky <kendy@novell.com>
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 3 or later (the "GPLv3+"), or
+# the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
+# in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
+# instead of those above.
+#
+PRJ=..$/..
+PRJNAME=desktop
+TARGET=oosplash
+
+NO_DEFAULT_STL=TRUE
+
+.INCLUDE : settings.mk
+
+.IF "$(ENABLE_QUICKSTART_LIBPNG)"=="TRUE"
+CFLAGS+=-DENABLE_QUICKSTART_LIBPNG
+.ENDIF
+
+STDLIB=
+CFLAGS+=$(LIBPNG_CFLAGS)
+
+OBJFILES= \
+ $(OBJ)$/splashx.obj \
+ $(OBJ)$/start.obj \
+ $(OBJ)$/args.obj
+
+.IF "$(OS)"!="MACOSX"
+PAGEIN_OBJS= \
+ $(OBJ)$/pagein.obj \
+ $(OBJ)$/file_image_unx.obj
+.ENDIF
+
+APP1TARGET = $(TARGET)
+APP1RPATH = BRAND
+APP1OBJS = $(OBJFILES) $(PAGEIN_OBJS)
+APP1LIBSALCPPRT=
+APP1CODETYPE = C
+APP1STDLIBS = $(PTHREAD_LIBS) $(X11LINK_DYNAMIC) $(SALLIB) $(LIBPNG_LIBS)
+.IF "$(OS)"=="SOLARIS"
+APP1STDLIBS+= -lsocket
+.ENDIF
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/desktop/unx/source/officeloader/makefile.mk b/desktop/unx/source/officeloader/makefile.mk
new file mode 100755
index 000000000000..050da981e88d
--- /dev/null
+++ b/desktop/unx/source/officeloader/makefile.mk
@@ -0,0 +1,47 @@
+#*************************************************************************
+#
+# 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=officeloader
+LIBTARGET=NO
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+OBJFILES = \
+ $(OBJ)$/officeloader.obj
+
+# --- Targets ------------------------------------------------------
+
+
+.INCLUDE : target.mk
+
diff --git a/desktop/unx/source/officeloader/officeloader.cxx b/desktop/unx/source/officeloader/officeloader.cxx
new file mode 100644
index 000000000000..3927d8e14714
--- /dev/null
+++ b/desktop/unx/source/officeloader/officeloader.cxx
@@ -0,0 +1,113 @@
+/* -*- 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/main.h>
+#include <osl/process.h>
+#include <rtl/ustring.hxx>
+
+#include "../../../source/inc/exithelper.hxx"
+
+using namespace desktop;
+using ::rtl::OUString;
+
+SAL_IMPLEMENT_MAIN()
+{
+ oslProcess process;
+ oslProcessError error;
+
+ OUString sExecutableFile;
+ rtl_uString **pCommandArgs;
+ sal_uInt32 nCommandArgs;
+
+ osl_getExecutableFile( &sExecutableFile.pData );
+
+ sExecutableFile += OUString( RTL_CONSTASCII_USTRINGPARAM(".bin") );
+
+ nCommandArgs = osl_getCommandArgCount();
+ pCommandArgs = new rtl_uString *[nCommandArgs];
+
+ for ( sal_uInt32 i = 0; i < nCommandArgs; i++ )
+ {
+ pCommandArgs[i] = NULL;
+ osl_getCommandArg( i, &pCommandArgs[i] );
+ }
+
+ bool bRestart = false;
+ bool bFirstRun = true;
+ oslProcessExitCode exitcode = 255;
+
+ do {
+ error = osl_executeProcess(
+ sExecutableFile.pData,
+ bFirstRun ? pCommandArgs : NULL,
+ bFirstRun ? nCommandArgs : 0,
+ 0,
+ NULL,
+ NULL,
+ NULL,
+ 0,
+ &process
+ );
+
+ if ( osl_Process_E_None == error )
+ {
+ oslProcessInfo info;
+
+ info.Size = sizeof(info);
+
+ error = osl_joinProcess( process );
+ if ( osl_Process_E_None != error )
+ break;
+
+ error = osl_getProcessInfo( process, osl_Process_EXITCODE, &info );
+ if ( osl_Process_E_None != error )
+ break;
+
+ if ( info.Fields & osl_Process_EXITCODE )
+ {
+ exitcode = info.Code;
+ bRestart = (ExitHelper::E_CRASH_WITH_RESTART == exitcode || ExitHelper::E_NORMAL_RESTART == exitcode);
+ }
+ else
+ break;
+
+ osl_freeProcessHandle( process );
+
+ }
+
+ bFirstRun = false;
+
+ } while ( bRestart );
+
+ return exitcode;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/unx/source/splashx.c b/desktop/unx/source/splashx.c
new file mode 100755
index 000000000000..711671fe28d4
--- /dev/null
+++ b/desktop/unx/source/splashx.c
@@ -0,0 +1,659 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Version: MPL 1.1 / GPLv3+ / LGPLv3+
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Initial Developer of the Original Code is
+ * Novell, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 2010 the
+ * Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s): Jan Holesovsky <kendy@novell.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
+ * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
+ * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
+ * instead of those above.
+ */
+
+#ifdef ENABLE_QUICKSTART_LIBPNG
+
+#include <X11/Xlib.h>
+#include <X11/Xatom.h>
+#include <X11/Xutil.h>
+
+#define USE_LIBPNG
+
+#include "osl/endian.h"
+#include <fcntl.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#ifdef USE_LIBPNG
+# include <png.h>
+#endif
+
+#include "splashx.h"
+
+typedef struct {
+ unsigned char b, g, r;
+} color_t;
+
+#define WINDOW_WIDTH 440
+#define WINDOW_HEIGHT 299
+
+#define PROGRESS_XOFFSET 12
+#define PROGRESS_YOFFSET 18
+#define PROGRESS_BARSPACE 2
+
+static Display *display = NULL;
+static int screen;
+static int depth;
+static Visual *visual = NULL;
+
+static int width = WINDOW_WIDTH;
+static int height = WINDOW_HEIGHT;
+
+static Colormap color_map;
+static Window win;
+static GC gc;
+
+// Progress bar values
+// taken from desktop/source/splash/splash.cxx
+static int tlx = 212;
+static int tly = 216;
+static int barwidth = 263;
+static int barheight = 8;
+static int barspace = PROGRESS_BARSPACE;
+static color_t barcol = { 18, 202, 157 };
+static color_t framecol = { 0xD3, 0xD3, 0xD3 };
+
+static XColor barcolor;
+static XColor framecolor;
+
+static unsigned char **bitmap_rows = NULL;
+
+#define BMP_HEADER_LEN 14
+#define WIN_INFO_LEN 40
+
+#define UINT8( x ) ( (unsigned int)( ( (uint8_t *)( x ) )[0] ) )
+
+#define UINT16( x ) ( ( (unsigned int)( ( (uint8_t *)( x ) )[0] ) ) + \
+ ( ( (unsigned int)( ( (uint8_t *)( x ) )[1] ) ) << 8 ) )
+
+#define UINT32( x ) ( ( (unsigned int)( ( (uint8_t *)( x ) )[0] ) ) + \
+ ( ( (unsigned int)( ( (uint8_t *)( x ) )[1] ) ) << 8 ) + \
+ ( ( (unsigned int)( ( (uint8_t *)( x ) )[2] ) ) << 16 ) + \
+ ( ( (unsigned int)( ( (uint8_t *)( x ) )[3] ) ) << 24 ) )
+
+#define MAX( x, y ) ( ( (x) > (y) )? (x): (y) )
+
+#define LOAD_FAILURE( msg ) \
+ { \
+ fprintf( stderr, "%s: " msg, filename ); \
+ close( fd ); \
+ return 0; \
+ }
+
+#ifdef USE_LIBPNG
+
+/* libpng-1.2.41 */
+#ifndef PNG_TRANSFORM_GRAY_TO_RGB
+# define PNG_TRANSFORM_GRAY_TO_RGB 0x2000
+#endif
+
+png_structp png_ptr = NULL;
+png_infop info_ptr = NULL;
+
+int splash_load_bmp( const char *filename )
+{
+ FILE *file;
+
+ if ( !(file = fopen( filename, "r" ) ) )
+ return 0;
+
+ png_ptr = png_create_read_struct( PNG_LIBPNG_VER_STRING, 0, 0, 0 );
+ info_ptr = png_create_info_struct(png_ptr);
+ png_init_io( png_ptr, file );
+
+ if( setjmp( png_jmpbuf( png_ptr ) ) )
+ {
+ png_destroy_read_struct( &png_ptr, &info_ptr, NULL );
+ fclose( file );
+ return 0;
+ }
+
+ png_read_png( png_ptr, info_ptr,
+ PNG_TRANSFORM_EXPAND | PNG_TRANSFORM_STRIP_ALPHA |
+ PNG_TRANSFORM_GRAY_TO_RGB | PNG_TRANSFORM_BGR, NULL);
+
+ bitmap_rows = png_get_rows( png_ptr, info_ptr );
+ width = png_get_image_width( png_ptr, info_ptr );
+ height = png_get_image_height( png_ptr, info_ptr );
+
+#if 0
+ {
+ int i,j;
+ for (j = 0; j < height; j++) {
+ for (i = 0; i < width*3; i++) {
+ fprintf (stderr, "%.2x", bitmap_rows[j][i]);
+ }
+ fprintf (stderr, "\n");
+ }
+ }
+#endif
+
+ return 1;
+}
+#else
+
+/* Load the specified Windows 24bit BMP to 'bitmap'
+ * Return: 1 - success, 0 - failure */
+int splash_load_bmp( const char *filename )
+{
+ int fd = open( filename, O_RDONLY );
+ if ( fd < 0 )
+ return 0;
+
+ char file_header[ BMP_HEADER_LEN ];
+
+ if ( read( fd, file_header, BMP_HEADER_LEN ) != BMP_HEADER_LEN || file_header[0] != 'B' || file_header[1] != 'M' )
+ LOAD_FAILURE( "Not a bitmap.\n" );
+
+/* int file_size = UINT32( file_header + 2 ); */
+
+ char info_header[ WIN_INFO_LEN ];
+ if ( read( fd, info_header, 4 ) != 4 )
+ LOAD_FAILURE( "Unable to read the header.\n" );
+
+ int header_size = UINT32( info_header );
+ if ( header_size != WIN_INFO_LEN )
+ LOAD_FAILURE( "Not a Windows bitmap.\n" );
+
+ if ( read( fd, info_header + 4, WIN_INFO_LEN - 4 ) != WIN_INFO_LEN - 4 )
+ LOAD_FAILURE( "The header ended too early.\n" );
+
+ width = UINT32( info_header + 4 );
+ height = UINT32( info_header + 8 );
+
+ int bits = UINT16( info_header + 14 );
+ int compression = UINT16( info_header + 16 );
+
+ if ( bits != 24 )
+ LOAD_FAILURE( "Just 24 bpp bitmaps are supported.\n" );
+
+ if ( compression != 0 )
+ LOAD_FAILURE( "Just uncompressed bitmaps are supported.\n" );
+
+ size_t bitmap_size = width * height * 3;
+ unsigned char *bitmap = malloc( bitmap_size );
+ if ( bitmap == NULL )
+ LOAD_FAILURE( "Cannot allocate memory for the data.\n" );
+
+ if ( read( fd, bitmap, bitmap_size ) != bitmap_size )
+ LOAD_FAILURE( "Cannot read the bitmap data.\n" );
+
+ bitmap_rows = malloc (sizeof (unsigned char*) * height);
+ int i;
+ for (i = 0; i < height; i++)
+ bitmap_rows[i] = bitmap + (width * height * 3) - width * 3 * (i + 1);
+
+ close( fd );
+ return 1;
+}
+#endif
+
+static void setup_color( int val[3], color_t *col )
+{
+ if ( val[0] < 0 || val[1] < 0 || val[2] < 0 )
+ return;
+
+#define CONVERT_COLOR( from,to ) if ( from < 0 ) to = 0; else if ( from > 255 ) to = 255; else to = from;
+ CONVERT_COLOR( val[0], col->r );
+ CONVERT_COLOR( val[1], col->g );
+ CONVERT_COLOR( val[2], col->b );
+#undef CONVERT_COLOR
+}
+
+// setup
+void splash_setup( int barc[3], int framec[3], int posx, int posy, int w, int h )
+{
+ if ( width <= 500 )
+ {
+ barwidth = width - ( 2 * PROGRESS_XOFFSET );
+ barheight = 6;
+ tlx = PROGRESS_XOFFSET;
+ tly = height - PROGRESS_YOFFSET;
+
+ barcol.r = 0;
+ barcol.g = 0;
+ barcol.b = 128;
+ }
+
+ if ( posx >= 0 )
+ tlx = posx;
+ if ( posy >= 0 )
+ tly = posy;
+ if ( w >= 0 )
+ barwidth = w;
+ if ( h >= 0 )
+ barheight = h;
+
+ setup_color( barc, &barcol );
+ setup_color( framec, &framecol );
+}
+
+// Universal shift: bits >= 0 - left, otherwise right
+#define SHIFT( x, bits ) ( ( (bits) >= 0 )? ( (x) << (bits) ): ( (x) >> -(bits) ) )
+
+// Position of the highest bit (more or less integer log2)
+inline int HIGHEST_BIT( unsigned long x )
+{
+ int i = 0;
+ for ( ; x; ++i )
+ x >>= 1;
+
+ return i;
+}
+
+// Number of bits set to 1
+inline int BITS( unsigned long x )
+{
+ int i = 0;
+ for ( ; x; x >>= 1 )
+ if ( x & 1UL )
+ ++i;
+
+ return i;
+}
+
+// Set 'bitmap' as the background of our 'win' window
+static void create_pixmap()
+{
+ if ( !bitmap_rows )
+ return;
+
+ Pixmap pixmap = XCreatePixmap( display, win, width, height, depth );
+
+ unsigned long value_mask = 0;
+ XGCValues values;
+ GC pixmap_gc = XCreateGC( display, pixmap, value_mask, &values );
+
+ if ( visual->class == TrueColor )
+ {
+ unsigned long red_mask = visual->red_mask;
+ unsigned long green_mask = visual->green_mask;
+ unsigned long blue_mask = visual->blue_mask;
+
+ unsigned long red_delta_mask = ( 1UL << ( 8 - BITS( red_mask ) ) ) - 1;
+ unsigned long green_delta_mask = ( 1UL << ( 8 - BITS( green_mask ) ) ) - 1;
+ unsigned long blue_delta_mask = ( 1UL << ( 8 - BITS( blue_mask ) ) ) - 1;
+
+ int red_shift = HIGHEST_BIT( red_mask ) - 8;
+ int green_shift = HIGHEST_BIT( green_mask ) - 8;
+ int blue_shift = HIGHEST_BIT( blue_mask ) - 8;
+
+ XImage *image = XCreateImage( display, visual, depth, ZPixmap,
+ 0, NULL, width, height, 32, 0 );
+
+ int bytes_per_line = image->bytes_per_line;
+ int bpp = image->bits_per_pixel;
+ int byte_order = image->byte_order;
+#if defined( _LITTLE_ENDIAN )
+ int machine_byte_order = LSBFirst;
+#elif defined( _BIG_ENDIAN )
+ int machine_byte_order = MSBFirst;
+#else
+ {
+ fprintf( stderr, "Unsupported machine endianity.\n" );
+ XFreeGC( display, pixmap_gc );
+ XFreePixmap( display, pixmap );
+ XDestroyImage( image );
+ return;
+ }
+#endif
+
+ char *data = malloc( height * bytes_per_line );
+ image->data = data;
+
+ // The following dithers & converts the color_t color to one
+ // acceptable for the visual
+#define COPY_IN_OUT( pix_size, code ) \
+ { \
+ int x, y; \
+ for ( y = 0; y < height; ++y ) \
+ { \
+ out = data + y * bytes_per_line; \
+ unsigned long red_delta = 0, green_delta = 0, blue_delta = 0; \
+ color_t *in = (color_t *)bitmap_rows[y]; \
+ for ( x = 0; x < width; ++x, ++in ) \
+ { \
+ unsigned long red = in->r + red_delta; \
+ unsigned long green = in->g + green_delta; \
+ unsigned long blue = in->b + blue_delta; \
+ red_delta = red & red_delta_mask; \
+ green_delta = green & green_delta_mask; \
+ blue_delta = blue & blue_delta_mask; \
+ if ( red > 255 ) \
+ red = 255; \
+ if ( green > 255 ) \
+ green = 255; \
+ if ( blue > 255 ) \
+ blue = 255; \
+ unsigned long pixel = \
+ ( SHIFT( red, red_shift ) & red_mask ) | \
+ ( SHIFT( green, green_shift ) & green_mask ) | \
+ ( SHIFT( blue, blue_shift ) & blue_mask ); \
+ code \
+ } \
+ } \
+ }
+
+ char *out = data;
+
+ if ( bpp == 32 )
+ {
+ if ( machine_byte_order == byte_order )
+ COPY_IN_OUT( 4, *( (uint32_t *)out ) = (uint32_t)pixel; out += 4; )
+ else
+ COPY_IN_OUT( 4, uint32_t tmp = pixel;
+ *( (uint8_t *)out ) = *( (uint8_t *)(&tmp) + 3 );
+ *( (uint8_t *)out + 1 ) = *( (uint8_t *)(&tmp) + 2 );
+ *( (uint8_t *)out + 2 ) = *( (uint8_t *)(&tmp) + 1 );
+ *( (uint8_t *)out + 3 ) = *( (uint8_t *)(&tmp) );
+ out += 4; )
+ }
+ else if ( bpp == 24 )
+ {
+ if ( machine_byte_order == byte_order && byte_order == LSBFirst )
+ COPY_IN_OUT( 3, *( (color_t *)out ) = *( (color_t *)( &pixel ) ); out += 3; )
+ else if ( machine_byte_order == byte_order && byte_order == MSBFirst )
+ COPY_IN_OUT( 3, uint32_t tmp = pixel;
+ *( (uint8_t *)out ) = *( (uint8_t *)(&tmp) + 1 );
+ *( (uint8_t *)out + 1 ) = *( (uint8_t *)(&tmp) + 2 );
+ *( (uint8_t *)out + 2 ) = *( (uint8_t *)(&tmp) + 3 );
+ out += 3; )
+ else
+ COPY_IN_OUT( 3, uint32_t tmp = pixel;
+ *( (uint8_t *)out ) = *( (uint8_t *)(&tmp) + 3 );
+ *( (uint8_t *)out + 1 ) = *( (uint8_t *)(&tmp) + 2 );
+ *( (uint8_t *)out + 2 ) = *( (uint8_t *)(&tmp) + 1 );
+ out += 3; )
+ }
+ else if ( bpp == 16 )
+ {
+ if ( machine_byte_order == byte_order )
+ COPY_IN_OUT( 2, *( (uint16_t *)out ) = (uint16_t)pixel; out += 2; )
+ else
+ COPY_IN_OUT( 2, uint16_t tmp = pixel;
+ *( (uint8_t *)out ) = *( (uint8_t *)(&tmp) + 1 );
+ *( (uint8_t *)out + 1 ) = *( (uint8_t *)(&tmp) );
+ out += 2; );
+ }
+ else if ( bpp == 8 )
+ {
+ COPY_IN_OUT( 1, *( (uint8_t *)out ) = (uint8_t)pixel; ++out; )
+ }
+ else
+ {
+ fprintf( stderr, "Unsupported depth: %d bits per pixel.\n", bpp );
+ XFreeGC( display, pixmap_gc );
+ XFreePixmap( display, pixmap );
+ XDestroyImage( image );
+ return;
+ }
+
+#undef COPY_IN_OUT
+
+ XPutImage( display, pixmap, pixmap_gc, image, 0, 0, 0, 0, width, height );
+ XDestroyImage( image );
+ }
+ else //if ( depth == 1 || visual->class == DirectColor )
+ {
+ // FIXME Something like the following, but faster ;-) - XDrawPoint is not
+ // a good idea...
+ int x, y;
+ for ( y = 0; y < height; ++y )
+ {
+ color_t *color = (color_t *)&bitmap_rows[y];
+
+ int delta = 0;
+ for ( x = 0; x < width; ++x, ++color )
+ {
+ int rnd = (int)( ( (long)( random() - RAND_MAX/2 ) * 32000 )/RAND_MAX );
+ int luminance = delta + rnd + 299 * (int)color->r + 587 * (int)color->g + 114 * (int)color->b;
+
+ if ( luminance < 128000 )
+ {
+ XSetForeground( display, pixmap_gc, BlackPixel( display, screen ) );
+ delta = luminance;
+ }
+ else
+ {
+ XSetForeground( display, pixmap_gc, WhitePixel( display, screen ) );
+ delta = luminance - 255000;
+ }
+
+ XDrawPoint( display, pixmap, pixmap_gc, x, y );
+ }
+ }
+ }
+
+ XSetWindowBackgroundPixmap( display, win, pixmap );
+
+ XFreeGC( display, pixmap_gc );
+ XFreePixmap( display, pixmap );
+}
+
+// The old method of hiding the window decorations
+static void suppress_decorations_motif()
+{
+ struct {
+ unsigned long flags, functions, decorations;
+ long input_mode;
+ } mwmhints;
+
+ Atom a = XInternAtom( display, "_MOTIF_WM_HINTS", False );
+
+ mwmhints.flags = 15; // functions, decorations, input_mode, status
+ mwmhints.functions = 2; // ?
+ mwmhints.decorations = 0;
+ mwmhints.input_mode = 0;
+
+ XChangeProperty( display, win, a, a, 32,
+ PropModeReplace, (unsigned char*)&mwmhints, 5 );
+}
+
+// This is a splash, set it as such.
+// If it fails, just hide the decorations...
+static void suppress_decorations()
+{
+ Atom atom_type = XInternAtom( display, "_NET_WM_WINDOW_TYPE", True );
+ Atom atom_splash = XInternAtom( display, "_NET_WM_WINDOW_TYPE_SPLASH", True );
+
+ if ( atom_type != None && atom_splash != None )
+ XChangeProperty( display, win, atom_type, XA_ATOM, 32,
+ PropModeReplace, (unsigned char*)&atom_splash, 1 );
+ //else
+ suppress_decorations_motif(); // FIXME: Unconditional until Metacity/compiz's SPLASH handling is fixed
+}
+
+// Create the window
+// Return: 1 - success, 0 - failure
+int splash_create_window( int argc, char** argv )
+{
+ char *display_name = NULL;
+ int i;
+ for ( i = 0; i < argc; i++ )
+ {
+ if ( !strcmp( argv[i], "-display" ) || !strcmp( argv[i], "--display" ) )
+ display_name = ( i + 1 < argc )? argv[i+1]: NULL;
+ }
+
+ if ( !display_name )
+ display_name = getenv( "DISPLAY" );
+
+ // init display
+ display = XOpenDisplay( display_name );
+ if ( !display )
+ {
+ fprintf( stderr, "Failed to open display\n" );
+ return 0;
+ }
+
+ // create the window
+ screen = DefaultScreen( display );
+ depth = DefaultDepth( display, screen );
+ color_map = DefaultColormap( display, screen );
+ visual = DefaultVisual( display, screen );
+
+ Window root_win = RootWindow( display, screen );
+ int display_width = DisplayWidth( display, screen );
+ int display_height = DisplayHeight( display, screen );
+
+ win = XCreateSimpleWindow( display, root_win,
+ ( display_width - width ) / 2, ( display_height - height ) / 2,
+ width, height, 0,
+ BlackPixel( display, screen ), BlackPixel( display, screen ) );
+
+ XSetWindowColormap( display, win, color_map );
+
+ // setup colors
+#define FILL_COLOR( xcol,col ) xcol.red = 256*col.r; xcol.green = 256*col.g; xcol.blue = 256*col.b;
+ FILL_COLOR( barcolor, barcol );
+ FILL_COLOR( framecolor, framecol );
+#undef FILL_COLOR
+
+ XAllocColor( display, color_map, &barcolor );
+ XAllocColor( display, color_map, &framecolor );
+
+ // not resizable, no decorations, etc.
+ unsigned long value_mask = 0;
+ XGCValues values;
+ gc = XCreateGC( display, win, value_mask, &values );
+
+ XSizeHints size_hints;
+ size_hints.flags = PPosition | PSize | PMinSize | PMaxSize;
+ size_hints.min_width = width;
+ size_hints.max_width = width;
+ size_hints.min_height = height;
+ size_hints.max_height = height;
+
+ char *name = "OpenOffice.org";
+ char *icon = "icon"; // FIXME
+
+ XSetStandardProperties( display, win, name, icon, None,
+ 0, 0, &size_hints );
+
+ // the actual work
+ suppress_decorations();
+ create_pixmap();
+
+ // show it
+ XSelectInput( display, win, 0 );
+ XMapWindow( display, win );
+
+ return 1;
+}
+
+// Re-draw & process the events
+// Just throwing them away - we do not need anything more...
+static void process_events()
+{
+ XEvent xev;
+ int num_events;
+
+ XFlush( display );
+ num_events = XPending( display );
+ while ( num_events > 0 )
+ {
+ num_events--;
+ XNextEvent( display, &xev );
+ //process_event(xev);
+ }
+}
+
+// Draw the progress
+void splash_draw_progress( int progress )
+{
+ // sanity
+ if ( progress < 0 )
+ progress = 0;
+ if ( progress > 100 )
+ progress = 100;
+
+ // draw progress...
+ int length = ( progress * barwidth / 100 ) - ( 2 * barspace );
+ if ( length < 0 )
+ length = 0;
+
+ // border
+ XSetForeground( display, gc, framecolor.pixel );
+ XDrawRectangle( display, win, gc,
+ tlx, tly,
+ barwidth, barheight );
+
+ // progress bar
+ XSetForeground( display, gc, barcolor.pixel );
+ XFillRectangle( display, win, gc,
+ tlx + barspace, tly + barspace,
+ length + 1, barheight - 2*barspace + 1 );
+
+ // pending events
+ process_events();
+}
+
+// Close the window & cleanup
+void splash_close_window()
+{
+ XCloseDisplay( display );
+#ifdef USE_LIBPNG
+ png_destroy_read_struct( &png_ptr, &info_ptr, NULL );
+#else
+ free( bitmap_rows );
+#endif
+ bitmap_rows = NULL;
+}
+
+#else /* not ENABLE_QUICKSTART_LIBPNG */
+
+/* Stubs that will never be called in this case */
+
+int splash_load_bmp( const char *filename )
+{
+ (void)filename;
+ return 1;
+}
+void splash_setup( int barc[3], int framec[3], int posx, int posy, int w, int h )
+{
+ (void)barc; (void)framec; (void)posx; (void)posy; (void)w; (void)h;
+}
+int splash_create_window( int argc, char** argv )
+{
+ (void)argc; (void)argv;
+ return 1;
+}
+void splash_close_window()
+{
+}
+void splash_draw_progress( int progress )
+{
+ (void)progress;
+}
+
+#endif // ENABLE_QUICKSTART_LIBPNG
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/unx/source/splashx.h b/desktop/unx/source/splashx.h
new file mode 100755
index 000000000000..537034c6efc8
--- /dev/null
+++ b/desktop/unx/source/splashx.h
@@ -0,0 +1,65 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Version: MPL 1.1 / GPLv3+ / LGPLv3+
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Initial Developer of the Original Code is
+ * Novell, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 2010 the
+ * Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s): Jan Holesovsky <kendy@novell.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
+ * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
+ * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
+ * instead of those above.
+ */
+#ifndef _SPLASHX_H
+#define _SPLASHX_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Load the specified bitmap so we can have as a background of the
+// splash.
+//
+// Note: Must be called before the create_window(), otherwise there will be no
+// image in the splash, just black rectangle.
+//
+// Return: 1 - success, 0 - failure (non-existing, etc.)
+int splash_load_bmp( const char *filename );
+
+// Init some of the values
+// If not called, the defaults are used
+// barc, framec - colors, posx, posy - position, w, h - size
+void splash_setup( int barc[3], int framec[3], int posx, int posy, int w, int h );
+
+// Create the splash window
+// Return: 1 - success, 0 - failure
+int splash_create_window( int argc, char** argv );
+
+// Destroy the splash window
+void splash_close_window();
+
+// Update the progress bar
+void splash_draw_progress( int progress );
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _SPLASHX_H
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/unx/source/start.c b/desktop/unx/source/start.c
new file mode 100755
index 000000000000..e81cd6129d0a
--- /dev/null
+++ b/desktop/unx/source/start.c
@@ -0,0 +1,1012 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Version: MPL 1.1 / GPLv3+ / LGPLv3+
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Initial Developer of the Original Code is
+ * Novell, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 2010 the
+ * Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s): Jan Holesovsky <kendy@novell.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
+ * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
+ * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
+ * instead of those above.
+ */
+#include <signal.h>
+#include <unistd.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#include <sys/un.h>
+#include <sys/poll.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <libgen.h>
+#include <string.h>
+
+#include <osl/nlsupport.h>
+#include <osl/process.h>
+#include <osl/thread.h>
+#include <rtl/bootstrap.h>
+#include <rtl/digest.h>
+#include <rtl/ustrbuf.h>
+#include <sal/main.h>
+
+#include "args.h"
+#include "splashx.h"
+
+#define IMG_SUFFIX ".png"
+#define PIPEDEFAULTPATH "/tmp"
+#define PIPEALTERNATEPATH "/var/tmp"
+
+/* Easier conversions: rtl_uString to rtl_String */
+static rtl_String *
+ustr_to_str( rtl_uString *pStr )
+{
+ rtl_String *pOut = NULL;
+
+ rtl_uString2String( &pOut, rtl_uString_getStr( pStr ),
+ rtl_uString_getLength( pStr ), osl_getThreadTextEncoding(), OUSTRING_TO_OSTRING_CVTFLAGS );
+
+ return pOut;
+}
+
+/* Easier conversions: char * to rtl_uString */
+static rtl_uString *
+charp_to_ustr( const char *pStr )
+{
+ rtl_uString *pOut = NULL;
+
+ rtl_string2UString( &pOut, pStr, strlen( pStr ), osl_getThreadTextEncoding(), OSTRING_TO_OUSTRING_CVTFLAGS );
+
+ return pOut;
+}
+
+/* Easier debugging of rtl_uString values. */
+#if OSL_DEBUG_LEVEL > 0
+static void
+ustr_debug( const char *pMessage, rtl_uString *pStr )
+{
+ rtl_String *pOut = ustr_to_str( pStr );
+
+ fprintf( stderr, "%s: %s\n", pMessage, rtl_string_getStr( pOut ) );
+
+ rtl_string_release( pOut );
+ return;
+}
+#else
+#define ustr_debug( a, b ) {}
+#endif
+
+typedef struct {
+ int status_fd;
+ oslProcess child;
+} ChildInfo;
+
+static int
+child_info_get_status_fd (ChildInfo *info)
+{
+ return info->status_fd;
+}
+
+static void
+child_info_destroy (ChildInfo *info)
+{
+ close (info->status_fd);
+ osl_freeProcessHandle (info->child);
+ free (info);
+}
+
+static ChildInfo *
+child_spawn ( Args *args, sal_Bool bAllArgs, sal_Bool bWithStatus )
+{
+ rtl_uString *pApp = NULL, *pTmp = NULL;
+ rtl_uString **ppArgs;
+ sal_uInt32 nArgs, i;
+ char buffer[64];
+ ChildInfo *info;
+ int status_pipe[2];
+ oslProcessError nError;
+
+ info = calloc (1, sizeof (ChildInfo));
+
+ /* create pipe */
+ if ( pipe( status_pipe ) < 0 )
+ {
+ fprintf( stderr, "ERROR: no file handles\n");
+ exit( 1 );
+ }
+ info->status_fd = status_pipe[0];
+
+ /* application name */
+ rtl_uString_newFromAscii( &pApp, "file://" );
+ rtl_uString_newConcat( &pApp, pApp, args->pAppPath );
+ rtl_uString_newFromAscii( &pTmp, "/soffice.bin" );
+ rtl_uString_newConcat( &pApp, pApp, pTmp );
+ rtl_uString_release( pTmp );
+ pTmp = NULL;
+
+ /* copy args */
+ nArgs = bAllArgs ? args->nArgsTotal : args->nArgsEnv;
+ ppArgs = (rtl_uString **)calloc( nArgs + 1, sizeof( rtl_uString* ) );
+ for ( i = 0; i < nArgs; ++i )
+ ppArgs[i] = args->ppArgs[i];
+
+ if( bWithStatus )
+ {
+ /* add the pipe arg */
+ snprintf (buffer, 63, "--splash-pipe=%d", status_pipe[1]);
+ rtl_uString_newFromAscii( &pTmp, buffer );
+ ppArgs[nArgs] = pTmp;
+ ++nArgs;
+ }
+
+ /* start the main process */
+ nError = osl_executeProcess( pApp, ppArgs, nArgs,
+ osl_Process_NORMAL,
+ NULL,
+ NULL,
+ NULL, 0,
+ &info->child );
+
+ if (pTmp)
+ rtl_uString_release( pTmp );
+ free (ppArgs);
+
+ if ( nError != osl_Process_E_None )
+ {
+ fprintf( stderr, "ERROR %d forking process", nError );
+ ustr_debug( "", pApp );
+ rtl_uString_release( pApp );
+ _exit (1);
+ }
+
+ rtl_uString_release( pApp );
+ close( status_pipe[1] );
+
+ return info;
+}
+
+static sal_Bool
+child_exited_wait (ChildInfo *info, sal_Bool bShortWait)
+{
+ TimeValue t = { 0, 250 /* ms */ * 1000 * 1000 };
+ if (!bShortWait)
+ t.Seconds = 1024;
+ return osl_joinProcessWithTimeout (info->child, &t) != osl_Process_E_TimedOut;
+}
+
+static int
+child_get_exit_code (ChildInfo *info)
+{
+ oslProcessInfo inf;
+
+ inf.Code = -1;
+ inf.Size = sizeof (inf);
+ if (osl_getProcessInfo (info->child, osl_Process_EXITCODE, &inf) != osl_Process_E_None)
+ {
+ fprintf (stderr, "Warning: failed to fetch libreoffice exit status\n");
+ return -1;
+ }
+ return inf.Code;
+}
+
+typedef enum { ProgressContinue, ProgressRestart, ProgressExit } ProgressStatus;
+
+/* Path of the application. */
+static rtl_uString *
+get_app_path( const char *pAppExec )
+{
+ char pRealPath[PATH_MAX];
+ rtl_uString *pResult;
+
+ char *pOrigPath = strdup( pAppExec );
+ char *pPath = dirname( pOrigPath );
+
+ realpath( pPath, pRealPath );
+ pResult = charp_to_ustr( pRealPath );
+ free( pOrigPath );
+
+ return pResult;
+}
+
+/* Compute the OOo md5 hash from 'pText' */
+static rtl_uString *
+get_md5hash( rtl_uString *pText )
+{
+ rtl_uString *pResult = NULL;
+ sal_Int32 nCapacity = 100;
+
+#if OSL_DEBUG_LEVEL > 0
+ fprintf (stderr, "Generate pipe md5 for '%s'\n", ustr_to_str (pText)->buffer);
+#endif
+
+ if ( !pText )
+ return NULL;
+
+ unsigned char *pData = (unsigned char *)rtl_uString_getStr( pText );
+ sal_uInt32 nSize = rtl_uString_getLength( pText ) * sizeof( sal_Unicode );
+ if ( !pData )
+ return NULL;
+
+ rtlDigest digest = rtl_digest_create( rtl_Digest_AlgorithmMD5 );
+ if ( digest == 0 )
+ return NULL;
+
+ sal_uInt32 md5_key_len = rtl_digest_queryLength( digest );
+ sal_uInt8 *md5_buf = (sal_uInt8 *)calloc( md5_key_len, sizeof( sal_uInt8 ) );
+
+ rtl_digest_init( digest, pData , nSize );
+ rtl_digest_update( digest, pData, nSize );
+ rtl_digest_get( digest, md5_buf, md5_key_len );
+ rtl_digest_destroy( digest );
+
+ /* create hex-value string from the MD5 value to keep
+ the string size minimal */
+ rtl_uString_new_WithLength( &pResult, nCapacity );
+ sal_uInt32 i = 0;
+ for ( ; i < md5_key_len; ++i )
+ {
+ char val[3];
+ snprintf( val, 3, "%x", md5_buf[i] ); /* sic! we ignore some of the 0's */
+
+ rtl_uStringbuffer_insert_ascii( &pResult, &nCapacity, rtl_uString_getLength( pResult ),
+ val, strlen( val ) );
+ }
+
+ /* cleanup */
+ free( md5_buf );
+
+ return pResult;
+}
+
+/* Construct the pipe name */
+static rtl_uString *
+get_pipe_path( rtl_uString *pAppPath )
+{
+ rtl_uString *pPath = NULL, *pTmp = NULL, *pUserInstallation = NULL;
+ rtl_uString *pResult = NULL, *pBasePath = NULL, *pAbsUserInstallation = NULL;
+
+ /* setup bootstrap filename */
+ rtl_uString_newFromAscii( &pPath, "file://" );
+ rtl_uString_newConcat( &pPath, pPath, pAppPath );
+ rtl_uString_newFromAscii( &pTmp, "/" );
+ rtl_uString_newConcat( &pPath, pPath, pTmp );
+ rtl_uString_newFromAscii( &pTmp, SAL_CONFIGFILE( "bootstrap" ) );
+ rtl_uString_newConcat( &pPath, pPath, pTmp );
+
+ ustr_debug( "bootstap", pPath );
+
+ /* read userinstallation value */
+ rtlBootstrapHandle handle = rtl_bootstrap_args_open( pPath );
+
+ rtl_uString_newFromAscii( &pTmp, "UserInstallation" );
+ rtl_bootstrap_get_from_handle( handle, pTmp, &pUserInstallation, NULL );
+
+ rtl_bootstrap_args_close( handle );
+
+ /* turn it into an absolute path - unwinding symlinks etc. */
+ if ( osl_getProcessWorkingDir (&pBasePath) ||
+ osl_getAbsoluteFileURL( pBasePath, pUserInstallation, &pAbsUserInstallation ) )
+ rtl_uString_newFromString (&pAbsUserInstallation, pUserInstallation);
+
+ /* create the pipe name */
+ ustr_debug( "user installation", pAbsUserInstallation );
+ rtl_uString *pMd5hash = get_md5hash( pAbsUserInstallation );
+ if ( !pMd5hash )
+ rtl_uString_new( &pMd5hash );
+
+ if ( access( PIPEDEFAULTPATH, R_OK|W_OK ) == 0 )
+ rtl_uString_newFromAscii( &pResult, PIPEDEFAULTPATH );
+ else
+ rtl_uString_newFromAscii( &pResult, PIPEALTERNATEPATH );
+
+ rtl_uString_newFromAscii( &pTmp, "/OSL_PIPE_" );
+ rtl_uString_newConcat( &pResult, pResult, pTmp );
+
+ sal_Unicode pUnicode[RTL_USTR_MAX_VALUEOFINT32];
+ rtl_ustr_valueOfInt32( pUnicode, (int)getuid(), 10 );
+ rtl_uString_newFromStr( &pTmp, pUnicode );
+ rtl_uString_newConcat( &pResult, pResult, pTmp );
+
+ rtl_uString_newFromAscii( &pTmp, "_SingleOfficeIPC_" );
+ rtl_uString_newConcat( &pResult, pResult, pTmp );
+
+ rtl_uString_newConcat( &pResult, pResult, pMd5hash );
+
+ ustr_debug( "result", pResult );
+
+ /* cleanup */
+ rtl_uString_release( pMd5hash );
+ rtl_uString_release( pPath );
+ rtl_uString_release( pTmp );
+ rtl_uString_release( pBasePath );
+ rtl_uString_release( pUserInstallation );
+ rtl_uString_release( pAbsUserInstallation );
+
+ return pResult;
+}
+
+/* Get fd of the pipe of the already running OOo. */
+static int
+connect_pipe( rtl_uString *pPipePath )
+{
+ int fd;
+ size_t len;
+ struct sockaddr_un addr;
+
+ rtl_String *pPipeStr = ustr_to_str( pPipePath );
+
+ memset( &addr, 0, sizeof( addr ) );
+
+ if ( ( fd = socket( AF_UNIX, SOCK_STREAM, 0 ) ) < 0 )
+ return fd;
+
+ fcntl( fd, F_SETFD, FD_CLOEXEC );
+
+ addr.sun_family = AF_UNIX;
+ strncpy( addr.sun_path, rtl_string_getStr( pPipeStr ), sizeof( addr.sun_path ) );
+ rtl_string_release( pPipeStr );
+
+/* cut / paste from osl's pipe.c */
+#if defined(FREEBSD)
+ len = SUN_LEN( &addr );
+#else
+ len = sizeof( addr );
+#endif
+
+ if ( connect( fd, (struct sockaddr *)&addr, len ) < 0 )
+ return -1;
+
+ return fd;
+}
+
+/* Escape: "," -> "\\,", "\0" -> "\\0", "\\" -> "\\\\" */
+static rtl_uString *
+escape_path( rtl_uString *pToEscape )
+{
+ rtl_uString *pBuffer = NULL;
+ sal_Int32 nCapacity = 1000;
+
+ rtl_uString_new_WithLength( &pBuffer, nCapacity );
+
+ sal_Int32 i = 0;
+ sal_Int32 nEscapeLength = rtl_uString_getLength( pToEscape );
+ for ( ; i < nEscapeLength; ++i )
+ {
+ sal_Unicode c = pToEscape->buffer[i];
+ switch ( c )
+ {
+ case (sal_Unicode)'\0':
+ rtl_uStringbuffer_insert_ascii( &pBuffer, &nCapacity,
+ rtl_uString_getLength( pBuffer ),
+ RTL_CONSTASCII_STRINGPARAM( "\\0" ) );
+ break;
+ case (sal_Unicode)',':
+ rtl_uStringbuffer_insert_ascii( &pBuffer, &nCapacity,
+ rtl_uString_getLength( pBuffer ),
+ RTL_CONSTASCII_STRINGPARAM( "\\," ) );
+ break;
+ case (sal_Unicode)'\\':
+ rtl_uStringbuffer_insert_ascii( &pBuffer, &nCapacity,
+ rtl_uString_getLength( pBuffer ),
+ RTL_CONSTASCII_STRINGPARAM( "\\\\" ) );
+ break;
+ default:
+ rtl_uStringbuffer_insert( &pBuffer, &nCapacity,
+ rtl_uString_getLength( pBuffer ),
+ &c, 1 );
+ }
+ }
+
+ return pBuffer;
+}
+
+/* Send args to the OOo instance (using the 'fd' file descriptor) */
+static sal_Bool
+send_args( int fd, rtl_uString *pCwdPath )
+{
+ rtl_uString *pBuffer = NULL, *pTmp = NULL;
+ sal_Int32 nCapacity = 1000;
+ rtl_String *pOut = NULL;
+ sal_Bool bResult;
+ size_t nLen;
+ rtl_uString *pEscapedCwdPath = escape_path( pCwdPath );
+
+ rtl_uString_new_WithLength( &pBuffer, nCapacity );
+ rtl_uString_new( &pTmp );
+
+ rtl_uStringbuffer_insert_ascii( &pBuffer, &nCapacity,
+ rtl_uString_getLength( pBuffer ),
+ RTL_CONSTASCII_STRINGPARAM( "InternalIPC::Arguments" ) );
+
+ if ( rtl_uString_getLength( pEscapedCwdPath ) )
+ {
+ rtl_uStringbuffer_insert_ascii( &pBuffer, &nCapacity,
+ rtl_uString_getLength( pBuffer ),
+ RTL_CONSTASCII_STRINGPARAM( "1" ) );
+ rtl_uStringbuffer_insert( &pBuffer, &nCapacity,
+ rtl_uString_getLength( pBuffer ),
+ rtl_uString_getStr( pEscapedCwdPath ),
+ rtl_uString_getLength( pEscapedCwdPath ) );
+ }
+ else
+ rtl_uStringbuffer_insert_ascii( &pBuffer, &nCapacity,
+ rtl_uString_getLength( pBuffer ),
+ RTL_CONSTASCII_STRINGPARAM( "0" ) );
+
+ sal_Bool bDontConvertNext = sal_False;
+ sal_uInt32 nArg;
+ sal_uInt32 nArgCount = osl_getCommandArgCount();
+ for ( nArg = 0; nArg < nArgCount; ++nArg )
+ {
+ rtl_uStringbuffer_insert_ascii( &pBuffer, &nCapacity,
+ rtl_uString_getLength( pBuffer ),
+ ",", 1 );
+
+ osl_getCommandArg( nArg, &pTmp );
+
+ // this is not a param, we have to prepend filenames with file://
+ // FIXME: improve the check
+ if ( ( pTmp->buffer[0] != (sal_Unicode)'-' ) )
+ {
+ sal_Int32 nFirstColon = rtl_ustr_indexOfChar_WithLength( pTmp->buffer, pTmp->length, ':' );
+ sal_Int32 nFirstSlash = rtl_ustr_indexOfChar_WithLength( pTmp->buffer, pTmp->length, '/' );
+
+ // check that pTmp is not an URI yet
+ // note ".uno" ".slot" & "vnd.sun.star.script" are special urls that
+ // don't expect a following '/'
+
+ const char* schemes[] = { "slot:", ".uno:", "vnd.sun.star.script:" };
+ sal_Bool bIsSpecialURL = sal_False;
+ int index = 0;
+ int len = SAL_N_ELEMENTS(schemes);
+ for ( ; index < len; ++index )
+ {
+ if ( rtl_ustr_indexOfAscii_WithLength( pTmp->buffer
+ , pTmp->length , schemes[ index ], strlen(schemes[ index ] )) == 0 )
+ {
+ bIsSpecialURL = sal_True;
+ break;
+ }
+ }
+
+ if ( !bIsSpecialURL && ( nFirstColon < 1 || ( nFirstSlash != nFirstColon + 1 ) ) )
+ {
+ // some of the switches (currently just -pt) don't want to
+ // have the filenames as URIs
+ if ( !bDontConvertNext )
+ osl_getAbsoluteFileURL( pCwdPath, pTmp, &pTmp );
+ }
+ }
+
+ // don't convert filenames with some of the switches
+ // (currently just -pt)
+ bDontConvertNext = !rtl_ustr_ascii_compareIgnoreAsciiCase( pTmp->buffer, "-pt" );
+
+ rtl_uString *pEscapedTmp = escape_path( pTmp );
+
+ rtl_uStringbuffer_insert( &pBuffer, &nCapacity,
+ rtl_uString_getLength( pBuffer ),
+ rtl_uString_getStr( pEscapedTmp ),
+ rtl_uString_getLength( pEscapedTmp ) );
+
+ rtl_uString_release( pEscapedTmp );
+ }
+
+ ustr_debug( "Pass args", pBuffer );
+
+ pOut = ustr_to_str( pBuffer );
+
+ nLen = rtl_string_getLength( pOut ) + 1;
+ bResult = ( write( fd, rtl_string_getStr( pOut ), nLen ) == (ssize_t) nLen );
+
+ /* cleanup */
+ rtl_uString_release( pEscapedCwdPath );
+ rtl_uString_release( pBuffer );
+ rtl_uString_release( pTmp );
+ rtl_string_release( pOut );
+
+ return bResult;
+}
+
+static void
+load_splash_image( rtl_uString *pUAppPath )
+{
+ char *pBuffer, *pSuffix, *pLocale;
+ int nLocSize;
+ rtl_Locale *pLoc = NULL;
+ rtl_String *pLang, *pCountry, *pAppPath;
+
+ osl_getProcessLocale (&pLoc);
+ pLang = ustr_to_str (pLoc->Language);
+ pCountry = ustr_to_str (pLoc->Country);
+
+ nLocSize = strlen (pLang->buffer) + strlen (pCountry->buffer) + 8;
+ pLocale = malloc (nLocSize);
+ pLocale[0] = '-';
+ strcpy (pLocale + 1, pLang->buffer);
+ strcat (pLocale, "_");
+ strcat (pLocale, pCountry->buffer);
+
+ rtl_string_release( pCountry );
+ rtl_string_release( pLang );
+
+ pAppPath = ustr_to_str (pUAppPath);
+ pBuffer = malloc (pAppPath->length + nLocSize + 256);
+ strcpy (pBuffer, pAppPath->buffer);
+ pSuffix = pBuffer + pAppPath->length;
+ rtl_string_release( pAppPath );
+
+ strcpy (pSuffix, "/edition/intro");
+ strcat (pSuffix, pLocale);
+ strcat (pSuffix, IMG_SUFFIX);
+ if ( splash_load_bmp( pBuffer ) )
+ goto cleanup;
+
+ strcpy (pSuffix, "/edition/intro" IMG_SUFFIX);
+ if ( splash_load_bmp( pBuffer ) )
+ goto cleanup;
+
+ strcpy (pSuffix, "/intro");
+ strcat (pSuffix, pLocale);
+ strcat (pSuffix, IMG_SUFFIX);
+ if ( splash_load_bmp( pBuffer ) )
+ goto cleanup;
+
+ strcpy (pSuffix, "/intro" IMG_SUFFIX);
+ if ( splash_load_bmp( pBuffer ) )
+ goto cleanup;
+
+ fprintf (stderr, "Failed to find intro image\n");
+
+ cleanup:
+ free (pLocale);
+ free (pBuffer);
+}
+
+/* Fill 'array' with values of the key 'name'.
+ Its value is a comma delimited list of integers */
+static void
+get_bootstrap_value( int *array, int size, rtlBootstrapHandle handle, const char *name )
+{
+ rtl_uString *pKey = NULL, *pValue = NULL;
+
+ /* get the value from the ini file */
+ rtl_uString_newFromAscii( &pKey, name );
+ rtl_bootstrap_get_from_handle( handle, pKey, &pValue, NULL );
+
+ /* the value is several numbers delimited by ',' - parse it */
+ if ( rtl_uString_getLength( pValue ) > 0 )
+ {
+ rtl_uString *pToken = NULL;
+ int i = 0;
+ sal_Int32 nIndex = 0;
+ for ( ; ( nIndex >= 0 ) && ( i < size ); ++i )
+ {
+ nIndex = rtl_uString_getToken( &pToken, pValue, 0, ',', nIndex );
+ array[i] = rtl_ustr_toInt32( rtl_uString_getStr( pToken ), 10 );
+ }
+
+ rtl_uString_release( pToken );
+ }
+
+ /* cleanup */
+ rtl_uString_release( pKey );
+ rtl_uString_release( pValue );
+}
+
+/* Load the colors and size of the splash. */
+static void
+load_splash_defaults( rtl_uString *pAppPath, sal_Bool *bNoDefaults )
+{
+ rtl_uString *pSettings = NULL, *pTmp = NULL;
+ rtlBootstrapHandle handle;
+
+ /* costruct the sofficerc file location */
+ rtl_uString_newFromAscii( &pSettings, "file://" );
+ rtl_uString_newConcat( &pSettings, pSettings, pAppPath );
+ rtl_uString_newFromAscii( &pTmp, "/" );
+ rtl_uString_newConcat( &pSettings, pSettings, pTmp );
+ rtl_uString_newFromAscii( &pTmp, SAL_CONFIGFILE( "soffice" ) );
+ rtl_uString_newConcat( &pSettings, pSettings, pTmp );
+
+ /* use it as the bootstrap file */
+ handle = rtl_bootstrap_args_open( pSettings );
+
+ int logo[1] = { -1 },
+ bar[3] = { -1, -1, -1 },
+ frame[3] = { -1, -1, -1 },
+ pos[2] = { -1, -1 },
+ size[2] = { -1, -1 };
+
+ /* get the values */
+ get_bootstrap_value( logo, 1, handle, "Logo" );
+ get_bootstrap_value( bar, 3, handle, "ProgressBarColor" );
+ get_bootstrap_value( frame, 3, handle, "ProgressFrameColor" );
+ get_bootstrap_value( pos, 2, handle, "ProgressPosition" );
+ get_bootstrap_value( size, 2, handle, "ProgressSize" );
+
+ if ( logo[0] == 0 )
+ *bNoDefaults = sal_True;
+
+ splash_setup( bar, frame, pos[0], pos[1], size[0], size[1] );
+
+ /* cleanup */
+ rtl_bootstrap_args_close( handle );
+ rtl_uString_release( pSettings );
+ rtl_uString_release( pTmp );
+}
+
+#define BUFFER_LEN 255
+
+/* Read the percent to show in splash. */
+static ProgressStatus
+read_percent( ChildInfo *info, int *pPercent )
+{
+ static char pBuffer[BUFFER_LEN + 1];
+ static char *pNext = pBuffer;
+ static ssize_t nRead = 0;
+
+ char *pBegin;
+ char *pIter;
+
+ /* from the last call */
+ int nNotProcessed = nRead - ( pNext - pBuffer );
+ if ( nNotProcessed >= BUFFER_LEN )
+ return sal_False;
+
+ memmove( pBuffer, pNext, nNotProcessed );
+
+ /* read data */
+ nRead = read( child_info_get_status_fd (info),
+ pBuffer + nNotProcessed, BUFFER_LEN - nNotProcessed );
+ if ( nRead < 0 )
+ return sal_False;
+
+ nRead += nNotProcessed;
+ pBuffer[nRead] = '\0';
+
+ /* skip old data */
+ pBegin = pBuffer;
+ pNext = pBuffer;
+ for ( pIter = pBuffer; *pIter; ++pIter )
+ {
+ if ( *pIter == '\n' )
+ {
+ pBegin = pNext;
+ pNext = pIter + 1;
+ }
+ }
+
+#if OSL_DEBUG_LEVEL > 0
+ fprintf( stderr, "Got status: %s\n", pBegin );
+#endif
+ if ( !strncasecmp( pBegin, "end", 3 ) )
+ return ProgressExit;
+ else if ( !strncasecmp( pBegin, "restart", 7 ) )
+ return ProgressRestart;
+ else if ( sscanf( pBegin, "%d%%", pPercent ) )
+ return ProgressContinue;
+
+ /* unexpected - let's exit the splash to be safe */
+ return ProgressExit;
+}
+
+/* Simple system check. */
+static void
+system_checks( void )
+{
+#ifdef LINUX
+ struct stat buf;
+
+ /* check proc is mounted - lots of things fail otherwise */
+ if ( stat( "/proc/version", &buf ) != 0 )
+ {
+ fprintf( stderr, "ERROR: /proc not mounted - LibreOffice is unlikely to work well if at all" );
+ exit( 1 );
+ }
+#endif
+}
+
+/* re-use the pagein code */
+extern int pagein_execute (int argc, char **argv);
+
+void
+exec_pagein (Args *args)
+{
+// no pagein for the while on OSX
+#ifdef MACOSX
+ (void)args;
+#else
+ char *argv[5];
+ rtl_String *app_path;
+
+ app_path = ustr_to_str (args->pAppPath);
+
+ argv[0] = "dummy-pagein";
+ argv[1] = malloc (app_path->length + sizeof ("-L/../basis-link/program") + 2);
+ strcpy (argv[1], "-L");
+ strcat (argv[1], app_path->buffer);
+ strcat (argv[1], "/../basis-link/program");
+ argv[2] = "@pagein-common";
+ argv[3] = (char *)args->pPageinType;
+ argv[4] = NULL;
+
+ rtl_string_release( app_path );
+
+ pagein_execute (args->pPageinType ? 4 : 3, argv);
+
+ free (argv[1]);
+#endif
+}
+
+static void extend_library_path (const char *new_element)
+{
+ rtl_uString *pEnvName=NULL, *pOrigEnvVar=NULL, *pNewEnvVar=NULL;
+ const char *pathname;
+#ifdef AIX
+ pathname = "LIBPATH";
+#else
+ pathname = "LD_LIBRARY_PATH";
+#endif
+
+ rtl_uString_newFromAscii( &pEnvName, pathname );
+ rtl_uString_newFromAscii( &pNewEnvVar, new_element );
+
+ osl_getEnvironment( pEnvName, &pOrigEnvVar );
+ if (pOrigEnvVar && pOrigEnvVar->length)
+ {
+ rtl_uString *pDelim = NULL;
+ rtl_uString_newFromAscii( &pDelim, ":" );
+ rtl_uString_newConcat( &pNewEnvVar, pNewEnvVar, pDelim );
+ rtl_uString_newConcat( &pNewEnvVar, pNewEnvVar, pOrigEnvVar );
+ rtl_uString_release( pDelim );
+ }
+
+ osl_setEnvironment( pEnvName, pNewEnvVar );
+
+ if (pOrigEnvVar)
+ rtl_uString_release( pOrigEnvVar );
+ rtl_uString_release( pNewEnvVar );
+ rtl_uString_release( pEnvName );
+}
+
+static void
+exec_javaldx (Args *args)
+{
+ char newpath[4096];
+ sal_uInt32 nArgs;
+ rtl_uString *pApp;
+ rtl_uString **ppArgs;
+ rtl_uString *pTmp, *pTmp2;
+ rtl_uString *pEnvironment[1] = { NULL };
+
+ ppArgs = (rtl_uString **)calloc( args->nArgsEnv + 2, sizeof( rtl_uString* ) );
+
+ for ( nArgs = 0; nArgs < args->nArgsEnv; ++nArgs )
+ ppArgs[nArgs] = args->ppArgs[nArgs];
+
+ /* Use absolute path to redirectrc */
+ pTmp = NULL;
+ rtl_uString_newFromAscii( &pTmp, "-env:INIFILENAME=vnd.sun.star.pathname:" );
+ rtl_uString_newConcat( &pTmp, pTmp, args->pAppPath );
+ pTmp2 = NULL;
+ rtl_uString_newFromAscii( &pTmp2, "/redirectrc" );
+ rtl_uString_newConcat( &pTmp, pTmp, pTmp2 );
+ ppArgs[nArgs] = pTmp;
+ rtl_uString_release (pTmp2);
+ nArgs++;
+
+ oslProcess javaldx = NULL;
+ oslFileHandle fileOut= 0;
+ oslProcessError err;
+
+ /* And also to javaldx */
+ pApp = NULL;
+ rtl_uString_newFromAscii( &pApp, "file://" );
+ rtl_uString_newConcat( &pApp, pApp, args->pAppPath );
+ pTmp = NULL;
+ rtl_uString_newFromAscii( &pTmp, "/../ure/bin/javaldx" );
+ rtl_uString_newConcat( &pApp, pApp, pTmp );
+ rtl_uString_release( pTmp );
+
+ /* unset to avoid bogus console output */
+ rtl_uString_newFromAscii( &pEnvironment[0], "G_SLICE" );
+
+ err = osl_executeProcess_WithRedirectedIO( pApp, ppArgs, nArgs,
+ osl_Process_NORMAL,
+ NULL, // security
+ NULL, // work dir
+ pEnvironment, 1,
+ &javaldx, // process handle
+ NULL,
+ &fileOut,
+ NULL);
+
+ rtl_uString_release( pEnvironment[0] );
+ rtl_uString_release( ppArgs[nArgs-1] );
+ rtl_uString_release( pApp );
+ free( ppArgs );
+
+ if( err != osl_Process_E_None)
+ {
+ fprintf (stderr, "Warning: failed to launch javaldx - java may not fuction correctly\n");
+ return;
+ } else {
+ char *chomp;
+ sal_uInt64 bytes_read;
+
+ /* Magically osl_readLine doesn't work with pipes with E_SPIPE - so be this lame instead: */
+ while (osl_readFile (fileOut, newpath, SAL_N_ELEMENTS (newpath), &bytes_read) == osl_File_E_INTR);
+
+ if (bytes_read <= 0) {
+ fprintf (stderr, "Warning: failed to read path from javaldx\n");
+ return;
+ }
+ newpath[bytes_read] = '\0';
+
+ if ((chomp = strstr (newpath, "\n")))
+ *chomp = '\0';
+ }
+
+#if OSL_DEBUG_LEVEL > 0
+ fprintf (stderr, "Adding javaldx path of '%s'\n", newpath);
+#endif
+ extend_library_path (newpath);
+
+ osl_freeProcessHandle(javaldx);
+}
+
+SAL_IMPLEMENT_MAIN_WITH_ARGS( argc, argv )
+{
+ int fd = 0;
+ sal_Bool bSentArgs = sal_False;
+ const char* pUsePlugin;
+ rtl_uString *pPipePath = NULL;
+ Args *args;
+
+ /* turn SIGPIPE into an error */
+ signal( SIGPIPE, SIG_IGN );
+
+ args = args_parse ();
+ args->pAppPath = get_app_path( argv[0] );
+ if ( !args->pAppPath )
+ {
+ fprintf( stderr, "ERROR: Can't read app link\n" );
+ exit( 1 );
+ }
+ ustr_debug( "App path", args->pAppPath );
+
+#ifndef ENABLE_QUICKSTART_LIBPNG
+ /* we can't load and render it anyway */
+ args->bInhibitSplash = sal_True;
+#endif
+
+ pUsePlugin = getenv( "SAL_USE_VCLPLUGIN" );
+ if ( pUsePlugin && !strcmp(pUsePlugin, "svp") )
+ args->bInhibitSplash = sal_True;
+
+ pPipePath = get_pipe_path( args->pAppPath );
+
+ if ( ( fd = connect_pipe( pPipePath ) ) >= 0 )
+ {
+ rtl_uString *pCwdPath = NULL;
+ osl_getProcessWorkingDir( &pCwdPath );
+
+ bSentArgs = send_args( fd, pCwdPath );
+
+ close( fd );
+ }
+#if OSL_DEBUG_LEVEL > 0
+ else
+ ustr_debug( "Failed to connect to pipe", pPipePath );
+#endif
+
+ if ( !bSentArgs )
+ {
+ /* we have to prepare for, and exec the binary */
+ int nPercent = 0;
+ ChildInfo *info;
+ sal_Bool bAllArgs = sal_True;
+ sal_Bool bHaveWindow = sal_False;
+ sal_Bool bShortWait, bRestart;
+
+ /* sanity check pieces */
+ system_checks();
+
+ /* load splash image and create window */
+ if ( !args->bInhibitSplash )
+ {
+ sal_Bool bNoDefaults = sal_False;
+ load_splash_image( args->pAppPath );
+ load_splash_defaults( args->pAppPath, &bNoDefaults );
+
+ if (!bNoDefaults &&
+ ( bHaveWindow = splash_create_window( argc, argv ) ) )
+ splash_draw_progress( 0 );
+ }
+
+ /* pagein */
+ if (!args->bInhibitJavaLdx)
+ exec_pagein (args);
+
+ /* javaldx */
+ if (!args->bInhibitJavaLdx)
+ exec_javaldx (args);
+
+ do {
+ bRestart = sal_False;
+
+ /* fast updates if we have somewhere to update it to */
+ bShortWait = bHaveWindow;
+
+ /* Periodically update the splash & the percent according
+ to what status_fd says, poll quickly only while starting */
+ info = child_spawn (args, bAllArgs, bShortWait);
+ while (!child_exited_wait (info, bShortWait))
+ {
+ ProgressStatus eResult;
+
+ splash_draw_progress( nPercent );
+ eResult = read_percent( info, &nPercent );
+ if (eResult != ProgressContinue)
+ {
+ splash_close_window ();
+ bShortWait = sal_False;
+ }
+
+#if OSL_DEBUG_LEVEL > 0
+ fprintf( stderr, "Polling, result is %s\n",
+ ( eResult == ProgressContinue )? "continue" :
+ ( ( eResult == ProgressRestart )? "restart" : "exit" ) );
+#endif
+ }
+
+#if OSL_DEBUG_LEVEL > 0
+ fprintf (stderr, "Exited with code '%d'\n", child_get_exit_code (info));
+#endif
+
+ switch (child_get_exit_code (info)) {
+ case 79: // re-start with just -env: parameters
+ fprintf (stderr, "FIXME: re-start with just -env: params !\n");
+ bRestart = sal_True;
+ bAllArgs = sal_False;
+ break;
+ case 81: // re-start with all arguments
+ fprintf (stderr, "FIXME: re-start with all params !\n");
+ bRestart = sal_True;
+ bAllArgs = sal_True;
+ break;
+ default:
+ break;
+ }
+
+ child_info_destroy (info);
+ } while (bRestart);
+ }
+
+ /* cleanup */
+ rtl_uString_release( pPipePath );
+ args_free (args);
+
+ return 0;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/unx/splash/exports.map b/desktop/unx/splash/exports.map
new file mode 100755
index 000000000000..218f0536d7e2
--- /dev/null
+++ b/desktop/unx/splash/exports.map
@@ -0,0 +1,9 @@
+UDK_3_0_0 {
+ global:
+ GetVersionInfo;
+ component_getImplementationEnvironment;
+ component_getFactory;
+
+ local:
+ *;
+};
diff --git a/desktop/unx/splash/makefile.mk b/desktop/unx/splash/makefile.mk
new file mode 100755
index 000000000000..e338cfe36b83
--- /dev/null
+++ b/desktop/unx/splash/makefile.mk
@@ -0,0 +1,76 @@
+#
+# Version: MPL 1.1 / GPLv3+ / LGPLv3+
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Initial Developer of the Original Code is
+# Novell, Inc.
+# Portions created by the Initial Developer are Copyright (C) 2010 the
+# Initial Developer. All Rights Reserved.
+#
+# Contributor(s): Jan Holesovsky <kendy@novell.com>
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 3 or later (the "GPLv3+"), or
+# the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
+# in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
+# instead of those above.
+#
+PRJ=..$/..
+
+PRJNAME=desktop
+TARGET=spl_unx
+LIBTARGET=NO
+
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+.IF "$(OS)"=="MACOSX"
+dummy:
+ @echo "Unix quickstarter disabled for mac"
+.ELSE
+
+# --- Files --------------------------------------------------------
+
+SLOFILES = $(SLO)$/unxsplash.obj
+
+SHL1DEPN= makefile.mk
+SHL1OBJS= $(SLOFILES)
+
+
+SHL1TARGET=$(TARGET)$(DLLPOSTFIX)
+SHL1IMPLIB=i$(TARGET)
+
+SHL1VERSIONMAP=exports.map
+SHL1DEF=$(MISC)$/$(SHL1TARGET).def
+DEF1NAME=$(SHL1TARGET)
+
+SHL1STDLIBS= \
+ $(CPPUHELPERLIB) \
+ $(CPPULIB) \
+ $(SALLIB)
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
+ALLTAR : $(MISC)/splash.component
+
+$(MISC)/splash.component .ERRREMOVE : $(SOLARENV)/bin/createcomponent.xslt \
+ splash.component
+ $(XSLTPROC) --nonet --stringparam uri \
+ '$(COMPONENTPREFIX_BASIS_NATIVE)$(SHL1TARGETN:f)' -o $@ \
+ $(SOLARENV)/bin/createcomponent.xslt splash.component
+
+.ENDIF \ No newline at end of file
diff --git a/desktop/unx/splash/splash.component b/desktop/unx/splash/splash.component
new file mode 100755
index 000000000000..cd7792744ea0
--- /dev/null
+++ b/desktop/unx/splash/splash.component
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<component loader="com.sun.star.loader.SharedLibrary"
+ xmlns="http://openoffice.org/2010/uno-components">
+ <implementation name="com.sun.star.office.comp.PipeSplashScreen">
+ <service name="com.sun.star.office.PipeSplashScreen"/>
+ </implementation>
+</component>
diff --git a/desktop/unx/splash/unxsplash.cxx b/desktop/unx/splash/unxsplash.cxx
new file mode 100644
index 000000000000..de703ba5c3de
--- /dev/null
+++ b/desktop/unx/splash/unxsplash.cxx
@@ -0,0 +1,196 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * Copyright 2010, Novell Inc.
+ * 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.
+ *
+ * Contributor(s): Jan Holesovsky <kendy@novell.com>
+ *
+ ************************************************************************/
+#include "unxsplash.hxx"
+#include <stdio.h>
+#include <unotools/bootstrap.hxx>
+#include <osl/process.h>
+#include <tools/urlobj.hxx>
+#include <tools/stream.hxx>
+#include <sfx2/sfx.hrc>
+#include <com/sun/star/registry/XRegistryKey.hpp>
+#include <cppuhelper/implementationentry.hxx>
+#include <rtl/logfile.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <rtl/math.hxx>
+
+#define PIPE_ARG "--splash-pipe="
+
+using namespace ::rtl;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::registry;
+
+namespace desktop
+{
+ UnxSplashScreen::UnxSplashScreen( const Reference< uno::XComponentContext >& xCtx )
+ : m_xCtx( xCtx ),
+ m_pOutFd( NULL )
+{
+}
+
+UnxSplashScreen::~UnxSplashScreen()
+{
+#if OSL_DEBUG_LEVEL > 1
+ fprintf( stderr, "UnxSplashScreen::~UnxSplashScreen()\n" );
+#endif
+
+ if ( m_pOutFd )
+ {
+ fclose( m_pOutFd );
+ m_pOutFd = NULL;
+ }
+}
+
+void SAL_CALL UnxSplashScreen::start( const OUString& /*aText*/, sal_Int32 /*nRange*/ )
+ throw ( RuntimeException )
+{
+}
+
+void SAL_CALL UnxSplashScreen::end()
+ throw ( RuntimeException )
+{
+#if OSL_DEBUG_LEVEL > 1
+ fprintf( stderr, "UnxSplashScreen::end()\n" );
+#endif
+
+ fprintf( m_pOutFd, "end\n" );
+ fflush( m_pOutFd );
+}
+
+void SAL_CALL UnxSplashScreen::reset()
+ throw ( RuntimeException )
+{
+#if OSL_DEBUG_LEVEL > 1
+ fprintf( stderr, "UnxSplashScreen::reset()\n" );
+#endif
+
+ fprintf( m_pOutFd, "restart\n" );
+ fflush( m_pOutFd );
+}
+
+void SAL_CALL UnxSplashScreen::setText( const OUString& /*aText*/ )
+ throw ( RuntimeException )
+{
+ // TODO?
+}
+
+void SAL_CALL UnxSplashScreen::setValue( sal_Int32 nValue )
+ throw ( RuntimeException )
+{
+ if ( m_pOutFd )
+ {
+ fprintf( m_pOutFd, "%"SAL_PRIdINT32"%%\n", nValue );
+ fflush( m_pOutFd );
+ }
+}
+
+// XInitialize
+void SAL_CALL
+UnxSplashScreen::initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any>& )
+ throw ( RuntimeException )
+{
+ for ( sal_uInt32 i = 0; i < osl_getCommandArgCount(); i++ )
+ {
+ rtl::OUString aArg;
+ if ( osl_getCommandArg( i, &aArg.pData ) )
+ break;
+ if ( aArg.matchIgnoreAsciiCaseAsciiL( PIPE_ARG, sizeof( PIPE_ARG ) - 1, 0 ) )
+ {
+ OUString aNum = aArg.copy( sizeof( PIPE_ARG ) - 1 );
+ int fd = aNum.toInt32();
+ m_pOutFd = fdopen( fd, "w" );
+#if OSL_DEBUG_LEVEL > 1
+ fprintf( stderr, "Got argument '--splash-pipe=%d ('%s') (%p)\n",
+ fd, (const sal_Char *)rtl::OUStringToOString( aNum, RTL_TEXTENCODING_UTF8 ),
+ m_pOutFd );
+#endif
+ }
+ }
+}
+}
+
+using namespace desktop;
+
+// get service instance...
+static uno::Reference< uno::XInterface > m_xINSTANCE;
+
+uno::Reference< uno::XInterface > SAL_CALL UnxSplash_createInstance(const uno::Reference< uno::XComponentContext > & xCtx ) throw( uno::Exception )
+{
+ static osl::Mutex m_aMutex;
+ if ( !m_xINSTANCE.is() )
+ {
+ osl::MutexGuard guard( m_aMutex );
+ if ( !m_xINSTANCE.is() )
+ m_xINSTANCE = (cppu::OWeakObject*) new UnxSplashScreen( xCtx );
+ }
+
+ return m_xINSTANCE;
+}
+
+OUString UnxSplash_getImplementationName()
+{
+ return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.office.comp.PipeSplashScreen" ) );
+}
+
+uno::Sequence< OUString > SAL_CALL UnxSplash_getSupportedServiceNames() throw()
+{
+ const OUString aServiceName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.office.PipeSplashScreen" ) );
+ const uno::Sequence< OUString > aSeq( &aServiceName, 1 );
+ return aSeq;
+}
+
+::cppu::ImplementationEntry aEntries[] =
+{
+ {
+ UnxSplash_createInstance, UnxSplash_getImplementationName,
+ UnxSplash_getSupportedServiceNames,
+ ::cppu::createSingleComponentFactory,
+ 0, 0
+ },
+ { 0, 0, 0, 0, 0, 0 }
+};
+
+extern "C"
+{
+
+SAL_DLLPUBLIC_EXPORT void SAL_CALL
+component_getImplementationEnvironment( const sal_Char ** ppEnvTypeName,
+ uno_Environment ** )
+{ *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; }
+
+SAL_DLLPUBLIC_EXPORT void* SAL_CALL
+component_getFactory( const sal_Char* pImplName, void* pServiceManager, void* pRegistryKey )
+{
+ return ::cppu::component_getFactoryHelper( pImplName, pServiceManager,
+ pRegistryKey, aEntries );
+}
+
+} // extern "C"
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/unx/splash/unxsplash.hxx b/desktop/unx/splash/unxsplash.hxx
new file mode 100644
index 000000000000..b25e858d9bac
--- /dev/null
+++ b/desktop/unx/splash/unxsplash.hxx
@@ -0,0 +1,83 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Version: MPL 1.1 / GPLv3+ / LGPLv3+
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Initial Developer of the Original Code is
+ * Novell, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 2010 the
+ * Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s): Jan Holesovsky <kendy@novell.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
+ * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
+ * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
+ * instead of those above.
+ */
+#include <stdio.h>
+
+#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/uno/XComponentContext.hpp>
+#include <com/sun/star/task/XStatusIndicator.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <cppuhelper/implbase2.hxx>
+#include <cppuhelper/interfacecontainer.h>
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#include <osl/mutex.hxx>
+#include <rtl/bootstrap.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 UnxSplashScreen : public ::cppu::WeakImplHelper2< XStatusIndicator, XInitialization >
+{
+private:
+ // don't allow anybody but ourselves to create instances of this class
+ UnxSplashScreen( const UnxSplashScreen& );
+ UnxSplashScreen( void );
+ UnxSplashScreen operator =( const UnxSplashScreen& );
+
+ virtual ~UnxSplashScreen();
+
+ static UnxSplashScreen *m_pINSTANCE;
+
+ static osl::Mutex m_aMutex;
+ Reference< XComponentContext > m_xCtx;
+
+ FILE *m_pOutFd;
+
+public:
+ UnxSplashScreen( const Reference< XComponentContext >& xCtx );
+
+ // XStatusIndicator
+ virtual void SAL_CALL start( const OUString& aText, sal_Int32 nRange ) throw ( RuntimeException );
+ 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 );
+
+ // XInitialize
+ virtual void SAL_CALL initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any>& aArguments ) throw ( RuntimeException );
+};
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/util/hidother.src b/desktop/util/hidother.src
new file mode 100644
index 000000000000..a7ca7c09874e
--- /dev/null
+++ b/desktop/util/hidother.src
@@ -0,0 +1,54 @@
+/*************************************************************************
+ *
+ * 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 "../source/inc/helpid.hrc"
+
+hidspecial HID_PACKAGE_MANAGER { HelpID = HID_PACKAGE_MANAGER; };
+hidspecial HID_PACKAGE_MANAGER_MENU_ITEM { HelpID = HID_PACKAGE_MANAGER_MENU_ITEM; };
+hidspecial HID_PACKAGE_MANAGER_TREELISTBOX { HelpID = HID_PACKAGE_MANAGER_TREELISTBOX; };
+hidspecial HID_PACKAGE_MANAGER_PROGRESS { HelpID = HID_PACKAGE_MANAGER_PROGRESS; };
+hidspecial HID_PACKAGE_MANAGER_PROGRESS_CANCEL { HelpID = HID_PACKAGE_MANAGER_PROGRESS_CANCEL; };
+
+hidspecial HID_PACKAGE_MANAGER_UPD_REQ { HelpID = HID_PACKAGE_MANAGER_UPD_REQ; };
+
+hidspecial HID_FIRSTSTART_PREV { HelpId = HID_FIRSTSTART_PREV;};
+hidspecial HID_FIRSTSTART_NEXT { HelpId = HID_FIRSTSTART_NEXT;};
+hidspecial HID_FIRSTSTART_CANCEL { HelpId = HID_FIRSTSTART_CANCEL;};
+hidspecial HID_FIRSTSTART_FINISH { HelpId = HID_FIRSTSTART_FINISH;};
+hidspecial UID_FIRSTSTART_HELP { HelpId = UID_FIRSTSTART_HELP;};
+
+hidspecial UID_BTN_LICENSE_ACCEPT { HelpId = UID_BTN_LICENSE_ACCEPT;};
+
+hidspecial HID_DEPLOYMENT_GUI_UPDATE { HelpId = HID_DEPLOYMENT_GUI_UPDATE;};
+hidspecial HID_DEPLOYMENT_GUI_UPDATEINSTALL { HelpId = HID_DEPLOYMENT_GUI_UPDATEINSTALL;};
+
+hidspecial HID_EXTENSION_MANAGER_LISTBOX { HelpId = HID_EXTENSION_MANAGER_LISTBOX; };
+hidspecial HID_EXTENSION_MANAGER_LISTBOX_OPTIONS { HelpId = HID_EXTENSION_MANAGER_LISTBOX_OPTIONS; };
+hidspecial HID_EXTENSION_MANAGER_LISTBOX_ENABLE { HelpId = HID_EXTENSION_MANAGER_LISTBOX_ENABLE; };
+hidspecial HID_EXTENSION_MANAGER_LISTBOX_DISABLE { HelpId = HID_EXTENSION_MANAGER_LISTBOX_DISABLE; };
+hidspecial HID_EXTENSION_MANAGER_LISTBOX_REMOVE { HelpId = HID_EXTENSION_MANAGER_LISTBOX_REMOVE; };
+
diff --git a/desktop/util/makefile.mk b/desktop/util/makefile.mk
new file mode 100755
index 000000000000..df2fe688b9fa
--- /dev/null
+++ b/desktop/util/makefile.mk
@@ -0,0 +1,258 @@
+#*************************************************************************
+#
+# 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=soffice
+TARGETTYPE=GUI
+LIBTARGET=NO
+GEN_HID=TRUE
+GEN_HID_OTHER=TRUE
+
+# --- Settings -----------------------------------------------------------
+
+.INCLUDE : settings.mk
+
+UWINAPILIB =
+
+VERINFONAME=verinfo
+
+# --- Resourcen ----------------------------------------------------
+
+.IF "$(GUI)" == "WNT"
+RCFILES=verinfo.rc
+.ENDIF
+.IF "$(GUI)" == "OS2"
+RCFILES=ooverinfo2.rc
+.ENDIF
+
+# --- Linken der Applikation ---------------------------------------
+
+.IF "$(OS)" == "MACOSX"
+LINKFLAGSAPPGUI!:= $(LINKFLAGSAPPGUI:s/-bind_at_load//)
+.ENDIF # MACOSX
+
+RESLIB1NAME= dkt
+RESLIB1IMAGES= $(PRJ)$/res
+RESLIB1SRSFILES= $(SRS)$/desktop.srs
+
+.IF "$(L10N_framework)"==""
+.IF "$(LINK_SO)"=="TRUE"
+.IF "$(GUI)" != "OS2"
+APP1TARGET=so$/$(TARGET)
+APP1NOSAL=TRUE
+APP1RPATH=BRAND
+APP1OBJS=$(OBJ)$/copyright_ascii_sun.obj $(OBJ)$/main.obj
+APP1STDLIBS = $(SALLIB) $(SOFFICELIB)
+APP1DEPN= $(APP1RES) verinfo.rc
+
+.IF "$(GUI)" == "WNT"
+APP1RES= $(RES)$/desktop.res
+APP1ICON=$(SOLARRESDIR)$/icons/so9_main_app.ico
+APP1VERINFO=verinfo.rc
+APP1LINKRES=$(MISC)$/$(TARGET)1.res
+APP1STACK=10000000
+
+.ENDIF # WNT
+
+.ENDIF # "$(GUI)" != "OS2"
+
+.ENDIF # "$(LINK_SO)"=="TRUE"
+
+APP5TARGET=soffice
+APP5NOSAL=TRUE
+APP5RPATH=BRAND
+APP5OBJS=$(OBJ)$/copyright_ascii_ooo.obj $(OBJ)$/main.obj
+APP5STDLIBS = $(SALLIB) $(SOFFICELIB)
+.IF "$(OS)" == "LINUX"
+APP5STDLIBS+= -lXext -lX11
+.ENDIF # LINUX
+
+APP5DEPN= $(APP1TARGETN) $(APP5RES) ooverinfo.rc
+APP5DEF= $(MISCX)$/$(TARGET).def
+
+.IF "$(GUI)" == "WNT"
+APP5RES= $(RES)$/oodesktop.res
+APP5ICON=$(SOLARRESDIR)$/icons/ooo3_main_app.ico
+APP5VERINFO=ooverinfo.rc
+APP5LINKRES=$(MISC)$/ooffice5.res
+APP5STACK=10000000
+.ENDIF # WNT
+
+.IF "$(GUI)" == "OS2"
+APP5DEF= # automatic
+APP5RES= $(RES)$/oodesktop.res
+APP5ICON=$(SOLARRESDIR)$/icons/ooo-main-app.ico
+APP5VERINFO=ooverinfo2.rc
+APP5LINKRES=$(MISC)$/ooffice.res
+.ENDIF # OS2
+
+.IF "$(GUI)" == "WNT"
+.IF "$(LINK_SO)"=="TRUE"
+APP6TARGET=so$/officeloader
+APP6RES=$(RES)$/soloader.res
+APP6NOSAL=TRUE
+APP6DEPN= $(APP1TARGETN) $(APP6RES) verinfo.rc
+APP6VERINFO=verinfo.rc
+APP6LINKRES=$(MISC)$/soffice6.res
+APP6ICON=$(SOLARRESDIR)$/icons/so9_main_app.ico
+APP6OBJS = \
+ $(OBJ)$/extendloaderenvironment.obj \
+ $(OBJ)$/officeloader.obj \
+ $(SOLARLIBDIR)$/pathutils-obj.obj
+STDLIB6=$(ADVAPI32LIB) $(SHELL32LIB) $(SHLWAPILIB)
+.ENDIF # "$(LINK_SO)"=="TRUE"
+
+APP7TARGET=officeloader
+APP7RES=$(RES)$/ooloader.res
+APP7NOSAL=TRUE
+APP7DEPN= $(APP1TARGETN) $(APP7RES) ooverinfo.rc
+APP7VERINFO=ooverinfo.rc
+APP7LINKRES=$(MISC)$/ooffice7.res
+APP7ICON=$(SOLARRESDIR)$/icons/ooo3_main_app.ico
+APP7OBJS = \
+ $(OBJ)$/extendloaderenvironment.obj \
+ $(OBJ)$/officeloader.obj \
+ $(SOLARLIBDIR)$/pathutils-obj.obj
+STDLIB7=$(ADVAPI32LIB) $(SHELL32LIB) $(SHLWAPILIB)
+.ELIF "$(OS)" == "MACOSX"
+APP6TARGET=officeloader
+APP6NOSAL=TRUE
+APP6RPATH=BRAND
+APP6OBJS=$(OBJ)$/copyright_ascii_ooo.obj $(OBJ)$/officeloader.obj
+APP6STDLIBS = $(SALLIB)
+APP5DEPN= $(APP1TARGETN) $(APP5RES) ooverinfo.rc
+APP5DEF= $(MISCX)$/$(TARGET).def
+.ENDIF # WNT
+
+.ENDIF
+
+# --- Targets -------------------------------------------------------------
+
+.INCLUDE : target.mk
+
+.IF "$(L10N_framework)"==""
+
+.IF "$(APP1TARGETN)"!=""
+$(APP1TARGETN) : $(MISC)$/binso_created.flg
+.ENDIF # "$(APP1TARGETN)"!=""
+
+.IF "$(APP5TARGETN)"!=""
+$(APP5TARGETN) : $(MISC)$/binso_created.flg
+.ENDIF # "$(APP6TARGETN)"!=""
+
+.IF "$(APP6TARGETN)"!=""
+$(APP6TARGETN) : $(MISC)$/binso_created.flg
+.ENDIF # "$(APP6TARGETN)"!=""
+
+.IF "$(GUI)" == "WNT"
+ALLTAR: $(MISC)$/$(TARGET).exe.manifest
+ALLTAR: $(MISC)$/$(TARGET).bin.manifest
+ALLTAR: $(BIN)$/$(TARGET).bin
+.IF "$(LINK_SO)"=="TRUE"
+ALLTAR: $(BIN)$/so$/$(TARGET).bin
+.ENDIF # "$(LINK_SO)"=="TRUE"
+.ENDIF # WNT
+
+.IF "$(GUI)" == "OS2"
+ALLTAR: $(BIN)$/$(TARGET).bin
+.ENDIF # OS2
+
+$(BIN)$/soffice_oo$(EXECPOST) : $(APP5TARGETN)
+ $(COPY) $< $@
+
+.IF "$(GUI)" != "OS2"
+.IF "$(LINK_SO)"=="TRUE"
+$(BIN)$/so$/soffice_so$(EXECPOST) : $(APP1TARGETN)
+ $(COPY) $< $@
+
+ALLTAR : $(BIN)$/so$/soffice_so$(EXECPOST)
+.ENDIF # "$(LINK_SO)"=="TRUE"
+ALLTAR : $(BIN)$/soffice_oo$(EXECPOST)
+.ENDIF
+
+.IF "$(OS)" == "MACOSX"
+.IF "$(LINK_SO)"=="TRUE"
+$(BIN)$/so$/soffice_mac$(EXECPOST) : $(APP1TARGETN)
+ $(COPY) $< $@
+
+ALLTAR : $(BIN)$/so$/soffice_mac$(EXECPOST)
+.ENDIF # "$(LINK_SO)"=="TRUE"
+
+$(BIN)$/soffice_mac$(EXECPOST) : $(APP5TARGETN)
+ $(COPY) $< $@
+
+ALLTAR : $(BIN)$/soffice_mac$(EXECPOST)
+
+.ENDIF # "$(OS)" == "MACOSX"
+
+.IF "$(GUI)" == "WNT"
+
+# create a manifest file with the same name as the
+# office executable file soffice.exe.manifest
+.IF "$(CCNUMVER)" <= "001399999999"
+$(MISC)$/$(TARGET).exe.manifest: template.manifest
+ $(COPY) $< $@
+.ELSE
+$(MISC)$/$(TARGET).exe.template.manifest: template.manifest
+ $(COPY) $< $@
+
+$(MISC)$/$(TARGET).exe.linker.manifest: $(BIN)$/$(TARGET)$(EXECPOST)
+ mt.exe -inputresource:$(BIN)$/$(TARGET)$(EXECPOST) -out:$@
+
+$(MISC)$/$(TARGET).exe.manifest: $(MISC)$/$(TARGET).exe.template.manifest $(MISC)$/$(TARGET).exe.linker.manifest
+ mt.exe -manifest $(MISC)$/$(TARGET).exe.linker.manifest $(MISC)$/$(TARGET).exe.template.manifest -out:$@
+.ENDIF
+
+# create a manifest file with the same name as the
+# office executable file soffice.bin.manifest
+.IF "$(CCNUMVER)" <= "001399999999"
+$(MISC)$/$(TARGET).bin.manifest: template.manifest
+ $(COPY) $< $@
+.ELSE
+$(MISC)$/$(TARGET).bin.manifest: $(MISC)$/$(TARGET).exe.manifest
+ $(COPY) $(MISC)$/$(TARGET).exe.manifest $@
+.ENDIF
+
+$(BIN)$/$(TARGET).bin: $(BIN)$/$(TARGET)$(EXECPOST)
+ $(COPY) $< $@
+
+$(BIN)$/so$/$(TARGET).bin: $(BIN)$/so$/$(TARGET)$(EXECPOST)
+ $(COPY) $< $@
+
+.ENDIF # WNT
+
+.IF "$(GUI)" == "OS2"
+$(BIN)$/$(TARGET).bin: $(BIN)$/$(TARGET)$(EXECPOST)
+ $(COPY) $< $@
+.ENDIF # OS2
+
+$(MISC)$/binso_created.flg :
+ @@-$(MKDIRHIER) $(BIN)$/so && $(TOUCH) $@
+
+.ENDIF
diff --git a/desktop/util/ooverinfo.rc b/desktop/util/ooverinfo.rc
new file mode 100755
index 000000000000..be7469563968
--- /dev/null
+++ b/desktop/util/ooverinfo.rc
@@ -0,0 +1,112 @@
+/*************************************************************************
+ *
+ * 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 VER_FIRSTYEAR 2000
+
+#include <windows.h>
+#include "version.hrc"
+
+// -----------------------------------------------------------------------
+// version information
+// -----------------------------------------------------------------------
+
+VS_VERSION_INFO versioninfo
+ fileversion VERSION, SUBVERSION, VERVARIANT, VER_COUNT
+ productversion VERSION, SUBVERSION, VERVARIANT, VER_COUNT
+ fileflagsmask 0x3F
+ fileflags
+#if defined(DEBUG)
+ VS_FF_DEBUG |
+#endif
+#ifdef VER_PREL
+ VS_FF_PRERELEASE |
+#endif
+ 0
+ fileos VOS_NT_WINDOWS32
+ filetype VFT_APP
+ {
+ block "StringFileInfo"
+ {
+ block "040904E4"
+ {
+ // International StringTable
+ value "CompanyName", "The Document Foundation\0"
+ value "FileDescription", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\0"
+ value "FileVersion", PPS(VER_LEVEL) "\0"
+ value "ProductVersion", PPS(VER_LEVEL) "\0"
+ value "OriginalFilename", "SOFFICE.EXE\0"
+ value "InternalName", "SOFFICE\0"
+ value "LegalCopyright", S_CRIGHT " Oracle, Inc.\0"
+ }
+ }
+
+ block "VarFileInfo"
+ {
+ value "Translation", 0x0409, 1252
+ }
+ }
+
+2 ICON "icons\\oasis-text.ico"
+3 ICON "icons\\oasis-text-template.ico"
+4 ICON "icons\\oasis-spreadsheet.ico"
+5 ICON "icons\\oasis-spreadsheet-template.ico"
+6 ICON "icons\\oasis-drawing.ico"
+7 ICON "icons\\oasis-drawing-template.ico"
+8 ICON "icons\\oasis-presentation.ico"
+9 ICON "icons\\oasis-presentation-template.ico"
+10 ICON "icons\\oasis-presentation-template.ico"
+11 ICON "icons\\oasis-master-document.ico"
+12 ICON "icons\\oasis-web-template.ico"
+13 ICON "icons\\oasis-empty-document.ico"
+14 ICON "icons\\oasis-database.ico"
+15 ICON "icons\\oasis-formula.ico"
+16 ICON "icons\\oasis-web-template.ico"
+17 ICON "icons\\empty-document.ico"
+18 ICON "icons\\empty-document.ico"
+19 ICON "icons\\ooo3_open.ico"
+20 ICON "icons\\empty-document.ico"
+21 ICON "icons\\ooo3_writer_app.ico"
+22 ICON "icons\\ooo3_calc_app.ico"
+23 ICON "icons\\ooo3_draw_app.ico"
+24 ICON "icons\\ooo3_impress_app.ico"
+25 ICON "icons\\ooo3_math_app.ico"
+26 ICON "icons\\ooo3_base_app.ico"
+27 ICON "icons\\oasis-empty-document.ico"
+28 ICON "icons\\text.ico"
+29 ICON "icons\\text-template.ico"
+30 ICON "icons\\spreadsheet.ico"
+31 ICON "icons\\spreadsheet-template.ico"
+32 ICON "icons\\drawing.ico"
+33 ICON "icons\\drawing-template.ico"
+34 ICON "icons\\presentation.ico"
+35 ICON "icons\\presentation-template.ico"
+36 ICON "icons\\master-document.ico"
+37 ICON "icons\\empty-document.ico"
+38 ICON "icons\\database.ico"
+39 ICON "icons\\formula.ico"
+40 ICON "icons\\oxt-extension.ico"
+
diff --git a/desktop/util/ooverinfo2.rc b/desktop/util/ooverinfo2.rc
new file mode 100755
index 000000000000..caacb294122d
--- /dev/null
+++ b/desktop/util/ooverinfo2.rc
@@ -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 "version.hrc"
+
+// -----------------------------------------------------------------------
+
+// -----------------------------------------------------------------------
+// language/character set specification table
+// -----------------------------------------------------------------------
+
+
+ICON 2 "icons/oasis-text.ico"
+ICON 3 "icons/oasis-text-template.ico"
+ICON 4 "icons/oasis-spreadsheet.ico"
+ICON 5 "icons/oasis-spreadsheet-template.ico"
+ICON 6 "icons/oasis-drawing.ico"
+ICON 7 "icons/oasis-drawing-template.ico"
+ICON 8 "icons/oasis-presentation.ico"
+ICON 9 "icons/oasis-presentation-template.ico"
+ICON 10 "icons/oasis-presentation-template.ico"
+// ICON 11 "icons/oasis-master-document.ico"
+// ICON 12 "icons/oasis-web-template.ico"
+ICON 13 "icons/oasis-empty-document.ico"
+ICON 14 "icons/oasis-database.ico"
+ICON 15 "icons/oasis-formula.ico"
+ICON 16 "icons/oasis-web-template.ico"
+ICON 17 "icons/empty-document.ico"
+ICON 18 "icons/empty-document.ico"
+ICON 19 "icons/ooo-open.ico"
+ICON 20 "icons/empty-document.ico"
+ICON 21 "icons/ooo-writer-app.ico"
+ICON 22 "icons/ooo-calc-app.ico"
+ICON 23 "icons/ooo-draw-app.ico"
+ICON 24 "icons/ooo-impress-app.ico"
+ICON 25 "icons/ooo-math-app.ico"
+ICON 26 "icons/ooo-base-app.ico"
+ICON 27 "icons/oasis-empty-document.ico"
+ICON 28 "icons/text.ico"
+ICON 29 "icons/text-template.ico"
+ICON 30 "icons/spreadsheet.ico"
+ICON 31 "icons/spreadsheet-template.ico"
+ICON 32 "icons/drawing.ico"
+ICON 33 "icons/drawing-template.ico"
+ICON 34 "icons/presentation.ico"
+ICON 35 "icons/presentation-template.ico"
+ICON 36 "icons/master-document.ico"
+ICON 37 "icons/empty-document.ico"
+ICON 38 "icons/database.ico"
+ICON 39 "icons/formula.ico"
+ICON 40 "icons/oxt-extension.ico"
+
diff --git a/desktop/util/soffice.ico b/desktop/util/soffice.ico
new file mode 100644
index 000000000000..88ccf5e5a6a0
--- /dev/null
+++ b/desktop/util/soffice.ico
Binary files differ
diff --git a/desktop/util/template.manifest b/desktop/util/template.manifest
new file mode 100755
index 000000000000..d3bd0c101f2f
--- /dev/null
+++ b/desktop/util/template.manifest
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+<assemblyIdentity version="1.0.0.0" processorArchitecture="x86" name="LibreOffice" type="win32" />
+<description>http://www.documentfoundation.org</description>
+<dependency>
+<dependentAssembly>
+<assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" publicKeyToken="6595b64144ccf1df" language="*" processorArchitecture="x86"/>
+</dependentAssembly>
+</dependency>
+</assembly>
diff --git a/desktop/util/verinfo.rc b/desktop/util/verinfo.rc
new file mode 100644
index 000000000000..f24dff55169e
--- /dev/null
+++ b/desktop/util/verinfo.rc
@@ -0,0 +1,116 @@
+/*************************************************************************
+ *
+ * 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 VER_FIRSTYEAR 2007
+
+#include <windows.h>
+#include "version_so.hrc"
+
+// -----------------------------------------------------------------------
+// version information
+// -----------------------------------------------------------------------
+
+VS_VERSION_INFO versioninfo
+#ifndef SUBVERSION
+ fileversion VERSION, 0, VERVARIANT, VER_COUNT
+ productversion VERSION, 0, VERVARIANT, VER_COUNT
+#else
+ fileversion VERSION, SUBVERSION, VERVARIANT, VER_COUNT
+ productversion VERSION, SUBVERSION, VERVARIANT, VER_COUNT
+#endif
+ fileflagsmask 0x3F
+ fileflags
+#if defined(DEBUG)
+ VS_FF_DEBUG |
+#endif
+#ifdef VER_PREL
+ VS_FF_PRERELEASE |
+#endif
+ 0
+ fileos VOS_NT_WINDOWS32
+ filetype VFT_APP
+ {
+ block "StringFileInfo"
+ {
+ block "040904E4"
+ {
+ // International StringTable
+ value "CompanyName", "The Document Foundation\0"
+ value "FileDescription", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\0"
+ value "FileVersion", PPS(VER_LEVEL) "\0"
+ value "ProductVersion", PPS(VER_LEVEL) "\0"
+ value "OriginalFilename", "SOFFICE.EXE\0"
+ value "InternalName", "SOFFICE\0"
+ value "LegalCopyright", S_CRIGHT " Oracle and/or its affiliates. All rights reserved.\0"
+ }
+ }
+
+ block "VarFileInfo"
+ {
+ value "Translation", 0x0409, 1252
+ }
+ }
+
+2 ICON "icons\\oasis-text.ico"
+3 ICON "icons\\oasis-text-template.ico"
+4 ICON "icons\\oasis-spreadsheet.ico"
+5 ICON "icons\\oasis-spreadsheet-template.ico"
+6 ICON "icons\\oasis-drawing.ico"
+7 ICON "icons\\oasis-drawing-template.ico"
+8 ICON "icons\\oasis-presentation.ico"
+9 ICON "icons\\oasis-presentation-template.ico"
+10 ICON "icons\\oasis-presentation-template.ico"
+11 ICON "icons\\oasis-master-document.ico"
+12 ICON "icons\\oasis-web-template.ico"
+13 ICON "icons\\oasis-empty-document.ico"
+14 ICON "icons\\oasis-database.ico"
+15 ICON "icons\\oasis-formula.ico"
+16 ICON "icons\\oasis-web-template.ico"
+17 ICON "icons\\empty-document.ico"
+18 ICON "icons\\empty-document.ico"
+19 ICON "icons\\so9_main_app.ico"
+20 ICON "icons\\empty-document.ico"
+21 ICON "icons\\so9_writer_app.ico"
+22 ICON "icons\\so9_calc_app.ico"
+23 ICON "icons\\so9_draw_app.ico"
+24 ICON "icons\\so9_impress_app.ico"
+25 ICON "icons\\so9_math_app.ico"
+26 ICON "icons\\so9_base_app.ico"
+27 ICON "icons\\oasis-empty-document.ico"
+28 ICON "icons\\text.ico"
+29 ICON "icons\\text-template.ico"
+30 ICON "icons\\spreadsheet.ico"
+31 ICON "icons\\spreadsheet-template.ico"
+32 ICON "icons\\drawing.ico"
+33 ICON "icons\\drawing-template.ico"
+34 ICON "icons\\presentation.ico"
+35 ICON "icons\\presentation-template.ico"
+36 ICON "icons\\master-document.ico"
+37 ICON "icons\\empty-document.ico"
+38 ICON "icons\\database.ico"
+39 ICON "icons\\formula.ico"
+40 ICON "icons\\oxt-extension.ico"
diff --git a/desktop/win32/source/QuickStart/OOQuickStart.rc b/desktop/win32/source/QuickStart/OOQuickStart.rc
new file mode 100755
index 000000000000..9baf7e864f5f
--- /dev/null
+++ b/desktop/win32/source/QuickStart/OOQuickStart.rc
@@ -0,0 +1,130 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#define APSTUDIO_HIDDEN_SYMBOLS
+#include "windows.h"
+#undef APSTUDIO_HIDDEN_SYMBOLS
+#include "resource.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// German (Germany) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_DEU)
+#ifdef _WIN32
+LANGUAGE LANG_GERMAN, SUBLANG_GERMAN
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+ICON_ACTIVE ICON DISCARDABLE "icons/ooo3_main_app.ico"
+IDI_QUICKSTART ICON DISCARDABLE "icons/ooo3_main_app.ico"
+IDI_SMALL ICON DISCARDABLE "icons/ooo3_main_app.ico"
+ICON_INACTIVE ICON DISCARDABLE "icons/ooo3_main_app.ico"
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Accelerator
+//
+
+IDC_QUICKSTART ACCELERATORS MOVEABLE PURE
+BEGIN
+ "?", IDM_ABOUT, ASCII, ALT
+ "/", IDM_ABOUT, ASCII, ALT
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_ABOUTBOX DIALOG DISCARDABLE 22, 17, 230, 75
+STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU
+CAPTION "About"
+FONT 8, "System"
+BEGIN
+ ICON IDI_QUICKSTART,IDC_MYICON,14,9,16,16
+ LTEXT "QuickStart Version 1.0",IDC_STATIC,49,10,119,8,
+ SS_NOPREFIX
+ LTEXT "Copyright (C) 2001",IDC_STATIC,49,20,119,8
+ DEFPUSHBUTTON "OK",IDOK,195,6,30,11,WS_GROUP
+END
+
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#define APSTUDIO_HIDDEN_SYMBOLS\r\n"
+ "#include ""windows.h""\r\n"
+ "#undef APSTUDIO_HIDDEN_SYMBOLS\r\n"
+ "#include ""resource.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// String Table
+//
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ IDS_APP_TITLE "SoQuickStart"
+ IDC_QUICKSTART "QUICKSTART"
+ IDS_TOOLTIP "StarOffice 6.0 QuickStart"
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ IDS_EXIT "Exit"
+END
+
+#endif // German (Germany) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/desktop/win32/source/QuickStart/QuickStart.cpp b/desktop/win32/source/QuickStart/QuickStart.cpp
new file mode 100755
index 000000000000..999701da985a
--- /dev/null
+++ b/desktop/win32/source/QuickStart/QuickStart.cpp
@@ -0,0 +1,426 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+// QuickStart.cpp : Defines the entry point for the application.
+//
+
+#include "stdafx.h"
+#include "resource.h"
+#include <systools/win32/uwinapi.h>
+#include <stdio.h>
+
+#define MY_TASKBAR_NOTIFICATION WM_USER+1
+
+#define MAX_LOADSTRING 100
+
+// message used to communicate with soffice
+#define TERMINATIONVETO_MESSAGE "SO TerminationVeto"
+#define TERMINATE_MESSAGE "SO Terminate"
+#define LISTENER_WINDOWCLASS "SO Listener Class"
+#define KILLTRAY_MESSAGE "SO KillTray"
+
+static UINT aTerminationVetoMessage = 0x7FFF;
+static UINT aTerminateMessage = 0x7FFF;
+static HMENU popupMenu = NULL;
+static bool bTerminateVeto = true;
+
+#define UPDATE_TIMER 1
+
+// Global Variables:
+HINSTANCE hInst; // current instance
+TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
+TCHAR szWindowClass[MAX_LOADSTRING]; // The title bar text
+
+TCHAR szExitString[MAX_LOADSTRING];
+TCHAR szTooltipString[MAX_LOADSTRING];
+
+// Foward declarations of functions included in this code module:
+ATOM MyRegisterClass(HINSTANCE hInstance);
+BOOL InitInstance(HINSTANCE, int);
+LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
+LRESULT CALLBACK About(HWND, UINT, WPARAM, LPARAM);
+
+bool SofficeRuns()
+{
+ // check for soffice by searching the communication window
+ return ( FindWindowEx( NULL, NULL, LISTENER_WINDOWCLASS, NULL ) == NULL ) ? false : true;
+}
+
+bool launchSoffice( )
+{
+ if ( !SofficeRuns() )
+ {
+ // UINT ret = WinExec( "h:\\office60.630b\\program\\swriter.exe -bean", SW_SHOW );
+ char filename[_MAX_PATH + 1];
+
+ filename[_MAX_PATH] = 0;
+ GetModuleFileName( NULL, filename, _MAX_PATH ); // soffice resides in the same dir
+ char *p = strrchr( filename, '\\' );
+ if ( !p )
+ return false;
+
+ strncpy( p+1, "soffice.exe", _MAX_PATH - (p+1 - filename) );
+
+ char imagename[_MAX_PATH + 1];
+
+ imagename[_MAX_PATH] = 0;
+ _snprintf(imagename, _MAX_PATH, "\"%s\" -quickstart", filename );
+
+ UINT ret = WinExec( imagename, SW_SHOW );
+ if ( ret < 32 )
+ return false;
+/*
+ // wait until we can communicate
+ int retry = 30;
+ while (retry-- && !SofficeRuns() )
+ Sleep(1000);
+
+ return SofficeRuns();
+ */
+ return true;
+ }
+ else
+ return true;
+}
+
+void NotifyListener( HWND hWnd )
+{
+ static HICON hIconActive=NULL;
+ //static HICON hIconInActive=NULL;
+
+ if( !hIconActive )
+ {
+ hIconActive = (HICON)LoadImage( GetModuleHandle( NULL ), MAKEINTRESOURCE( ICON_ACTIVE ),
+ IMAGE_ICON, GetSystemMetrics( SM_CXSMICON ), GetSystemMetrics( SM_CYSMICON ),
+ LR_DEFAULTCOLOR | LR_SHARED );
+
+/* hIconInActive = (HICON)LoadImage( GetModuleHandle( NULL ), MAKEINTRESOURCE( ICON_INACTIVE ),
+ IMAGE_ICON, GetSystemMetrics( SM_CXSMICON ), GetSystemMetrics( SM_CYSMICON ),
+ LR_DEFAULTCOLOR | LR_SHARED );
+ */
+ }
+
+ NOTIFYICONDATA nid;
+ nid.cbSize = sizeof(NOTIFYICONDATA);
+ nid.hWnd = hWnd;
+ nid.uID = IDM_QUICKSTART;
+ nid.szTip[SAL_N_ELEMENTS(nid.szTip) - 1] = 0;
+// nid.hIcon = bTerminateVeto ? hIconActive : hIconInActive;
+// strncpy(nid.szTip, bTerminateVeto ? STRING_QUICKSTARTACTIVE : STRING_QUICKSTARTINACTIVE, SAL_N_ELEMENTS(nid.szTip) - 1 );
+ nid.hIcon = hIconActive;
+ strncpy(nid.szTip, szTooltipString, SAL_N_ELEMENTS(nid.szTip) - 1);
+ nid.uFlags = NIF_TIP|NIF_ICON;
+
+ // update systray
+ Shell_NotifyIcon( NIM_MODIFY, &nid );
+ //CheckMenuItem( popupMenu, IDM_QUICKSTART, bTerminateVeto ? MF_CHECKED : MF_UNCHECKED );
+
+ // notify listener
+ SendMessage( HWND_BROADCAST, aTerminationVetoMessage, (WORD) bTerminateVeto, 0L );
+}
+
+
+
+int APIENTRY WinMain(HINSTANCE hInstance,
+ HINSTANCE /*hPrevInstance*/,
+ LPSTR /*lpCmdLine*/,
+ int nCmdShow)
+{
+ // Look for -killtray argument
+
+ for ( int i = 1; i < __argc; i++ )
+ {
+ if ( 0 == strcmp( __argv[i], "-killtray" ) )
+ {
+ HWND hwndTray = FindWindow( LISTENER_WINDOWCLASS, NULL );
+
+ if ( hwndTray )
+ {
+ UINT uMsgKillTray = RegisterWindowMessage( KILLTRAY_MESSAGE );
+ SendMessage( hwndTray, uMsgKillTray, 0, 0 );
+ }
+
+ return 0;
+ }
+ }
+
+ launchSoffice();
+ return 0;
+
+ // TODO: Place code here.
+ MSG msg;
+ HACCEL hAccelTable;
+ aTerminationVetoMessage = RegisterWindowMessage( TERMINATIONVETO_MESSAGE );
+ aTerminateMessage = RegisterWindowMessage( TERMINATE_MESSAGE );
+
+ // Initialize global strings
+ LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
+ LoadString(hInstance, IDC_QUICKSTART, szWindowClass, MAX_LOADSTRING);
+
+ LoadString(hInstance, IDS_EXIT, szExitString, MAX_LOADSTRING);
+ LoadString(hInstance, IDS_TOOLTIP, szTooltipString, MAX_LOADSTRING);
+
+ MyRegisterClass(hInstance);
+
+ // Perform application initialization:
+ if (!InitInstance (hInstance, nCmdShow))
+ {
+ return FALSE;
+ }
+
+ hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_QUICKSTART);
+
+ // Main message loop:
+ while (GetMessage(&msg, NULL, 0, 0))
+ {
+ if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
+ {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+ }
+
+ return msg.wParam;
+}
+
+
+
+//
+// FUNCTION: MyRegisterClass()
+//
+// PURPOSE: Registers the window class.
+//
+// COMMENTS:
+//
+// This function and its usage is only necessary if you want this code
+// to be compatible with Win32 systems prior to the 'RegisterClassEx'
+// function that was added to Windows 95. It is important to call this function
+// so that the application will get 'well formed' small icons associated
+// with it.
+//
+ATOM MyRegisterClass(HINSTANCE hInstance)
+{
+ WNDCLASSEX wcex;
+
+ wcex.cbSize = sizeof(WNDCLASSEX);
+
+ wcex.style = CS_HREDRAW | CS_VREDRAW;
+ wcex.lpfnWndProc = (WNDPROC)WndProc;
+ wcex.cbClsExtra = 0;
+ wcex.cbWndExtra = 0;
+ wcex.hInstance = hInstance;
+ wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_QUICKSTART);
+ wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
+ wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
+ wcex.lpszMenuName = NULL;
+ wcex.lpszClassName = szWindowClass;
+ wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);
+
+ return RegisterClassEx(&wcex);
+}
+
+//
+// FUNCTION: InitInstance(HANDLE, int)
+//
+// PURPOSE: Saves instance handle and creates main window
+//
+// COMMENTS:
+//
+// In this function, we save the instance handle in a global variable and
+// create and display the main program window.
+//
+BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
+{
+ HWND hWnd;
+
+ hInst = hInstance; // Store instance handle in our global variable
+
+ hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
+ CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
+
+ if (!hWnd)
+ {
+ return FALSE;
+ }
+
+ nCmdShow = SW_HIDE; // hide main window, we only need the taskbar icon
+ ShowWindow(hWnd, nCmdShow);
+ UpdateWindow(hWnd);
+
+ return TRUE;
+}
+
+//
+// FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
+//
+// PURPOSE: Processes messages for the main window.
+//
+// WM_COMMAND - process the application menu
+// WM_PAINT - Paint the main window
+// WM_DESTROY - post a quit message and return
+//
+//
+LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ switch (message)
+ {
+ case WM_CREATE:
+ {
+ // make sure soffice runs
+ if( !launchSoffice() )
+ return -1;
+
+ // create popup menu
+ popupMenu = CreatePopupMenu();
+ static int count=0;
+
+ // Add my items
+ MENUITEMINFO mi;
+ mi.cbSize = sizeof(MENUITEMINFO);
+ mi.fMask=MIIM_TYPE|MIIM_STATE|MIIM_ID;
+ mi.fType=MFT_STRING;
+ mi.fState=MFS_ENABLED|MFS_DEFAULT;
+ mi.wID = IDM_QUICKSTART;
+ mi.hSubMenu=NULL;
+ mi.hbmpChecked=NULL;
+ mi.hbmpUnchecked=NULL;
+ mi.dwItemData=NULL;
+ mi.dwTypeData = "QuickStart";
+ mi.cch = strlen(mi.dwTypeData);
+// InsertMenuItem(popupMenu, count++, TRUE, &mi);
+
+ mi.cbSize = sizeof(MENUITEMINFO);
+ mi.fMask=MIIM_TYPE|MIIM_STATE|MIIM_ID;
+ mi.fType=MFT_STRING;
+ mi.fState=MFS_ENABLED;
+ mi.wID = IDM_ABOUT;
+ mi.hSubMenu=NULL;
+ mi.hbmpChecked=NULL;
+ mi.hbmpUnchecked=NULL;
+ mi.dwItemData=NULL;
+ mi.dwTypeData = "Info...";
+ mi.cch = strlen(mi.dwTypeData);
+// InsertMenuItem(popupMenu, count++, TRUE, &mi);
+
+ mi.cbSize = sizeof(MENUITEMINFO);
+ mi.fMask=MIIM_TYPE;
+ mi.fType=MFT_SEPARATOR;
+ mi.hSubMenu=NULL;
+ mi.hbmpChecked=NULL;
+ mi.hbmpUnchecked=NULL;
+ mi.dwItemData=NULL;
+// InsertMenuItem(popupMenu, count++, TRUE, &mi);
+
+ mi.cbSize = sizeof(MENUITEMINFO);
+ mi.fMask=MIIM_TYPE|MIIM_STATE|MIIM_ID;
+ mi.fType=MFT_STRING;
+ mi.fState=MFS_ENABLED;
+ mi.wID = IDM_EXIT;
+ mi.hSubMenu=NULL;
+ mi.hbmpChecked=NULL;
+ mi.hbmpUnchecked=NULL;
+ mi.dwItemData=NULL;
+ mi.dwTypeData = szExitString;
+ mi.cch = strlen(mi.dwTypeData);
+ InsertMenuItem(popupMenu, count++, TRUE, &mi);
+
+ // add taskbar icon
+ NOTIFYICONDATA nid;
+ nid.cbSize = sizeof(NOTIFYICONDATA);
+ nid.hWnd = hWnd;
+ nid.uID = IDM_QUICKSTART;
+ nid.uFlags = NIF_MESSAGE;
+ nid.uCallbackMessage=MY_TASKBAR_NOTIFICATION;
+ Shell_NotifyIcon(NIM_ADD, &nid);
+
+ // and update state
+ NotifyListener( hWnd );
+
+ // check for soffice
+ SetTimer(hWnd, UPDATE_TIMER, 3000, NULL);
+ }
+ break;
+
+ case MY_TASKBAR_NOTIFICATION: // message from taskbar
+ switch(lParam)
+ {
+/*
+ case WM_LBUTTONDBLCLK:
+ bTerminateVeto = bTerminateVeto ? false : true;
+ NotifyListener( hWnd );
+ break;
+ */
+
+ case WM_LBUTTONDOWN:
+ case WM_RBUTTONDOWN:
+ {
+ POINT pt;
+ GetCursorPos(&pt);
+ SetForegroundWindow( hWnd );
+ int m = TrackPopupMenuEx(popupMenu, TPM_RETURNCMD|TPM_LEFTALIGN|TPM_RIGHTBUTTON,
+ pt.x, pt.y, hWnd, NULL);
+ // BUGFIX: See Q135788 (PRB: Menus for Notification Icons Don't Work Correctly)
+ PostMessage(hWnd, NULL, 0, 0);
+ switch(m)
+ {
+ case IDM_QUICKSTART:
+ bTerminateVeto = bTerminateVeto ? false : true;
+ NotifyListener( hWnd );
+ break;
+ case IDM_ABOUT:
+ DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
+ break;
+ case IDM_EXIT:
+ DestroyWindow(hWnd);
+ break;
+ }
+ }
+ break;
+ }
+ break;
+
+ case WM_TIMER:
+ if( wParam == UPDATE_TIMER )
+ {
+ // update state
+ NotifyListener( hWnd );
+ }
+ break;
+
+ case WM_DESTROY:
+ // try to terminate office
+ SendMessage( HWND_BROADCAST, aTerminateMessage, 0, 0L );
+
+ // delete taskbar icon
+ NOTIFYICONDATA nid;
+ nid.cbSize=sizeof(NOTIFYICONDATA);
+ nid.hWnd = hWnd;
+ nid.uID = IDM_QUICKSTART;
+ Shell_NotifyIcon(NIM_DELETE, &nid);
+
+ PostQuitMessage(0);
+ break;
+ default:
+ return DefWindowProc(hWnd, message, wParam, lParam);
+ }
+ return 0;
+}
+
+// Mesage handler for about box.
+LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM)
+{
+ switch (message)
+ {
+ case WM_INITDIALOG:
+ return TRUE;
+
+ case WM_COMMAND:
+ if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
+ {
+ EndDialog(hDlg, LOWORD(wParam));
+ return TRUE;
+ }
+ break;
+ }
+ return FALSE;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/win32/source/QuickStart/QuickStart.h b/desktop/win32/source/QuickStart/QuickStart.h
new file mode 100755
index 000000000000..b61a04075e08
--- /dev/null
+++ b/desktop/win32/source/QuickStart/QuickStart.h
@@ -0,0 +1,15 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+
+#if !defined(AFX_QUICKSTART_H__7D38EE02_7699_4CF0_AFF9_FD92E05CC009__INCLUDED_)
+#define AFX_QUICKSTART_H__7D38EE02_7699_4CF0_AFF9_FD92E05CC009__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+#include "resource.h"
+
+
+#endif // !defined(AFX_QUICKSTART_H__7D38EE02_7699_4CF0_AFF9_FD92E05CC009__INCLUDED_)
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/win32/source/QuickStart/StdAfx.h b/desktop/win32/source/QuickStart/StdAfx.h
new file mode 100755
index 000000000000..f5277a01332c
--- /dev/null
+++ b/desktop/win32/source/QuickStart/StdAfx.h
@@ -0,0 +1,42 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+// stdafx.h : include file for standard system include files,
+// or project specific include files that are used frequently, but
+// are changed infrequently
+//
+
+#if !defined(AFX_STDAFX_H__A9DB83DB_A9FD_11D0_BFD1_444553540000__INCLUDED_)
+#define AFX_STDAFX_H__A9DB83DB_A9FD_11D0_BFD1_444553540000__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
+
+
+// Windows Header Files:
+#if defined _MSC_VER
+#pragma warning(push, 1)
+#endif
+#include <windows.h>
+#include <shellapi.h>
+#if defined _MSC_VER
+#pragma warning(pop)
+#endif
+
+// C RunTime Header Files
+#include <stdlib.h>
+#include <malloc.h>
+#include <memory.h>
+#include <tchar.h>
+
+// Local Header Files
+
+// TODO: reference additional headers your program requires here
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
+
+#endif // !defined(AFX_STDAFX_H__A9DB83DB_A9FD_11D0_BFD1_444553540000__INCLUDED_)
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/win32/source/QuickStart/makefile.mk b/desktop/win32/source/QuickStart/makefile.mk
new file mode 100644
index 000000000000..41242d849dfb
--- /dev/null
+++ b/desktop/win32/source/QuickStart/makefile.mk
@@ -0,0 +1,74 @@
+#*************************************************************************
+#
+# 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=sysui
+TARGET=quickstart
+LIBTARGET=NO
+ENABLE_EXCEPTIONS=TRUE
+TARGETTYPE=GUI
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+UWINAPILIB =
+
+# --- Resources ----------------------------------------------------
+
+RCFILES=OOQuickStart.rc
+
+# --- Files --------------------------------------------------------
+
+OBJFILES=$(OBJ)$/QuickStart.obj
+
+APP1OBJS=$(OBJFILES)
+APP1NOSAL=TRUE
+APP1TARGET=$(TARGET)
+APP1RPATH=BRAND
+.IF "$(COM)"=="GCC"
+APP1STDLIBS=-luuid
+.ELSE
+APP1STDLIBS=comsupp.lib
+.ENDIF
+
+APP1STDLIBS+=$(SHELL32LIB)\
+ $(OLE32LIB)\
+ $(GDI32LIB)\
+ $(OLEAUT32LIB)\
+ $(COMDLG32LIB)\
+ $(KERNEL32LIB)\
+ $(OLEAUT32LIB)
+
+APP1NOSVRES=$(RES)$/$(TARGET).res
+
+
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/desktop/win32/source/QuickStart/resource.h b/desktop/win32/source/QuickStart/resource.h
new file mode 100755
index 000000000000..dc4a70ab5193
--- /dev/null
+++ b/desktop/win32/source/QuickStart/resource.h
@@ -0,0 +1,35 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by QUICKSTART.RC
+//
+#define IDR_MAINFRAME 128
+#define IDD_QUICKSTART_DIALOG 102
+#define IDD_ABOUTBOX 103
+#define IDS_APP_TITLE 103
+#define IDM_ABOUT 104
+#define IDM_EXIT 105
+#define IDS_HELLO 106
+#define IDI_QUICKSTART 107
+#define IDI_SMALL 108
+#define IDC_QUICKSTART 109
+#define IDM_QUICKSTART 110
+#define IDS_TOOLTIP 111
+#define IDS_EXIT 112
+#define ICON_ACTIVE 1
+#define ICON_INACTIVE 2
+#define IDC_MYICON 3
+#define IDC_STATIC -1
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+
+#define _APS_NEXT_RESOURCE_VALUE 129
+#define _APS_NEXT_COMMAND_VALUE 32771
+#define _APS_NEXT_CONTROL_VALUE 1000
+#define _APS_NEXT_SYMED_VALUE 113
+#endif
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/win32/source/QuickStart/so/QuickStart.rc b/desktop/win32/source/QuickStart/so/QuickStart.rc
new file mode 100755
index 000000000000..732904dc745a
--- /dev/null
+++ b/desktop/win32/source/QuickStart/so/QuickStart.rc
@@ -0,0 +1,130 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "../resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#define APSTUDIO_HIDDEN_SYMBOLS
+#include "windows.h"
+#undef APSTUDIO_HIDDEN_SYMBOLS
+#include "resource.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// German (Germany) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_DEU)
+#ifdef _WIN32
+LANGUAGE LANG_GERMAN, SUBLANG_GERMAN
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+ICON_ACTIVE ICON DISCARDABLE "icons/so9_main_app.ico"
+IDI_QUICKSTART ICON DISCARDABLE "icons/so9_main_app.ico"
+IDI_SMALL ICON DISCARDABLE "icons/so9_main_app.ico"
+ICON_INACTIVE ICON DISCARDABLE "icons/so9_main_app.ico"
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Accelerator
+//
+
+IDC_QUICKSTART ACCELERATORS MOVEABLE PURE
+BEGIN
+ "?", IDM_ABOUT, ASCII, ALT
+ "/", IDM_ABOUT, ASCII, ALT
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_ABOUTBOX DIALOG DISCARDABLE 22, 17, 230, 75
+STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU
+CAPTION "About"
+FONT 8, "System"
+BEGIN
+ ICON IDI_QUICKSTART,IDC_MYICON,14,9,16,16
+ LTEXT "QuickStart Version 1.0",IDC_STATIC,49,10,119,8,
+ SS_NOPREFIX
+ LTEXT "Copyright (C) 2001",IDC_STATIC,49,20,119,8
+ DEFPUSHBUTTON "OK",IDOK,195,6,30,11,WS_GROUP
+END
+
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#define APSTUDIO_HIDDEN_SYMBOLS\r\n"
+ "#include ""windows.h""\r\n"
+ "#undef APSTUDIO_HIDDEN_SYMBOLS\r\n"
+ "#include ""resource.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// String Table
+//
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ IDS_APP_TITLE "SoQuickStart"
+ IDC_QUICKSTART "QUICKSTART"
+ IDS_TOOLTIP "Oracle Open Office 3.2 QuickStart"
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ IDS_EXIT "Exit"
+END
+
+#endif // German (Germany) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/desktop/win32/source/QuickStart/so/makefile.mk b/desktop/win32/source/QuickStart/so/makefile.mk
new file mode 100755
index 000000000000..50154c7d50b2
--- /dev/null
+++ b/desktop/win32/source/QuickStart/so/makefile.mk
@@ -0,0 +1,77 @@
+#*************************************************************************
+#
+# 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=sysui
+TARGET=soquickstart
+LIBTARGET=NO
+ENABLE_EXCEPTIONS=TRUE
+TARGETTYPE=GUI
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+UWINAPILIB =
+
+# --- Resources ----------------------------------------------------
+
+.IF "$(LINK_SO)"=="TRUE"
+
+RCFILES=QuickStart.rc
+INCPRE=..
+
+# --- Files --------------------------------------------------------
+
+OBJFILES=$(OBJ)$/QuickStart.obj
+
+APP1OBJS=$(OBJFILES)
+APP1NOSAL=TRUE
+APP1TARGET=$(TARGET)
+APP1RPATH=BRAND
+.IF "$(COM)"=="GCC"
+APP1STDLIBS=-luuid
+.ELSE
+APP1STDLIBS=comsupp.lib
+.ENDIF
+
+APP1STDLIBS+=$(SHELL32LIB)\
+ $(OLE32LIB)\
+ $(GDI32LIB)\
+ $(OLEAUT32LIB)\
+ $(COMDLG32LIB)\
+ $(KERNEL32LIB)\
+ $(OLEAUT32LIB)
+
+APP1NOSVRES=$(RES)$/$(TARGET).res
+
+.ENDIF # "$(LINK_SO)"=="TRUE"
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/desktop/win32/source/applauncher/launcher.cxx b/desktop/win32/source/applauncher/launcher.cxx
new file mode 100644
index 000000000000..a7a17b59a215
--- /dev/null
+++ b/desktop/win32/source/applauncher/launcher.cxx
@@ -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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include "launcher.hxx"
+
+
+#ifndef _WINDOWS_
+# define WIN32_LEAN_AND_MEAN
+#if defined _MSC_VER
+#pragma warning(push, 1)
+#endif
+# include <windows.h>
+# include <shellapi.h>
+#if defined _MSC_VER
+#pragma warning(pop)
+#endif
+#endif
+
+
+#include <stdlib.h>
+#include <malloc.h>
+
+
+#ifdef __MINGW32__
+extern "C" int APIENTRY WinMain( HINSTANCE, HINSTANCE, LPSTR, int )
+#else
+extern "C" int APIENTRY _tWinMain( HINSTANCE, HINSTANCE, LPTSTR, int )
+#endif
+{
+ // Retreive startup info
+
+ STARTUPINFO aStartupInfo;
+
+ ZeroMemory( &aStartupInfo, sizeof(aStartupInfo) );
+ aStartupInfo.cb = sizeof( aStartupInfo );
+ GetStartupInfo( &aStartupInfo );
+
+ // Retrieve command line
+
+ LPTSTR lpCommandLine = GetCommandLine();
+
+ LPTSTR *ppArguments = NULL;
+ int nArguments = 0;
+
+ ppArguments = GetArgv( &nArguments );
+
+ {
+ lpCommandLine = (LPTSTR)_alloca( sizeof(_TCHAR) * (_tcslen(lpCommandLine) + _tcslen(APPLICATION_SWITCH) + 2) );
+
+ _tcscpy( lpCommandLine, GetCommandLine() );
+ _tcscat( lpCommandLine, _T(" ") );
+ _tcscat( lpCommandLine, APPLICATION_SWITCH );
+ }
+
+
+ // Calculate application name
+
+ TCHAR szApplicationName[MAX_PATH];
+ TCHAR szDrive[MAX_PATH];
+ TCHAR szDir[MAX_PATH];
+ TCHAR szFileName[MAX_PATH];
+ TCHAR szExt[MAX_PATH];
+
+ GetModuleFileName( NULL, szApplicationName, MAX_PATH );
+ _tsplitpath( szApplicationName, szDrive, szDir, szFileName, szExt );
+ _tmakepath( szApplicationName, szDrive, szDir, OFFICE_IMAGE_NAME, _T(".exe") );
+
+ PROCESS_INFORMATION aProcessInfo;
+
+ BOOL fSuccess = CreateProcess(
+ szApplicationName,
+ lpCommandLine,
+ NULL,
+ NULL,
+ TRUE,
+ 0,
+ NULL,
+ NULL,
+ &aStartupInfo,
+ &aProcessInfo );
+
+ if ( fSuccess )
+ {
+ // Wait for soffice process to be terminated to allow other applications
+ // to wait for termination of started process
+
+ WaitForSingleObject( aProcessInfo.hProcess, INFINITE );
+
+ CloseHandle( aProcessInfo.hProcess );
+ CloseHandle( aProcessInfo.hThread );
+
+ return 0;
+ }
+
+ DWORD dwError = GetLastError();
+
+ LPVOID lpMsgBuf;
+
+ FormatMessage(
+ FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL,
+ dwError,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
+ (LPTSTR)&lpMsgBuf,
+ 0,
+ NULL
+ );
+
+ // Display the string.
+ MessageBox( NULL, (LPCTSTR)lpMsgBuf, NULL, MB_OK | MB_ICONERROR );
+
+ // Free the buffer.
+ LocalFree( lpMsgBuf );
+
+ return GetLastError();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/win32/source/applauncher/launcher.hxx b/desktop/win32/source/applauncher/launcher.hxx
new file mode 100644
index 000000000000..46829d67037c
--- /dev/null
+++ b/desktop/win32/source/applauncher/launcher.hxx
@@ -0,0 +1,24 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+#pragma once
+#ifndef __cplusplus
+#error Need C++ to compile
+#endif
+
+#ifndef _INC_TCHAR
+# ifdef UNICODE
+# define _UNICODE
+# endif
+# include <tchar.h>
+#endif
+
+#ifdef UNICODE
+# define GetArgv( pArgc ) CommandLineToArgvW( GetCommandLine(), pArgc )
+#else
+# define GetArgv( pArgc ) (*pArgc = __argc, __argv)
+#endif
+
+#define OFFICE_IMAGE_NAME _T("soffice")
+
+extern _TCHAR APPLICATION_SWITCH[];
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/win32/source/applauncher/makefile.mk b/desktop/win32/source/applauncher/makefile.mk
new file mode 100755
index 000000000000..d08309bbed24
--- /dev/null
+++ b/desktop/win32/source/applauncher/makefile.mk
@@ -0,0 +1,150 @@
+#*************************************************************************
+#
+# 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=applauncher
+LIBTARGET=NO
+TARGETTYPE=GUI
+UWINAPILIB=
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+CDEFS+=-DUNICODE
+
+
+OBJFILES= \
+ $(OBJ)$/launcher.obj \
+ $(OBJ)$/swriter.obj \
+ $(OBJ)$/scalc.obj \
+ $(OBJ)$/sdraw.obj \
+ $(OBJ)$/simpress.obj \
+ $(OBJ)$/sbase.obj \
+ $(OBJ)$/smath.obj \
+ $(OBJ)$/sweb.obj
+
+# SO launcher
+.IF "$(LINK_SO)"=="TRUE"
+.IF "$(BUILD_SPECIAL)"!=""
+APP1DEPN= $(APP1RES) verinfo.rc
+APP1TARGET=so$/swriter
+APP1NOSAL=TRUE
+APP1LINKRES=$(MISC)$/$(TARGET)1.res
+APP1ICON=$(SOLARRESDIR)$/icons/so9_writer_app.ico
+APP1OBJS = \
+ $(OBJ)$/launcher.obj\
+ $(OBJ)$/swriter.obj
+APP1STDLIBS = $(SHELL32LIB)
+APP1VERINFO=verinfo.rc
+APP1PRODUCTDEF+=-DRES_APP_NAME=swriter
+
+APP2TARGET=so$/scalc
+APP2NOSAL=TRUE
+APP2LINKRES=$(MISC)$/$(TARGET)2.res
+APP2ICON=$(SOLARRESDIR)$/icons/so9_calc_app.ico
+APP2OBJS = \
+ $(OBJ)$/launcher.obj\
+ $(OBJ)$/scalc.obj
+APP2STDLIBS = $(SHELL32LIB)
+APP2DEPN=verinfo.rc
+APP2VERINFO=verinfo.rc
+APP2PRODUCTDEF+=-DRES_APP_NAME=scalc
+
+APP3TARGET=so$/sdraw
+APP3NOSAL=TRUE
+APP3LINKRES=$(MISC)$/$(TARGET)3.res
+APP3ICON=$(SOLARRESDIR)$/icons/so9_draw_app.ico
+APP3OBJS = \
+ $(OBJ)$/launcher.obj\
+ $(OBJ)$/sdraw.obj
+APP3STDLIBS = $(SHELL32LIB)
+APP3DEPN=verinfo.rc
+APP3VERINFO=verinfo.rc
+APP3PRODUCTDEF+=-DRES_APP_NAME=sdraw
+
+APP4TARGET=so$/simpress
+APP4NOSAL=TRUE
+APP4LINKRES=$(MISC)$/$(TARGET)4.res
+APP4ICON=$(SOLARRESDIR)$/icons/so9_impress_app.ico
+APP4OBJS = \
+ $(OBJ)$/launcher.obj\
+ $(OBJ)$/simpress.obj
+APP4STDLIBS = $(SHELL32LIB)
+APP4DEPN=verinfo.rc
+APP4VERINFO=verinfo.rc
+APP4PRODUCTDEF+=-DRES_APP_NAME=simpress
+
+APP5TARGET=so$/sbase
+APP5NOSAL=TRUE
+APP5LINKRES=$(MISC)$/$(TARGET)5.res
+APP5ICON=$(SOLARRESDIR)$/icons/so9_base_app.ico
+APP5OBJS = \
+ $(OBJ)$/launcher.obj\
+ $(OBJ)$/sbase.obj
+APP5STDLIBS = $(SHELL32LIB)
+APP5DEPN=verinfo.rc
+APP5VERINFO=verinfo.rc
+APP5PRODUCTDEF+=-DRES_APP_NAME=sbase
+
+APP6TARGET=so$/smath
+APP6NOSAL=TRUE
+APP6LINKRES=$(MISC)$/$(TARGET)6.res
+APP6ICON=$(SOLARRESDIR)$/icons/so9_math_app.ico
+APP6OBJS = \
+ $(OBJ)$/launcher.obj\
+ $(OBJ)$/smath.obj
+APP6STDLIBS = $(SHELL32LIB)
+APP6DEPN=verinfo.rc
+APP6VERINFO=verinfo.rc
+APP6PRODUCTDEF+=-DRES_APP_NAME=smath
+
+APP7TARGET=so$/sweb
+APP7NOSAL=TRUE
+APP7LINKRES=$(MISC)$/$(TARGET)7.res
+APP7ICON=$(SOLARRESDIR)$/icons/so9_writer_app.ico
+APP7OBJS = \
+ $(OBJ)$/launcher.obj\
+ $(OBJ)$/sweb.obj
+APP7STDLIBS = $(SHELL32LIB)
+APP7DEPN=verinfo.rc
+APP7VERINFO=verinfo.rc
+APP7PRODUCTDEF+=-DRES_APP_NAME=sweb
+
+
+.ENDIF # "$(BUILD_SPECIAL)"!=""
+.ENDIF # "$(LINK_SO)"=="TRUE"
+
+# --- Targets ------------------------------------------------------
+
+
+.INCLUDE : target.mk
+
diff --git a/desktop/win32/source/applauncher/ooo/makefile.mk b/desktop/win32/source/applauncher/ooo/makefile.mk
new file mode 100755
index 000000000000..02f240cce9e0
--- /dev/null
+++ b/desktop/win32/source/applauncher/ooo/makefile.mk
@@ -0,0 +1,130 @@
+#*************************************************************************
+#
+# 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=applauncher
+LIBTARGET=NO
+TARGETTYPE=GUI
+UWINAPILIB=
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+APP1TARGET=swriter
+APP1DEPN=verinfo.rc
+APP1VERINFO=verinfo.rc
+APP1NOSAL=TRUE
+APP1LINKRES=$(MISC)$/$(TARGET)1.res
+APP1ICON=$(SOLARRESDIR)$/icons/ooo3_writer_app.ico
+APP1OBJS = \
+ $(OBJ)$/launcher.obj\
+ $(OBJ)$/swriter.obj
+APP1STDLIBS = $(SHELL32LIB)
+APP1PRODUCTDEF+=-DRES_APP_NAME=$(APP1TARGET)
+
+APP2TARGET=scalc
+APP2DEPN=verinfo.rc
+APP2VERINFO=verinfo.rc
+APP2NOSAL=TRUE
+APP2LINKRES=$(MISC)$/$(TARGET)2.res
+APP2ICON=$(SOLARRESDIR)$/icons/ooo3_calc_app.ico
+APP2OBJS = \
+ $(OBJ)$/launcher.obj\
+ $(OBJ)$/scalc.obj
+APP2STDLIBS = $(SHELL32LIB)
+APP2PRODUCTDEF+=-DRES_APP_NAME=$(APP2TARGET)
+
+APP3TARGET=sdraw
+APP3DEPN=verinfo.rc
+APP3VERINFO=verinfo.rc
+APP3NOSAL=TRUE
+APP3LINKRES=$(MISC)$/$(TARGET)3.res
+APP3ICON=$(SOLARRESDIR)$/icons/ooo3_draw_app.ico
+APP3OBJS = \
+ $(OBJ)$/launcher.obj\
+ $(OBJ)$/sdraw.obj
+APP3STDLIBS = $(SHELL32LIB)
+APP3PRODUCTDEF+=-DRES_APP_NAME=$(APP3TARGET)
+
+APP4TARGET=simpress
+APP4DEPN=verinfo.rc
+APP4VERINFO=verinfo.rc
+APP4NOSAL=TRUE
+APP4LINKRES=$(MISC)$/$(TARGET)4.res
+APP4ICON=$(SOLARRESDIR)$/icons/ooo3_impress_app.ico
+APP4OBJS = \
+ $(OBJ)$/launcher.obj\
+ $(OBJ)$/simpress.obj
+APP4STDLIBS = $(SHELL32LIB)
+APP4PRODUCTDEF+=-DRES_APP_NAME=$(APP4TARGET)
+
+APP5TARGET=smath
+APP5DEPN=verinfo.rc
+APP5VERINFO=verinfo.rc
+APP5NOSAL=TRUE
+APP5LINKRES=$(MISC)$/$(TARGET)5.res
+APP5ICON=$(SOLARRESDIR)$/icons/ooo3_math_app.ico
+APP5OBJS = \
+ $(OBJ)$/launcher.obj\
+ $(OBJ)$/smath.obj
+APP5STDLIBS = $(SHELL32LIB)
+APP5PRODUCTDEF+=-DRES_APP_NAME=$(APP5TARGET)
+
+APP6TARGET=sbase
+APP6DEPN=verinfo.rc
+APP6VERINFO=verinfo.rc
+APP6NOSAL=TRUE
+APP6LINKRES=$(MISC)$/$(TARGET)6.res
+APP6ICON=$(SOLARRESDIR)$/icons/ooo3_base_app.ico
+APP6OBJS = \
+ $(OBJ)$/launcher.obj\
+ $(OBJ)$/sbase.obj
+APP6STDLIBS = $(SHELL32LIB)
+APP6PRODUCTDEF+=-DRES_APP_NAME=$(APP6TARGET)
+
+APP7TARGET=sweb
+APP7DEPN=verinfo.rc
+APP7VERINFO=verinfo.rc
+APP7NOSAL=TRUE
+APP7LINKRES=$(MISC)$/$(TARGET)7.res
+APP7ICON=$(SOLARRESDIR)$/icons/ooo3_writer_app.ico
+APP7OBJS = \
+ $(OBJ)$/launcher.obj\
+ $(OBJ)$/sweb.obj
+APP7STDLIBS = $(SHELL32LIB)
+APP7PRODUCTDEF+=-DRES_APP_NAME=$(APP7TARGET)
+
+# --- Targets ------------------------------------------------------
+
+
+.INCLUDE : target.mk
+
diff --git a/desktop/win32/source/applauncher/ooo/verinfo.rc b/desktop/win32/source/applauncher/ooo/verinfo.rc
new file mode 100755
index 000000000000..61e9147a4ab6
--- /dev/null
+++ b/desktop/win32/source/applauncher/ooo/verinfo.rc
@@ -0,0 +1,71 @@
+/*************************************************************************
+ *
+ * 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 VER_FIRSTYEAR 2009
+
+#include <windows.h>
+#include "version.hrc"
+
+// -----------------------------------------------------------------------
+// version information
+// -----------------------------------------------------------------------
+
+VS_VERSION_INFO versioninfo
+ fileversion VERSION, SUBVERSION, VERVARIANT, VER_COUNT
+ productversion VERSION, SUBVERSION, VERVARIANT, VER_COUNT
+ fileflagsmask 0x3F
+ fileflags
+#if defined(DEBUG)
+ VS_FF_DEBUG |
+#endif
+#ifdef VER_PREL
+ VS_FF_PRERELEASE |
+#endif
+ 0
+ fileos VOS_NT_WINDOWS32
+ filetype VFT_APP
+ {
+ block "StringFileInfo"
+ {
+ block "040904E4"
+ {
+ // International StringTable
+ value "CompanyName", "The Document Foundation\0"
+ value "FileDescription", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\0"
+ value "FileVersion", PPS(VER_LEVEL) "\0"
+ value "ProductVersion", PPS(VER_LEVEL) "\0"
+ value "OriginalFilename", PPS(RES_APP_NAME) ".exe\0"
+ value "InternalName", PPS(RES_APP_NAME) "\0"
+ value "LegalCopyright", S_CRIGHT " Oracle and/or its affiliates. All rights reserved.\0"
+ }
+ }
+
+ block "VarFileInfo"
+ {
+ value "Translation", 0x0409, 1252
+ }
+ }
diff --git a/desktop/win32/source/applauncher/sbase.cxx b/desktop/win32/source/applauncher/sbase.cxx
new file mode 100644
index 000000000000..9a1f31d3dce0
--- /dev/null
+++ b/desktop/win32/source/applauncher/sbase.cxx
@@ -0,0 +1,37 @@
+/* -*- 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 "launcher.hxx"
+
+_TCHAR APPLICATION_SWITCH[] = _T( "-base" );
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/win32/source/applauncher/scalc.cxx b/desktop/win32/source/applauncher/scalc.cxx
new file mode 100644
index 000000000000..ceca63e14450
--- /dev/null
+++ b/desktop/win32/source/applauncher/scalc.cxx
@@ -0,0 +1,37 @@
+/* -*- 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 "launcher.hxx"
+
+_TCHAR APPLICATION_SWITCH[] = _T( "-calc" );
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/win32/source/applauncher/sdraw.cxx b/desktop/win32/source/applauncher/sdraw.cxx
new file mode 100644
index 000000000000..034a7c4f949c
--- /dev/null
+++ b/desktop/win32/source/applauncher/sdraw.cxx
@@ -0,0 +1,37 @@
+/* -*- 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 "launcher.hxx"
+
+_TCHAR APPLICATION_SWITCH[] = _T( "-draw" );
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/win32/source/applauncher/simpress.cxx b/desktop/win32/source/applauncher/simpress.cxx
new file mode 100644
index 000000000000..cd01d01b346d
--- /dev/null
+++ b/desktop/win32/source/applauncher/simpress.cxx
@@ -0,0 +1,37 @@
+/* -*- 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 "launcher.hxx"
+
+_TCHAR APPLICATION_SWITCH[] = _T( "-impress" );
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/win32/source/applauncher/smath.cxx b/desktop/win32/source/applauncher/smath.cxx
new file mode 100644
index 000000000000..3e670cd8e692
--- /dev/null
+++ b/desktop/win32/source/applauncher/smath.cxx
@@ -0,0 +1,37 @@
+/* -*- 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 "launcher.hxx"
+
+_TCHAR APPLICATION_SWITCH[] = _T( "-math" );
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/win32/source/applauncher/sweb.cxx b/desktop/win32/source/applauncher/sweb.cxx
new file mode 100644
index 000000000000..1c2fd8eabd6c
--- /dev/null
+++ b/desktop/win32/source/applauncher/sweb.cxx
@@ -0,0 +1,37 @@
+/* -*- 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 "launcher.hxx"
+
+_TCHAR APPLICATION_SWITCH[] = _T( "-web" );
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/win32/source/applauncher/swriter.cxx b/desktop/win32/source/applauncher/swriter.cxx
new file mode 100644
index 000000000000..1909cb97cded
--- /dev/null
+++ b/desktop/win32/source/applauncher/swriter.cxx
@@ -0,0 +1,35 @@
+/* -*- 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 "launcher.hxx"
+
+_TCHAR APPLICATION_SWITCH[] = _T( "-writer" );
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/win32/source/applauncher/verinfo.rc b/desktop/win32/source/applauncher/verinfo.rc
new file mode 100755
index 000000000000..afb58f3a377c
--- /dev/null
+++ b/desktop/win32/source/applauncher/verinfo.rc
@@ -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.
+ *
+ *************************************************************************/
+
+#define VER_FIRSTYEAR 2009
+
+#include <windows.h>
+#include "version_so.hrc"
+
+// -----------------------------------------------------------------------
+// version information
+// -----------------------------------------------------------------------
+
+VS_VERSION_INFO versioninfo
+#ifndef SUBVERSION
+ fileversion VERSION, 0, VERVARIANT, VER_COUNT
+ productversion VERSION, 0, VERVARIANT, VER_COUNT
+#else
+ fileversion VERSION, SUBVERSION, VERVARIANT, VER_COUNT
+ productversion VERSION, SUBVERSION, VERVARIANT, VER_COUNT
+#endif
+ fileflagsmask 0x3F
+ fileflags
+#if defined(DEBUG)
+ VS_FF_DEBUG |
+#endif
+#ifdef VER_PREL
+ VS_FF_PRERELEASE |
+#endif
+ 0
+ fileos VOS_NT_WINDOWS32
+ filetype VFT_APP
+ {
+ block "StringFileInfo"
+ {
+ block "040904E4"
+ {
+ // International StringTable
+ value "CompanyName", "The Document Foundation\0"
+ value "FileDescription", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\0"
+ value "FileVersion", PPS(VER_LEVEL) "\0"
+ value "ProductVersion", PPS(VER_LEVEL) "\0"
+ value "OriginalFilename", PPS(RES_APP_NAME) ".exe\0"
+ value "InternalName", PPS(RES_APP_NAME) "\0"
+ value "LegalCopyright", S_CRIGHT " Oracle and/or its affiliates. All rights reserved.\0"
+ }
+ }
+
+ block "VarFileInfo"
+ {
+ value "Translation", 0x0409, 1252
+ }
+ }
diff --git a/desktop/win32/source/extendloaderenvironment.cxx b/desktop/win32/source/extendloaderenvironment.cxx
new file mode 100644
index 000000000000..ee9de7f6099f
--- /dev/null
+++ b/desktop/win32/source/extendloaderenvironment.cxx
@@ -0,0 +1,185 @@
+/* -*- 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>
+
+#define WIN32_LEAN_AND_MEAN
+#if defined _MSC_VER
+#pragma warning(push, 1)
+#endif
+#include <windows.h>
+#include <shlwapi.h>
+#if defined _MSC_VER
+#pragma warning(pop)
+#endif
+
+#include "tools/pathutils.hxx"
+
+#include "extendloaderenvironment.hxx"
+
+namespace {
+
+void fail() {
+ LPWSTR buf = NULL;
+ FormatMessageW(
+ FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL,
+ GetLastError(), 0, reinterpret_cast< LPWSTR >(&buf), 0, NULL);
+ MessageBoxW(NULL, buf, NULL, MB_OK | MB_ICONERROR);
+ LocalFree(buf);
+ TerminateProcess(GetCurrentProcess(), 255);
+}
+
+bool contains(WCHAR const * paths, WCHAR const * path, WCHAR const * pathEnd) {
+ WCHAR const * q = path;
+ for (WCHAR const * p = paths;; ++p) {
+ WCHAR c = *p;
+ switch (c) {
+ case L'\0':
+ return q == pathEnd;
+ case L';':
+ if (q == pathEnd) {
+ return true;
+ }
+ q = path;
+ break;
+ default:
+ if (q != NULL) {
+ if (q != pathEnd && *q == c) {
+ ++q;
+ } else {
+ q = NULL;
+ }
+ }
+ break;
+ }
+ }
+}
+
+}
+
+namespace desktop_win32 {
+
+void extendLoaderEnvironment(WCHAR * binPath, WCHAR * iniDirectory) {
+ if (!GetModuleFileNameW(NULL, iniDirectory, MAX_PATH)) {
+ fail();
+ }
+ WCHAR * iniDirEnd = tools::filename(iniDirectory);
+ WCHAR name[MAX_PATH + MY_LENGTH(L".bin")];
+ // hopefully std::size_t is large enough to not overflow
+ WCHAR * nameEnd = name;
+ for (WCHAR * p = iniDirEnd; *p != L'\0'; ++p) {
+ *nameEnd++ = *p;
+ }
+ if (!(nameEnd - name >= 4 && nameEnd[-4] == L'.' &&
+ (nameEnd[-3] == L'E' || nameEnd[-3] == L'e') &&
+ (nameEnd[-2] == L'X' || nameEnd[-2] == L'x') &&
+ (nameEnd[-1] == L'E' || nameEnd[-1] == L'e')))
+ {
+ *nameEnd = L'.';
+ nameEnd += 4;
+ }
+ nameEnd[-3] = 'b';
+ nameEnd[-2] = 'i';
+ nameEnd[-1] = 'n';
+ tools::buildPath(binPath, iniDirectory, iniDirEnd, name, nameEnd - name);
+ *iniDirEnd = L'\0';
+ WCHAR path[MAX_PATH];
+ WCHAR * pathEnd = tools::buildPath(
+ path, iniDirectory, iniDirEnd, MY_STRING(L"..\\basis-link"));
+ if (pathEnd == NULL) {
+ fail();
+ }
+ std::size_t const maxEnv = 32767;
+ WCHAR pad[2 * MAX_PATH + maxEnv];
+ // hopefully std::size_t is large enough to not overflow
+ WCHAR * padEnd = NULL;
+ WCHAR env[maxEnv];
+ DWORD n = GetEnvironmentVariableW(L"PATH", env, maxEnv);
+ if (n >= maxEnv || n == 0 && GetLastError() != ERROR_ENVVAR_NOT_FOUND) {
+ fail();
+ }
+ env[n] = L'\0';
+ bool exclude1;
+ pathEnd = tools::resolveLink(path);
+ if (pathEnd == NULL) {
+ if (GetLastError() != ERROR_FILE_NOT_FOUND) {
+ fail();
+ }
+ // This path is only taken by testtool.exe in basis program directory;
+ // its PATH needs to include the brand program directory:
+ pathEnd = tools::buildPath(
+ path, iniDirectory, iniDirEnd, MY_STRING(L".."));
+ if (pathEnd == NULL) {
+ fail();
+ }
+ padEnd = tools::buildPath(
+ pad, path, pathEnd, MY_STRING(L"\\..\\program"));
+ if (padEnd == NULL) {
+ fail();
+ }
+ exclude1 = contains(env, pad, padEnd);
+ } else {
+ exclude1 = true;
+ }
+ WCHAR * pad2 = exclude1 ? pad : padEnd + 1;
+ pathEnd = tools::buildPath(path, path, pathEnd, MY_STRING(L"\\ure-link"));
+ if (pathEnd == NULL) {
+ fail();
+ }
+ pathEnd = tools::resolveLink(path);
+ if (pathEnd == NULL) {
+ fail();
+ }
+ padEnd = tools::buildPath(pad2, path, pathEnd, MY_STRING(L"\\bin"));
+ if (padEnd == NULL) {
+ fail();
+ }
+ bool exclude2 = contains(env, pad2, padEnd);
+ if (!(exclude1 && exclude2)) {
+ if (!(exclude1 || exclude2)) {
+ pad2[-1] = L';';
+ }
+ WCHAR * p = exclude2 ? pad2 - 1 : padEnd;
+ if (n != 0) {
+ *p++ = L';';
+ }
+ for (DWORD i = 0; i <= n; ++i) {
+ *p++ = env[i];
+ }
+ if (!SetEnvironmentVariableW(L"PATH", pad)) {
+ fail();
+ }
+ }
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/win32/source/extendloaderenvironment.hxx b/desktop/win32/source/extendloaderenvironment.hxx
new file mode 100644
index 000000000000..ace91b1a913d
--- /dev/null
+++ b/desktop/win32/source/extendloaderenvironment.hxx
@@ -0,0 +1,96 @@
+/* -*- 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_WIN32_SOURCE_EXTENDLOADERENVIRONMENT_HXX
+#define INCLUDED_DESKTOP_WIN32_SOURCE_EXTENDLOADERENVIRONMENT_HXX
+
+#include "sal/config.h"
+
+#include <cstddef>
+
+#include <tchar.h>
+
+#define MY_LENGTH(s) (sizeof (s) / sizeof *(s) - 1)
+#define MY_STRING(s) (s), MY_LENGTH(s)
+
+namespace desktop_win32 {
+
+inline WCHAR * commandLineAppend(
+ WCHAR * buffer, WCHAR const * text, std::size_t length)
+{
+ wcsncpy(buffer, text, length + 1); // trailing null
+ return buffer + length;
+}
+
+inline WCHAR * commandLineAppend(WCHAR * buffer, WCHAR const * text) {
+ return commandLineAppend(buffer, text, wcslen(text));
+}
+
+inline WCHAR * commandLineAppendEncoded(WCHAR * buffer, WCHAR const * text) {
+ std::size_t n = 0;
+ for (;;) {
+ WCHAR c = *text++;
+ if (c == L'\0') {
+ break;
+ } else if (c == L'$') {
+ buffer = commandLineAppend(buffer, MY_STRING(L"\\$"));
+ n = 0;
+ } else if (c == L'\\') {
+ buffer = commandLineAppend(buffer, MY_STRING(L"\\\\"));
+ n += 2;
+ } else {
+ *buffer++ = c;
+ n = 0;
+ }
+ }
+ // The command line will continue with a double quote, so double any
+ // preceding backslashes as required by Windows:
+ for (std::size_t i = 0; i < n; ++i) {
+ *buffer++ = L'\\';
+ }
+ *buffer = L'\0';
+ return buffer;
+}
+
+// Set the PATH environment variable in the current (loader) process, so that a
+// following CreateProcess has the necessary environment:
+// @param binPath
+// Must point to an array of size at least MAX_PATH. Is filled with the null
+// terminated full path to the "bin" file corresponding to the current
+// executable.
+// @param iniDirectory
+// Must point to an array of size at least MAX_PATH. Is filled with the null
+// terminated full directory path (ending in "\") to the "ini" file
+// corresponding to the current executable.
+void extendLoaderEnvironment(WCHAR * binPath, WCHAR * iniDirectory);
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/win32/source/guiloader/genericloader.cxx b/desktop/win32/source/guiloader/genericloader.cxx
new file mode 100644
index 000000000000..1d2075a65bc8
--- /dev/null
+++ b/desktop/win32/source/guiloader/genericloader.cxx
@@ -0,0 +1,178 @@
+/* -*- 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 UNICODE
+#define _UNICODE
+
+#define WIN32_LEAN_AND_MEAN
+#if defined _MSC_VER
+#pragma warning(push, 1)
+#endif
+#include <windows.h>
+#include <shellapi.h>
+#if defined _MSC_VER
+#pragma warning(pop)
+#endif
+
+#include <tchar.h>
+
+#include <malloc.h>
+#include <string.h>
+#include <stdlib.h>
+#include <systools/win32/uwinapi.h>
+
+#include "tools/pathutils.hxx"
+#include "../extendloaderenvironment.hxx"
+
+//---------------------------------------------------------------------------
+
+static int GenericMain()
+{
+ TCHAR szTargetFileName[MAX_PATH];
+ TCHAR szIniDirectory[MAX_PATH];
+ STARTUPINFO aStartupInfo;
+
+ desktop_win32::extendLoaderEnvironment(szTargetFileName, szIniDirectory);
+
+ ZeroMemory( &aStartupInfo, sizeof(aStartupInfo) );
+ aStartupInfo.cb = sizeof(aStartupInfo);
+
+ GetStartupInfo( &aStartupInfo );
+
+ DWORD dwExitCode = (DWORD)-1;
+
+ PROCESS_INFORMATION aProcessInfo;
+
+ size_t iniDirLen = wcslen(szIniDirectory);
+ WCHAR cwd[MAX_PATH];
+ DWORD cwdLen = GetCurrentDirectoryW(MAX_PATH, cwd);
+ if (cwdLen >= MAX_PATH) {
+ cwdLen = 0;
+ }
+ WCHAR redirect[MAX_PATH];
+ DWORD dummy;
+ bool hasRedirect =
+ tools::buildPath(
+ redirect, szIniDirectory, szIniDirectory + iniDirLen,
+ MY_STRING(L"redirect.ini")) != NULL &&
+ (GetBinaryType(redirect, &dummy) || // cheaper check for file existence?
+ GetLastError() != ERROR_FILE_NOT_FOUND);
+ LPTSTR cl1 = GetCommandLine();
+ WCHAR * cl2 = new WCHAR[
+ wcslen(cl1) +
+ (hasRedirect
+ ? (MY_LENGTH(L" \"-env:INIFILENAME=vnd.sun.star.pathname:") +
+ iniDirLen + MY_LENGTH(L"redirect.ini\""))
+ : 0) +
+ MY_LENGTH(L" \"-env:OOO_CWD=2") + 4 * cwdLen + MY_LENGTH(L"\"") + 1];
+ // 4 * cwdLen: each char preceded by backslash, each trailing backslash
+ // doubled
+ WCHAR * p = desktop_win32::commandLineAppend(cl2, cl1);
+ if (hasRedirect) {
+ p = desktop_win32::commandLineAppend(
+ p, MY_STRING(L" \"-env:INIFILENAME=vnd.sun.star.pathname:"));
+ p = desktop_win32::commandLineAppend(p, szIniDirectory);
+ p = desktop_win32::commandLineAppend(p, MY_STRING(L"redirect.ini\""));
+ }
+ p = desktop_win32::commandLineAppend(p, MY_STRING(L" \"-env:OOO_CWD="));
+ if (cwdLen == 0) {
+ p = desktop_win32::commandLineAppend(p, MY_STRING(L"0"));
+ } else {
+ p = desktop_win32::commandLineAppend(p, MY_STRING(L"2"));
+ p = desktop_win32::commandLineAppendEncoded(p, cwd);
+ }
+ desktop_win32::commandLineAppend(p, MY_STRING(L"\""));
+
+ BOOL fSuccess = CreateProcess(
+ szTargetFileName,
+ cl2,
+ NULL,
+ NULL,
+ TRUE,
+ 0,
+ NULL,
+ szIniDirectory,
+ &aStartupInfo,
+ &aProcessInfo );
+
+ delete[] cl2;
+
+ if ( fSuccess )
+ {
+ DWORD dwWaitResult;
+
+ do
+ {
+ // On Windows XP it seems as the desktop calls WaitForInputIdle after "OpenWidth" so we have to do so
+ // as if we where processing any messages
+
+ dwWaitResult = MsgWaitForMultipleObjects( 1, &aProcessInfo.hProcess, FALSE, INFINITE, QS_ALLEVENTS );
+
+ if ( WAIT_OBJECT_0 + 1 == dwWaitResult )
+ {
+ MSG msg;
+
+ PeekMessage( &msg, NULL, 0, 0, PM_REMOVE );
+ }
+ } while ( WAIT_OBJECT_0 + 1 == dwWaitResult );
+
+ dwExitCode = 0;
+ GetExitCodeProcess( aProcessInfo.hProcess, &dwExitCode );
+
+ CloseHandle( aProcessInfo.hProcess );
+ CloseHandle( aProcessInfo.hThread );
+ }
+
+ return dwExitCode;
+}
+
+//---------------------------------------------------------------------------
+
+#ifdef __MINGW32__
+int WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, int )
+#else
+int WINAPI _tWinMain( HINSTANCE, HINSTANCE, LPTSTR, int )
+#endif
+{
+ return GenericMain();
+}
+
+//---------------------------------------------------------------------------
+
+#ifdef __MINGW32__
+int __cdecl main()
+#else
+int __cdecl _tmain()
+#endif
+{
+ return GenericMain();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/win32/source/guiloader/makefile.mk b/desktop/win32/source/guiloader/makefile.mk
new file mode 100755
index 000000000000..7912471fba13
--- /dev/null
+++ b/desktop/win32/source/guiloader/makefile.mk
@@ -0,0 +1,66 @@
+#*************************************************************************
+#
+# 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=guiloader
+LIBTARGET=NO
+TARGETTYPE=GUI
+UWINAPILIB=
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+APP1TARGET=guiloader
+APP1NOSAL=TRUE
+APP1ICON=$(SOLARRESDIR)$/icons/ooo-main-app.ico
+APP1OBJS=\
+ $(OBJ)$/extendloaderenvironment.obj \
+ $(OBJ)$/genericloader.obj \
+ $(SOLARLIBDIR)$/pathutils-obj.obj
+STDLIB1=$(SHLWAPILIB)
+
+.IF "$(LINK_SO)"=="TRUE"
+APP2TARGET=so$/guiloader
+APP2NOSAL=TRUE
+APP2ICON=$(SOLARRESDIR)$/icons/so9_main_app.ico
+APP2OBJS=\
+ $(OBJ)$/extendloaderenvironment.obj \
+ $(OBJ)$/genericloader.obj \
+ $(SOLARLIBDIR)$/pathutils-obj.obj
+STDLIB2=$(SHLWAPILIB)
+.ENDIF # "$(LINK_SO)"=="TRUE"
+
+# --- Targets ------------------------------------------------------
+
+
+.INCLUDE : target.mk
+
diff --git a/desktop/win32/source/guistdio/guistdio.cxx b/desktop/win32/source/guistdio/guistdio.cxx
new file mode 100644
index 000000000000..1c12089818f0
--- /dev/null
+++ b/desktop/win32/source/guistdio/guistdio.cxx
@@ -0,0 +1,33 @@
+/* -*- 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 "guistdio.inc"
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/win32/source/guistdio/guistdio.inc b/desktop/win32/source/guistdio/guistdio.inc
new file mode 100755
index 000000000000..05d462d23197
--- /dev/null
+++ b/desktop/win32/source/guistdio/guistdio.inc
@@ -0,0 +1,454 @@
+/*************************************************************************
+ *
+ * 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 UNICODE
+#define WIN32_LEAN_AND_MEAN
+#ifdef _MSC_VER
+#pragma warning(push,1) // disable warnings within system headers
+#endif
+#include <windows.h>
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#define _UNICODE
+#include <tchar.h>
+
+#include <string.h>
+#include <stdlib.h>
+#include <systools/win32/uwinapi.h>
+
+#include <stdio.h>
+#include <sal/macros.h>
+
+#ifdef UNOPKG
+
+DWORD passOutputToConsole(HANDLE readPipe, HANDLE console)
+{
+ BYTE aBuffer[1024];
+ DWORD dwRead = 0;
+ HANDLE hReadPipe = readPipe;
+ BOOL fSuccess;
+ DWORD dwWritten;
+
+ //Indicates that we read an odd number of bytes. That is, we only read half of the last
+ //wchar_t
+ bool bIncompleteWchar = false;
+ //fprintf, fwprintf will both send char data without the terminating zero.
+ //fwprintf converts the unicode string first.
+ //We expect here to receive unicode without the terminating zero.
+ //unopkg and the extension manager code MUST
+ //use dp_misc::writeConsole instead of using fprintf, etc.
+
+ DWORD dwToRead = sizeof(aBuffer);
+ BYTE * pBuffer = aBuffer;
+ while ( ReadFile( hReadPipe, pBuffer, dwToRead, &dwRead, NULL ) )
+ {
+ //If the previous ReadFile call read an odd number of bytes, then the last one was
+ //put at the front of the buffer. We increase the number of read bytes by one to reflect
+ //that one byte.
+ if (bIncompleteWchar)
+ dwRead++;
+ //We must make sure that only complete wchar_t|s are written. WriteConsolse takes
+ //the number of wchar_t|s as argument. ReadFile, however, reads bytes.
+ bIncompleteWchar = dwRead % 2 ? true : false;
+ if (bIncompleteWchar)
+ {
+ //To test this case, give aBuffer a small odd size, e.g. aBuffer[3]
+ //The last byte, which is the incomplete wchar_t (half of it), will not be written.
+ fSuccess = WriteConsoleW( console, aBuffer,
+ (dwRead - 1) / 2, &dwWritten, NULL );
+
+ //Move the last byte to the front of the buffer, so that it is the start of the
+ //next string
+ aBuffer[0] = aBuffer[dwRead - 1];
+
+ //Make sure that ReadFile does not overwrite the first byte the next time
+ dwToRead = sizeof(aBuffer) - 1;
+ pBuffer = aBuffer + 1;
+
+ }
+ else
+ { //We have read an even number of bytes. Therefore, we do not put the last incomplete
+ //wchar_t at the front of the buffer. We will use the complete buffer the next time
+ //when ReadFile is called.
+ dwToRead = sizeof(aBuffer);
+ pBuffer = aBuffer;
+ fSuccess = WriteConsoleW( console,
+ aBuffer, dwRead / 2, &dwWritten, NULL );
+ }
+ }
+
+ return 0;
+}
+
+#endif
+
+#ifdef UNOPKG
+DWORD WINAPI OutputThread( LPVOID pParam )
+{
+ return passOutputToConsole((HANDLE)pParam, GetStdHandle( STD_OUTPUT_HANDLE ));
+}
+
+#else
+DWORD WINAPI OutputThread( LPVOID pParam )
+{
+ BYTE aBuffer[256];
+ DWORD dwRead = 0;
+ HANDLE hReadPipe = (HANDLE)pParam;
+ while ( ReadFile( hReadPipe, &aBuffer, sizeof(aBuffer), &dwRead, NULL ) )
+ {
+ BOOL fSuccess;
+ DWORD dwWritten;
+
+ fSuccess = WriteFile( GetStdHandle( STD_OUTPUT_HANDLE ), aBuffer, dwRead, &dwWritten, NULL );
+ }
+
+ return 0;
+}
+#endif
+//---------------------------------------------------------------------------
+// Thread that reads from child process standard error pipe
+//---------------------------------------------------------------------------
+
+#ifdef UNOPKG
+DWORD WINAPI ErrorThread( LPVOID pParam )
+{
+ return passOutputToConsole((HANDLE)pParam, GetStdHandle( STD_ERROR_HANDLE ));
+}
+
+#else
+DWORD WINAPI ErrorThread( LPVOID pParam )
+{
+ BYTE aBuffer[256];
+ DWORD dwRead = 0;
+ HANDLE hReadPipe = (HANDLE)pParam;
+
+ while ( ReadFile( hReadPipe, &aBuffer, sizeof(aBuffer), &dwRead, NULL ) )
+ {
+ BOOL fSuccess;
+ DWORD dwWritten;
+
+ fSuccess = WriteFile( GetStdHandle( STD_ERROR_HANDLE ), aBuffer, dwRead, &dwWritten, NULL );
+ }
+
+ return 0;
+}
+#endif
+//---------------------------------------------------------------------------
+// Thread that writes to child process standard input pipe
+//---------------------------------------------------------------------------
+#ifdef UNOPKG
+
+DWORD WINAPI InputThread( LPVOID pParam )
+{
+ DWORD dwRead = 0;
+ HANDLE hWritePipe = (HANDLE)pParam;
+
+ //We need to read in the complete input until we encounter a new line before
+ //converting to Unicode. This is necessary because the input string can use
+ //characters of one, two, and more bytes. If the last character is not
+ //complete, then it will not be converted properly.
+
+ //Find out how a new line (0xd 0xa) looks like with the used code page.
+ //Characters may have one or multiple bytes and different byte ordering
+ //can be used (little and big endian);
+ int cNewLine = WideCharToMultiByte(
+ GetConsoleCP(), 0, L"\r\n", 2, NULL, 0, NULL, NULL);
+ char * mbBuff = new char[cNewLine];
+ WideCharToMultiByte(
+ GetConsoleCP(), 0, L"\r\n", 2, mbBuff, cNewLine, NULL, NULL);
+
+ const size_t dwBufferSize = 256;
+ char* readBuf = (char*) malloc(dwBufferSize);
+ int readAll = 0;
+ size_t curBufSize = dwBufferSize;
+
+ while ( ReadFile( GetStdHandle( STD_INPUT_HANDLE ),
+ readBuf + readAll,
+ curBufSize - readAll, &dwRead, NULL ) )
+ {
+ readAll += dwRead;
+ int lastBufSize = curBufSize;
+ //Grow the buffer if necessary
+ if (readAll > curBufSize * 0.7)
+ {
+ curBufSize *= 2;
+ readBuf = (char *) realloc(readBuf, curBufSize);
+ }
+
+ //If the buffer was filled completely then
+ //there could be more input coming. But if we read from the console
+ //and the console input fits exactly in the buffer, then the next
+ //ReadFile would block until the users presses return, etc.
+ //Therefor we check if last character is a new line.
+ //To test this, set dwBufferSize to 4 and enter "no". This should produce
+ //4 bytes with most code pages.
+ if ( readAll == lastBufSize
+ && memcmp(readBuf + lastBufSize - cNewLine, mbBuff, cNewLine) != 0)
+ {
+ //The buffer was completely filled and the last byte(s) are no
+ //new line, so there is more to come.
+ continue;
+ }
+ //Obtain the size of the buffer for the converted string.
+ int sizeWBuf = MultiByteToWideChar(
+ GetConsoleCP(), MB_PRECOMPOSED, readBuf, readAll, NULL, 0);
+
+ wchar_t * wideBuf = new wchar_t[sizeWBuf];
+
+ //Do the conversion.
+ MultiByteToWideChar(
+ GetConsoleCP(), MB_PRECOMPOSED, readBuf, readAll, wideBuf, sizeWBuf);
+
+ BOOL fSuccess;
+ DWORD dwWritten;
+ fSuccess = WriteFile( hWritePipe, wideBuf, sizeWBuf * 2, &dwWritten, NULL );
+ delete[] wideBuf;
+ readAll = 0;
+ }
+ delete[] mbBuff;
+ free(readBuf);
+ return 0;
+}
+#else
+DWORD WINAPI InputThread( LPVOID pParam )
+{
+ BYTE aBuffer[256];
+ DWORD dwRead = 0;
+ HANDLE hWritePipe = (HANDLE)pParam;
+
+ while ( ReadFile( GetStdHandle( STD_INPUT_HANDLE ), &aBuffer, sizeof(aBuffer), &dwRead, NULL ) )
+ {
+ BOOL fSuccess;
+ DWORD dwWritten;
+
+ fSuccess = WriteFile( hWritePipe, aBuffer, dwRead, &dwWritten, NULL );
+ }
+
+ return 0;
+}
+#endif
+
+//---------------------------------------------------------------------------
+// Thread that waits until child process reached input idle
+//---------------------------------------------------------------------------
+
+DWORD WINAPI WaitForUIThread( LPVOID pParam )
+{
+ HANDLE hProcess = (HANDLE)pParam;
+
+#ifndef UNOPKG
+ if ( !_tgetenv( TEXT("UNOPKG") ) )
+ WaitForInputIdle( hProcess, INFINITE );
+#endif
+
+ return 0;
+}
+
+
+//---------------------------------------------------------------------------
+// Ctrl-Break handler that terminates the child process if Ctrl-C was pressed
+//---------------------------------------------------------------------------
+
+HANDLE hTargetProcess = INVALID_HANDLE_VALUE;
+
+BOOL WINAPI CtrlBreakHandler(
+ DWORD // control signal type
+)
+{
+ TerminateProcess( hTargetProcess, 255 );
+ return TRUE;
+}
+
+
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+
+#ifdef __MINGW32__
+int main( int, char ** )
+#else
+int _tmain( int, _TCHAR ** )
+#endif
+{
+ TCHAR szTargetFileName[MAX_PATH] = TEXT("");
+ STARTUPINFO aStartupInfo;
+ PROCESS_INFORMATION aProcessInfo;
+
+ ZeroMemory( &aStartupInfo, sizeof(aStartupInfo) );
+ aStartupInfo.cb = sizeof(aStartupInfo);
+ aStartupInfo.dwFlags = STARTF_USESTDHANDLES;
+
+ // Create an output pipe where the write end is inheritable
+
+ HANDLE hOutputRead, hOutputWrite;
+
+ if ( CreatePipe( &hOutputRead, &hOutputWrite, NULL, 0 ) )
+ {
+ HANDLE hTemp;
+
+ DuplicateHandle( GetCurrentProcess(), hOutputWrite, GetCurrentProcess(), &hTemp, 0, TRUE, DUPLICATE_SAME_ACCESS );
+ CloseHandle( hOutputWrite );
+ hOutputWrite = hTemp;
+
+ aStartupInfo.hStdOutput = hOutputWrite;
+ }
+
+ // Create an error pipe where the write end is inheritable
+
+ HANDLE hErrorRead, hErrorWrite;
+
+ if ( CreatePipe( &hErrorRead, &hErrorWrite, NULL, 0 ) )
+ {
+ HANDLE hTemp;
+
+ DuplicateHandle( GetCurrentProcess(), hErrorWrite, GetCurrentProcess(), &hTemp, 0, TRUE, DUPLICATE_SAME_ACCESS );
+ CloseHandle( hErrorWrite );
+ hErrorWrite = hTemp;
+
+ aStartupInfo.hStdError = hErrorWrite;
+ }
+
+ // Create an input pipe where the read end is inheritable
+
+ HANDLE hInputRead, hInputWrite;
+
+ if ( CreatePipe( &hInputRead, &hInputWrite, NULL, 0 ) )
+ {
+ HANDLE hTemp;
+
+ DuplicateHandle( GetCurrentProcess(), hInputRead, GetCurrentProcess(), &hTemp, 0, TRUE, DUPLICATE_SAME_ACCESS );
+ CloseHandle( hInputRead );
+ hInputRead = hTemp;
+
+ aStartupInfo.hStdInput = hInputRead;
+ }
+
+ // Get image path with same name but with .exe extension
+
+ TCHAR szModuleFileName[MAX_PATH];
+
+ GetModuleFileName( NULL, szModuleFileName, MAX_PATH );
+ _TCHAR *lpLastDot = _tcsrchr( szModuleFileName, '.' );
+ if ( lpLastDot && 0 == _tcsicmp( lpLastDot, _T(".COM") ) )
+ {
+ size_t len = lpLastDot - szModuleFileName;
+ _tcsncpy( szTargetFileName, szModuleFileName, len );
+ _tcsncpy( szTargetFileName + len, _T(".EXE"), SAL_N_ELEMENTS(szTargetFileName) - len );
+ }
+
+ // Create process with same command line, environment and stdio handles which
+ // are directed to the created pipes
+
+ BOOL fSuccess = CreateProcess(
+ szTargetFileName,
+ GetCommandLine(),
+ NULL,
+ NULL,
+ TRUE,
+ 0,
+ NULL,
+ NULL,
+ &aStartupInfo,
+ &aProcessInfo );
+
+ if ( fSuccess )
+ {
+ // These pipe ends are inherited by the child process and no longer used
+ CloseHandle( hOutputWrite );
+ CloseHandle( hErrorWrite );
+ CloseHandle( hInputRead );
+
+ // Set the Ctrl-Break handler
+ hTargetProcess = aProcessInfo.hProcess;
+ SetConsoleCtrlHandler( CtrlBreakHandler, TRUE );
+
+ // Create threads that redirect remote pipe io to current process's console stdio
+
+ DWORD dwOutputThreadId, dwErrorThreadId, dwInputThreadId;
+
+ HANDLE hOutputThread = CreateThread( NULL, 0, OutputThread, (LPVOID)hOutputRead, 0, &dwOutputThreadId );
+ HANDLE hErrorThread = CreateThread( NULL, 0, OutputThread, (LPVOID)hErrorRead, 0, &dwErrorThreadId );
+ HANDLE hInputThread = CreateThread( NULL, 0, InputThread, (LPVOID)hInputWrite, 0, &dwInputThreadId );
+
+ // Create thread that wait until child process entered input idle
+
+ DWORD dwWaitForUIThreadId;
+ HANDLE hWaitForUIThread = CreateThread( NULL, 0, WaitForUIThread, (LPVOID)aProcessInfo.hProcess, 0, &dwWaitForUIThreadId );
+
+ DWORD dwWaitResult;
+ HANDLE hObjects[] =
+ {
+ hTargetProcess,
+ hWaitForUIThread,
+ hOutputThread,
+ hErrorThread
+ };
+
+ #ifdef UNOPKG
+ dwWaitResult = WaitForMultipleObjects( SAL_N_ELEMENTS(hObjects), hObjects, TRUE, INFINITE );
+ #else
+ bool bDetach = false;
+ int nOpenPipes = 2;
+ do
+ {
+ dwWaitResult = WaitForMultipleObjects( SAL_N_ELEMENTS(hObjects), hObjects, FALSE, INFINITE );
+
+ switch ( dwWaitResult )
+ {
+ case WAIT_OBJECT_0: // The child process has terminated
+ case WAIT_OBJECT_0 + 1: // The child process entered input idle
+ bDetach = true;
+ break;
+ case WAIT_OBJECT_0 + 2: // The remote end of stdout pipe was closed
+ case WAIT_OBJECT_0 + 3: // The remote end of stderr pipe was closed
+ bDetach = --nOpenPipes <= 0;
+ break;
+ default: // Something went wrong
+ bDetach = true;
+ break;
+ }
+ } while( !bDetach );
+
+#endif
+
+ CloseHandle( hOutputThread );
+ CloseHandle( hErrorThread );
+ CloseHandle( hInputThread );
+ CloseHandle( hWaitForUIThread );
+
+ DWORD dwExitCode = 0;
+ GetExitCodeProcess( aProcessInfo.hProcess, &dwExitCode );
+ CloseHandle( aProcessInfo.hProcess );
+ CloseHandle( aProcessInfo.hThread );
+
+ return dwExitCode;
+ }
+
+ return -1;
+}
diff --git a/desktop/win32/source/guistdio/makefile.mk b/desktop/win32/source/guistdio/makefile.mk
new file mode 100755
index 000000000000..660a48bcdca9
--- /dev/null
+++ b/desktop/win32/source/guistdio/makefile.mk
@@ -0,0 +1,58 @@
+#*************************************************************************
+#
+# 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=guistdio
+LIBTARGET=NO
+ENABLE_EXCEPTIONS=TRUE
+TARGETTYPE=CUI
+UWINAPILIB=
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+CFLAGS+= $(LFS_CFLAGS)
+CXXFLAGS+= $(LFS_CFLAGS)
+
+# --- Files --------------------------------------------------------
+
+OBJFILES=$(APP1OBJS) $(APP2OBJS)
+
+APP1NOSAL=TRUE
+APP1OBJS=$(OBJ)$/guistdio.obj
+APP1TARGET=$(TARGET)
+
+APP2NOSAL=TRUE
+APP2OBJS=$(OBJ)$/unopkgio.obj
+APP2TARGET=unopkgio
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/desktop/win32/source/guistdio/unopkgio.cxx b/desktop/win32/source/guistdio/unopkgio.cxx
new file mode 100644
index 000000000000..8790cedfe98f
--- /dev/null
+++ b/desktop/win32/source/guistdio/unopkgio.cxx
@@ -0,0 +1,34 @@
+/* -*- 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"
+
+#define UNOPKG
+#include "guistdio.inc"
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/win32/source/lwrapa.cxx b/desktop/win32/source/lwrapa.cxx
new file mode 100644
index 000000000000..eba3059da517
--- /dev/null
+++ b/desktop/win32/source/lwrapa.cxx
@@ -0,0 +1,35 @@
+/* -*- 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 LOCAL
+#include "wrapper.h"
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/win32/source/lwrapw.cxx b/desktop/win32/source/lwrapw.cxx
new file mode 100644
index 000000000000..90a8b5d88f55
--- /dev/null
+++ b/desktop/win32/source/lwrapw.cxx
@@ -0,0 +1,36 @@
+/* -*- 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 LOCAL
+#define UNICODE
+#include "wrapper.h"
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/win32/source/main.h b/desktop/win32/source/main.h
new file mode 100755
index 000000000000..9e3039da1884
--- /dev/null
+++ b/desktop/win32/source/main.h
@@ -0,0 +1,15 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int MainA();
+int MainW();
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/win32/source/makefile.mk b/desktop/win32/source/makefile.mk
new file mode 100755
index 000000000000..564ba319eb56
--- /dev/null
+++ b/desktop/win32/source/makefile.mk
@@ -0,0 +1,63 @@
+#*************************************************************************
+#
+# 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=sowrap
+LIBTARGET=NO
+AUTOSEG=true
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+UWINAPILIB =
+
+# --- Files --------------------------------------------------------
+
+OBJFILES = \
+ $(OBJ)$/wrappera.obj \
+ $(OBJ)$/wrapperw.obj \
+ $(OBJ)$/lwrapa.obj \
+ $(OBJ)$/lwrapw.obj \
+ $(OBJ)$/rwrapa.obj \
+ $(OBJ)$/rwrapw.obj \
+ $(OBJ)$/sowrapper.obj \
+ $(OBJ)$/extendloaderenvironment.obj \
+ $(OBJ)$/unoinfo.obj
+
+APP1TARGET = unoinfo
+APP1OBJS = $(OBJ)$/unoinfo.obj $(SOLARLIBDIR)$/pathutils-obj.obj
+APP1STDLIBS =
+APP1RPATH = BRAND
+
+# --- Targets ------------------------------------------------------
+
+
+.INCLUDE : target.mk
+
diff --git a/desktop/win32/source/officeloader/makefile.mk b/desktop/win32/source/officeloader/makefile.mk
new file mode 100755
index 000000000000..5609dea25085
--- /dev/null
+++ b/desktop/win32/source/officeloader/makefile.mk
@@ -0,0 +1,45 @@
+#*************************************************************************
+#
+# 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=officeloader
+LIBTARGET=NO
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+OBJFILES = \
+ $(OBJ)$/officeloader.obj
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/desktop/win32/source/officeloader/officeloader.cxx b/desktop/win32/source/officeloader/officeloader.cxx
new file mode 100644
index 000000000000..7a08d7ee64c7
--- /dev/null
+++ b/desktop/win32/source/officeloader/officeloader.cxx
@@ -0,0 +1,430 @@
+/* -*- 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 UNICODE
+#define _UNICODE
+
+#include <cstddef>
+
+#define WIN32_LEAN_AND_MEAN
+#if defined _MSC_VER
+#pragma warning(push, 1)
+#endif
+#include <windows.h>
+#include <shellapi.h>
+#if defined _MSC_VER
+#pragma warning(pop)
+#endif
+
+#include <tchar.h>
+
+#include <malloc.h>
+#include <string.h>
+#include <stdlib.h>
+#include <systools/win32/uwinapi.h>
+
+#include "rtl/string.h"
+#include <sal/macros.h>
+
+#include "../../../source/inc/exithelper.hxx"
+#include "../extendloaderenvironment.hxx"
+
+#define PIPE_PREFIX TEXT("\\\\.\\pipe\\OSL_PIPE_")
+#define PIPE_POSTFIX TEXT("_SingleOfficeIPC_")
+#define PIPE_TERMINATION_SEQUENCE "InternalIPC::ProcessingDone"
+
+BOOL WINAPI ConvertSidToStringSid( PSID pSid, LPTSTR* StringSid )
+{
+ PSID_IDENTIFIER_AUTHORITY psia;
+ DWORD dwSubAuthorities;
+ DWORD dwSidRev=SID_REVISION;
+ DWORD dwCounter;
+ DWORD dwSidSize;
+
+ // Validate the binary SID.
+
+ if(!IsValidSid(pSid)) return FALSE;
+
+ // Get the identifier authority value from the SID.
+
+ psia = GetSidIdentifierAuthority(pSid);
+
+ // Get the number of subauthorities in the SID.
+
+ dwSubAuthorities = *GetSidSubAuthorityCount(pSid);
+
+ // Compute the buffer length.
+ // S-SID_REVISION- + IdentifierAuthority- + subauthorities- + NULL
+
+ dwSidSize=(15 + 12 + (12 * dwSubAuthorities) + 1) * sizeof(TCHAR);
+
+ *StringSid = (LPTSTR)LocalAlloc( LMEM_FIXED, dwSidSize );
+
+ // Add 'S' prefix and revision number to the string.
+
+ dwSidSize=wsprintf(*StringSid, TEXT("S-%lu-"), dwSidRev );
+
+ // Add a SID identifier authority to the string.
+
+ if ( (psia->Value[0] != 0) || (psia->Value[1] != 0) )
+ {
+ dwSidSize+=wsprintf(*StringSid + lstrlen(*StringSid),
+ TEXT("0x%02hx%02hx%02hx%02hx%02hx%02hx"),
+ (USHORT)psia->Value[0],
+ (USHORT)psia->Value[1],
+ (USHORT)psia->Value[2],
+ (USHORT)psia->Value[3],
+ (USHORT)psia->Value[4],
+ (USHORT)psia->Value[5]);
+ }
+ else
+ {
+ dwSidSize+=wsprintf(*StringSid + lstrlen(*StringSid),
+ TEXT("%lu"),
+ (ULONG)(psia->Value[5] ) +
+ (ULONG)(psia->Value[4] << 8) +
+ (ULONG)(psia->Value[3] << 16) +
+ (ULONG)(psia->Value[2] << 24) );
+ }
+
+ // Add SID subauthorities to the string.
+ for (dwCounter=0 ; dwCounter < dwSubAuthorities ; dwCounter++)
+ {
+ dwSidSize+=wsprintf(*StringSid + dwSidSize, TEXT("-%lu"),
+ *GetSidSubAuthority(pSid, dwCounter) );
+ }
+
+ return TRUE;
+}
+
+
+//---------------------------------------------------------------------------
+
+static LPTSTR *GetCommandArgs( int *pArgc )
+{
+#ifdef UNICODE
+ return CommandLineToArgvW( GetCommandLineW(), pArgc );
+#else
+ *pArgc = __argc;
+ return __argv;
+#endif
+}
+
+//---------------------------------------------------------------------------
+
+namespace {
+
+bool writeArgument(HANDLE pipe, char prefix, WCHAR const * argument) {
+ CHAR szBuffer[4096];
+ int n = WideCharToMultiByte(
+ CP_UTF8, 0, argument, -1, szBuffer, sizeof (szBuffer), NULL, NULL);
+ char b[1 + 2 * ((sizeof szBuffer) - 1)]; // hopefully does not overflow
+ b[0] = prefix;
+ char * p = b + 1;
+ for (int i = 0; i < n - 1; ++i) { // cannot underflow (n >= 0)
+ char c = szBuffer[i];
+ switch (c) {
+ case '\0':
+ *p++ = '\\';
+ *p++ = '0';
+ break;
+ case ',':
+ *p++ = '\\';
+ *p++ = ',';
+ break;
+ case '\\':
+ *p++ = '\\';
+ *p++ = '\\';
+ break;
+ default:
+ *p++ = c;
+ break;
+ }
+ }
+ DWORD w;
+ return WriteFile(pipe, b, p - b, &w, NULL);
+}
+
+}
+
+#ifdef __MINGW32__
+int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE, LPSTR, int )
+#else
+int WINAPI _tWinMain( HINSTANCE, HINSTANCE, LPTSTR, int )
+#endif
+{
+ TCHAR szTargetFileName[MAX_PATH] = TEXT("");
+ TCHAR szIniDirectory[MAX_PATH];
+ TCHAR szPerfTuneIniFile[MAX_PATH] = TEXT("");
+ STARTUPINFO aStartupInfo;
+
+ desktop_win32::extendLoaderEnvironment(szTargetFileName, szIniDirectory);
+
+ ZeroMemory( &aStartupInfo, sizeof(aStartupInfo) );
+ aStartupInfo.cb = sizeof(aStartupInfo);
+
+ GetStartupInfo( &aStartupInfo );
+ // Get image path with same name but with .bin extension
+
+ TCHAR szModuleFileName[MAX_PATH];
+
+ GetModuleFileName( NULL, szModuleFileName, MAX_PATH );
+ _TCHAR *lpLastSlash = _tcsrchr( szModuleFileName, '\\' );
+ if ( lpLastSlash )
+ {
+ size_t len = lpLastSlash - szModuleFileName + 1;
+ _tcsncpy( szPerfTuneIniFile, szModuleFileName, len );
+ _tcsncpy( szPerfTuneIniFile + len, _T("perftune.ini"), SAL_N_ELEMENTS(szPerfTuneIniFile) - len );
+ }
+
+ // Create process with same command line, environment and stdio handles which
+ // are directed to the created pipes
+
+ DWORD dwExitCode = (DWORD)-1;
+
+ BOOL fSuccess = FALSE;
+ LPTSTR lpCommandLine = NULL;
+ int argc = 0;
+ LPTSTR * argv = NULL;
+ bool bFirst = true;
+ WCHAR cwd[MAX_PATH];
+ DWORD cwdLen = GetCurrentDirectoryW(MAX_PATH, cwd);
+ if (cwdLen >= MAX_PATH) {
+ cwdLen = 0;
+ }
+
+ do
+ {
+ TCHAR szKey[32];
+
+ GetPrivateProfileString(
+ TEXT("PerformanceTuning"),
+ TEXT("FastPipeCommunication"),
+ TEXT("0"),
+ szKey,
+ SAL_N_ELEMENTS(szKey),
+ szPerfTuneIniFile
+ );
+
+ if ( 0 == _tcscmp( szKey, TEXT("1") ) )
+ {
+ HANDLE hProcessToken;
+
+ if ( OpenProcessToken( GetCurrentProcess(), TOKEN_QUERY, &hProcessToken ) )
+ {
+ TCHAR szPipeName[4096];
+
+
+ DWORD dwTokenLength = 0;
+
+
+ fSuccess = GetTokenInformation( hProcessToken, TokenUser, NULL, dwTokenLength, &dwTokenLength );
+
+ PVOID pTokenInfo = _alloca(dwTokenLength);
+ fSuccess = GetTokenInformation( hProcessToken, TokenUser, pTokenInfo, dwTokenLength, &dwTokenLength );
+ CloseHandle( hProcessToken );
+
+ PSID pSid = ((PTOKEN_USER)pTokenInfo)->User.Sid;
+ LPTSTR szUserIdent = NULL;
+ TCHAR szSUPD[11] = TEXT("0");
+
+ fSuccess = ConvertSidToStringSid( pSid, &szUserIdent );
+
+ _tcsncpy( szPipeName, PIPE_PREFIX, SAL_N_ELEMENTS(szPipeName) );
+ _tcsncat( szPipeName, szUserIdent, SAL_N_ELEMENTS(szPipeName) - _tcslen(szPipeName) - 1 );
+ _tcsncat( szPipeName, PIPE_POSTFIX, SAL_N_ELEMENTS(szPipeName) - _tcslen(szPipeName) - 1 );
+ _tcsncat( szPipeName, _ultot( SUPD, szSUPD, 10), SAL_N_ELEMENTS(szPipeName) - _tcslen(szPipeName) - 1 );
+
+ LocalFree( szUserIdent );
+
+ HANDLE hPipe = CreateFile(
+ szPipeName,
+ GENERIC_READ|GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+
+ if ( INVALID_HANDLE_VALUE != hPipe )
+ {
+ DWORD dwBytesWritten;
+ int argc = 0;
+ LPWSTR *argv = CommandLineToArgvW( GetCommandLine(), &argc );
+
+ fSuccess = WriteFile( hPipe, RTL_CONSTASCII_STRINGPARAM("InternalIPC::Arguments"), &dwBytesWritten, NULL );
+ if (fSuccess) {
+ if (cwdLen > 0) {
+ fSuccess = writeArgument(hPipe, '2', cwd);
+ } else {
+ fSuccess = WriteFile(
+ hPipe, RTL_CONSTASCII_STRINGPARAM("0"),
+ &dwBytesWritten, NULL);
+ }
+ }
+ for ( int argn = 1; fSuccess && argn < argc; argn++ )
+ {
+ fSuccess = writeArgument(hPipe, ',', argv[argn]);
+ }
+
+ if ( fSuccess )
+ {
+ fSuccess = WriteFile( hPipe, "", 1, &dwBytesWritten, NULL );
+ if ( fSuccess )
+ {
+ DWORD dwBytesRead = 0;
+ char *pBuffer = (char *)_alloca( sizeof(PIPE_TERMINATION_SEQUENCE) );
+ fSuccess = ReadFile( hPipe, pBuffer, sizeof(PIPE_TERMINATION_SEQUENCE) - 1, &dwBytesRead, NULL );
+ if ( fSuccess )
+ {
+ pBuffer[dwBytesRead] = 0;
+ if ( 0 != strcmp( PIPE_TERMINATION_SEQUENCE, pBuffer ) )
+ fSuccess = FALSE;
+ }
+ }
+ }
+
+ CloseHandle( hPipe );
+
+ return fSuccess ? 0 : -1;
+ }
+
+ }
+ }
+
+ if ( bFirst ) {
+ argv = GetCommandArgs(&argc);
+ std::size_t n = wcslen(argv[0]) + 2;
+ for (int i = 1; i < argc; ++i) {
+ n += wcslen(argv[i]) + 3;
+ }
+ n += MY_LENGTH(L" \"-env:OOO_CWD=2") + 4 * cwdLen +
+ MY_LENGTH(L"\"") + 1;
+ // 4 * cwdLen: each char preceded by backslash, each trailing
+ // backslash doubled
+ lpCommandLine = new WCHAR[n];
+ }
+ WCHAR * p = desktop_win32::commandLineAppend(
+ lpCommandLine, MY_STRING(L"\""));
+ p = desktop_win32::commandLineAppend(p, argv[0]);
+ for (int i = 1; i < argc; ++i) {
+ if (bFirst || ::desktop::ExitHelper::E_NORMAL_RESTART == dwExitCode || wcsncmp(argv[i], MY_STRING(L"-env:")) == 0) {
+ p = desktop_win32::commandLineAppend(p, MY_STRING(L"\" \""));
+ p = desktop_win32::commandLineAppend(p, argv[i]);
+ }
+ }
+
+ p = desktop_win32::commandLineAppend(
+ p, MY_STRING(L"\" \"-env:OOO_CWD="));
+ if (cwdLen == 0) {
+ p = desktop_win32::commandLineAppend(p, MY_STRING(L"0"));
+ } else {
+ p = desktop_win32::commandLineAppend(p, MY_STRING(L"2"));
+ p = desktop_win32::commandLineAppendEncoded(p, cwd);
+ }
+ desktop_win32::commandLineAppend(p, MY_STRING(L"\""));
+ bFirst = false;
+
+ TCHAR szParentProcessId[64]; // This is more than large enough for a 128 bit decimal value
+ BOOL bHeadlessMode( FALSE );
+
+ {
+ // Check command line arguments for "--headless" parameter. We only
+ // set the environment variable "ATTACHED_PARENT_PROCESSID" for the headless
+ // mode as self-destruction of the soffice.bin process can lead to
+ // certain side-effects (log-off can result in data-loss, ".lock" is not deleted.
+ // See 138244 for more information.
+ int argc;
+ LPTSTR *argv = GetCommandArgs( &argc );
+
+ if ( argc > 1 )
+ {
+ int n;
+
+ for ( n = 1; n < argc; n++ )
+ {
+ if ( 0 == _tcsnicmp( argv[n], _T("-headless"), 9 ) ||
+ 0 == _tcsnicmp( argv[n], _T("--headless"), 9 ) )
+ {
+ bHeadlessMode = TRUE;
+ }
+ }
+ }
+ }
+
+ if ( _ltot( (long)GetCurrentProcessId(),szParentProcessId, 10 ) && bHeadlessMode )
+ SetEnvironmentVariable( TEXT("ATTACHED_PARENT_PROCESSID"), szParentProcessId );
+
+ PROCESS_INFORMATION aProcessInfo;
+
+ fSuccess = CreateProcess(
+ szTargetFileName,
+ lpCommandLine,
+ NULL,
+ NULL,
+ TRUE,
+ 0,
+ NULL,
+ szIniDirectory,
+ &aStartupInfo,
+ &aProcessInfo );
+
+ if ( fSuccess )
+ {
+ DWORD dwWaitResult;
+
+ do
+ {
+ // On Windows XP it seems as the desktop calls WaitForInputIdle after "OpenWidth" so we have to do so
+ // as if we where processing any messages
+
+ dwWaitResult = MsgWaitForMultipleObjects( 1, &aProcessInfo.hProcess, FALSE, INFINITE, QS_ALLEVENTS );
+
+ if ( WAIT_OBJECT_0 + 1 == dwWaitResult )
+ {
+ MSG msg;
+
+ PeekMessage( &msg, NULL, 0, 0, PM_REMOVE );
+ }
+ } while ( WAIT_OBJECT_0 + 1 == dwWaitResult );
+
+ dwExitCode = 0;
+ GetExitCodeProcess( aProcessInfo.hProcess, &dwExitCode );
+
+ CloseHandle( aProcessInfo.hProcess );
+ CloseHandle( aProcessInfo.hThread );
+ }
+ } while ( false );
+ delete[] lpCommandLine;
+
+ return fSuccess ? dwExitCode : -1;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/win32/source/rebase/Resource.h b/desktop/win32/source/rebase/Resource.h
new file mode 100755
index 000000000000..a8e23f2eba1d
--- /dev/null
+++ b/desktop/win32/source/rebase/Resource.h
@@ -0,0 +1,41 @@
+/* -*- 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 _RESOURCE_H
+#define _RESOURCE_H
+
+#define IDS_APP_TITLE 10
+#define IDS_MSG_OPTIMIZED_FOR_CLIENT 11
+#define IDS_MSG_OPTIMIZED_FOR_SERVER 12
+#define IDS_MSG_NO_INSTALLATION_FOUND 13
+
+#define IDI_REBASEGUI 99
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/win32/source/rebase/makefile.mk b/desktop/win32/source/rebase/makefile.mk
new file mode 100755
index 000000000000..724ea0edf465
--- /dev/null
+++ b/desktop/win32/source/rebase/makefile.mk
@@ -0,0 +1,89 @@
+#*************************************************************************
+#
+# 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=rebasegui
+LIBTARGET=NO
+TARGETTYPE=GUI
+UWINAPILIB=
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+OBJFILES = \
+ $(OBJ)$/rebase.obj \
+ $(OBJ)$/rebasegui.obj
+
+ULFFILES= rebasegui.ulf
+
+.IF "$(WITH_LANG)"!=""
+ULFDIR:=$(COMMONMISC)$/$(TARGET)
+.ELSE # "$(WITH_LANG)"!=""
+ULFDIR:=.
+.ENDIF # "$(WITH_LANG)"!=""
+
+RCFILES= $(RES)$/$(TARGET).rc
+
+# --- Targets ------------------------------------------------------
+
+APP1NOSAL= TRUE
+APP1TARGET= rebaseoo
+
+APP1STDLIBS= $(SHELL32LIB) $(SOLARLIBDIR)$/pathutils-obj.obj
+.IF "$(COM)"=="GCC"
+ APP1STDLIBS+=$(PSDK_HOME)$/lib$/imagehlp.lib
+.ELSE
+ APP1STDLIBS+=imagehlp.lib
+.ENDIF
+
+APP1OBJS= $(OBJ)$/rebase.obj
+
+APP1RPATH= BRAND
+
+APP2NOSAL= TRUE
+APP2TARGET= rebasegui
+APP2STDLIBS= $(SHELL32LIB) $(SOLARLIBDIR)$/pathutils-obj.obj
+
+APP2OBJS= $(OBJ)$/rebasegui.obj
+
+APP2DEF= $(MISC)$/$(TARGET).def
+APP2RPATH= BRAND
+
+APP2RES= $(RES)$/$(TARGET).res
+APP2NOSVRES= $(RES)$/$(TARGET).res
+
+# --- setup --------------------------------------------------------------
+
+.INCLUDE : target.mk
+
+$(RCFILES) : $(ULFDIR)$/rebasegui.ulf makefile.mk rcfooter.txt rcheader.txt rctmpl.txt
+ $(LNGCONVEX) -ulf $(ULFDIR)$/rebasegui.ulf -rc $(RCFILES) -rct rctmpl.txt -rch rcheader.txt -rcf rcfooter.txt
diff --git a/desktop/win32/source/rebase/rcfooter.txt b/desktop/win32/source/rebase/rcfooter.txt
new file mode 100755
index 000000000000..3237729437f5
--- /dev/null
+++ b/desktop/win32/source/rebase/rcfooter.txt
@@ -0,0 +1,2 @@
+
+// The end
diff --git a/desktop/win32/source/rebase/rcheader.txt b/desktop/win32/source/rebase/rcheader.txt
new file mode 100755
index 000000000000..56afc5377920
--- /dev/null
+++ b/desktop/win32/source/rebase/rcheader.txt
@@ -0,0 +1,39 @@
+#if defined(_MSC_VER) && (_MSC_VER < 1500)
+#include <winres.h>
+#else
+#define WINVER 0x0500
+#include <winresrc.h>
+#define IDC_STATIC (-1)
+#endif
+#include "resource.h"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 1,1,1,0
+ PRODUCTVERSION 1,1,1,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x9L
+#else
+ FILEFLAGS 0x8L
+#endif
+ FILEOS 0x40004L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
diff --git a/desktop/win32/source/rebase/rctmpl.txt b/desktop/win32/source/rebase/rctmpl.txt
new file mode 100755
index 000000000000..97a2775e9b02
--- /dev/null
+++ b/desktop/win32/source/rebase/rctmpl.txt
@@ -0,0 +1,9 @@
+// String Table
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ IDS_APP_TITLE %APP_TITLE%
+ IDS_MSG_OPTIMIZED_FOR_CLIENT %MSG_OPTIMIZED_FOR_CLIENT%
+ IDS_MSG_OPTIMIZED_FOR_SERVER %MSG_OPTIMIZED_FOR_SERVER%
+ IDS_MSG_NO_INSTALLATION_FOUND %MSG_NO_INSTALLATION_FOUND%
+END
diff --git a/desktop/win32/source/rebase/rebase.cxx b/desktop/win32/source/rebase/rebase.cxx
new file mode 100644
index 000000000000..ba6c3937227a
--- /dev/null
+++ b/desktop/win32/source/rebase/rebase.cxx
@@ -0,0 +1,191 @@
+/* -*- 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"
+#define UNICODE
+#define _UNICODE
+
+#define WIN32_LEAN_AND_MEAN
+#if defined _MSC_VER
+#pragma warning(push, 1)
+#endif
+#include <windows.h>
+#include <shellapi.h>
+#include <imagehlp.h>
+#include <wchar.h>
+#if defined _MSC_VER
+#pragma warning(pop)
+#endif
+
+#include <time.h>
+#include "sal/config.h"
+#include <sal/macros.h>
+#include "tools/pathutils.hxx"
+
+#define MY_LENGTH(s) (sizeof (s) / sizeof *(s) - 1)
+#define MY_STRING(s) (s), MY_LENGTH(s)
+
+const int FORMAT_MESSAGE_SIZE = 4096;
+const DWORD PE_Signature = 0x00004550;
+const DWORD BASEVIRTUALADDRESS = 0x10000000;
+
+namespace
+{
+
+bool IsValidHandle( HANDLE handle )
+{
+ return ((NULL != handle) && (INVALID_HANDLE_VALUE != handle));
+}
+
+void fail()
+{
+ LPWSTR buf = NULL;
+ FormatMessageW(
+ FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL,
+ GetLastError(), 0, reinterpret_cast< LPWSTR >(&buf), 0, NULL);
+ MessageBoxW(NULL, buf, NULL, MB_OK | MB_ICONERROR);
+ LocalFree(buf);
+ TerminateProcess(GetCurrentProcess(), 255);
+}
+
+bool rebaseImage( wchar_t* pszFilePath, ULONG nNewImageBase)
+{
+ ULONG ulOldImageSize;
+ ULONG_PTR lpOldImageBase;
+ ULONG ulNewImageSize;
+ ULONG_PTR lpNewImageBase = nNewImageBase;
+ ULONG ulDateTimeStamp = 0;
+ bool bResult(false);
+
+ char cszFilePath[_MAX_PATH+1] = {0};
+ int nResult = WideCharToMultiByte(CP_ACP, 0, pszFilePath, -1, cszFilePath, _MAX_PATH, NULL, NULL);
+
+ if (nResult != 0)
+ {
+ BOOL bResult = ReBaseImage(
+ cszFilePath,
+ "",
+ TRUE,
+ FALSE,
+ FALSE,
+ 0,
+ &ulOldImageSize,
+ &lpOldImageBase,
+ &ulNewImageSize,
+ &lpNewImageBase,
+ ulDateTimeStamp );
+ }
+
+ return bResult;
+}
+
+wchar_t* getBrandPath(wchar_t * path)
+{
+ DWORD n = GetModuleFileNameW(NULL, path, MAX_PATH);
+ if (n == 0 || n >= MAX_PATH) {
+ exit(EXIT_FAILURE);
+ }
+ return tools::filename(path);
+}
+
+void rebaseImagesInFolder( wchar_t* pszFolder, DWORD nNewImageBase )
+{
+ wchar_t szPattern[MAX_PATH];
+ wchar_t *lpLastSlash = wcsrchr( pszFolder, '\\' );
+ if ( lpLastSlash )
+ {
+ size_t len = lpLastSlash - pszFolder + 1;
+ wcsncpy( szPattern, pszFolder, len );
+ wcsncpy( szPattern + len, TEXT("*.dll"), SAL_N_ELEMENTS(szPattern) - len );
+ }
+
+ WIN32_FIND_DATA aFindFileData;
+ HANDLE hFind = FindFirstFile( szPattern, &aFindFileData );
+
+ if ( IsValidHandle(hFind) )
+ {
+ BOOL fSuccess = false;
+
+ do
+ {
+ wchar_t szLibFilePath[MAX_PATH];
+ wchar_t *lpLastSlash = wcsrchr( pszFolder, '\\' );
+ if ( lpLastSlash )
+ {
+ size_t len = lpLastSlash - pszFolder + 1;
+ wcsncpy( szLibFilePath, pszFolder, len );
+ wcsncpy( szLibFilePath + len, aFindFileData.cFileName, SAL_N_ELEMENTS(szLibFilePath) - len );
+ }
+
+ rebaseImage( szLibFilePath, nNewImageBase );
+ fSuccess = FindNextFile( hFind, &aFindFileData );
+ }
+ while ( fSuccess );
+
+ FindClose( hFind );
+ }
+}
+
+}
+
+extern "C" int APIENTRY WinMain( HINSTANCE, HINSTANCE, LPSTR, int )
+{
+ wchar_t path[MAX_PATH];
+
+ wchar_t * pathEnd = getBrandPath(path);
+
+ if (tools::buildPath(path, path, pathEnd, MY_STRING(L"")) == NULL)
+ fail();
+ rebaseImagesInFolder(path, BASEVIRTUALADDRESS);
+
+ if (tools::buildPath(path, path, pathEnd, MY_STRING(L"..\\basis-link")) == NULL)
+ fail();
+ pathEnd = tools::resolveLink(path);
+
+ if ( pathEnd == NULL )
+ return 0;
+
+ if (tools::buildPath(path, path, pathEnd, MY_STRING(L"\\program\\")) == NULL)
+ fail();
+ rebaseImagesInFolder(path, BASEVIRTUALADDRESS);
+
+ if (tools::buildPath(path, path, pathEnd, MY_STRING(L"\\ure-link")) == NULL)
+ fail();
+ pathEnd = tools::resolveLink(path);
+
+ if ( pathEnd == NULL )
+ return 0;
+
+ if (tools::buildPath(path, path, pathEnd, MY_STRING(L"\\bin\\")) == NULL)
+ fail();
+ rebaseImagesInFolder(path, BASEVIRTUALADDRESS);
+
+ return 0;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/win32/source/rebase/rebasegui.cxx b/desktop/win32/source/rebase/rebasegui.cxx
new file mode 100644
index 000000000000..71b4f1246447
--- /dev/null
+++ b/desktop/win32/source/rebase/rebasegui.cxx
@@ -0,0 +1,200 @@
+/* -*- 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"
+
+#define UNICODE 1
+#define _UNICODE 1
+
+#ifndef _WINDOWS_
+# define WIN32_LEAN_AND_MEAN
+#if defined _MSC_VER
+#pragma warning(push, 1)
+#endif
+# include <windows.h>
+# include <shellapi.h>
+# include <wchar.h>
+#if defined _MSC_VER
+#pragma warning(pop)
+#endif
+#endif
+
+#include "Resource.h"
+#include <time.h>
+#include "sal/config.h"
+#include "tools/pathutils.hxx"
+
+const DWORD PE_Signature = 0x00004550;
+
+#define MY_LENGTH(s) (sizeof (s) / sizeof *(s) - 1)
+#define MY_STRING(s) (s), MY_LENGTH(s)
+#define MAX_STR_CAPTION 256
+#define MAX_TEXT_LENGTH 1024
+
+static void failPath(wchar_t* pszAppTitle, wchar_t* pszMsg)
+{
+ MessageBoxW(NULL, pszMsg, pszAppTitle, MB_OK | MB_ICONERROR);
+ TerminateProcess(GetCurrentProcess(), 255);
+}
+
+static void fail()
+{
+ LPWSTR buf = NULL;
+ FormatMessageW(
+ FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL,
+ GetLastError(), 0, reinterpret_cast< LPWSTR >(&buf), 0, NULL);
+ MessageBoxW(NULL, buf, NULL, MB_OK | MB_ICONERROR);
+ LocalFree(buf);
+ TerminateProcess(GetCurrentProcess(), 255);
+}
+
+static LPVOID getVirtualBaseAddress( wchar_t* pszFilePath )
+{
+ HANDLE hFile;
+ HANDLE hFileMapping;
+ LPVOID lpFileBase = 0;
+ PIMAGE_DOS_HEADER lpDosHeader;
+ PIMAGE_NT_HEADERS lpNTHeader;
+
+ hFile = CreateFile(pszFilePath,
+ GENERIC_READ, FILE_SHARE_READ, NULL,
+ OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
+ 0);
+
+ if ( hFile == INVALID_HANDLE_VALUE )
+ {
+ return NULL;
+ }
+
+ hFileMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
+ if ( hFileMapping == 0 )
+ {
+ CloseHandle(hFile);
+ return NULL;
+ }
+
+ lpFileBase = MapViewOfFile(hFileMapping, FILE_MAP_READ, 0, 0, 0);
+ if ( lpFileBase == 0 )
+ {
+ CloseHandle(hFileMapping);
+ CloseHandle(hFile);
+ return NULL;
+ }
+
+ lpDosHeader = (PIMAGE_DOS_HEADER)lpFileBase;
+ if ( lpDosHeader->e_magic == IMAGE_DOS_SIGNATURE )
+ {
+ lpNTHeader = (PIMAGE_NT_HEADERS)((char*)lpDosHeader + lpDosHeader->e_lfanew);
+ if (lpNTHeader->Signature == PE_Signature )
+ lpFileBase = reinterpret_cast<LPVOID>( lpNTHeader->OptionalHeader.ImageBase );
+ }
+
+ UnmapViewOfFile(lpFileBase);
+ CloseHandle(hFileMapping);
+ CloseHandle(hFile);
+
+ return lpFileBase;
+}
+
+static bool checkImageVirtualBaseAddress(wchar_t* pszFilePath, LPVOID lpVBA)
+{
+ LPVOID lpImageVBA = getVirtualBaseAddress(pszFilePath);
+ if ( lpImageVBA == lpVBA )
+ return true;
+ else
+ return false;
+}
+
+static wchar_t* getBrandPath(wchar_t * pszPath)
+{
+ DWORD n = GetModuleFileNameW(NULL, pszPath, MAX_PATH);
+ if (n == 0 || n >= MAX_PATH) {
+ exit(EXIT_FAILURE);
+ }
+ return tools::filename(pszPath);
+}
+
+extern "C" int APIENTRY WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, int )
+{
+ wchar_t* pAppTitle = new wchar_t[ MAX_STR_CAPTION ];
+ pAppTitle[0] = '\0';
+ LoadString( hInst, IDS_APP_TITLE, pAppTitle, MAX_STR_CAPTION );
+
+ wchar_t* pTextServer = new wchar_t[ MAX_TEXT_LENGTH ];
+ pTextServer[0] = '\0';
+ LoadString( hInst, IDS_MSG_OPTIMIZED_FOR_SERVER, pTextServer, MAX_TEXT_LENGTH );
+
+ wchar_t* pTextClient = new wchar_t[ MAX_TEXT_LENGTH ];
+ pTextClient[0] = '\0';
+ LoadString( hInst, IDS_MSG_OPTIMIZED_FOR_CLIENT, pTextClient, MAX_TEXT_LENGTH );
+
+ wchar_t* pTextNoInstallation = new wchar_t[ MAX_TEXT_LENGTH ];
+ pTextNoInstallation[0] = '\0';
+ LoadString( hInst, IDS_MSG_NO_INSTALLATION_FOUND, pTextNoInstallation, MAX_TEXT_LENGTH );
+
+ LPVOID VBA = (void*)0x10000000;
+ wchar_t path[MAX_PATH];
+
+ wchar_t * pathEnd = getBrandPath(path);
+
+ if (tools::buildPath(path, path, pathEnd, MY_STRING(L"libxml2.dll")) == NULL)
+ fail();
+ bool bFast = checkImageVirtualBaseAddress(path, VBA);
+
+ if (tools::buildPath(path, path, pathEnd, MY_STRING(L"..\\basis-link")) == NULL)
+ fail();
+ pathEnd = tools::resolveLink(path);
+
+ if (pathEnd == NULL)
+ failPath(pAppTitle, pTextNoInstallation);
+
+ if (tools::buildPath(path, path, pathEnd, MY_STRING(L"\\program\\vclmi.dll")) == NULL)
+ fail();
+ bFast &= checkImageVirtualBaseAddress(path, VBA);
+
+ if (tools::buildPath(path, path, pathEnd, MY_STRING(L"\\ure-link")) == NULL)
+ fail();
+ pathEnd = tools::resolveLink(path);
+
+ if (pathEnd == NULL)
+ failPath(pAppTitle, pTextNoInstallation);
+
+ if (tools::buildPath(path, path, pathEnd, MY_STRING(L"\\bin\\sal3.dll")) == NULL)
+ fail();
+ bFast &= checkImageVirtualBaseAddress(path, VBA);
+
+ const wchar_t* pOutput = pTextClient;
+ if (!bFast)
+ pOutput = pTextServer;
+
+ MessageBoxW( NULL, pOutput, pAppTitle, MB_OK );
+
+ return 0;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/win32/source/rebase/rebasegui.ulf b/desktop/win32/source/rebase/rebasegui.ulf
new file mode 100755
index 000000000000..ee6b6e828ac1
--- /dev/null
+++ b/desktop/win32/source/rebase/rebasegui.ulf
@@ -0,0 +1,11 @@
+[%APP_TITLE%]
+en-US = "Installation Status"
+
+[%MSG_OPTIMIZED_FOR_CLIENT%]
+en-US = "Installation is optimized for clients."
+
+[%MSG_OPTIMIZED_FOR_SERVER%]
+en-US = "Installation is optimized for servers."
+
+[%MSG_NO_INSTALLATION_FOUND%]
+en-US = "Cannot find Office installation."
diff --git a/desktop/win32/source/rwrapa.cxx b/desktop/win32/source/rwrapa.cxx
new file mode 100644
index 000000000000..080cb4e4be05
--- /dev/null
+++ b/desktop/win32/source/rwrapa.cxx
@@ -0,0 +1,35 @@
+/* -*- 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 REMOTE
+#include "wrapper.h"
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/win32/source/rwrapw.cxx b/desktop/win32/source/rwrapw.cxx
new file mode 100644
index 000000000000..15abc299a341
--- /dev/null
+++ b/desktop/win32/source/rwrapw.cxx
@@ -0,0 +1,36 @@
+/* -*- 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 REMOTE
+#define UNICODE
+#include "wrapper.h"
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/win32/source/setup/Resource.h b/desktop/win32/source/setup/Resource.h
new file mode 100644
index 000000000000..600056d0a8ee
--- /dev/null
+++ b/desktop/win32/source/setup/Resource.h
@@ -0,0 +1,82 @@
+/* -*- 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 _RESOURCE_H
+#define _RESOURCE_H
+
+#define IDS_APP_TITLE 10
+#define IDS_APP_PROD_TITLE 11
+#define IDS_OUTOFMEM 12
+#define IDS_NOMSI 13
+#define IDS_USER_CANCELLED 14
+#define IDS_REQUIRES_ADMIN_PRIV 15
+#define IDS_FILE_NOT_FOUND 16
+#define IDS_INVALID_PARAM 17
+#define IDS_ALLOW_MSI_UPDATE 18
+#define IDS_USAGE 19
+#define IDS_ALREADY_RUNNING 20
+#define IDS_UNKNOWN_ERROR 21
+#define IDS_INVALID_PROFILE 22
+#define IDS_UNKNOWN_LANG 23
+#define IDS_SETUP_TO_OLD 24
+#define IDS_SETUP_NOT_FOUND 25
+#define IDS_LANGUAGE_ENGLISH 50
+#define IDS_LANGUAGE_SPAIN 51
+#define IDS_LANGUAGE_GERMAN 52
+#define IDS_LANGUAGE_ZH_TW 53
+#define IDS_LANGUAGE_CS 54
+#define IDS_LANGUAGE_DA 55
+#define IDS_LANGUAGE_DE_DE 56
+#define IDS_LANGUAGE_EL 57
+#define IDS_LANGUAGE_EN_US 58
+#define IDS_LANGUAGE_ES 59
+#define IDS_LANGUAGE_FI 60
+#define IDS_LANGUAGE_FR_FR 61
+#define IDS_LANGUAGE_HE 62
+#define IDS_LANGUAGE_HU 63
+#define IDS_LANGUAGE_IT_IT 64
+#define IDS_LANGUAGE_JA 65
+#define IDS_LANGUAGE_KO 66
+#define IDS_LANGUAGE_NL_NL 67
+#define IDS_LANGUAGE_NO_NO 68
+#define IDS_LANGUAGE_PL 69
+#define IDS_LANGUAGE_PT_BR 70
+#define IDS_LANGUAGE_RU 71
+#define IDS_LANGUAGE_SK 72
+#define IDS_LANGUAGE_SV_SE 73
+#define IDS_LANGUAGE_TH 74
+#define IDS_LANGUAGE_TR 75
+#define IDS_LANGUAGE_ET 76
+#define IDS_LANGUAGE_ZH_CN 77
+#define IDS_LANGUAGE_PT_PT 78
+
+#define IDI_INSTALLER 99
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/win32/source/setup/makefile.mk b/desktop/win32/source/setup/makefile.mk
new file mode 100644
index 000000000000..f0c6e0e955fd
--- /dev/null
+++ b/desktop/win32/source/setup/makefile.mk
@@ -0,0 +1,90 @@
+#*************************************************************************
+#
+# 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 = loader2
+LIBTARGET = NO
+DYNAMIC_CRT =
+TARGETTYPE = GUI
+
+ENABLE_EXCEPTIONS = TRUE
+
+# --- Settings ------------------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Allgemein -----------------------------------------------------------
+
+INCPRE+=$(MFC_INCLUDE)
+
+.IF "$(USE_DEBUG_RUNTIME)"!=""
+CDEFS+=-D_DEBUG
+.ENDIF # "$(USE_DEBUG_RUNTIME)"!=""
+
+RCFILES= $(RES)$/$(TARGET).rc
+
+ULFFILES= setup.ulf
+
+.IF "$(WITH_LANG)"!=""
+ULFDIR:=$(COMMONMISC)$/$(TARGET)
+.ELSE # "$(WITH_LANG)"!=""
+ULFDIR:=.
+.ENDIF # "$(WITH_LANG)"!=""
+
+OBJFILES= $(OBJ)$/setup_main.obj \
+ $(OBJ)$/setup_w.obj
+
+# --- Targets ------------------------------------------------------
+# Generate the native Windows resource file
+# using lngconvex.exe
+
+UWINAPILIB= $(0)
+LIBSALCPPRT= $(0)
+
+APP1NOSAL= TRUE
+APP1TARGET= loader2
+
+APP1STDLIBS= $(GDI32LIB) $(ADVAPI32LIB) $(SHELL32LIB) $(MSILIB)
+.IF "$(COM)"!="GCC"
+APP1STDLIBS+= libcmt.lib
+.ENDIF
+APP1OBJS= $(OBJFILES)
+
+APP1DEF= $(MISC)$/$(TARGET).def
+
+APP1RES= $(RES)$/$(TARGET).res
+APP1NOSVRES= $(RES)$/$(TARGET).res
+
+# --- setup --------------------------------------------------------------
+
+.INCLUDE : target.mk
+
+$(RCFILES) : $(ULFDIR)$/setup.ulf makefile.mk rcfooter.txt rcheader.txt rctmpl.txt
+ $(LNGCONVEX) -ulf $(ULFDIR)$/setup.ulf -rc $(RCFILES) -rct rctmpl.txt -rch rcheader.txt -rcf rcfooter.txt
+
diff --git a/desktop/win32/source/setup/rcfooter.txt b/desktop/win32/source/setup/rcfooter.txt
new file mode 100644
index 000000000000..3237729437f5
--- /dev/null
+++ b/desktop/win32/source/setup/rcfooter.txt
@@ -0,0 +1,2 @@
+
+// The end
diff --git a/desktop/win32/source/setup/rcheader.txt b/desktop/win32/source/setup/rcheader.txt
new file mode 100644
index 000000000000..9a59ad7f6477
--- /dev/null
+++ b/desktop/win32/source/setup/rcheader.txt
@@ -0,0 +1,43 @@
+#if defined(_MSC_VER) && (_MSC_VER < 1500)
+#include <winres.h>
+#else
+#define WINVER 0x0500
+#include <winresrc.h>
+#define LB_ADDSTRING (WM_USER+1)
+#define CB_ADDSTRING (WM_USER+3)
+#define IDC_STATIC (-1)
+#endif
+#include "resource.h"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 1,1,1,0
+ PRODUCTVERSION 1,1,1,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x9L
+#else
+ FILEFLAGS 0x8L
+#endif
+ FILEOS 0x40004L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+IDI_INSTALLER ICON "setup.ico"
+
diff --git a/desktop/win32/source/setup/rctmpl.txt b/desktop/win32/source/setup/rctmpl.txt
new file mode 100644
index 000000000000..59f454f70c16
--- /dev/null
+++ b/desktop/win32/source/setup/rctmpl.txt
@@ -0,0 +1,49 @@
+// String Table
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ IDS_APP_TITLE %APP_TITLE%
+ IDS_APP_PROD_TITLE %APP_PROD_TITLE%
+ IDS_OUTOFMEM %OUTOFMEM%
+ IDS_NOMSI %NOMSI%
+ IDS_USER_CANCELLED %USER_CANCELLED%
+ IDS_REQUIRES_ADMIN_PRIV %REQUIRES_ADMIN_PRIV%
+ IDS_FILE_NOT_FOUND %FILE_NOT_FOUND%
+ IDS_INVALID_PARAM %INVALID_PARAM%
+ IDS_SETUP_TO_OLD %SETUP_TO_OLD%
+ IDS_SETUP_NOT_FOUND %SETUP_NOT_FOUND%
+ IDS_USAGE %USAGE%
+ IDS_ALREADY_RUNNING %ALREADY_RUNNING%
+ IDS_UNKNOWN_ERROR %UNKNOWN_ERROR%
+ IDS_INVALID_PROFILE %INVALID_PROFILE%
+ IDS_UNKNOWN_LANG %UNKNOWN_LANG%
+ IDS_LANGUAGE_ENGLISH %LANGUAGE_ENGLISH%
+ IDS_LANGUAGE_SPAIN %LANGUAGE_SPAIN%
+ IDS_LANGUAGE_GERMAN %LANGUAGE_GERMAN%
+ IDS_LANGUAGE_ZH_TW %LANGUAGE_ZH_TW%
+ IDS_LANGUAGE_CS %LANGUAGE_CS%
+ IDS_LANGUAGE_DA %LANGUAGE_DA%
+ IDS_LANGUAGE_DE_DE %LANGUAGE_DE_DE%
+ IDS_LANGUAGE_EL %LANGUAGE_EL%
+ IDS_LANGUAGE_EN_US %LANGUAGE_EN_US%
+ IDS_LANGUAGE_ES %LANGUAGE_ES%
+ IDS_LANGUAGE_FI %LANGUAGE_FI%
+ IDS_LANGUAGE_FR_FR %LANGUAGE_FR_FR%
+ IDS_LANGUAGE_HE %LANGUAGE_HE%
+ IDS_LANGUAGE_HU %LANGUAGE_HU%
+ IDS_LANGUAGE_IT_IT %LANGUAGE_IT_IT%
+ IDS_LANGUAGE_JA %LANGUAGE_JA%
+ IDS_LANGUAGE_KO %LANGUAGE_KO%
+ IDS_LANGUAGE_NL_NL %LANGUAGE_NL_NL%
+ IDS_LANGUAGE_NO_NO %LANGUAGE_NO_NO%
+ IDS_LANGUAGE_PL %LANGUAGE_PL%
+ IDS_LANGUAGE_PT_BR %LANGUAGE_PT_BR%
+ IDS_LANGUAGE_RU %LANGUAGE_RU%
+ IDS_LANGUAGE_SK %LANGUAGE_SK%
+ IDS_LANGUAGE_SV_SE %LANGUAGE_SV_SE%
+ IDS_LANGUAGE_TH %LANGUAGE_TH%
+ IDS_LANGUAGE_TR %LANGUAGE_TR%
+ IDS_LANGUAGE_ET %LANGUAGE_ET%
+ IDS_LANGUAGE_ZH_CN %LANGUAGE_ZH_CN%
+ IDS_LANGUAGE_PT_PT %LANGUAGE_PT_PT%
+END
diff --git a/desktop/win32/source/setup/setup.cpp b/desktop/win32/source/setup/setup.cpp
new file mode 100644
index 000000000000..52746837646c
--- /dev/null
+++ b/desktop/win32/source/setup/setup.cpp
@@ -0,0 +1,2063 @@
+/* -*- 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 WIN // scope W32 API
+#define _WIN32_WINNT 0x0501
+
+#if defined _MSC_VER
+#pragma warning(push, 1)
+#endif
+#include <windows.h>
+#if defined _MSC_VER
+#pragma warning(pop)
+#endif
+#include <tchar.h>
+#include <assert.h>
+#include <shlwapi.h>
+#include <new>
+#include <time.h>
+#include <mbctype.h>
+#include <locale.h>
+#include <Msiquery.h>
+#include <MsiDefs.h>
+#include "strsafe.h"
+
+#include "setup.hxx"
+
+#include "resource.h"
+
+//--------------------------------------------------------------------------
+
+#define MAX_STR_LENGTH 32000
+#define MAX_TEXT_LENGTH 1024
+#define MAX_LANGUAGE_LEN 80
+#define MAX_STR_CAPTION 256
+#define VERSION_SIZE 80
+#define SECTION_SETUP TEXT( "Setup" )
+#define SECTION_LANGUAGE TEXT( "Languages" )
+#define PRODUCT_NAME_VAR TEXT( "%PRODUCTNAME" )
+#define PRODUCT_VERSION TEXT( "ProductVersion" )
+#define ERROR_SHOW_USAGE -2
+#define ERROR_SETUP_TO_OLD -3
+#define ERROR_SETUP_NOT_FOUND -4
+
+#define PARAM_SETUP_USED TEXT( " SETUP_USED=1 " )
+#define PARAM_PACKAGE TEXT( "/I " )
+#define PARAM_MINOR_UPGRADE TEXT( "/FVOMUS " )
+#define PARAM_ADMIN TEXT( "/A " )
+#define PARAM_TRANSFORM TEXT( " TRANSFORMS=" )
+#define PARAM_REBOOT TEXT( " REBOOT=Force" )
+#define PARAM_PATCH TEXT( " /update " )
+#define PARAM_REG_ALL_MSO_TYPES TEXT( "REGISTER_ALL_MSO_TYPES=1 " )
+#define PARAM_REG_NO_MSO_TYPES TEXT( "REGISTER_NO_MSO_TYPES=1 " )
+#define PARAM_SILENTINSTALL TEXT( " /QB" )
+
+#define PARAM_RUNNING TEXT( "ignore_running" )
+#define CMDLN_REG_ALL_MSO_TYPES TEXT( "msoreg=1" )
+#define CMDLN_REG_NO_MSO_TYPES TEXT( "msoreg=0" )
+
+#define MSI_DLL TEXT( "msi.dll" )
+#define ADVAPI32_DLL TEXT( "advapi32.dll" )
+#define PROFILE_NAME TEXT( "setup.ini" )
+
+#define RUNTIME_X64_NAME TEXT( "redist\\vcredist_x64.exe" )
+#define RUNTIME_X86_NAME TEXT( "redist\\vcredist_x86.exe" )
+#define PRODUCTCODE_X86 TEXT( "{1F1C2DFC-2D24-3E06-BCB8-725134ADF989}" )
+#define PRODUCTCODE_X64 TEXT( "{4B6C7001-C7D6-3710-913E-5BC23FCE91E6}" )
+
+#define MSIAPI_DllGetVersion "DllGetVersion"
+#define ADVAPI32API_CheckTokenMembership "CheckTokenMembership"
+
+typedef HRESULT (CALLBACK* PFnDllGetVersion)( DLLVERSIONINFO *pdvi);
+typedef BOOL (WINAPI* PFnCheckTokenMembership)(HANDLE TokenHandle, PSID SidToCheck, PBOOL IsMember);
+
+#ifdef DEBUG
+inline void OutputDebugStringFormat( LPCTSTR pFormat, ... )
+{
+ TCHAR buffer[1024];
+ va_list args;
+
+ va_start( args, pFormat );
+ StringCchVPrintf( buffer, sizeof(buffer), pFormat, args );
+ OutputDebugString( buffer );
+}
+#else
+static inline void OutputDebugStringFormat( LPCTSTR, ... )
+{
+}
+#endif
+
+//--------------------------------------------------------------------------
+
+const TCHAR sInstKey[] = TEXT( "Software\\Microsoft\\Windows\\CurrentVersion\\Installer" );
+const TCHAR sInstLocValue[] = TEXT( "InstallerLocation" );
+const TCHAR sMsiDll[] = TEXT( "\\msi.dll" );
+const TCHAR sMsiExe[] = TEXT( "\\msiexec.exe" );
+const TCHAR sDelayReboot[] = TEXT( " /c:\"msiinst /delayreboot\"" );
+const TCHAR sMsiQuiet[] = TEXT( " /q" );
+const TCHAR sMemMapName[] = TEXT( "Global\\MsiErrorObject" );
+
+//--------------------------------------------------------------------------
+SetupAppX::SetupAppX()
+{
+ m_hInst = NULL;
+ m_hMapFile = NULL;
+ m_pAppTitle = NULL;
+ m_pCmdLine = NULL;
+
+ m_pDatabase = NULL;
+ m_pReqVersion = NULL;
+ m_pProductName = NULL;
+ m_pAdvertise = NULL;
+ m_pTmpName = NULL;
+ m_pLogFile = NULL;
+ m_pModuleFile = NULL;
+ m_pPatchFiles = NULL;
+ m_pMSIErrorCode = NULL;
+ m_pUpgradeKey = NULL;
+ m_pProductVersion = NULL;
+
+ m_pErrorText = new TCHAR[ MAX_TEXT_LENGTH ];
+ m_pErrorText[0] = '\0';
+
+ m_nLanguageID = 0;
+ m_nLanguageCount = 0;
+ m_ppLanguageList = NULL;
+
+ m_bQuiet = false;
+ m_bRegNoMsoTypes = false;
+ m_bRegAllMsoTypes = false;
+ m_bIsMinorUpgrade = false;
+ m_bSupportsPatch = false;
+
+ m_bIgnoreAlreadyRunning = false;
+}
+
+//--------------------------------------------------------------------------
+SetupAppX::~SetupAppX()
+{
+ if ( m_ppLanguageList )
+ {
+ for ( int i = 0; i < m_nLanguageCount; i++ )
+ if ( m_ppLanguageList[i] )
+ delete m_ppLanguageList[ i ];
+ delete [] m_ppLanguageList;
+ }
+
+ time_t aTime;
+ time( &aTime );
+ tm *pTime = localtime( &aTime ); // Convert time to struct tm form
+
+ Log( TEXT( "End: %s\n\r\n\r\n" ), _tasctime( pTime ) );
+
+ if ( m_pLogFile ) fclose( m_pLogFile );
+
+ if ( m_pTmpName )
+ {
+ _tremove( m_pTmpName );
+ free( m_pTmpName );
+ }
+
+ if ( m_pMSIErrorCode ) UnmapViewOfFile( m_pMSIErrorCode );
+ if ( m_hMapFile ) CloseHandle( m_hMapFile );
+
+ if ( m_pAppTitle ) delete [] m_pAppTitle;
+ if ( m_pDatabase ) delete [] m_pDatabase;
+ if ( m_pReqVersion ) delete [] m_pReqVersion;
+ if ( m_pProductName ) delete [] m_pProductName;
+ if ( m_pAdvertise ) delete [] m_pAdvertise;
+ if ( m_pLogFile ) delete [] m_pLogFile;
+ if ( m_pErrorText ) delete [] m_pErrorText;
+ if ( m_pModuleFile ) delete [] m_pModuleFile;
+ if ( m_pPatchFiles ) delete [] m_pPatchFiles;
+ if ( m_pUpgradeKey ) delete [] m_pUpgradeKey;
+ if ( m_pProductVersion ) delete [] m_pProductVersion;
+}
+
+//--------------------------------------------------------------------------
+boolean SetupAppX::Initialize( HINSTANCE hInst )
+{
+ m_pCmdLine = WIN::GetCommandLine();
+ m_hInst = hInst;
+
+ // Load our AppTitle (caption)
+ m_pAppTitle = new TCHAR[ MAX_STR_CAPTION ];
+ m_pAppTitle[0] = '\0';
+ WIN::LoadString( hInst, IDS_APP_TITLE, m_pAppTitle, MAX_STR_CAPTION );
+
+ // Obtain path we are running from
+ m_pModuleFile = new TCHAR[ MAX_PATH ];
+ m_pModuleFile[ 0 ] = '\0';
+
+ if ( 0 == WIN::GetModuleFileName( hInst, m_pModuleFile, MAX_PATH ) )
+ {
+ SetError( WIN::GetLastError() );
+ return false;
+ }
+
+ if ( ! GetCmdLineParameters( &m_pCmdLine ) )
+ return false;
+
+ m_hMapFile = CreateFileMapping(
+ INVALID_HANDLE_VALUE, // use paging file
+ NULL, // default security
+ PAGE_READWRITE, // read/write access
+ 0, // max. object size
+ sizeof( int ), // buffer size
+ sMemMapName );
+ if ( m_hMapFile )
+ {
+ m_pMSIErrorCode = (int*) MapViewOfFile( m_hMapFile, // handle to map object
+ FILE_MAP_ALL_ACCESS, // read/write permission
+ 0,
+ 0,
+ sizeof( int ) );
+ if ( m_pMSIErrorCode )
+ *m_pMSIErrorCode = 0;
+ else
+ OutputDebugStringFormat( TEXT("Could not map view of file (%d).\n"), GetLastError() );
+ }
+ else
+ OutputDebugStringFormat( TEXT("Could not create file mapping object (%d).\n"), GetLastError() );
+
+ Log( TEXT("Starting: %s\r\n"), m_pModuleFile );
+ Log( TEXT(" CommandLine=<%s>\r\n"), m_pCmdLine );
+
+ if ( m_bQuiet )
+ Log( TEXT(" Using quiet install mode\r\n") );
+
+ time_t aTime;
+ time( &aTime );
+ tm* pTime = localtime( &aTime );
+ Log( TEXT(" Begin: %s\n"), _tasctime( pTime ) );
+
+ return true;
+}
+
+//--------------------------------------------------------------------------
+boolean SetupAppX::GetProfileSection( LPCTSTR pFileName, LPCTSTR pSection,
+ DWORD& rSize, LPTSTR *pRetBuf )
+{
+ if ( !rSize || !*pRetBuf )
+ {
+ rSize = 10000;
+ *pRetBuf = new TCHAR[ rSize ];
+ }
+
+ DWORD nRet = GetPrivateProfileSection( pSection, *pRetBuf, rSize, pFileName );
+
+ while ( nRet && ( nRet + 2 >= rSize ) ) // buffer was too small, retry until big enough
+ {
+ if (rSize > 1000000)
+ break;
+ delete [] (*pRetBuf);
+ rSize = rSize * 2;
+ *pRetBuf = new TCHAR[ rSize ];
+
+ nRet = GetPrivateProfileSection( pSection, *pRetBuf, rSize, pFileName );
+ }
+
+ if ( !nRet )
+ {
+ SetError( WIN::GetLastError() );
+
+ TCHAR sBuf[80];
+ StringCchPrintf( sBuf, 80, TEXT("ERROR: GetPrivateProfileSection(): GetLastError returned %u\r\n"), GetError() );
+ Log( sBuf );
+ return false;
+ }
+ else if ( nRet + 2 >= rSize )
+ {
+ SetError( ERROR_OUTOFMEMORY );
+ Log( TEXT( "ERROR: GetPrivateProfileSection() out of memory\r\n" ) );
+ return false;
+ }
+
+ Log( TEXT( " GetProfileSection read %s\r\n" ), pSection );
+
+ return true;
+}
+
+//--------------------------------------------------------------------------
+boolean SetupAppX::ReadProfile()
+{
+ boolean bRet = false;
+ TCHAR *sProfilePath = 0;
+
+ if ( GetPathToFile( PROFILE_NAME, &sProfilePath ) )
+ {
+ DWORD nSize = 0;
+ LPTSTR pRetBuf = NULL;
+
+ Log( TEXT( " Open ini file: <%s>\r\n" ), sProfilePath );
+
+ bRet = GetProfileSection( sProfilePath, SECTION_SETUP, nSize, &pRetBuf );
+
+ if ( !bRet )
+ {
+ LPTSTR pTmpFile = CopyIniFile( sProfilePath );
+ delete [] sProfilePath;
+ sProfilePath = pTmpFile;
+
+ if ( sProfilePath )
+ {
+ SetError( ERROR_SUCCESS );
+
+ Log( TEXT( " Could not open inifile, copied ini file to: <%s>\r\n" ), sProfilePath );
+ bRet = GetProfileSection( sProfilePath, SECTION_SETUP, nSize, &pRetBuf );
+ }
+ }
+
+ if ( bRet )
+ {
+ LPTSTR pCurLine = pRetBuf;
+ while ( *pCurLine )
+ {
+ LPTSTR pName = 0;
+ LPTSTR pValue = 0;
+
+ pCurLine += GetNameValue( pCurLine, &pName, &pValue );
+
+ if ( lstrcmpi( TEXT( "database" ), pName ) == 0 )
+ {
+ m_pDatabase = pValue;
+ Log( TEXT( " Database = %s\r\n" ), pValue );
+ }
+ else if ( lstrcmpi( TEXT( "msiversion" ), pName ) == 0 )
+ {
+ m_pReqVersion = pValue;
+ Log( TEXT( " msiversion = %s\r\n" ), pValue );
+ }
+ else if ( lstrcmpi( TEXT( "productname" ), pName ) == 0 )
+ {
+ m_pProductName = pValue;
+ Log( TEXT( " productname = %s\r\n" ), pValue );
+ m_pAppTitle = SetProdToAppTitle( m_pProductName );
+ }
+ else if ( lstrcmpi( TEXT( "upgradekey" ), pName ) == 0 )
+ {
+ m_pUpgradeKey = pValue;
+ Log( TEXT( " upgradekey = %s\r\n" ), pValue );
+ }
+ else if ( lstrcmpi( TEXT( "productversion" ), pName ) == 0 )
+ {
+ m_pProductVersion = pValue;
+ Log( TEXT( " productversion = %s\r\n" ), pValue );
+ }
+ else if ( lstrcmpi( TEXT( "productcode" ), pName ) == 0 )
+ {
+ delete [] pValue;
+ }
+ else
+ {
+ Log( TEXT( "Warning: unknown entry in profile <%s>\r\n" ), pName );
+ delete [] pValue;
+ }
+ }
+ }
+
+ if ( bRet && ( !m_pDatabase || !m_pReqVersion || !m_pProductName ) )
+ {
+ Log( TEXT( "ERROR: incomplete 'Setup' section in profile\r\n" ) );
+ SetError( ERROR_INVALID_DATA );
+ bRet = false;
+ }
+
+ if ( bRet )
+ bRet = GetProfileSection( sProfilePath, SECTION_LANGUAGE, nSize, &pRetBuf );
+
+ if ( bRet )
+ {
+ LPTSTR pName = 0;
+ LPTSTR pValue = 0;
+ LPTSTR pCurLine = pRetBuf;
+ LPTSTR pLastChar;
+ int nNext = 0;
+
+ // first line in this section should be the language count
+ nNext = GetNameValue( pCurLine, &pName, &pValue );
+ if ( lstrcmpi( TEXT( "count" ), pName ) == 0 )
+ {
+ Log( TEXT( " Languages = %s\r\n" ), pValue );
+ m_nLanguageCount = _tcstol( pValue, &pLastChar, 10 );
+ pCurLine += nNext;
+ delete [] pValue;
+ }
+
+ m_ppLanguageList = new LanguageDataX*[ m_nLanguageCount ];
+
+ for ( int i=0; i < m_nLanguageCount; i++ )
+ {
+ if ( !*pCurLine )
+ {
+ m_nLanguageCount = i;
+ break;
+ }
+
+ pCurLine += GetNameValue( pCurLine, &pName, &pValue );
+ m_ppLanguageList[ i ] = new LanguageDataX( pValue );
+ Log( TEXT( " Language = %s\r\n" ), pValue );
+
+ if ( m_ppLanguageList[ i ]->m_pTransform )
+ Log( TEXT( " Transform = %s\r\n" ), m_ppLanguageList[ i ]->m_pTransform );
+
+ delete [] pValue;
+ }
+ }
+
+ if ( pRetBuf )
+ delete [] pRetBuf;
+ }
+
+ if ( sProfilePath && ! m_pTmpName )
+ delete [] sProfilePath;
+
+ return bRet;
+}
+
+//--------------------------------------------------------------------------
+void SetupAppX::AddFileToPatchList( TCHAR* pPath, TCHAR* pFile )
+{
+ if ( m_pPatchFiles == NULL )
+ {
+ m_pPatchFiles = new TCHAR[ MAX_STR_LENGTH ];
+ StringCchCopy( m_pPatchFiles, MAX_STR_LENGTH, TEXT("\"") );
+ }
+ else
+ StringCchCat( m_pPatchFiles, MAX_STR_LENGTH, TEXT(";") );
+
+ StringCchCat( m_pPatchFiles, MAX_STR_LENGTH, pPath );
+ StringCchCat( m_pPatchFiles, MAX_STR_LENGTH, pFile );
+}
+
+//--------------------------------------------------------------------------
+boolean SetupAppX::GetPatches()
+{
+ boolean bRet = true;
+
+ int nPatternLen = lstrlen( m_pModuleFile ) + 7; // 1 for null terminator, 1 for back slash, 5 for extensions
+ TCHAR* pPattern = new TCHAR[ nPatternLen ];
+ TCHAR* pBaseDir = new TCHAR[ nPatternLen ];
+
+ // find 'setup.exe' in the path so we can remove it
+ TCHAR *pFilePart = 0;
+ if ( 0 == GetFullPathName( m_pModuleFile, nPatternLen, pPattern, &pFilePart ) )
+ {
+ SetError( WIN::GetLastError() );
+ bRet = false;
+ }
+ else
+ {
+ if ( pFilePart )
+ *pFilePart = '\0';
+ StringCchCopy( pBaseDir, nPatternLen, pPattern );
+ StringCchCat( pPattern, nPatternLen, TEXT("*.msp") );
+
+ WIN32_FIND_DATA aFindFileData;
+
+ HANDLE hFindPatches = FindFirstFile( pPattern, &aFindFileData );
+
+ if ( hFindPatches != INVALID_HANDLE_VALUE )
+ {
+ if ( ! IsPatchInstalled( pBaseDir, aFindFileData.cFileName ) )
+ AddFileToPatchList( pBaseDir, aFindFileData.cFileName );
+
+ while ( FindNextFile( hFindPatches, &aFindFileData ) )
+ {
+ if ( ! IsPatchInstalled( pBaseDir, aFindFileData.cFileName ) )
+ AddFileToPatchList( pBaseDir, aFindFileData.cFileName );
+ }
+
+ if ( m_pPatchFiles != NULL )
+ StringCchCat( m_pPatchFiles, MAX_STR_LENGTH, TEXT("\"") );
+
+ FindClose( hFindPatches );
+ }
+ }
+
+ delete [] pPattern;
+ delete [] pBaseDir;
+
+ return bRet;
+}
+
+//--------------------------------------------------------------------------
+boolean SetupAppX::GetPathToFile( TCHAR* pFileName, TCHAR** pPath )
+{
+ // generate the path to the file = szModuleFile + FileName
+ // note: FileName is a relative path
+
+ boolean bRet = true;
+
+ int nTempPath = lstrlen( m_pModuleFile ) + lstrlen( pFileName ) + 2; // 1 for null terminator, 1 for back slash
+ TCHAR* pTempPath = new TCHAR[ nTempPath ];
+
+ // find 'setup.exe' in the path so we can remove it
+ TCHAR *pFilePart = 0;
+ if ( 0 == GetFullPathName( m_pModuleFile, nTempPath, pTempPath, &pFilePart ) )
+ {
+ SetError( WIN::GetLastError() );
+ bRet = false;
+ }
+ else
+ {
+ if ( pFilePart )
+ *pFilePart = '\0';
+
+ StringCchCat( pTempPath, nTempPath, pFileName );
+
+ int nPath = 2 * nTempPath;
+ *pPath = new TCHAR[ nPath ];
+
+ // normalize the path
+ int nReturn = GetFullPathName( pTempPath, nPath, *pPath, &pFilePart );
+
+ if ( nReturn > nPath )
+ {
+ // try again, with larger buffer
+ delete [] (*pPath);
+ nPath = nReturn;
+ *pPath = new TCHAR[ nPath ];
+
+ nReturn = GetFullPathName( pTempPath, nPath, *pPath, &pFilePart );
+ }
+
+ if ( 0 == nReturn )
+ {
+ // error -- invalid path
+ SetError( WIN::GetLastError() );
+ bRet = false;
+ }
+ }
+
+ if ( bRet ) // check for the file's existence
+ {
+ DWORD dwFileAttrib = GetFileAttributes( *pPath );
+
+ if (0xFFFFFFFF == dwFileAttrib)
+ {
+ StringCchCopy( m_pErrorText, MAX_TEXT_LENGTH, pFileName );
+ SetError( ERROR_FILE_NOT_FOUND );
+ bRet = false;
+ }
+ }
+
+ delete [] pTempPath;
+ return bRet;
+}
+
+//--------------------------------------------------------------------------
+int SetupAppX::GetNameValue( TCHAR* pLine, TCHAR** pName, TCHAR** pValue )
+{
+ int nRet = lstrlen( pLine ) + 1;
+ *pValue = 0;
+
+ if ( nRet == 1 )
+ return nRet;
+
+ LPTSTR pChar = pLine;
+ LPTSTR pLast = NULL;
+
+ // Skip leading spaces.
+ while (' ' == *pChar || '\t' == *pChar)
+ pChar = CharNext( pChar );
+
+ *pName = pChar;
+
+ // look for the end of the name
+ while( *pChar && (' ' != *pChar) &&
+ ( '\t' != *pChar ) && ( '=' != *pChar ) )
+ pChar = CharNext( pChar );
+
+ if ( ! *pChar )
+ return nRet;
+
+ pLast = pChar;
+ pChar = CharNext( pChar );
+ *pLast = '\0';
+
+ // look for the start of the value
+ while( ( ' ' == *pChar ) || ( '\t' == *pChar ) ||
+ ( '=' == *pChar ) )
+ pChar = CharNext( pChar );
+
+ int nValueLen = lstrlen( pChar ) + 1;
+ *pValue = new TCHAR[ nValueLen ];
+
+ if ( *pValue )
+ StringCchCopy( *pValue, nValueLen, pChar );
+
+ return nRet;
+}
+
+//--------------------------------------------------------------------------
+boolean SetupAppX::ChooseLanguage( long& rLanguage )
+{
+ rLanguage = 0;
+
+ if ( m_bQuiet )
+ return true;
+
+ // When there are none or only one language, there is nothing
+ // to do here
+ if ( m_nLanguageCount > 1 )
+ {
+ TCHAR *sString = new TCHAR[ MAX_LANGUAGE_LEN ];
+
+ LANGID nUserDefLang = GetUserDefaultLangID();
+ LANGID nSysDefLang = GetSystemDefaultLangID();
+
+ int nUserPrimary = PRIMARYLANGID( nUserDefLang );
+ int nSysPrimary = PRIMARYLANGID( nSysDefLang );
+
+ long nUserIndex = -1;
+ long nUserPrimIndex = -1;
+ long nSystemIndex = -1;
+ long nSystemPrimIndex = -1;
+ long nParamIndex = -1;
+
+ for ( long i=0; i<GetLanguageCount(); i++ )
+ {
+ long nLanguage = GetLanguageID( i );
+ int nPrimary = PRIMARYLANGID( nLanguage );
+ GetLanguageName( nLanguage, sString );
+ Log( TEXT( " Info: found Language: %s\r\n" ), sString );
+
+ if ( nLanguage == nUserDefLang )
+ nUserIndex = i;
+ if ( nPrimary == nUserPrimary )
+ nUserPrimIndex = i;
+ if ( nLanguage == nSysDefLang )
+ nSystemIndex = i;
+ if ( nPrimary == nSysPrimary )
+ nSystemPrimIndex = i;
+ if ( m_nLanguageID && ( nLanguage == m_nLanguageID ) )
+ nParamIndex = i;
+ }
+
+ if ( m_nLanguageID && ( nParamIndex == -1 ) )
+ {
+ Log( TEXT( "Warning: Language chosen with parameter -lang not found.\r\n" ) );
+ }
+
+ if ( nParamIndex != -1 )
+ {
+ Log( TEXT( "Info: Found language chosen with parameter -lang.\r\n" ) );
+ rLanguage = GetLanguageID( nParamIndex );
+ }
+ else if ( nUserIndex != -1 )
+ {
+ Log( TEXT( "Info: Found user default language.\r\n" ) );
+ rLanguage = GetLanguageID( nUserIndex );
+ }
+ else if ( nUserPrimIndex != -1 )
+ {
+ Log( TEXT( "Info: Found user default primary language.\r\n" ) );
+ rLanguage = GetLanguageID( nUserPrimIndex );
+ }
+ else if ( nSystemIndex != -1 )
+ {
+ Log( TEXT( "Info: Found system default language.\r\n" ) );
+ rLanguage = GetLanguageID( nSystemIndex );
+ }
+ else if ( nSystemPrimIndex != -1 )
+ {
+ Log( TEXT( "Info: Found system default primary language.\r\n" ) );
+ rLanguage = GetLanguageID( nSystemPrimIndex );
+ }
+ else
+ {
+ Log( TEXT( "Info: Use default language from ini file.\r\n" ) );
+ rLanguage = GetLanguageID( 0 );
+ }
+ delete [] sString;
+ }
+
+ return true;
+}
+
+//--------------------------------------------------------------------------
+HMODULE SetupAppX::LoadMsiLibrary()
+{
+ HMODULE hMsi = NULL;
+ HKEY hInstKey = NULL;
+
+ // find registered location of Msi.dll
+ if ( ERROR_SUCCESS == RegOpenKeyEx( HKEY_LOCAL_MACHINE, sInstKey, 0, KEY_READ, &hInstKey ) )
+ {
+ long nRet = ERROR_SUCCESS;
+ TCHAR *sMsiFolder = new TCHAR[ MAX_PATH + 1 ];
+ DWORD dwMsiFolderSize = MAX_PATH + 1;
+ DWORD dwType = 0;
+
+ if ( ERROR_MORE_DATA == ( nRet = RegQueryValueEx( hInstKey, sInstLocValue, NULL,
+ &dwType, (BYTE*)sMsiFolder, &dwMsiFolderSize ) ) )
+ {
+ // try again with larger buffer
+ delete [] sMsiFolder;
+ sMsiFolder = new TCHAR[ dwMsiFolderSize ];
+
+ nRet = RegQueryValueEx( hInstKey, sInstLocValue, NULL, &dwType,
+ (BYTE*)sMsiFolder, &dwMsiFolderSize );
+ }
+
+ if ( ERROR_SUCCESS == nRet && dwType == REG_SZ && dwMsiFolderSize > 0 )
+ {
+ // load Msi.dll from registered location
+ int nLength = lstrlen( sMsiDll ) + dwMsiFolderSize + 1; // use StringCchLength ?
+ TCHAR *pMsiLocation = new TCHAR[ nLength ];
+
+ if ( SUCCEEDED( StringCchCopy( pMsiLocation, nLength, sMsiFolder ) ) &&
+ SUCCEEDED( StringCchCat( pMsiLocation, nLength, sMsiDll ) ) )
+ {
+ hMsi = LoadLibrary( pMsiLocation );
+ }
+ }
+ }
+
+ if ( !hMsi ) // use the default location
+ {
+ hMsi = LoadLibrary( sMsiDll );
+ }
+
+ return hMsi;
+}
+
+//--------------------------------------------------------------------------
+LPCTSTR SetupAppX::GetPathToMSI()
+{
+ LPTSTR sMsiPath = NULL;
+ HKEY hInstKey = NULL;
+ TCHAR *sMsiFolder = new TCHAR[ MAX_PATH + 1 ];
+ DWORD nMsiFolderSize = MAX_PATH + 1;
+
+ sMsiFolder[0] = '\0';
+
+ // find registered location of Msi.dll
+ if ( ERROR_SUCCESS == RegOpenKeyEx( HKEY_LOCAL_MACHINE, sInstKey, 0, KEY_READ, &hInstKey ) )
+ {
+ LONG nRet = ERROR_SUCCESS;
+ DWORD dwType = 0;
+
+ if ( ERROR_MORE_DATA == ( nRet = RegQueryValueEx( hInstKey, sInstLocValue, NULL,
+ &dwType, (BYTE*)sMsiFolder, &nMsiFolderSize ) ) )
+ {
+ // try again with larger buffer
+ delete [] sMsiFolder;
+ sMsiFolder = new TCHAR[ nMsiFolderSize ];
+
+ nRet = RegQueryValueEx( hInstKey, sInstLocValue, NULL, &dwType,
+ (BYTE*)sMsiFolder, &nMsiFolderSize );
+ }
+
+ if ( ERROR_SUCCESS != nRet || dwType != REG_SZ || nMsiFolderSize == 0 )
+ sMsiFolder[0] = '\0';
+ }
+
+ if ( sMsiFolder[0] == '\0' ) // use the default location
+ {
+ Log( TEXT( " Could not find path to msiexec.exe in registry" ) );
+
+ DWORD nRet = WIN::GetSystemDirectory( sMsiFolder, nMsiFolderSize );
+ if ( nRet > nMsiFolderSize )
+ {
+ delete [] sMsiFolder;
+ sMsiFolder = new TCHAR[ nRet ];
+ nMsiFolderSize = nRet;
+
+ nRet = WIN::GetSystemDirectory( sMsiFolder, nMsiFolderSize );
+ }
+ if ( 0 == nRet )
+ {
+ sMsiFolder[0] = '\0';
+ SetError( WIN::GetLastError() );
+ }
+ nMsiFolderSize = nRet;
+ }
+
+ if ( sMsiFolder[0] != '\0' )
+ {
+ int nLength = lstrlen( sMsiExe ) + lstrlen( sMsiFolder ) + 1;
+ sMsiPath = new TCHAR[ nLength ];
+
+ if ( FAILED( StringCchCopy( sMsiPath, nLength, sMsiFolder ) ) ||
+ FAILED( StringCchCat( sMsiPath, nLength, sMsiExe ) ) )
+ {
+ delete [] sMsiPath;
+ sMsiPath = NULL;
+ }
+ }
+
+ if ( ! sMsiPath )
+ Log( TEXT( "ERROR: Can't build path to msiexec.exe!" ) );
+
+ return sMsiPath;
+}
+
+//--------------------------------------------------------------------------
+boolean SetupAppX::LaunchInstaller( LPCTSTR pParam )
+{
+ LPCTSTR sMsiPath = GetPathToMSI();
+
+ if ( !sMsiPath )
+ {
+ Log( TEXT( "ERROR: msiexec not found!" ) );
+ SetError( ERROR_FILE_NOT_FOUND );
+ return false;
+ }
+
+ STARTUPINFO aSUI;
+ PROCESS_INFORMATION aPI;
+
+ Log( TEXT( " Will install using <%s>\r\n" ), sMsiPath );
+ Log( TEXT( " Parameters are: %s\r\n" ), pParam );
+
+ OutputDebugStringFormat( TEXT( " Will install using <%s>\r\n" ), sMsiPath );
+ OutputDebugStringFormat( TEXT( " Parameters are: %s\r\n" ), pParam );
+
+ ZeroMemory( (void*)&aPI, sizeof( PROCESS_INFORMATION ) );
+ ZeroMemory( (void*)&aSUI, sizeof( STARTUPINFO ) );
+
+ aSUI.cb = sizeof(STARTUPINFO);
+ aSUI.dwFlags = STARTF_USESHOWWINDOW;
+ aSUI.wShowWindow = SW_SHOW;
+
+ DWORD nCmdLineLength = lstrlen( sMsiPath ) + lstrlen( pParam ) + 2;
+ TCHAR *sCmdLine = new TCHAR[ nCmdLineLength ];
+
+ if ( FAILED( StringCchCopy( sCmdLine, nCmdLineLength, sMsiPath ) ) ||
+ FAILED( StringCchCat( sCmdLine, nCmdLineLength, TEXT( " " ) ) ) ||
+ FAILED( StringCchCat( sCmdLine, nCmdLineLength, pParam ) ) )
+ {
+ delete [] sCmdLine;
+ SetError( ERROR_INSTALL_FAILURE );
+ return false;
+ }
+
+ if ( !WIN::CreateProcess( NULL, sCmdLine, NULL, NULL, FALSE,
+ CREATE_DEFAULT_ERROR_MODE, NULL, NULL,
+ &aSUI, &aPI ) )
+ {
+ Log( TEXT( "ERROR: Could not create process %s.\r\n" ), sCmdLine );
+ SetError( WIN::GetLastError() );
+ delete [] sCmdLine;
+ return false;
+ }
+
+ DWORD nResult = WaitForProcess( aPI.hProcess );
+ bool bRet = true;
+
+ if( ERROR_SUCCESS != nResult )
+ {
+ Log( TEXT( "ERROR: While waiting for %s.\r\n" ), sCmdLine );
+ SetError( nResult );
+ bRet = false;
+ }
+ else
+ {
+ GetExitCodeProcess( aPI.hProcess, &nResult );
+ SetError( nResult );
+
+ if ( nResult != ERROR_SUCCESS )
+ {
+ TCHAR sBuf[80];
+ StringCchPrintf( sBuf, 80, TEXT("Warning: msiexec returned %u.\r\n"), nResult );
+ Log( sBuf );
+ }
+ else
+ Log( TEXT( " Installation completed successfully.\r\n" ) );
+ }
+
+ CloseHandle( aPI.hProcess );
+
+ delete [] sCmdLine;
+
+ return bRet;
+}
+
+//--------------------------------------------------------------------------
+boolean SetupAppX::Install( long nLanguage )
+{
+ LPTSTR pTransform = NULL;
+
+ if ( nLanguage ) // look for transformation
+ {
+ for ( int i = 0; i < m_nLanguageCount; i++ )
+ {
+ if ( m_ppLanguageList[i]->m_nLanguageID == nLanguage )
+ {
+ if ( m_ppLanguageList[i]->m_pTransform )
+ {
+ if ( !GetPathToFile( m_ppLanguageList[i]->m_pTransform,
+ &pTransform ) )
+ {
+ Log( TEXT( "ERROR: Could not find transform <%s\r\n" ), m_ppLanguageList[i]->m_pTransform );
+ return false;
+ }
+ }
+ break;
+ }
+ }
+ }
+
+ TCHAR *pDataBasePath = NULL;
+
+ if ( ! GetPathToFile( m_pDatabase, &pDataBasePath ) )
+ {
+ Log( TEXT( "ERROR: Could not find database <%s\r\n" ), m_pDatabase );
+ SetError( ERROR_INSTALL_SOURCE_ABSENT );
+ return false;
+ }
+
+ // we will always use the parameter setup used
+ int nParLen = lstrlen( PARAM_SETUP_USED );
+
+ if ( m_bRegNoMsoTypes )
+ nParLen += lstrlen( PARAM_REG_NO_MSO_TYPES );
+ else if ( m_bRegAllMsoTypes )
+ nParLen += lstrlen( PARAM_REG_ALL_MSO_TYPES );
+
+ if ( m_pAdvertise )
+ nParLen += lstrlen( m_pAdvertise ) + 1; // one for the space
+ else if ( m_bIsMinorUpgrade )
+ nParLen += lstrlen( PARAM_MINOR_UPGRADE );
+ else
+ nParLen += lstrlen( PARAM_PACKAGE );
+
+ nParLen += lstrlen( pDataBasePath ) + 3; // two quotes, one null
+
+ if ( NeedReboot() )
+ nParLen += lstrlen( PARAM_REBOOT );
+
+ if ( m_pPatchFiles )
+ {
+ nParLen += lstrlen( PARAM_PATCH );
+ nParLen += lstrlen( m_pPatchFiles );
+ }
+
+ if ( pTransform )
+ {
+ nParLen += lstrlen( PARAM_TRANSFORM );
+ nParLen += lstrlen( pTransform ) + 2; // two quotes
+ }
+
+ if ( m_pCmdLine )
+ nParLen += lstrlen( m_pCmdLine ) + 1; // one for the space;
+
+ TCHAR *pParams = new TCHAR[ nParLen ];
+
+ StringCchCopy( pParams, nParLen, PARAM_SETUP_USED );
+
+ if ( m_bRegNoMsoTypes )
+ StringCchCat( pParams, nParLen, PARAM_REG_NO_MSO_TYPES );
+ else if ( m_bRegAllMsoTypes )
+ StringCchCat( pParams, nParLen, PARAM_REG_ALL_MSO_TYPES );
+
+ if ( m_pAdvertise )
+ StringCchCat( pParams, nParLen, m_pAdvertise );
+ else if ( IsAdminInstall() )
+ StringCchCat( pParams, nParLen, PARAM_ADMIN );
+ else if ( m_bIsMinorUpgrade )
+ StringCchCat( pParams, nParLen, PARAM_MINOR_UPGRADE );
+ else
+ StringCchCat( pParams, nParLen, PARAM_PACKAGE );
+
+ StringCchCat( pParams, nParLen, TEXT( "\"" ) );
+ StringCchCat( pParams, nParLen, pDataBasePath );
+ StringCchCat( pParams, nParLen, TEXT( "\"" ) );
+
+ if ( NeedReboot() )
+ StringCchCat( pParams, nParLen, PARAM_REBOOT );
+
+ if ( m_pPatchFiles )
+ {
+ StringCchCat( pParams, nParLen, PARAM_PATCH );
+ StringCchCat( pParams, nParLen, m_pPatchFiles );
+ }
+
+ if ( pTransform )
+ {
+ StringCchCat( pParams, nParLen, PARAM_TRANSFORM );
+ StringCchCat( pParams, nParLen, TEXT( "\"" ) );
+ StringCchCat( pParams, nParLen, pTransform );
+ StringCchCat( pParams, nParLen, TEXT( "\"" ) );
+ }
+
+ if ( m_pCmdLine )
+ {
+ StringCchCat( pParams, nParLen, TEXT( " " ) );
+ StringCchCat( pParams, nParLen, m_pCmdLine );
+ }
+
+ return LaunchInstaller( pParams );
+}
+
+//--------------------------------------------------------------------------
+UINT SetupAppX::GetError() const
+{
+ UINT nErr = 0;
+
+ if ( m_pMSIErrorCode )
+ nErr = (UINT) *m_pMSIErrorCode;
+
+ if ( nErr == 0 )
+ nErr = m_uiRet;
+
+ if ( nErr != 0 )
+ OutputDebugStringFormat( TEXT("Setup will return error (%d).\n"), nErr );
+ return nErr;
+}
+
+//--------------------------------------------------------------------------
+void SetupAppX::DisplayError( UINT nErr ) const
+{
+ TCHAR sError[ MAX_TEXT_LENGTH ] = {0};
+ TCHAR sTmp[ MAX_TEXT_LENGTH ] = {0};
+
+ UINT nMsgType = MB_OK | MB_ICONERROR;
+
+ switch ( nErr )
+ {
+ case ERROR_SUCCESS: break; // 0
+
+ case ERROR_FILE_NOT_FOUND: // 2
+ WIN::LoadString( m_hInst, IDS_FILE_NOT_FOUND, sTmp, MAX_TEXT_LENGTH );
+ StringCchPrintf( sError, MAX_TEXT_LENGTH, sTmp, m_pErrorText );
+ break;
+ case ERROR_INVALID_DATA: // 13
+ WIN::LoadString( m_hInst, IDS_INVALID_PROFILE, sError, MAX_TEXT_LENGTH );
+ break;
+ case ERROR_OUTOFMEMORY: WIN::LoadString( m_hInst, IDS_OUTOFMEM, sError, MAX_TEXT_LENGTH );
+ break;
+ case ERROR_INSTALL_USEREXIT:
+ WIN::LoadString( m_hInst, IDS_USER_CANCELLED, sError, MAX_TEXT_LENGTH );
+ break;
+ case ERROR_INSTALL_ALREADY_RUNNING: // 1618
+ WIN::LoadString( m_hInst, IDS_ALREADY_RUNNING, sError, MAX_TEXT_LENGTH );
+ break;
+ case ERROR_INSTALL_SOURCE_ABSENT:
+ WIN::LoadString( m_hInst, IDS_NOMSI, sError, MAX_TEXT_LENGTH );
+ break;
+ case ERROR_DS_INSUFF_ACCESS_RIGHTS: // 8344
+ WIN::LoadString( m_hInst, IDS_REQUIRES_ADMIN_PRIV, sError, MAX_TEXT_LENGTH );
+ break;
+ case E_ABORT: WIN::LoadString( m_hInst, IDS_UNKNOWN_ERROR, sError, MAX_TEXT_LENGTH );
+ break;
+ case ERROR_INVALID_PARAMETER: // 87
+ WIN::LoadString( m_hInst, IDS_INVALID_PARAM, sTmp, MAX_TEXT_LENGTH );
+ StringCchPrintf( sError, MAX_TEXT_LENGTH, sTmp, m_pErrorText );
+ break;
+
+ case ERROR_SETUP_TO_OLD: // - 3
+ WIN::LoadString( m_hInst, IDS_SETUP_TO_OLD, sTmp, MAX_TEXT_LENGTH );
+ StringCchPrintf( sError, MAX_TEXT_LENGTH, sTmp, m_pReqVersion, m_pErrorText );
+ break;
+ case ERROR_SETUP_NOT_FOUND: // - 4
+ WIN::LoadString( m_hInst, IDS_SETUP_NOT_FOUND, sTmp, MAX_TEXT_LENGTH );
+ StringCchPrintf( sError, MAX_TEXT_LENGTH, sTmp, m_pReqVersion );
+ break;
+ case ERROR_SHOW_USAGE: // - 2
+ nMsgType = MB_OK | MB_ICONINFORMATION;
+ WIN::LoadString( m_hInst, IDS_USAGE, sError, MAX_TEXT_LENGTH );
+ break;
+
+ default: WIN::LoadString( m_hInst, IDS_UNKNOWN_ERROR, sError, MAX_TEXT_LENGTH );
+ break;
+ }
+
+ if ( sError[0] )
+ {
+ if ( !m_bQuiet )
+ {
+ ConvertNewline( sError );
+ WIN::MessageBox( NULL, sError, m_pAppTitle, nMsgType );
+ }
+
+ Log( TEXT( "ERROR: %s\r\n" ), sError );
+ }
+}
+
+//--------------------------------------------------------------------------
+long SetupAppX::GetLanguageID( long nIndex ) const
+{
+ if ( nIndex >=0 && nIndex < m_nLanguageCount )
+ return m_ppLanguageList[ nIndex ]->m_nLanguageID;
+ else
+ return 0;
+}
+
+//--------------------------------------------------------------------------
+void SetupAppX::GetLanguageName( long nLanguage, LPTSTR sName ) const
+{
+ switch ( nLanguage )
+ {
+ case 1028: WIN::LoadString( m_hInst, IDS_LANGUAGE_ZH_TW, sName, MAX_LANGUAGE_LEN ); break;
+ case 1029: WIN::LoadString( m_hInst, IDS_LANGUAGE_CS, sName, MAX_LANGUAGE_LEN ); break;
+ case 1030: WIN::LoadString( m_hInst, IDS_LANGUAGE_DA, sName, MAX_LANGUAGE_LEN ); break;
+ case 1031: WIN::LoadString( m_hInst, IDS_LANGUAGE_DE_DE, sName, MAX_LANGUAGE_LEN ); break;
+ case 1032: WIN::LoadString( m_hInst, IDS_LANGUAGE_EL, sName, MAX_LANGUAGE_LEN ); break;
+ case 1033: WIN::LoadString( m_hInst, IDS_LANGUAGE_EN_US, sName, MAX_LANGUAGE_LEN ); break;
+ case 1034: WIN::LoadString( m_hInst, IDS_LANGUAGE_ES, sName, MAX_LANGUAGE_LEN ); break;
+ case 1035: WIN::LoadString( m_hInst, IDS_LANGUAGE_FI, sName, MAX_LANGUAGE_LEN ); break;
+ case 1036: WIN::LoadString( m_hInst, IDS_LANGUAGE_FR_FR, sName, MAX_LANGUAGE_LEN ); break;
+ case 1037: WIN::LoadString( m_hInst, IDS_LANGUAGE_HE, sName, MAX_LANGUAGE_LEN ); break;
+ case 1038: WIN::LoadString( m_hInst, IDS_LANGUAGE_HU, sName, MAX_LANGUAGE_LEN ); break;
+ case 1040: WIN::LoadString( m_hInst, IDS_LANGUAGE_IT_IT, sName, MAX_LANGUAGE_LEN ); break;
+ case 1041: WIN::LoadString( m_hInst, IDS_LANGUAGE_JA, sName, MAX_LANGUAGE_LEN ); break;
+ case 1042: WIN::LoadString( m_hInst, IDS_LANGUAGE_KO, sName, MAX_LANGUAGE_LEN ); break;
+ case 1043: WIN::LoadString( m_hInst, IDS_LANGUAGE_NL_NL, sName, MAX_LANGUAGE_LEN ); break;
+ case 1044: WIN::LoadString( m_hInst, IDS_LANGUAGE_NO_NO, sName, MAX_LANGUAGE_LEN ); break;
+ case 1045: WIN::LoadString( m_hInst, IDS_LANGUAGE_PL, sName, MAX_LANGUAGE_LEN ); break;
+ case 1046: WIN::LoadString( m_hInst, IDS_LANGUAGE_PT_BR, sName, MAX_LANGUAGE_LEN ); break;
+ case 1049: WIN::LoadString( m_hInst, IDS_LANGUAGE_RU, sName, MAX_LANGUAGE_LEN ); break;
+ case 1051: WIN::LoadString( m_hInst, IDS_LANGUAGE_SK, sName, MAX_LANGUAGE_LEN ); break;
+ case 1053: WIN::LoadString( m_hInst, IDS_LANGUAGE_SV_SE, sName, MAX_LANGUAGE_LEN ); break;
+ case 1054: WIN::LoadString( m_hInst, IDS_LANGUAGE_TH, sName, MAX_LANGUAGE_LEN ); break;
+ case 1055: WIN::LoadString( m_hInst, IDS_LANGUAGE_TR, sName, MAX_LANGUAGE_LEN ); break;
+ case 1061: WIN::LoadString( m_hInst, IDS_LANGUAGE_ET, sName, MAX_LANGUAGE_LEN ); break;
+ case 2052: WIN::LoadString( m_hInst, IDS_LANGUAGE_ZH_CN, sName, MAX_LANGUAGE_LEN ); break;
+ case 2070: WIN::LoadString( m_hInst, IDS_LANGUAGE_PT_PT, sName, MAX_LANGUAGE_LEN ); break;
+
+ default:
+ {
+ TCHAR sTmp[ MAX_LANGUAGE_LEN ] = {0};
+
+ WIN::LoadString( m_hInst, IDS_UNKNOWN_LANG, sTmp, MAX_LANGUAGE_LEN );
+ StringCchPrintf( sName, MAX_LANGUAGE_LEN, sTmp, nLanguage );
+ }
+ }
+}
+
+//--------------------------------------------------------------------------
+boolean SetupAppX::CheckVersion()
+{
+ boolean bRet = false;
+ HMODULE hMsi = LoadMsiLibrary();
+
+ Log( TEXT( " Looking for installed MSI with version >= %s\r\n" ), m_pReqVersion );
+
+ if ( !hMsi )
+ {
+ Log( TEXT( "Error: No MSI found!\r\n" ) );
+ SetError( (UINT) ERROR_SETUP_NOT_FOUND );
+ }
+ else
+ {
+ PFnDllGetVersion pDllGetVersion = (PFnDllGetVersion) GetProcAddress( hMsi, MSIAPI_DllGetVersion );
+
+ if ( pDllGetVersion )
+ {
+ DLLVERSIONINFO aInfo;
+
+ aInfo.cbSize = sizeof( DLLVERSIONINFO );
+ if ( NOERROR == pDllGetVersion( &aInfo ) )
+ {
+ TCHAR pMsiVersion[ VERSION_SIZE ];
+ StringCchPrintf( pMsiVersion, VERSION_SIZE, TEXT("%d.%d.%4d"),
+ aInfo.dwMajorVersion,
+ aInfo.dwMinorVersion,
+ aInfo.dwBuildNumber );
+ if ( _tcsncmp( pMsiVersion, m_pReqVersion, _tcslen( pMsiVersion ) ) < 0 )
+ {
+ StringCchCopy( m_pErrorText, MAX_TEXT_LENGTH, pMsiVersion );
+ SetError( (UINT) ERROR_SETUP_TO_OLD );
+ Log( TEXT( "Warning: Old MSI version found <%s>, update needed!\r\n" ), pMsiVersion );
+ }
+ else
+ {
+ Log( TEXT( " Found MSI version <%s>, no update needed\r\n" ), pMsiVersion );
+ bRet = true;
+ }
+ if ( aInfo.dwMajorVersion >= 3 )
+ m_bSupportsPatch = true;
+ else
+ Log( TEXT("Warning: Patching not supported! MSI-Version <%s>\r\n"), pMsiVersion );
+ }
+ }
+
+ FreeLibrary( hMsi );
+ }
+
+ return bRet;
+}
+
+//--------------------------------------------------------------------------
+boolean SetupAppX::CheckForUpgrade()
+{
+ // When we have patch files we will never try an Minor upgrade
+ if ( m_pPatchFiles ) return true;
+
+ if ( !m_pUpgradeKey || ( _tcslen( m_pUpgradeKey ) == 0 ) )
+ {
+ Log( TEXT( " No Upgrade Key Found -> continue with standard installation!\r\n" ) );
+ return true;
+ }
+
+ HKEY hInstKey = NULL;
+
+ if ( ERROR_SUCCESS == RegOpenKeyEx( HKEY_LOCAL_MACHINE, m_pUpgradeKey, 0, KEY_READ, &hInstKey ) )
+ {
+ Log( TEXT( " Found Upgrade Key in Registry (HKLM) -> will try minor upgrade!\r\n" ) );
+ m_bIsMinorUpgrade = true;
+ }
+ else if ( ERROR_SUCCESS == RegOpenKeyEx( HKEY_CURRENT_USER, m_pUpgradeKey, 0, KEY_READ, &hInstKey ) )
+ {
+ Log( TEXT( " Found Upgrade Key in Registry (HKCU) -> will try minor upgrade!\r\n" ) );
+ m_bIsMinorUpgrade = true;
+ }
+ else
+ {
+ Log( TEXT( " Didn't Find Upgrade Key in Registry -> continue with standard installation!\r\n" ) );
+ return true;
+ }
+
+ if ( m_pProductVersion && ( _tcslen( m_pProductVersion ) > 0 ) )
+ {
+ TCHAR *sProductVersion = new TCHAR[ MAX_PATH + 1 ];
+ DWORD nSize = MAX_PATH + 1;
+
+ sProductVersion[0] = '\0';
+
+ // get product version
+ if ( ERROR_SUCCESS == RegQueryValueEx( hInstKey, PRODUCT_VERSION, NULL, NULL, (LPBYTE)sProductVersion, &nSize ) )
+ {
+ if ( lstrcmpi( sProductVersion, m_pProductVersion ) == 0 )
+ {
+ Log( TEXT( " Same Product Version already installed, no minor upgrade!\r\n" ) );
+ m_bIsMinorUpgrade = false;
+ }
+ }
+
+ delete [] sProductVersion;
+ }
+
+ return true;
+}
+
+//--------------------------------------------------------------------------
+boolean SetupAppX::IsTerminalServerInstalled() const
+{
+ boolean bIsTerminalServer = false;
+
+ const TCHAR sSearchStr[] = TEXT("Terminal Server");
+ const TCHAR sKey[] = TEXT("System\\CurrentControlSet\\Control\\ProductOptions");
+ const TCHAR sValue[] = TEXT("ProductSuite");
+
+ DWORD dwSize = 0;
+ HKEY hKey = 0;
+ DWORD dwType = 0;
+
+ if ( ERROR_SUCCESS == RegOpenKeyEx( HKEY_LOCAL_MACHINE, sKey, 0, KEY_READ, &hKey ) &&
+ ERROR_SUCCESS == RegQueryValueEx( hKey, sValue, NULL, &dwType, NULL, &dwSize ) &&
+ dwSize > 0 &&
+ REG_MULTI_SZ == dwType )
+ {
+ TCHAR* sSuiteList = new TCHAR[ (dwSize*sizeof(byte)/sizeof(TCHAR)) + 1 ];
+
+ ZeroMemory(sSuiteList, dwSize);
+
+ if ( ERROR_SUCCESS == RegQueryValueEx( hKey, sValue, NULL, &dwType, (LPBYTE)sSuiteList, &dwSize) )
+ {
+ DWORD nMulti = 0;
+ DWORD nSrch = lstrlen( sSearchStr );
+ const TCHAR *sSubString = sSuiteList;
+
+ while (*sSubString)
+ {
+ nMulti = lstrlen( sSubString );
+ if ( nMulti == nSrch && 0 == lstrcmp( sSearchStr, sSubString ) )
+ {
+ bIsTerminalServer = true;
+ break;
+ }
+
+ sSubString += (nMulti + 1);
+ }
+ }
+ delete [] sSuiteList;
+ }
+
+ if ( hKey )
+ RegCloseKey( hKey );
+
+ return bIsTerminalServer;
+}
+
+//--------------------------------------------------------------------------
+boolean SetupAppX::AlreadyRunning() const
+{
+ if ( m_bIgnoreAlreadyRunning )
+ {
+ Log( TEXT("Ignoring already running MSI instance!\r\n") );
+ return false;
+ }
+
+ const TCHAR *sMutexName = NULL;
+ const TCHAR sGUniqueName[] = TEXT( "Global\\_MSISETUP_{EA8130C1-8D3D-4338-9309-1A52D530D846}" );
+ const TCHAR sUniqueName[] = TEXT( "_MSISETUP_{EA8130C1-8D3D-4338-9309-1A52D530D846}" );
+
+ if ( ( GetOSVersion() < 5 ) && ! IsTerminalServerInstalled() )
+ sMutexName = sUniqueName;
+ else
+ sMutexName = sGUniqueName;
+
+ HANDLE hMutex = 0;
+
+ hMutex = WIN::CreateMutex( NULL, FALSE, sMutexName );
+
+ if ( !hMutex || ERROR_ALREADY_EXISTS == WIN::GetLastError() )
+ {
+ if ( !hMutex )
+ Log( TEXT( "ERROR: AlreadyRunning() could not create mutex!\r\n" ) );
+ else
+ Log( TEXT( "ERROR: There's already a setup running!\r\n" ) );
+
+ return true;
+ }
+ Log( TEXT( " No running Setup found\r\n" ) );
+
+ return false;
+}
+
+//--------------------------------------------------------------------------
+DWORD SetupAppX::WaitForProcess( HANDLE hHandle )
+{
+ DWORD nResult = NOERROR;
+ boolean bLoop = true;
+
+ MSG aMsg;
+ ZeroMemory( (void*) &aMsg, sizeof(MSG) );
+
+ while ( bLoop )
+ {
+ switch ( WIN::MsgWaitForMultipleObjects( 1, &hHandle, false,
+ INFINITE, QS_ALLINPUT ) )
+ {
+ case WAIT_OBJECT_0: bLoop = false;
+ break;
+
+ case (WAIT_OBJECT_0 + 1):
+ {
+ if ( WIN::PeekMessage( &aMsg, NULL, NULL, NULL, PM_REMOVE ) )
+ {
+ WIN::TranslateMessage( &aMsg );
+ WIN::DispatchMessage( &aMsg );
+ }
+ break;
+ }
+
+ default:
+ {
+ nResult = WIN::GetLastError();
+ bLoop = false;
+ }
+ }
+ }
+
+ return nResult;
+}
+
+//--------------------------------------------------------------------------
+void SetupAppX::Log( LPCTSTR pMessage, LPCTSTR pText ) const
+{
+ if ( m_pLogFile )
+ {
+ static boolean bInit = false;
+
+ if ( !bInit )
+ {
+ bInit = true;
+ _ftprintf( m_pLogFile, TEXT("%c"), 0xfeff );
+
+ _tsetlocale( LC_ALL, TEXT("") );
+ _ftprintf( m_pLogFile, TEXT("\nCodepage=%s\nMultiByte Codepage=[%d]\n"),
+ _tsetlocale( LC_ALL, NULL ), _getmbcp() );
+ }
+ if ( pText )
+ {
+ _ftprintf( m_pLogFile, pMessage, pText );
+ OutputDebugStringFormat( pMessage, pText );
+ }
+ else
+ {
+ _ftprintf( m_pLogFile, pMessage );
+ OutputDebugStringFormat( pMessage );
+ }
+
+ fflush( m_pLogFile );
+ }
+}
+
+//--------------------------------------------------------------------------
+DWORD SetupAppX::GetNextArgument( LPCTSTR pStr, LPTSTR *pArg, LPTSTR *pNext,
+ boolean bStripQuotes )
+{
+ boolean bInQuotes = false;
+ boolean bFoundArgEnd = false;
+ LPCTSTR pChar = pStr;
+ LPCTSTR pFirst = NULL;
+
+ if ( NULL == pChar )
+ return ERROR_NO_MORE_ITEMS;
+
+ while ( ' ' == (*pChar) || '\t' == (*pChar) )
+ pChar = CharNext( pChar );
+
+ if ( '\0' == (*pChar) )
+ return ERROR_NO_MORE_ITEMS;
+
+ int nCount = 1;
+ pFirst = pChar;
+
+ while ( ! bFoundArgEnd )
+ {
+ if ( '\0' == (*pChar) )
+ bFoundArgEnd = true;
+ else if ( !bInQuotes && ' ' == (*pChar) )
+ bFoundArgEnd = true;
+ else if ( !bInQuotes && '\t' == (*pChar) )
+ bFoundArgEnd = true;
+ else
+ {
+ if ( '\"' == (*pChar) )
+ {
+ bInQuotes = !bInQuotes;
+ if ( bStripQuotes )
+ {
+ if ( pChar == pFirst )
+ pFirst = CharNext( pFirst );
+ nCount -= 1;
+ }
+ }
+
+ pChar = CharNext( pChar );
+ nCount += 1;
+ }
+ }
+
+ if ( pArg )
+ {
+ *pArg = new TCHAR[ nCount ];
+ StringCchCopyN ( *pArg, nCount, pFirst, nCount-1 );
+ }
+
+ if ( pNext )
+ *pNext = CharNext( pChar );
+
+ return ERROR_SUCCESS;
+}
+
+//--------------------------------------------------------------------------
+boolean SetupAppX::GetCmdLineParameters( LPTSTR *pCmdLine )
+{
+ int nRet = ERROR_SUCCESS;
+ LPTSTR pStart = NULL;
+ LPTSTR pNext = NULL;
+
+ if ( GetNextArgument( *pCmdLine, NULL, &pNext ) != ERROR_SUCCESS )
+ {
+ SetError( ERROR_NO_MORE_ITEMS );
+ return false;
+ }
+
+ int nSize = lstrlen( *pCmdLine ) + 2;
+ TCHAR *pNewCmdLine = new TCHAR[ nSize ];
+ pNewCmdLine[0] = '\0';
+
+ while ( GetNextArgument( pNext, &pStart, &pNext ) == ERROR_SUCCESS )
+ {
+ boolean bDeleteStart = true;
+
+ if ( (*pStart) == '/' || (*pStart) == '-' )
+ {
+ LPTSTR pSub = CharNext( pStart );
+ if ( (*pSub) == 'l' || (*pSub) == 'L' )
+ {
+ pSub = CharNext( pSub );
+ if ( (*pSub) == 'a' || (*pSub) == 'A' )
+ { // --- handle the lang parameter ---
+ LPTSTR pLanguage = NULL;
+ LPTSTR pLastChar;
+ if ( GetNextArgument( pNext, &pLanguage, &pNext, true ) != ERROR_SUCCESS )
+ {
+ StringCchCopy( m_pErrorText, MAX_TEXT_LENGTH, pStart );
+ nRet = ERROR_INVALID_PARAMETER;
+ break;
+ }
+
+ m_nLanguageID = _tcstol( pLanguage, &pLastChar, 10 );
+ delete [] pLanguage;
+ }
+ else
+ { // --- handle the l(og) parameter ---
+ boolean bAppend = false;
+ LPTSTR pFileName = NULL;
+
+ while ( *pSub )
+ {
+ if ( *pSub == '+' )
+ {
+ bAppend = true;
+ break;
+ }
+ pSub = CharNext( pSub );
+ }
+
+ if ( GetNextArgument( pNext, &pFileName, &pNext, true ) != ERROR_SUCCESS )
+ {
+ StringCchCopy( m_pErrorText, MAX_TEXT_LENGTH, pStart );
+ nRet = ERROR_INVALID_PARAMETER;
+ break;
+ }
+
+ if ( FAILED( StringCchCat( pNewCmdLine, nSize, pStart ) ) )
+ {
+ nRet = ERROR_OUTOFMEMORY;
+ break;
+ }
+ // we need to append a '+' otherwise msiexec would overwrite our log file
+ if ( !bAppend && FAILED( StringCchCat( pNewCmdLine, nSize, TEXT( "+" ) ) ) )
+ {
+ nRet = ERROR_OUTOFMEMORY;
+ break;
+ }
+ if ( FAILED( StringCchCat( pNewCmdLine, nSize, TEXT( " \"" ) ) ) ||
+ FAILED( StringCchCat( pNewCmdLine, nSize, pFileName ) ) ||
+ FAILED( StringCchCat( pNewCmdLine, nSize, TEXT( "\" " ) ) ) )
+ {
+ nRet = ERROR_OUTOFMEMORY;
+ break;
+ }
+
+ if ( bAppend )
+ m_pLogFile = _tfopen( pFileName, TEXT( "ab" ) );
+ else
+ m_pLogFile = _tfopen( pFileName, TEXT( "wb" ) );
+
+ delete [] pFileName;
+ }
+ }
+ else if ( (*pSub) == 'q' || (*pSub) == 'Q' )
+ { // --- Handle quiet file parameter ---
+ pSub = CharNext( pSub );
+ if ( ! (*pSub) || (*pSub) == 'n' || (*pSub) == 'N' )
+ m_bQuiet = true;
+
+ if ( FAILED( StringCchCat( pNewCmdLine, nSize, pStart ) ) ||
+ FAILED( StringCchCat( pNewCmdLine, nSize, TEXT( " " ) ) ) )
+ {
+ nRet = ERROR_OUTOFMEMORY;
+ break;
+ }
+ }
+ else if ( _tcsnicmp( pSub, PARAM_RUNNING, _tcslen( PARAM_RUNNING ) ) == 0 )
+ {
+ m_bIgnoreAlreadyRunning = true;
+ }
+ else if ( _tcsnicmp( pSub, CMDLN_REG_ALL_MSO_TYPES, _tcslen( CMDLN_REG_ALL_MSO_TYPES ) ) == 0 )
+ {
+ m_bRegAllMsoTypes = true;
+ }
+ else if ( _tcsnicmp( pSub, CMDLN_REG_NO_MSO_TYPES, _tcslen( CMDLN_REG_NO_MSO_TYPES ) ) == 0 )
+ {
+ m_bRegNoMsoTypes = true;
+ }
+ else if ( (*pSub) == 'i' || (*pSub) == 'I' || (*pSub) == 'f' || (*pSub) == 'F' ||
+ (*pSub) == 'p' || (*pSub) == 'P' || (*pSub) == 'x' || (*pSub) == 'X' ||
+ (*pSub) == 'y' || (*pSub) == 'Y' || (*pSub) == 'z' || (*pSub) == 'Z' )
+ {
+ StringCchCopy( m_pErrorText, MAX_TEXT_LENGTH, pStart );
+ nRet = ERROR_INVALID_PARAMETER;
+ break;
+ }
+ else if ( (*pSub) == 'a' || (*pSub) == 'A' )
+ { // --- Handle Adminstrative Installation ---
+ SetAdminInstall( true );
+ }
+ else if ( (*pSub) == 'j' || (*pSub) == 'J' )
+ { // --- Handle Adminstrative Installation ---
+ m_pAdvertise = pStart;
+ m_bQuiet = true;
+ bDeleteStart = false;
+ }
+ else if ( (*pSub) == '?' || (*pSub) == 'h' || (*pSub) == 'H' )
+ { // --- Handle Show Usage ---
+ nRet = ERROR_SHOW_USAGE;
+ break;
+ }
+ else
+ {
+ if ( FAILED( StringCchCat( pNewCmdLine, nSize, pStart ) ) ||
+ FAILED( StringCchCat( pNewCmdLine, nSize, TEXT( " " ) ) ) )
+ {
+ nRet = ERROR_OUTOFMEMORY;
+ break;
+ }
+ }
+ }
+ else
+ {
+ if ( FAILED( StringCchCat( pNewCmdLine, nSize, pStart ) ) ||
+ FAILED( StringCchCat( pNewCmdLine, nSize, TEXT( " " ) ) ) )
+ {
+ nRet = ERROR_OUTOFMEMORY;
+ break;
+ }
+ }
+
+ if ( bDeleteStart ) delete [] pStart;
+ pStart = NULL;
+ }
+
+ if ( pStart ) delete [] pStart;
+
+ *pCmdLine = pNewCmdLine;
+
+ if ( nRet != ERROR_SUCCESS )
+ {
+ SetError( nRet );
+ return false;
+ }
+ else
+ return true;;
+}
+
+//--------------------------------------------------------------------------
+boolean SetupAppX::IsAdmin()
+{
+ PSID aPsidAdmin;
+ SID_IDENTIFIER_AUTHORITY aAuthority = SECURITY_NT_AUTHORITY;
+
+ if ( !AllocateAndInitializeSid( &aAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID,
+ DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0,
+ &aPsidAdmin ) )
+ return false;
+
+ BOOL bIsAdmin = FALSE;
+
+ if ( GetOSVersion() >= 5 )
+ {
+ HMODULE hAdvapi32 = LoadLibrary( ADVAPI32_DLL );
+
+ if ( !hAdvapi32 )
+ bIsAdmin = FALSE;
+ else
+ {
+ PFnCheckTokenMembership pfnCheckTokenMembership = (PFnCheckTokenMembership) GetProcAddress( hAdvapi32, ADVAPI32API_CheckTokenMembership);
+ if ( !pfnCheckTokenMembership || !pfnCheckTokenMembership( NULL, aPsidAdmin, &bIsAdmin ) )
+ bIsAdmin = FALSE;
+ }
+ FreeLibrary( hAdvapi32 );
+ }
+ else
+ {
+ // NT4, check groups of user
+ HANDLE hAccessToken = 0;
+ UCHAR *szInfoBuffer = new UCHAR[ 1024 ]; // may need to resize if TokenInfo too big
+ DWORD dwInfoBufferSize = 1024;
+ DWORD dwRetInfoBufferSize = 0;
+ UINT i=0;
+
+ if ( WIN::OpenProcessToken( WIN::GetCurrentProcess(), TOKEN_READ, &hAccessToken ) )
+ {
+ bool bSuccess = false;
+ bSuccess = WIN::GetTokenInformation( hAccessToken, TokenGroups,
+ szInfoBuffer, dwInfoBufferSize,
+ &dwRetInfoBufferSize ) == TRUE;
+
+ if( dwRetInfoBufferSize > dwInfoBufferSize )
+ {
+ delete [] szInfoBuffer;
+ szInfoBuffer = new UCHAR[ dwRetInfoBufferSize ];
+ dwInfoBufferSize = dwRetInfoBufferSize;
+ bSuccess = WIN::GetTokenInformation( hAccessToken, TokenGroups,
+ szInfoBuffer, dwInfoBufferSize,
+ &dwRetInfoBufferSize ) == TRUE;
+ }
+
+ WIN::CloseHandle( hAccessToken );
+
+ if ( bSuccess )
+ {
+ PTOKEN_GROUPS pGroups = (PTOKEN_GROUPS)(UCHAR*) szInfoBuffer;
+ for( i=0; i<pGroups->GroupCount; i++ )
+ {
+ if( WIN::EqualSid( aPsidAdmin, pGroups->Groups[i].Sid ) )
+ {
+ bIsAdmin = TRUE;
+ break;
+ }
+ }
+ }
+
+ delete [] szInfoBuffer;
+ }
+ }
+
+ WIN::FreeSid( aPsidAdmin );
+
+ return bIsAdmin ? true : false;
+}
+
+//--------------------------------------------------------------------------
+LPTSTR SetupAppX::CopyIniFile( LPCTSTR pIniFile )
+{
+ m_pTmpName = _ttempnam( TEXT( "C:\\" ), TEXT( "Setup" ) );
+
+ if ( !m_pTmpName )
+ {
+ Log( TEXT( "ERROR: Could not create temp file\n" ) );
+ return NULL;
+ }
+
+ FILE *pOut = _tfopen( m_pTmpName, TEXT( "wb" ) );
+ FILE *pIn = _tfopen( pIniFile, TEXT( "rb" ) );
+
+ if ( pOut && pIn )
+ {
+ size_t nRead, nWritten;
+ BYTE pBuf[1024];
+
+ nRead = fread( pBuf, sizeof( BYTE ), 1024, pIn );
+ while ( nRead && !ferror( pIn ) )
+ {
+ nWritten = fwrite( pBuf, sizeof( BYTE ), nRead, pOut );
+ if ( nWritten != nRead )
+ {
+ Log( TEXT( "ERROR: Could not write all bytes to temp file\n" ) );
+ break;
+ }
+ nRead = fread( pBuf, sizeof( BYTE ), 1024, pIn );
+ }
+ }
+
+ if ( pOut ) fclose( pOut );
+ if ( pIn ) fclose( pIn );
+
+ return m_pTmpName;
+}
+
+//--------------------------------------------------------------------------
+void SetupAppX::ConvertNewline( LPTSTR pText ) const
+{
+ int i=0;
+
+ while ( pText[i] != 0 )
+ {
+ if ( ( pText[i] == '\\' ) && ( pText[i+1] == 'n' ) )
+ {
+ pText[i] = 0x0d;
+ pText[i+1] = 0x0a;
+ i+=2;
+ }
+ else
+ i+=1;
+ }
+}
+
+//--------------------------------------------------------------------------
+LPTSTR SetupAppX::SetProdToAppTitle( LPCTSTR pProdName )
+{
+ if ( !pProdName ) return m_pAppTitle;
+
+ LPTSTR pAppProdTitle = new TCHAR[ MAX_STR_CAPTION ];
+ pAppProdTitle[0] = '\0';
+
+ WIN::LoadString( m_hInst, IDS_APP_PROD_TITLE, pAppProdTitle, MAX_STR_CAPTION );
+
+ int nAppLen = lstrlen( pAppProdTitle );
+ int nProdLen = lstrlen( pProdName );
+
+ if ( ( nAppLen == 0 ) || ( nProdLen == 0 ) )
+ {
+ delete [] pAppProdTitle;
+ return m_pAppTitle;
+ }
+
+ int nLen = nAppLen + nProdLen + 3;
+
+ if ( nLen > STRSAFE_MAX_CCH ) return m_pAppTitle;
+
+ LPTSTR pIndex = _tcsstr( pAppProdTitle, PRODUCT_NAME_VAR );
+
+ if ( pIndex )
+ {
+ int nOffset = pIndex - pAppProdTitle;
+ int nVarLen = lstrlen( PRODUCT_NAME_VAR );
+
+ LPTSTR pNewTitle = new TCHAR[ nLen ];
+ pNewTitle[0] = '\0';
+
+ if ( nOffset > 0 )
+ {
+ StringCchCopyN( pNewTitle, nLen, pAppProdTitle, nOffset );
+ }
+
+ StringCchCat( pNewTitle, nLen, pProdName );
+
+ if ( nOffset + nVarLen < nAppLen )
+ {
+ StringCchCat( pNewTitle, nLen, pIndex + nVarLen );
+ }
+
+ delete [] m_pAppTitle;
+ m_pAppTitle = pNewTitle;
+ }
+
+ delete [] pAppProdTitle;
+
+ return m_pAppTitle;
+}
+
+
+//--------------------------------------------------------------------------
+boolean SetupAppX::IsPatchInstalled( TCHAR* pBaseDir, TCHAR* pFileName )
+{
+ if ( !m_bSupportsPatch )
+ return false;
+
+ PMSIHANDLE hSummaryInfo;
+ int nLen = lstrlen( pBaseDir ) + lstrlen( pFileName ) + 1;
+ TCHAR *szDatabasePath = new TCHAR [ nLen ];
+ TCHAR sBuf[80];
+
+ StringCchCopy( szDatabasePath, nLen, pBaseDir );
+ StringCchCat( szDatabasePath, nLen, pFileName );
+
+ UINT nRet = MsiGetSummaryInformation( NULL, szDatabasePath, 0, &hSummaryInfo );
+
+ if ( nRet != ERROR_SUCCESS )
+ {
+ StringCchPrintf( sBuf, 80, TEXT("ERROR: IsPatchInstalled: MsiGetSummaryInformation returned %u.\r\n"), nRet );
+ Log( sBuf );
+ return false;
+ }
+
+ UINT uiDataType;
+ LPTSTR szPatchID = new TCHAR[ 64 ];
+ DWORD cchValueBuf = 64;
+ nRet = MsiSummaryInfoGetProperty( hSummaryInfo, PID_REVNUMBER, &uiDataType, NULL, NULL, szPatchID, &cchValueBuf );
+
+ if ( nRet != ERROR_SUCCESS )
+ {
+ StringCchPrintf( sBuf, 80, TEXT("ERROR: IsPatchInstalled: MsiSummaryInfoGetProperty returned %u.\r\n"), nRet );
+ Log( sBuf );
+ return false;
+ }
+
+ nRet = MsiGetPatchInfo( szPatchID, INSTALLPROPERTY_LOCALPACKAGE, NULL, NULL );
+
+ StringCchPrintf( sBuf, 80, TEXT(" GetPatchInfo for (%s) returned (%u)\r\n"), szPatchID, nRet );
+ Log( sBuf );
+
+ delete []szPatchID;
+
+ if ( nRet == ERROR_BAD_CONFIGURATION )
+ return false;
+ else if ( nRet == ERROR_INVALID_PARAMETER )
+ return false;
+ else if ( nRet == ERROR_MORE_DATA )
+ return true;
+ else if ( nRet == ERROR_SUCCESS )
+ return true;
+ else if ( nRet == ERROR_UNKNOWN_PRODUCT )
+ return false;
+ else if ( nRet == ERROR_UNKNOWN_PROPERTY )
+ return false;
+ else return false;
+
+ return false;
+}
+
+//--------------------------------------------------------------------------
+boolean SetupAppX::InstallRuntimes( TCHAR *sProductCode, TCHAR *sRuntimePath )
+{
+ INSTALLSTATE nRet = MsiQueryProductState( sProductCode );
+ OutputDebugStringFormat( TEXT( "MsiQueryProductState returned <%d>\r\n" ), nRet );
+ if ( nRet == INSTALLSTATE_DEFAULT )
+ return true;
+
+ Log( TEXT( " Will install runtime <%s>\r\n" ), sRuntimePath );
+ OutputDebugStringFormat( TEXT( " Will install runtime <%s>\r\n" ), sRuntimePath );
+
+ STARTUPINFO aSUI;
+ PROCESS_INFORMATION aPI;
+
+ ZeroMemory( (void*)&aPI, sizeof( PROCESS_INFORMATION ) );
+ ZeroMemory( (void*)&aSUI, sizeof( STARTUPINFO ) );
+
+ aSUI.cb = sizeof(STARTUPINFO);
+ aSUI.dwFlags = STARTF_USESHOWWINDOW;
+ aSUI.wShowWindow = SW_SHOW;
+
+ DWORD nCmdLineLength = lstrlen( sRuntimePath ) + lstrlen( PARAM_SILENTINSTALL ) + 2;
+ TCHAR *sCmdLine = new TCHAR[ nCmdLineLength ];
+
+ if ( FAILED( StringCchCopy( sCmdLine, nCmdLineLength, sRuntimePath ) ) ||
+ FAILED( StringCchCat( sCmdLine, nCmdLineLength, PARAM_SILENTINSTALL ) ) )
+ {
+ delete [] sCmdLine;
+ SetError( ERROR_INSTALL_FAILURE );
+ return false;
+ }
+
+ if ( !WIN::CreateProcess( NULL, sCmdLine, NULL, NULL, FALSE,
+ CREATE_DEFAULT_ERROR_MODE, NULL, NULL,
+ &aSUI, &aPI ) )
+ {
+ Log( TEXT( "ERROR: Could not create process %s.\r\n" ), sCmdLine );
+ SetError( WIN::GetLastError() );
+ delete [] sCmdLine;
+ return false;
+ }
+
+ DWORD nResult = WaitForProcess( aPI.hProcess );
+ bool bRet = true;
+
+ if( ERROR_SUCCESS != nResult )
+ {
+ Log( TEXT( "ERROR: While waiting for %s.\r\n" ), sCmdLine );
+ SetError( nResult );
+ bRet = false;
+ }
+ else
+ {
+ GetExitCodeProcess( aPI.hProcess, &nResult );
+ SetError( nResult );
+
+ if ( nResult != ERROR_SUCCESS )
+ {
+ TCHAR sBuf[80];
+ StringCchPrintf( sBuf, 80, TEXT("Warning: install runtime returned %u.\r\n"), nResult );
+ Log( sBuf );
+ }
+ else
+ Log( TEXT( " Installation of runtime completed successfully.\r\n" ) );
+ }
+
+ CloseHandle( aPI.hProcess );
+
+ delete [] sCmdLine;
+
+ return bRet;
+}
+
+//--------------------------------------------------------------------------
+boolean SetupAppX::InstallRuntimes()
+{
+ TCHAR *sRuntimePath = 0;
+ SYSTEM_INFO siSysInfo;
+
+ HMODULE hKernel32 = ::LoadLibrary(_T("Kernel32.dll"));
+ if ( hKernel32 != NULL )
+ {
+ typedef void (CALLBACK* pfnGetNativeSystemInfo_t)(LPSYSTEM_INFO);
+ pfnGetNativeSystemInfo_t pfnGetNativeSystemInfo;
+ pfnGetNativeSystemInfo = (pfnGetNativeSystemInfo_t)::GetProcAddress(hKernel32, "GetNativeSystemInfo");
+ if ( pfnGetNativeSystemInfo != NULL )
+ {
+ pfnGetNativeSystemInfo(&siSysInfo);
+ }
+ else
+ {
+ // GetNativeSystemInfo does not exist. Maybe the code is running under Windows 2000.
+ // Use GetSystemInfo instead.
+ GetSystemInfo(&siSysInfo);
+ }
+ FreeLibrary(hKernel32);
+ }
+ else
+ {
+ // Failed to check Kernel32.dll. There may be something wrong.
+ // Use GetSystemInfo instead anyway.
+ GetSystemInfo(&siSysInfo);
+ }
+
+ OutputDebugStringFormat( TEXT( "found architecture<%d>\r\n" ), siSysInfo.wProcessorArchitecture );
+
+ if ( siSysInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64 )
+ {
+ if ( GetPathToFile( RUNTIME_X64_NAME, &sRuntimePath ) )
+ InstallRuntimes( PRODUCTCODE_X64, sRuntimePath );
+ else
+ Log( TEXT( "ERROR: no installer for x64 runtime libraries found!" ) );
+
+ if ( sRuntimePath )
+ {
+ delete [] sRuntimePath;
+ sRuntimePath = 0;
+ }
+ }
+
+ if ( GetPathToFile( RUNTIME_X86_NAME, &sRuntimePath ) )
+ InstallRuntimes( PRODUCTCODE_X86, sRuntimePath );
+ else
+ Log( TEXT( "ERROR: no installer for x86 runtime libraries found!" ) );
+
+ if ( sRuntimePath )
+ delete [] sRuntimePath;
+
+ return true;
+}
+
+//--------------------------------------------------------------------------
+//--------------------------------------------------------------------------
+LanguageDataX::LanguageDataX( LPTSTR pData )
+{
+ m_nLanguageID = 0;
+ m_pTransform = NULL;
+
+ LPTSTR pLastChar;
+
+ m_nLanguageID = _tcstol( pData, &pLastChar, 10 );
+
+ if ( *pLastChar == ',' )
+ {
+ pLastChar += 1;
+ int nLen = lstrlen( pLastChar ) + 1;
+ m_pTransform = new TCHAR [ nLen ];
+ StringCchCopy( m_pTransform, nLen, pLastChar );
+ }
+}
+
+//--------------------------------------------------------------------------
+LanguageDataX::~LanguageDataX()
+{
+ if ( m_pTransform ) delete [] m_pTransform;
+}
+
+//--------------------------------------------------------------------------
+//--------------------------------------------------------------------------
+SetupApp* Create_SetupAppX()
+{
+ return new SetupAppX;
+}
+
+//--------------------------------------------------------------------------
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/win32/source/setup/setup.hxx b/desktop/win32/source/setup/setup.hxx
new file mode 100644
index 000000000000..6eccda100699
--- /dev/null
+++ b/desktop/win32/source/setup/setup.hxx
@@ -0,0 +1,157 @@
+/* -*- 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 "setup_main.hxx"
+
+//--------------------------------------------------------------------------
+
+#ifdef SetupAppX
+ #undef SetupAppX
+#endif
+
+#ifdef Create_SetupAppX
+ #undef Create_SetupAppX
+#endif
+
+#ifdef LanguageDataX
+ #undef LanguageDataX
+#endif
+
+
+#ifdef UNICODE
+ #define SetupAppX SetupAppW
+ #define Create_SetupAppX Create_SetupAppW
+ #define LanguageDataX LanguageDataW
+#else
+ #define SetupAppX SetupAppA
+ #define Create_SetupAppX Create_SetupAppA
+ #define LanguageDataX LanguageDataA
+#endif
+
+//--------------------------------------------------------------------------
+
+struct LanguageDataX
+{
+ long m_nLanguageID;
+ LPTSTR m_pTransform;
+
+ LanguageDataX( LPTSTR pData );
+ ~LanguageDataX();
+};
+
+//--------------------------------------------------------------------------
+
+class SetupAppX : public SetupApp
+{
+ HINSTANCE m_hInst;
+ HANDLE m_hMapFile;
+ LPTSTR m_pAppTitle;
+ LPTSTR m_pCmdLine;
+ LPTSTR m_pDatabase;
+ LPTSTR m_pReqVersion;
+ LPTSTR m_pProductName;
+ LPTSTR m_pAdvertise;
+ LPTSTR m_pTmpName;
+ LPTSTR m_pErrorText;
+ LPTSTR m_pModuleFile;
+ LPTSTR m_pPatchFiles;
+ LPCTSTR m_pUpgradeKey;
+ LPCTSTR m_pProductVersion;
+ int *m_pMSIErrorCode;
+
+ boolean m_bQuiet : 1;
+ boolean m_bIgnoreAlreadyRunning : 1;
+ boolean m_bRegNoMsoTypes :1;
+ boolean m_bRegAllMsoTypes :1;
+ boolean m_bIsMinorUpgrade :1;
+ boolean m_bSupportsPatch :1;
+
+ FILE *m_pLogFile;
+
+ long m_nLanguageID;
+ long m_nLanguageCount;
+ LanguageDataX** m_ppLanguageList;
+
+private:
+
+ boolean GetPathToFile( TCHAR* pFileName, TCHAR **pPath );
+ LPCTSTR GetPathToMSI();
+
+ int GetNameValue( TCHAR* pLine, TCHAR **pName, TCHAR **pValue );
+ boolean GetProfileSection( LPCTSTR pFileName, LPCTSTR pSection,
+ DWORD& rSize, LPTSTR *pRetBuf );
+ LPTSTR CopyIniFile( LPCTSTR pIniFile );
+ void ConvertNewline( LPTSTR pText ) const;
+
+ boolean LaunchInstaller( LPCTSTR pParam );
+ HMODULE LoadMsiLibrary();
+ DWORD WaitForProcess( HANDLE hHandle );
+
+ boolean GetCmdLineParameters( LPTSTR *pCmdLine );
+ DWORD GetNextArgument( LPCTSTR pStr, LPTSTR *pArg,
+ LPTSTR *pNext, boolean bStripQuotes = false );
+ boolean IsAdmin();
+
+ boolean GetCommandLine();
+
+ boolean IsTerminalServerInstalled() const;
+ void AddFileToPatchList( TCHAR* pPath, TCHAR* pFile );
+ boolean IsPatchInstalled( TCHAR* pBaseDir, TCHAR* pFileName );
+ boolean InstallRuntimes( TCHAR* pProductCode, TCHAR* pFileName );
+
+public:
+ SetupAppX();
+ ~SetupAppX();
+
+ virtual boolean Initialize( HINSTANCE hInst );
+ virtual boolean AlreadyRunning() const;
+ virtual boolean ReadProfile();
+ virtual boolean GetPatches();
+ virtual boolean ChooseLanguage( long& rLanguage );
+ virtual boolean CheckVersion();
+ virtual boolean CheckForUpgrade();
+ virtual boolean InstallRuntimes();
+ virtual boolean Install( long nLanguage );
+
+ virtual UINT GetError() const;
+ virtual void DisplayError( UINT nErr ) const;
+
+ void Log( LPCTSTR pMessage, LPCTSTR pText = NULL ) const;
+
+ long GetLanguageCount() const { return m_nLanguageCount; }
+ long GetLanguageID( long nIndex ) const;
+ void GetLanguageName( long nLanguage, LPTSTR sName ) const;
+
+ LPCTSTR GetAppTitle() const { return m_pAppTitle; }
+ LPTSTR SetProdToAppTitle( LPCTSTR pProdName );
+ HINSTANCE GetHInst() const { return m_hInst; }
+};
+
+//--------------------------------------------------------------------------
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/win32/source/setup/setup.ico b/desktop/win32/source/setup/setup.ico
new file mode 100644
index 000000000000..2a7ebda53a25
--- /dev/null
+++ b/desktop/win32/source/setup/setup.ico
Binary files differ
diff --git a/desktop/win32/source/setup/setup.ulf b/desktop/win32/source/setup/setup.ulf
new file mode 100644
index 000000000000..85d43f43aa55
--- /dev/null
+++ b/desktop/win32/source/setup/setup.ulf
@@ -0,0 +1,162 @@
+[%APP_TITLE%]
+en-US = "Setup"
+
+
+[%APP_PROD_TITLE%]
+en-US = "The %PRODUCTNAME Setup"
+
+
+[%OUTOFMEM%]
+en-US = "Out of Memory"
+
+
+[%NOMSI%]
+en-US = "Setup was unable to find the msi package."
+
+
+[%USER_CANCELLED%]
+en-US = "Setup was cancelled"
+
+
+[%REQUIRES_ADMIN_PRIV%]
+en-US = "Administrator privileges are required for upgrading the Windows Installer."
+
+
+[%FILE_NOT_FOUND%]
+en-US = "Setup was unable to find the file '%s'."
+
+
+[%INVALID_PARAM%]
+en-US = "Invalid command line option '%s'. Please use '/?' for help."
+
+
+[%SETUP_TO_OLD%]
+en-US = "This package requires at least the version '%s' of the Windows Installer. \nYou have Windows Installer '%s' on your system!"
+
+[%SETUP_NOT_FOUND%]
+en-US = "This package requires the Windows Installer. \nYou need at least Windows Installer '%s' on your system!"
+
+
+[%USAGE%]
+en-US = "Usage:\n /? : Shows this dialog.\n /a : Performs an administrative installation.\n /j[u|m] : Performs an advertising installation.\n /q[n] : Do not show any user interface (silent mode).\n"
+
+
+[%ALREADY_RUNNING%]
+en-US = "There is already a setup process running."
+
+
+[%UNKNOWN_ERROR%]
+en-US = "An Unknown Error occurred!"
+
+
+[%INVALID_PROFILE%]
+en-US = "Invalid or incomplete profile."
+
+
+[%UNKNOWN_LANG%]
+en-US = "Unknown Language: %d"
+
+
+[%LANGUAGE_ZH_TW%]
+en-US = "Chinese (traditional)"
+
+
+[%LANGUAGE_CS%]
+en-US = "Czech"
+
+
+[%LANGUAGE_DA%]
+en-US = "Danish"
+
+
+[%LANGUAGE_DE_DE%]
+en-US = "German (Germany)"
+
+
+[%LANGUAGE_EL%]
+en-US = "Greek"
+
+
+[%LANGUAGE_EN_US%]
+en-US = "English (USA)"
+
+
+[%LANGUAGE_ES%]
+en-US = "Spanish (Spain)"
+
+
+[%LANGUAGE_FI%]
+en-US = "Finnish"
+
+
+[%LANGUAGE_FR_FR%]
+en-US = "French (France)"
+
+
+[%LANGUAGE_HE%]
+en-US = "Hebrew"
+
+
+[%LANGUAGE_HU%]
+en-US = "Hungarian"
+
+
+[%LANGUAGE_IT_IT%]
+en-US = "Italian (Italy)"
+
+
+[%LANGUAGE_JA%]
+en-US = "Japanese"
+
+
+[%LANGUAGE_KO%]
+en-US = "Korean"
+
+
+[%LANGUAGE_NL_NL%]
+en-US = "Dutch (Netherlands)"
+
+
+[%LANGUAGE_NO_NO%]
+en-US = "Norwegian (Bokmål)"
+
+
+[%LANGUAGE_PL%]
+en-US = "Polish"
+
+
+[%LANGUAGE_PT_BR%]
+en-US = "Portuguese (Brazil)"
+
+
+[%LANGUAGE_RU%]
+en-US = "Russian"
+
+
+[%LANGUAGE_SK%]
+en-US = "Slovakian"
+
+
+[%LANGUAGE_SV_SE%]
+en-US = "Swedish (Sweden)"
+
+
+[%LANGUAGE_TH%]
+en-US = "Thai"
+
+
+[%LANGUAGE_TR%]
+en-US = "Turkish"
+
+
+[%LANGUAGE_ET%]
+en-US = "Estonian"
+
+
+[%LANGUAGE_ZH_CN%]
+en-US = "Chinese (Simplified)"
+
+
+[%LANGUAGE_PT_PT%]
+en-US = "Portuguese (Portugal)"
+
diff --git a/desktop/win32/source/setup/setup_a.cxx b/desktop/win32/source/setup/setup_a.cxx
new file mode 100644
index 000000000000..a680673e1729
--- /dev/null
+++ b/desktop/win32/source/setup/setup_a.cxx
@@ -0,0 +1,34 @@
+/* -*- 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 "setup.cpp"
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/win32/source/setup/setup_help.hxx b/desktop/win32/source/setup/setup_help.hxx
new file mode 100644
index 000000000000..1330fa70f191
--- /dev/null
+++ b/desktop/win32/source/setup/setup_help.hxx
@@ -0,0 +1,49 @@
+/* -*- 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 SETUP_HELP_HXX
+#define SETUP_HELP_HXX
+
+//--------------------------------------------------------------------------
+
+
+#ifdef UNICODE
+#else
+ #define LanguageDataX LanguageDataA
+#endif
+
+//--------------------------------------------------------------------------
+
+class SetupHelperX
+{
+};
+
+//--------------------------------------------------------------------------
+
+#endif
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/win32/source/setup/setup_main.cxx b/desktop/win32/source/setup/setup_main.cxx
new file mode 100644
index 000000000000..0fb9aac2533e
--- /dev/null
+++ b/desktop/win32/source/setup/setup_main.cxx
@@ -0,0 +1,142 @@
+/* -*- 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"
+
+#if defined _MSC_VER
+#pragma warning(push, 1)
+#endif
+#include <windows.h>
+#if defined _MSC_VER
+#pragma warning(pop)
+#endif
+#include <new>
+
+#include "setup_main.hxx"
+
+//--------------------------------------------------------------------------
+
+void __cdecl newhandler()
+{
+ throw std::bad_alloc();
+ return;
+}
+
+//--------------------------------------------------------------------------
+
+SetupApp::SetupApp()
+{
+ m_uiRet = ERROR_SUCCESS;
+
+ // Get OS version
+ OSVERSIONINFO sInfoOS;
+
+ ZeroMemory( &sInfoOS, sizeof(OSVERSIONINFO) );
+ sInfoOS.dwOSVersionInfoSize = sizeof( OSVERSIONINFO );
+
+ GetVersionEx( &sInfoOS );
+
+ m_nOSVersion = sInfoOS.dwMajorVersion;
+ m_nMinorVersion = sInfoOS.dwMinorVersion;
+ m_bNeedReboot = false;
+ m_bAdministrative = false;
+}
+
+//--------------------------------------------------------------------------
+
+SetupApp::~SetupApp()
+{
+}
+
+//--------------------------------------------------------------------------
+
+extern "C" int __stdcall WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, int )
+{
+ // Get OS version
+ OSVERSIONINFO sInfoOS;
+
+ ZeroMemory( &sInfoOS, sizeof(OSVERSIONINFO) );
+ sInfoOS.dwOSVersionInfoSize = sizeof( OSVERSIONINFO );
+
+ GetVersionEx( &sInfoOS );
+
+ SetupApp *pSetup;
+
+ pSetup = Create_SetupAppW();
+
+ try
+ {
+ if ( ! pSetup->Initialize( hInst ) )
+ throw pSetup->GetError();
+
+ if ( pSetup->AlreadyRunning() )
+ throw (UINT) ERROR_INSTALL_ALREADY_RUNNING;
+
+ if ( ! pSetup->ReadProfile() )
+ throw pSetup->GetError();
+
+ if ( ! pSetup->CheckVersion() )
+ throw pSetup->GetError();
+
+ if ( ! pSetup->IsAdminInstall() )
+ if ( ! pSetup->GetPatches() )
+ throw pSetup->GetError();
+
+ // CheckForUpgrade() has to be called after calling GetPatches()!
+ if ( ! pSetup->CheckForUpgrade() )
+ throw pSetup->GetError();
+
+ long nLanguage;
+
+ if ( ! pSetup->ChooseLanguage( nLanguage ) )
+ throw pSetup->GetError();
+
+ if ( ! pSetup->InstallRuntimes() )
+ throw pSetup->GetError();
+
+ if ( ! pSetup->Install( nLanguage ) )
+ throw pSetup->GetError();
+ }
+ catch ( std::bad_alloc )
+ {
+ pSetup->DisplayError( ERROR_OUTOFMEMORY );
+ }
+ catch ( UINT &nErr )
+ {
+ pSetup->DisplayError( nErr );
+ }
+
+ int nRet = pSetup->GetError();
+
+ delete pSetup;
+
+ return nRet;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/win32/source/setup/setup_main.hxx b/desktop/win32/source/setup/setup_main.hxx
new file mode 100644
index 000000000000..dfcb201e3cd3
--- /dev/null
+++ b/desktop/win32/source/setup/setup_main.hxx
@@ -0,0 +1,74 @@
+/* -*- 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 SETUP_MAIN_HXX
+#define SETUP_MAIN_HXX
+
+class SetupApp
+{
+ DWORD m_nOSVersion;
+ DWORD m_nMinorVersion;
+ boolean m_bNeedReboot : 1;
+ boolean m_bAdministrative : 1;
+
+public:
+ UINT m_uiRet;
+
+ SetupApp();
+ virtual ~SetupApp();
+
+ virtual boolean Initialize( HINSTANCE hInst ) = 0;
+ virtual boolean AlreadyRunning() const = 0;
+ virtual boolean ReadProfile() = 0;
+ virtual boolean GetPatches() = 0;
+ virtual boolean ChooseLanguage( long& rLanguage ) = 0;
+ virtual boolean CheckVersion() = 0;
+ virtual boolean CheckForUpgrade() = 0;
+ virtual boolean InstallRuntimes() = 0;
+ virtual boolean Install( long nLanguage ) = 0;
+
+ virtual UINT GetError() const = 0;
+ virtual void DisplayError( UINT nErr ) const = 0;
+
+ void SetError( UINT nErr ) { m_uiRet = nErr; }
+ DWORD GetOSVersion() const { return m_nOSVersion; }
+ DWORD GetMinorVersion() const { return m_nMinorVersion; }
+
+ boolean IsAdminInstall() { return m_bAdministrative; }
+ void SetAdminInstall( boolean bValue ) { m_bAdministrative = bValue; }
+
+ void SetRebootNeeded( boolean bNeedReboot ) { m_bNeedReboot = bNeedReboot; }
+ boolean NeedReboot() const { return m_bNeedReboot; }
+};
+
+SetupApp* Create_SetupAppW();
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/win32/source/setup/setup_w.cxx b/desktop/win32/source/setup/setup_w.cxx
new file mode 100644
index 000000000000..9de15b2e535d
--- /dev/null
+++ b/desktop/win32/source/setup/setup_w.cxx
@@ -0,0 +1,37 @@
+/* -*- 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 UNICODE 1
+#define _UNICODE 1
+
+#include "setup.cpp"
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/win32/source/sowrapper.cxx b/desktop/win32/source/sowrapper.cxx
new file mode 100644
index 000000000000..f62536a86525
--- /dev/null
+++ b/desktop/win32/source/sowrapper.cxx
@@ -0,0 +1,50 @@
+/* -*- 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"
+
+#if defined _MSC_VER
+#pragma warning(push, 1)
+#endif
+#include <windows.h>
+#if defined _MSC_VER
+#pragma warning(pop)
+#endif
+#include "main.h"
+
+int APIENTRY WinMain( HINSTANCE, HINSTANCE, LPSTR, int )
+{
+ if ( (LONG)GetVersion() < 0 )
+ return MainA();
+ else
+ return MainW();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/win32/source/unoinfo.cxx b/desktop/win32/source/unoinfo.cxx
new file mode 100644
index 000000000000..0ce5c98b7215
--- /dev/null
+++ b/desktop/win32/source/unoinfo.cxx
@@ -0,0 +1,151 @@
+/* -*- 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 <cstddef>
+#include <stdio.h>
+#include <stdlib.h>
+#include <wchar.h>
+
+#define WIN32_LEAN_AND_MEAN
+#if defined _MSC_VER
+#pragma warning(push, 1)
+#endif
+#include <windows.h>
+#if defined _MSC_VER
+#pragma warning(pop)
+#endif
+
+#include "tools/pathutils.hxx"
+
+#define MY_LENGTH(s) (sizeof (s) / sizeof *(s) - 1)
+#define MY_STRING(s) (s), MY_LENGTH(s)
+
+namespace {
+
+wchar_t * getBrandPath(wchar_t * path) {
+ DWORD n = GetModuleFileNameW(NULL, path, MAX_PATH);
+ if (n == 0 || n >= MAX_PATH) {
+ exit(EXIT_FAILURE);
+ }
+ return tools::filename(path);
+}
+
+void writeNull() {
+ if (fwrite("\0\0", 1, 2, stdout) != 2) {
+ exit(EXIT_FAILURE);
+ }
+}
+
+void writePath(
+ wchar_t const * frontBegin, wchar_t const * frontEnd,
+ wchar_t const * backBegin, std::size_t backLength)
+{
+ wchar_t path[MAX_PATH];
+ wchar_t * end = tools::buildPath(
+ path, frontBegin, frontEnd, backBegin, backLength);
+ if (end == NULL) {
+ exit(EXIT_FAILURE);
+ }
+ std::size_t n = (end - path) * sizeof (wchar_t);
+ if (fwrite(path, 1, n, stdout) != n) {
+ exit(EXIT_FAILURE);
+ }
+}
+
+}
+
+#ifdef __MINGW32__
+int main(int argc, char ** argv, char **) {
+ if (argc == 2 && strcmp(argv[1], "c++") == 0) {
+#else
+int wmain(int argc, wchar_t ** argv, wchar_t **) {
+ if (argc == 2 && wcscmp(argv[1], L"c++") == 0) {
+#endif
+ wchar_t path[MAX_PATH];
+ wchar_t * pathEnd = getBrandPath(path);
+ if (tools::buildPath(path, path, pathEnd, MY_STRING(L"..\\basis-link"))
+ == NULL)
+ {
+ exit(EXIT_FAILURE);
+ }
+ pathEnd = tools::resolveLink(path);
+ if (pathEnd == NULL ||
+ (tools::buildPath(path, path, pathEnd, MY_STRING(L"\\ure-link")) ==
+ NULL))
+ {
+ exit(EXIT_FAILURE);
+ }
+ pathEnd = tools::resolveLink(path);
+ if (pathEnd == NULL) {
+ exit(EXIT_FAILURE);
+ }
+ writePath(path, pathEnd, MY_STRING(L"\\bin"));
+#ifdef __MINGW32__
+ } else if (argc == 2 && strcmp(argv[1], "java") == 0) {
+#else
+ } else if (argc == 2 && wcscmp(argv[1], L"java") == 0) {
+#endif
+ if (fwrite("1", 1, 1, stdout) != 1) {
+ exit(EXIT_FAILURE);
+ }
+ wchar_t path[MAX_PATH];
+ wchar_t * pathEnd = getBrandPath(path);
+ writePath(path, pathEnd, MY_STRING(L""));
+ if (tools::buildPath(path, path, pathEnd, MY_STRING(L"..\\basis-link"))
+ == NULL)
+ {
+ exit(EXIT_FAILURE);
+ }
+ pathEnd = tools::resolveLink(path);
+ if (pathEnd == NULL) {
+ exit(EXIT_FAILURE);
+ }
+ writeNull();
+ writePath(path, pathEnd, MY_STRING(L"\\program\\classes\\unoil.jar"));
+ if (tools::buildPath(path, path, pathEnd, MY_STRING(L"\\ure-link")) ==
+ NULL)
+ {
+ exit(EXIT_FAILURE);
+ }
+ pathEnd = tools::resolveLink(path);
+ if (pathEnd == NULL) {
+ exit(EXIT_FAILURE);
+ }
+ writeNull();
+ writePath(path, pathEnd, MY_STRING(L"\\java\\ridl.jar"));
+ writeNull();
+ writePath(path, pathEnd, MY_STRING(L"\\java\\jurt.jar"));
+ writeNull();
+ writePath(path, pathEnd, MY_STRING(L"\\java\\juh.jar"));
+ } else {
+ exit(EXIT_FAILURE);
+ }
+ exit(EXIT_SUCCESS);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/win32/source/wrapper.h b/desktop/win32/source/wrapper.h
new file mode 100755
index 000000000000..f0ff5b617f99
--- /dev/null
+++ b/desktop/win32/source/wrapper.h
@@ -0,0 +1,175 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+#pragma once
+#ifndef __cplusplus
+#error Need C++ to compile
+#endif
+
+#include "main.h"
+
+#ifndef _WINDOWS_
+#if defined _MSC_VER
+#pragma warning(push, 1)
+#endif
+# include <windows.h>
+#if defined _MSC_VER
+#pragma warning(pop)
+#endif
+#endif
+
+
+#ifndef _INC_TCHAR
+# ifdef UNICODE
+# define _UNICODE
+# endif
+# include <tchar.h>
+#endif
+
+#ifdef UNICODE
+# define Main MainW
+# define GetArgv( pArgc ) CommandLineToArgvW( GetCommandLine(), pArgc )
+# define PROCESS_CREATIONFLAGS CREATE_UNICODE_ENVIRONMENT
+#else
+# define GetArgv( pArgc ) (*pArgc = __argc, __argv)
+# define PROCESS_CREATIONFLAGS 0
+# define Main MainA
+#endif
+
+#define BIN_EXT_STR TEXT(".bin")
+#define PARAM_LIBPATH_STR TEXT("-libpath=")
+#define PARAM_LOCAL_STR TEXT("-local")
+#define PARAM_REMOTE_STR TEXT("-remote")
+
+#if defined( REMOTE )
+#define DEFAULT_LIBPATH TEXT("remote;")
+#elif defined( LOCAL )
+#define DEFAULT_LIBPATH TEXT("local;")
+#endif
+
+extern "C" int Main()
+{
+ // Retreive startup info
+
+ STARTUPINFO aStartupInfo;
+
+ ZeroMemory( &aStartupInfo, sizeof(aStartupInfo) );
+ aStartupInfo.cb = sizeof( aStartupInfo );
+ GetStartupInfo( &aStartupInfo );
+
+ // Retrieve command line
+
+ LPTSTR lpCommandLine = GetCommandLine();
+
+ LPTSTR *ppArguments = NULL;
+ int nArguments = 0;
+
+ ppArguments = GetArgv( &nArguments );
+
+ // Calculate application name
+
+
+ TCHAR szApplicationName[MAX_PATH];
+ TCHAR szDrive[MAX_PATH];
+ TCHAR szDir[MAX_PATH];
+ TCHAR szFileName[MAX_PATH];
+ TCHAR szExt[MAX_PATH];
+
+ GetModuleFileName( NULL, szApplicationName, MAX_PATH );
+ _tsplitpath( szApplicationName, szDrive, szDir, szFileName, szExt );
+ _tmakepath( szApplicationName, szDrive, szDir, szFileName, BIN_EXT_STR );
+
+ // Retreive actual environment
+
+ TCHAR szBuffer[1024];
+ TCHAR szPathValue[1024] = TEXT("");
+
+#ifdef DEFAULT_LIBPATH
+ _tmakepath( szPathValue, szDrive, szDir, DEFAULT_LIBPATH, TEXT("") );
+#endif
+
+ for ( int argn = 1; argn < nArguments; argn++ )
+ {
+ if ( 0 == _tcscmp( ppArguments[argn], PARAM_REMOTE_STR ) )
+ {
+ _tmakepath( szPathValue, szDrive, szDir, TEXT("remote;"), TEXT("") );
+ break;
+ }
+ else if ( 0 == _tcscmp( ppArguments[argn], PARAM_LOCAL_STR ) )
+ {
+ _tmakepath( szPathValue, szDrive, szDir, TEXT("local;"), TEXT("") );
+ break;
+ }
+ else if ( 0 == _tcsncmp( ppArguments[argn], PARAM_LIBPATH_STR, _tcslen(PARAM_LIBPATH_STR) ) )
+ {
+ LPTSTR pFileSpec = NULL;
+
+ GetFullPathName( ppArguments[argn] + _tcslen(PARAM_LIBPATH_STR), sizeof(szPathValue) / sizeof(TCHAR), szPathValue, &pFileSpec );
+ _tcscat( szPathValue, TEXT(";") );
+ break;
+ }
+ }
+
+ GetEnvironmentVariable( TEXT("PATH"), szBuffer, sizeof(szBuffer) );
+ _tcscat( szPathValue, szBuffer );
+ SetEnvironmentVariable( TEXT("PATH"), szPathValue);
+
+ LPVOID lpEnvironment = GetEnvironmentStrings();
+
+
+ // Retrieve current directory
+
+ TCHAR szCurrentDirectory[MAX_PATH];
+ GetCurrentDirectory( MAX_PATH, szCurrentDirectory );
+
+ // Set the Flags
+
+ DWORD dwCreationFlags = PROCESS_CREATIONFLAGS;
+
+ PROCESS_INFORMATION aProcessInfo;
+
+ BOOL fSuccess = CreateProcess(
+ szApplicationName,
+ lpCommandLine,
+ NULL,
+ NULL,
+ TRUE,
+ dwCreationFlags,
+ lpEnvironment,
+ szCurrentDirectory,
+ &aStartupInfo,
+ &aProcessInfo );
+
+ if ( fSuccess )
+ {
+ DWORD dwExitCode;
+
+ WaitForSingleObject( aProcessInfo.hProcess, INFINITE );
+ fSuccess = GetExitCodeProcess( aProcessInfo.hProcess, &dwExitCode );
+
+ return dwExitCode;
+ }
+
+ DWORD dwError = GetLastError();
+
+ LPVOID lpMsgBuf;
+
+ FormatMessage(
+ FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL,
+ dwError,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
+ (LPTSTR)&lpMsgBuf,
+ 0,
+ NULL
+ );
+
+ // Display the string.
+ MessageBox( NULL, (LPCTSTR)lpMsgBuf, NULL, MB_OK | MB_ICONERROR );
+
+ // Free the buffer.
+ LocalFree( lpMsgBuf );
+
+ return GetLastError();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/win32/source/wrappera.cxx b/desktop/win32/source/wrappera.cxx
new file mode 100644
index 000000000000..0a74b1030a3a
--- /dev/null
+++ b/desktop/win32/source/wrappera.cxx
@@ -0,0 +1,34 @@
+/* -*- 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 "wrapper.h"
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/win32/source/wrapperw.cxx b/desktop/win32/source/wrapperw.cxx
new file mode 100644
index 000000000000..d76ca9b678ad
--- /dev/null
+++ b/desktop/win32/source/wrapperw.cxx
@@ -0,0 +1,35 @@
+/* -*- 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 UNICODE
+#include "wrapper.h"
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/zipintro/delzip b/desktop/zipintro/delzip
new file mode 100755
index 000000000000..8b137891791f
--- /dev/null
+++ b/desktop/zipintro/delzip
@@ -0,0 +1 @@
+
diff --git a/desktop/zipintro/makefile.mk b/desktop/zipintro/makefile.mk
new file mode 100755
index 000000000000..83a91ad3c2ba
--- /dev/null
+++ b/desktop/zipintro/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=zipintro
+
+.INCLUDE : settings.mk
+
+ZIP1LIST= \
+ $(MISC)$/$(RSCDEFIMG)$/brand$/intro.png \
+ $(MISC)$/$(RSCDEFIMG)$/brand$/about.png
+ZIP2LIST= \
+ $(MISC)$/$(RSCDEFIMG)$/brand_dev$/intro.png \
+ $(MISC)$/$(RSCDEFIMG)$/brand_dev$/about.png
+ZIP3LIST= \
+ $(MISC)$/$(RSCDEFIMG)$/brand$/shell$/backing_left.png \
+ $(MISC)$/$(RSCDEFIMG)$/brand$/shell$/backing_right.png \
+ $(MISC)$/$(RSCDEFIMG)$/brand$/shell$/backing_space.png \
+ $(MISC)$/$(RSCDEFIMG)$/brand$/shell$/backing_rtl_left.png \
+ $(MISC)$/$(RSCDEFIMG)$/brand$/shell$/backing_rtl_right.png
+
+.IF "$(ENABLE_BROFFICE)"=="TRUE"
+ZIP1LIST+= \
+ $(MISC)$/$(RSCDEFIMG)$/brand$/intro-pt_BR.png \
+ $(MISC)$/$(RSCDEFIMG)$/brand$/about-pt_BR.png
+ZIP2LIST+= \
+ $(MISC)$/$(RSCDEFIMG)$/brand_dev$/intro-pt_BR.png \
+ $(MISC)$/$(RSCDEFIMG)$/brand_dev$/about-pt_BR.png
+ZIP3LIST+= \
+ $(MISC)$/$(RSCDEFIMG)$/brand$/shell$/backing_left-pt_BR.png \
+ $(MISC)$/$(RSCDEFIMG)$/brand$/shell$/backing_right-pt_BR.png
+.ENDIF # ENABLE_BROFFICE
+
+ZIP1TARGET=brand
+ZIP1DEPS=$(ZIP1LIST)
+ZIP2TARGET=brand_dev
+ZIP2DEPS=$(ZIP2LIST)
+ZIP3TARGET=shell
+ZIP3DEPS=$(ZIP3LIST)
+
+.INCLUDE : target.mk
+
+ALLTAR : \
+ $(COMMONBIN)$/intro.zip \
+ $(COMMONBIN)$/brand_dev$/intro.zip \
+ $(COMMONBIN)$/shell/shell.zip
+
+$(COMMONBIN)$/brand_dev$/intro.zip : $(COMMONBIN)$/brand_dev.zip
+ @@-$(MKDIR) $(@:d)
+ @$(COPY) $< $@
+
+$(COMMONBIN)$/intro.zip : $(COMMONBIN)$/brand.zip
+ @@-$(MKDIR) $(@:d)
+ @$(COPY) $< $@
+
+$(COMMONBIN)$/shell$/shell.zip : $(COMMONBIN)$/shell.zip
+ @@-$(MKDIR) $(@:d)
+ @$(COPY) $< $@
+
+$(MISC)$/%.bmp : $(SOLARSRC)$/%.bmp
+ @@-$(MKDIRHIER) $(@:d)
+ $(COPY) $< $@
+
+$(MISC)$/%.png : $(SOLARSRC)$/%.png
+ @@-$(MKDIRHIER) $(@:d)
+ $(COPY) $< $@
+
+.IF "$(INTRO_BITMAP)" != ""
+$(MISC)$/$(RSCDEFIMG)$/brand$/intro.png : $(INTRO_BITMAP)
+ @@-$(MKDIRHIER) $(@:d)
+ $(COPY) $< $@
+.ENDIF
+
+.IF "$(ABOUT_BITMAP)" != ""
+$(MISC)$/$(RSCDEFIMG)$/brand$/about.png : $(ABOUT_BITMAP)
+ @@-$(MKDIRHIER) $(@:d)
+ $(COPY) $< $@
+.ENDIF