diff options
Diffstat (limited to 'jvmfwk')
55 files changed, 11368 insertions, 0 deletions
diff --git a/jvmfwk/distributions/OpenOfficeorg/javavendors.xsd b/jvmfwk/distributions/OpenOfficeorg/javavendors.xsd new file mode 100644 index 000000000000..666372eee607 --- /dev/null +++ b/jvmfwk/distributions/OpenOfficeorg/javavendors.xsd @@ -0,0 +1,77 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<schema targetNamespace="http://openoffice.org/2004/java/framework/1.0" + xmlns:jf="http://openoffice.org/2004/java/framework/1.0" + xmlns="http://www.w3.org/2001/XMLSchema" + elementFormDefault="qualified"> + + <element name="javaSelection" type="jf:JavaSelectionType"> + <unique name="dummy1"> + <selector xpath="jf:plugins/jf:library"/> + <field xpath="@vendor"/> + </unique> + + + <keyref name="dummy2" refer="jf:pluginKey"> + <selector xpath="jf:vendorInfos/jf:vendor"/> + <field xpath="@name"/> + </keyref> + + <unique name="dummy3"> + <selector xpath="jf:vendorInfos/jf:vendor"/> + <field xpath="@name"/> + </unique> + + <key name="pluginKey"> + <selector xpath="jf:plugins/jf:library"/> + <field xpath="@vendor"/> + </key> + </element> + + <complexType name="JavaSelectionType"> + <sequence> + <element name="updated" type="date"/> + <element name="vendorInfos" type="jf:VendorInfoType"/> + <element name="plugins" type="jf:PluginType"/> + </sequence> + </complexType> + + + <complexType name="VendorInfoType"> + <sequence> + <element name="vendor" type="jf:VendorType" minOccurs="0" maxOccurs="unbounded"/> + </sequence> + </complexType> + + <complexType name="PluginType"> + <sequence> + <element name="library" type="jf:LibraryType" minOccurs="0" maxOccurs="unbounded"/> + </sequence> + </complexType> + + <complexType name="LibraryType"> + <simpleContent> + <extension base="string"> + <attribute name="vendor" use="required" type="string"/> + </extension> + </simpleContent> + </complexType> + + <complexType name="VendorType"> + <sequence> + <element name="minVersion" type="string" minOccurs="0"/> + <element name="maxVersion" type="string" minOccurs="0"/> + <element name="excludeVersions" minOccurs="0"> + <complexType> + <sequence> + <element name="version" type="string" minOccurs="0" maxOccurs="unbounded"/> + </sequence> + </complexType> + </element> + </sequence> + <attribute name="name" use="required" type="string"/> + </complexType> + + + +</schema> diff --git a/jvmfwk/distributions/OpenOfficeorg/javavendors_freebsd.xml b/jvmfwk/distributions/OpenOfficeorg/javavendors_freebsd.xml new file mode 100644 index 000000000000..2dd5fe35f555 --- /dev/null +++ b/jvmfwk/distributions/OpenOfficeorg/javavendors_freebsd.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<javaSelection xmlns="http://openoffice.org/2004/java/framework/1.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + + <updated>2008-08-27</updated> + + <vendorInfos> + <vendor name="Sun Microsystems Inc."> + <minVersion>1.5.0</minVersion> + </vendor> + <vendor name="The FreeBSD Foundation"> + <minVersion>1.6.0</minVersion> + </vendor> + <vendor name="Free Software Foundation, Inc."> + <minVersion>1.5.0</minVersion> + </vendor> + </vendorInfos> + + <plugins> + <library vendor="Sun Microsystems Inc.">vnd.sun.star.expand:$URE_INTERNAL_LIB_DIR/sunjavaplugin.so</library> + <library vendor="The FreeBSD Foundation">vnd.sun.star.expand:$URE_INTERNAL_LIB_DIR/sunjavaplugin.so</library> + <library vendor="Free Software Foundation, Inc.">vnd.sun.star.expand:$URE_INTERNAL_LIB_DIR/sunjavaplugin.so</library> + </plugins> +</javaSelection> diff --git a/jvmfwk/distributions/OpenOfficeorg/javavendors_linux.xml b/jvmfwk/distributions/OpenOfficeorg/javavendors_linux.xml new file mode 100644 index 000000000000..ed329e5788d3 --- /dev/null +++ b/jvmfwk/distributions/OpenOfficeorg/javavendors_linux.xml @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<javaSelection xmlns="http://openoffice.org/2004/java/framework/1.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + + <updated>2004-01-30</updated> + + <vendorInfos> + <vendor name="Sun Microsystems Inc."> + <minVersion>1.5.0</minVersion> + </vendor> + <vendor name="IBM Corporation"> + <minVersion>1.5.0</minVersion> + </vendor> + <vendor name="Blackdown Java-Linux Team"> + <minVersion>1.5.0</minVersion> + </vendor> + <vendor name="Free Software Foundation, Inc."> + <minVersion>1.5.0</minVersion> + </vendor> + <vendor name="BEA Systems, Inc."> + <minVersion>1.5.0</minVersion> + </vendor> + </vendorInfos> + + <plugins> + <library vendor="Sun Microsystems Inc.">vnd.sun.star.expand:$URE_INTERNAL_LIB_DIR/sunjavaplugin.so</library> + <library vendor="IBM Corporation">vnd.sun.star.expand:$URE_INTERNAL_LIB_DIR/sunjavaplugin.so</library> + <library vendor="Blackdown Java-Linux Team">vnd.sun.star.expand:$URE_INTERNAL_LIB_DIR/sunjavaplugin.so</library> + <library vendor="Free Software Foundation, Inc.">vnd.sun.star.expand:$URE_INTERNAL_LIB_DIR/sunjavaplugin.so</library> + <library vendor="BEA Systems, Inc.">vnd.sun.star.expand:$URE_INTERNAL_LIB_DIR/sunjavaplugin.so</library> + </plugins> +</javaSelection> diff --git a/jvmfwk/distributions/OpenOfficeorg/javavendors_macosx.xml b/jvmfwk/distributions/OpenOfficeorg/javavendors_macosx.xml new file mode 100644 index 000000000000..215d26c0ea2a --- /dev/null +++ b/jvmfwk/distributions/OpenOfficeorg/javavendors_macosx.xml @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<javaSelection xmlns="http://openoffice.org/2004/java/framework/1.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + + <updated>2006-05-02</updated> + + <vendorInfos> + <vendor name="Apple Computer, Inc."> + <minVersion>1.5.0</minVersion> + </vendor> + <vendor name="Apple Inc."> + <minVersion>1.5.0</minVersion> + </vendor> + </vendorInfos> + <plugins> + <library vendor="Apple Inc.">vnd.sun.star.expand:$URE_INTERNAL_LIB_DIR/sunjavaplugin.dylib</library> + <library vendor="Apple Computer, Inc.">vnd.sun.star.expand:$URE_INTERNAL_LIB_DIR/sunjavaplugin.dylib</library> + </plugins> +</javaSelection> diff --git a/jvmfwk/distributions/OpenOfficeorg/javavendors_os2.xml b/jvmfwk/distributions/OpenOfficeorg/javavendors_os2.xml new file mode 100644 index 000000000000..2de585472b86 --- /dev/null +++ b/jvmfwk/distributions/OpenOfficeorg/javavendors_os2.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<javaSelection xmlns="http://openoffice.org/2004/java/framework/1.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + + <updated>2004-01-30</updated> + + <vendorInfos> + <vendor name="Sun Microsystems Inc."> + <minVersion>1.4.2</minVersion> + </vendor> + <vendor name="IBM Corporation"> + <minVersion>1.4.2</minVersion> + </vendor> + </vendorInfos> + + <plugins> + <library vendor="Sun Microsystems Inc.">sunjavap.dll</library> + <library vendor="IBM Corporation">sunjavap.dll</library> + </plugins> +</javaSelection> diff --git a/jvmfwk/distributions/OpenOfficeorg/javavendors_template.xml b/jvmfwk/distributions/OpenOfficeorg/javavendors_template.xml new file mode 100644 index 000000000000..d18dc66585a5 --- /dev/null +++ b/jvmfwk/distributions/OpenOfficeorg/javavendors_template.xml @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<!-- +This is a template for the javavendors.xml. It shows how the file could +look like. +--> + +<javaSelection xmlns="http://openoffice.org/2004/java/framework/1.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://openoffice.org/2004/java/framework/1.0 file:/D:/cws-jl6/jvmfwk/source/javavendors.xsd" > + + <updated>2004-01-30</updated> + + <vendorInfos> + <vendor name="Sun Microsystems Inc."> + <minVersion>1.3.1</minVersion> + <maxVersion>1.5.0</maxVersion> + <excludeVersions> + <version>1.4.1</version> + </excludeVersions> + </vendor> + <vendor name="VendorX"> + <minVersion>1.4.2</minVersion> + <excludeVersions> + <version>1.5.0</version> + <version>1.4.3</version> + </excludeVersions> + </vendor> + </vendorInfos> + + <plugins> + <library vendor="Sun Microsystems Inc.">sunjavaplugin.dll</library> + <library vendor="VendorX">./pluginDir/vendorx.dll</library> + </plugins> +</javaSelection>
\ No newline at end of file diff --git a/jvmfwk/distributions/OpenOfficeorg/javavendors_unx.xml b/jvmfwk/distributions/OpenOfficeorg/javavendors_unx.xml new file mode 100755 index 000000000000..3b1f53fc4fce --- /dev/null +++ b/jvmfwk/distributions/OpenOfficeorg/javavendors_unx.xml @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<javaSelection xmlns="http://openoffice.org/2004/java/framework/1.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + + <updated>2004-01-30</updated> + + <vendorInfos> + <vendor name="Sun Microsystems Inc."> + <minVersion>1.5.0</minVersion> + </vendor> + </vendorInfos> + + <plugins> + <library vendor="Sun Microsystems Inc.">vnd.sun.star.expand:$URE_INTERNAL_LIB_DIR/sunjavaplugin.so</library> + </plugins> +</javaSelection> diff --git a/jvmfwk/distributions/OpenOfficeorg/javavendors_wnt.xml b/jvmfwk/distributions/OpenOfficeorg/javavendors_wnt.xml new file mode 100644 index 000000000000..a72216d66646 --- /dev/null +++ b/jvmfwk/distributions/OpenOfficeorg/javavendors_wnt.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<javaSelection xmlns="http://openoffice.org/2004/java/framework/1.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + + <updated>2004-01-30</updated> + + <vendorInfos> + <vendor name="Sun Microsystems Inc."> + <minVersion>1.5.0</minVersion> + </vendor> + <vendor name="IBM Corporation"> + <minVersion>1.5.0</minVersion> + </vendor> + </vendorInfos> + + <plugins> + <library vendor="Sun Microsystems Inc.">vnd.sun.star.expand:$URE_INTERNAL_LIB_DIR/sunjavaplugin.dll</library> + <library vendor="IBM Corporation">vnd.sun.star.expand:$URE_INTERNAL_LIB_DIR/sunjavaplugin.dll</library> + </plugins> +</javaSelection> diff --git a/jvmfwk/distributions/OpenOfficeorg/makefile.mk b/jvmfwk/distributions/OpenOfficeorg/makefile.mk new file mode 100755 index 000000000000..88afdb33f81c --- /dev/null +++ b/jvmfwk/distributions/OpenOfficeorg/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 = jvmfwk +TARGET = vendors_ooo + +.INCLUDE: settings.mk + +.IF "$(SOLAR_JAVA)"=="" +nojava: + @echo "Not building jvmfwk because Java is disabled" +.ENDIF + +.IF "$(SOLAR_JAVA)"!="" +$(BIN)$/javavendors.xml: javavendors_unx.xml javavendors_wnt.xml javavendors_macosx.xml javavendors_linux.xml +.IF "$(GUI)"=="UNX" +.IF "$(OS)"=="FREEBSD" + -$(COPY) javavendors_freebsd.xml $(BIN)$/javavendors.xml +.ELIF "$(OS)"=="MACOSX" + -$(COPY) javavendors_macosx.xml $(BIN)$/javavendors.xml +.ELIF "$(OS)"=="LINUX" || "$(OS)"=="AIX" + -$(COPY) javavendors_linux.xml $(BIN)$/javavendors.xml +.ELSE + -$(COPY) javavendors_unx.xml $(BIN)$/javavendors.xml +.ENDIF +.ELIF "$(GUI)"=="WNT" + -$(COPY) javavendors_wnt.xml $(BIN)$/javavendors.xml +.ELSE + @echo Unsupported platform. +.ENDIF + +.ENDIF # "$(SOLAR_JAVA)"!="" + + + + +.INCLUDE: target.mk + diff --git a/jvmfwk/inc/jvmfwk/framework.h b/jvmfwk/inc/jvmfwk/framework.h new file mode 100644 index 000000000000..11cca539cb05 --- /dev/null +++ b/jvmfwk/inc/jvmfwk/framework.h @@ -0,0 +1,871 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +/** @HTML */ + +#if !defined INCLUDED_JVMFWK_FRAMEWORK_H +#define INCLUDED_JVMFWK_FRAMEWORK_H + +#include "rtl/ustring.h" +#include "osl/mutex.h" +#ifdef SOLAR_JAVA +#include "jni.h" +#else +struct JavaVMOption; +struct JavaVM; +struct JNIEnv; +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** @file + <p>This library can operate in two modes, application mode and direct mode.</p> + + + <h2>Application Mode</h2> + In application mode the Java related settings are stored in files. + There are currently three files which need to be accessed. They are determined + by bootstrap parameters:</p> + <dl> + <dt>UNO_JAVA_JFW_VENDOR_SETTINGS</dt> + <dd>contains vendor and version information about JREs as well as the + location of plugin-libraries which are responsible for providing information + about these JREs as well as starting the VMs.</dd> + <dt>UNO_JAVA_JFW_USER_DATA</dt> + <dd>The file contains settings for a particular user. One can use the macro + $SYSUSERCONFIG in the URL which expands to a directory whery the user's data are + kept. On UNIX this would be the home directory and on Windows some sub-directory + of the "Documents and Settings" folder.The content of this file is an + implementation detail and may change in the future.</dd> + <dt>UNO_JAVA_JFW_SHARED_DATA</dt> + <dd>The file contains settings valid for all users. If a user changes a setting + then it takes precedence over the setting from UNO_JAVA_JFW_SHARED_DATA. + The content of this file is an implementation detail and may change in the future.</dd> + + <dt>UNO_JAVA_JFW_INSTALL_DATA</dt> + <dd><b>DEPRECATED. Support for this variable will soon be removed.</b><br> + The file contains settings for all users. A user cannot override these settings. + When this parameter is provided then UNO_JAVA_JFW_SHARED_DATA and UNO_JAVA_JFW_USER_DATA + are irrelevant. This parameter is intended for use during the setup. For example, to + install extensions which contain java components. If there is already a file at this + location then it will be overwritten if it is too old. The period of validatity is per + default one hour. This value can be overridden by the bootstrap parameter + UNO_JAVA_JFW_INSTALL_EXPIRE (<b>DEPRECATED</b>). Setting this variable to 1000 means + the settings file is only valid for 1000 seconds. + + <p>If one would not use UNO_JAVA_JFW_INSTALL_DATA during setup then most probably + a user installation directory would be created in the home directory of root. This is + because, java settings are determined and stored on behalf of the current user. In other + words UNO_JAVA_JFW_USER_DATA would be used which points into the user installation. + </p> + <p>UNO_JAVA_JFW_INSTALL_DATA could point into the shared installation, provided that + only people with root rights can install OOo. Then one has to take care that the + installer removes this file when uninstalling. + </p> + + + The content of this file is an implementation detail and may change in the future.</dd> + </dl> + + <p>The values for these parameters must be file URLs and include the file name, for + example:<br> + file:///d:/MyApp/javavendors.xml<br> + All files are XML files and must have the extension .xml.</p> + <p> + Modifying the shared settings is currently not supported by the framework. To provide + Java settings for all users one can run OOo and change the settings in the + options dialog. These settings are made persistent in the UNO_JAVA_JFW_USER_DATA. + The file can then be copied into the base installation. + Other users will use automatically these data but can override the settings in + the options dialog. This mechanism may change in the future. + </p> + <p>If shared Java settings are not supported by an application then it is not + necessary to specify the bootstrap parameter <code>UNO_JAVA_JFW_SHARED_DATA</code>. + </p> + + <p>Setting the class path used by a Java VM should not be necesarry. The locations + of Jar files should be knows by a class loader. If a jar file depends on another + jar file then it can be referenced in the manifest file of the first jar. However, + a user may add jars to the class path by using this API. If it becomes necessary + to add files to the class path which is to be used by all users then one can use + the bootrap parameter UNO_JAVA_JFW_CLASSPATH_URLS. The value contains of file URLs + which must be separated by spaces.</p> + + + <h2>Direct Mode</h2> + + <p>The direct mode is intended for a scenario where no configuration files + are available and a Java VM shall be run. That is, + the files containing the user and shared settings are not specified by the + bootstrap parameters UNO_JAVA_JFW_SHARED_DATA and UNO_JAVA_JFW_USER_DATA. + For example, tools, such as regcomp, may use this framework in a build + environment. Then one would want to use settings which have been specified + by the build environment. The framework would automatically use the + current settings when they change in the environment. + </p> + + <p> Here are examples how regcomp could be invoked using bootstrap parameters: + </p> + <p> + regcomp -env:UNO_JAVA_JFW_JREHOME=file:///d:/j2re1.4.2 + -env:"UNO_JAVA_JFW_CLASSPATH=d:\\solver\\bin\\classes.jar;d:\\solver\\bin\\jurt.jar" + -register .... + </p> + <p>If UNO_JAVA_JFW_VENDOR_SETTINGS is not set then a plugin library must be specified. For example:</p> + <p> + regcomp -env:UNO_JAVA_JFW_JREHOME=file:///d:/j2re1.4.2 + -env:"UNO_JAVA_JFW_CLASSPATH=d:\\solver\\bin\\classes.jar;d:\\solver\\bin\\jurt.jar" + -env:UNO_JAVA_JFW_PLUGIN=file:\\solver\\bin\\sunjavaplugin.dll -register .... + </p> + <p>Additionall parameters for the Java VM can be provided. For every parameter + a seperate bootstrap parameter must be specified. The names are + <code>UNO_JAVA_JFW_PARAMETER_X</code>, where X is 1,2, .. n. For example:</p> + <p> + regcomp -env:UNO_JAVA_JFW_PARAMETER_1=-Xdebug + -env:UNO_JAVA_JFW_PARAMETER_2=-Xrunjdwp:transport=dt_socket,server=y,address=8100 + -env:UNO_JAVA_JFW_JREHOME=file:///d:/j2re1.4.2 + -env:"UNO_JAVA_JFW_CLASSPATH=d:\\solver\\bin\\classes.jar;d:\\solver\\bin\\jurt.jar" + -register ....</p> + <p> + Here is a complete list of the bootstrap parameter for the direct mode: + </p> + <dl> + <dt>UNO_JAVA_JFW_JREHOME</dt> + <dd>Specifies a file URL to a JRE installation.It must ALWAYS be specified + in direct mode</dd> + <dt>UNO_JAVA_JFW_ENV_JREHOME</dt> + <dd>Setting this parameter, for example to "1" or "true", + causes the framework to use the environment variable JAVA_HOME. It is expected + that JAVA_HOME contains a system path rather than a file URL. This parameter + and UNO_JAVA_JFW_JREHOME are mutually exclusive</dd> + <dt>UNO_JAVA_JFW_CLASSPATH</dt> + <dd>Contains the class path which is to be used by the VM. Special character, + such as '\','{','}','$' must be preceded with '\'. See documentation about the + bootstrap parameter.</dd> + <dt>UNO_JAVA_JFW_ENV_CLASSPATH</dt> + <dd>Setting this parameter,for example to "1" or "true", + causes the framework to use the + environment variable CLASSPATH. If this variable and UNO_JAVA_JFW_CLASSPATH are + set then the class path is composed from UNO_JAVA_JFW_CLASSPATH and the environment + variable CLASSPATH.</dd> + <dt>UNO_JAVA_JFW_PLUGIN</dt> + <dd>Specified a file URL to a plugin library. If this variable is provided + then a javavendors.xml is ignored. It must be provided if no + javavendors.xml is available.</dd> + <dt>UNO_JAVA_JFW_PARAMETER_X</dt> + <dd>Specifies a parameter for the Java VM. The X is replaced by + non-negative natural numbers starting with 1.</dd> + </dl> + + <p>A note about bootstrap parameters. The implementation of the bootstrap + parameter mechanism interprets the characters '\', '$', '{', '}' as + escape characters. Thats why the Windows path contain double back-slashes. + One should also take into account that a console may have also special + escape characters.</p> + + <h2>What mode is used</h2> + <p> + The default mode is application mode. If at least one bootstrap parameter + for the direct mode is provided then direct mode is used. </p> + + <p> + All settings made by this API are done for the current user if not + mentioned differently.</p> + + <h2>Other bootstrap variables</h2> + <dl> + <dt>JFW_PLUGIN_DO_NOT_CHECK_ACCESSIBILITY</dt> + <dd>This is a unofficial variable which was introduced to workaround external issues. + It may be removed in the future. By setting it to 1, the framework will not try to + find out if the system is configured to use accessibility tools or if a JRE has an + accessibiliy bridge installed</dd> + </dl> +*/ + +/** indicates that a JRE has an accessibility bridge installed. + <p> + The flag is used with JavaInfo::nFeatures.</p> + */ +#define JFW_FEATURE_ACCESSBRIDGE 0x1l +/** indicates that there must be an environment set up before the Java process + runs. + <p>Therefore, when a Java is selected in OO then the office must be + restarted, so that the changes can take effect.</p> + */ +#define JFW_REQUIRE_NEEDRESTART 0x1l + +/** error codes which are returned by functions of this API. + */ +typedef enum _javaFrameworkError +{ + JFW_E_NONE, + JFW_E_ERROR, + JFW_E_INVALID_ARG, + JFW_E_NO_SELECT, + JFW_E_INVALID_SETTINGS, + JFW_E_NEED_RESTART, + JFW_E_RUNNING_JVM, + JFW_E_JAVA_DISABLED, + JFW_E_NO_PLUGIN, + JFW_E_NOT_RECOGNIZED, + JFW_E_FAILED_VERSION, + JFW_E_NO_JAVA_FOUND, + JFW_E_VM_CREATION_FAILED, + JFW_E_CONFIGURATION, + JFW_E_DIRECT_MODE +} javaFrameworkError; + +/** an instance of this struct represents an installation of a Java + Runtime Environment (JRE). + + <p> + Instances of this struct are created by the plug-in libraries which are used by + this framework (jvmfwk/vendorplugin.h). The memory of the instances is created + by <code>rtl_allocateMemory</code> (rtl/alloc.h). Therefore, the memory must + be freed by <code>rtl_freeMemory</code>. Also the contained members must be + freed particularly. + For convenience this API provides the function <code>jfw_freeJavaInfo</code> + which frees the objects properly. </p> + */ +struct _JavaInfo +{ + /** contains the vendor. + + <p>string must be the same as the one obtained from the + Java system property <code>java.vendor</code>. + </p> + */ + rtl_uString *sVendor; + /** contains the file URL to the installation directory. + */ + rtl_uString *sLocation; + /** contains the version of this Java distribution. + + <p>The version string must adhere to the rules + about how a version string has to be formed. These rules may + be vendor-dependent. Essentially the strings must syntactically + equal the Java system property <code>java.version</code>. + </p> + */ + rtl_uString *sVersion; + /** indicates supported special features. + + <p>For example, <code>JFW_FEATURE_ACCESSBRIDGE</code> indicates that + assistive technology tools are supported.</p> + */ + sal_uInt64 nFeatures; + /** indicates requirments for running the java runtime. + + <p>For example, it may be necessary to prepare the environment before + the runtime is created. That could mean, setting the + <code>LD_LIBRARY_PATH</code> + when <code>nRequirements</code> contains the flag + <code>JFW_REQUIRE_NEEDRESTART</code></p> + */ + sal_uInt64 nRequirements; + /** contains data needed for the creation of the java runtime. + + <p>There is no rule about the format and content of the sequence's + values. The plug-in libraries can put all data, necessary for + starting the java runtime into this sequence. </p> + */ + sal_Sequence * arVendorData; +}; + +typedef struct _JavaInfo JavaInfo; + +/** frees the memory of a <code>JavaInfo</code> object. + @param pInfo + The object which is to be freed. It can be NULL; + */ +void SAL_CALL jfw_freeJavaInfo(JavaInfo *pInfo); + + +/** compares two <code>JavaInfo</code> objects for equality. + + <p>Two <code>JavaInfo</code> objects are said to be equal if the contained + members of the first <code>JavaInfo</code> are equal to their counterparts + in the second <code>JavaInfo</code> object. The equality of the + <code>rtl_uString</code> members is determined + by the respective comparison function (see + <code>rtl::OUString::equals</code>). + Similiarly the equality of the <code>sal_Sequence</code> is + also determined by a comparison + function (see <code>rtl::ByteSequence::operator ==</code>). </p> + <p> + Both argument pointers must be valid.</p> + @param pInfoA + the first argument. + @param pInfoB + the second argument which is compared with the first. + @return + sal_True - both object represent the same JRE.</br> + sal_False - the objects represend different JREs + */ +sal_Bool SAL_CALL jfw_areEqualJavaInfo( + JavaInfo const * pInfoA,JavaInfo const * pInfoB); + +/** determines if a Java Virtual Machine is already running. + + <p>As long as the the office and the JREs only support one + Virtual Machine per process the Java settings, particulary the + selected Java, are not effective immediatly after changing when + a VM has already been running. That is, if a JRE A was used to start + a VM and then a JRE B is selected, then JRE B will only be used + after a restart of the office.</p> + <p> + By determining if a VM is running, the user can be presented a message, + that the changed setting may not be effective immediately.</p> + + @param bRunning + [out] sal_True - a VM is running. <br/> + sal_False - no VM is running. + + @return + JFW_E_NONE function ran successfully.<br/> + JFW_E_INVALID_ARG the parameter <code>bRunning</code> was NULL. +*/ +javaFrameworkError SAL_CALL jfw_isVMRunning(sal_Bool *bRunning); + +/** detects a suitable JRE and configures the framework to use it. + + <p>Which JREs can be used is determined by the file javavendors.xml, + which contains version requirements, as well as information about available + plug-in libraries. Only these libraries are responsible for locating JRE + installations.</p> + <p> + JREs can be provided by different vendors. In order to find the JREs of + a certain vendor a plug-in library must be provided. There must be only one + library for one vendor. The names of locations of those libraries have to + be put into the javavendors.xml file.<br/> + The function uses the plug-in libraries to obtain information about JRE + installation and checks if they there is one among them that supports + a set of features (currently only accessibilty is possible). If none was + found then it also uses a list of paths, which have been registered + by <code>jfw_addJRELocation</code> or <code>jfw_setJRELocations</code> + to find JREs. Found JREs are examined in the same way.</p> + <p> + A JRE installation is only selected if it meets the version requirements. + Information about the selected JRE are made persistent so that + subsequent calls to <code>jfw_getSelectedJRE</code> returns this + information.</p> + <p> + While determining a proper JRE this function takes into account if a + user requires support for assistive technology tools. If user + need that support they have to set up their system accordingly. When support + for assistive technology is required, then the lists of + <code>JavaInfo</code> objects, + which are provided by the <code>getJavaInfo</code> functions of the plug-ins, are + examined for a suitable JRE. That is, the <code>JavaInfo</code> objects + from the list + obtained from the first plug-in, are examined. If no <code>JavaInfo</code> + object has the flag + <code>JFW_FEATURE_ACCESSBRIDGE</code> in the member <code>nFeatures</code> + then the + next plug-in is used to obtain a list of <code>JavaInfo</code> objects. + This goes on until a <code>JavaInfo</code> object was found which + represents a suitable JRE. Or neither plug-in provided such a + <code>JavaInfo</code> object. In that case the first + <code>JavaInfo</code> object from the first plug-in is used to determine + the JRE which is to be used.</p> + <p> + If there is no need for the support of assistive technology tools then + the first <code>JavaInfo</code> object from the list obtained by the + first plug-in is used. If this plug-in does not find any JREs then the + next plug-in is used, and so on.</p> + + @param ppInfo + [out] a <code>JavaInfo</code> pointer, representing the selected JRE. + The caller has to free it by calling <code>jfw_freeJavaInfo<code>. The + <code>JavaInfo</code> is for informational purposes only. It is not + necessary to call <code>jfw_setSelectedJRE</code> afterwards.<br/> + <code>ppInfo</code>can be NULL. If <code>*ppInfo</code> is not null, then it is + overwritten, without attempting to free <code>*ppInfo</code>. + + @return + JFW_E_NONE function ran successfully.<br/> + JFW_E_ERROR an error occurred. <br/> + JFW_E_NO_PLUGIN a plug-in library could not be found.<br/> + JFW_E_NO_JAVA_FOUND no JRE was found that meets the requirements.</br> + JFW_E_DIRECT_MODE the function cannot be used in this mode. </br> + JFW_E_CONFIGURATION mode was not properly set or their prerequisites + were not met. + */ +javaFrameworkError SAL_CALL jfw_findAndSelectJRE(JavaInfo **pInfo); + +/** provides information about all availabe JRE installations. + + <p>The function determines dynamically what JREs are available. It uses + the plug-in libraries to provide lists of available <code>JavaInfo</code> + objects where each object represents a JRE (see vendorplugin.h, + getAllJavaInfos). It also uses a list of paths, which have been registered + by <code>jfw_addJRELocation</code> or <code>jfw_setJRELocations</code>. + It is checked if the path still contains a valid JRE and if so the respective + <code>JavaInfo</code> object will be appended to the array unless there is + already an equal object.</p> + + @param parInfo + [out] on returns it contains a pointer to an array of <code>JavaInfo</code> + pointers. + The caller must free the array with <code>rtl_freeMemory</code> and each + element of the array must be freed with <code>jfw_freeJavaInfo</code>. + @param pSize + [out] on return contains the size of array returned in <code>parInfo</code>. + + @return + JFW_E_NONE function ran successfully.<br/> + JFW_E_INVALID_ARG at least on of the parameters was NULL<br/> + JFW_E_ERROR an error occurred. <br/> + JFW_E_NO_PLUGIN a plug-in library could not be found.<br/> + JFW_E_CONFIGURATION mode was not properly set or their prerequisites + were not met. +*/ +javaFrameworkError SAL_CALL jfw_findAllJREs( + JavaInfo ***parInfo, sal_Int32 *pSize); + +/** determines if a path points to a Java installation. + + <p>If the path belongs to a JRE installation then it returns the + respective <code>JavaInfo</code> object. The function uses the + <code>getJavaInfoByPath</code> function of the plug-ins to obtain the + <code>JavaInfo</code> object. Only if the JRE found at the specified location + meets the version requirements as specified in the javavendors.xml file a + <code>JavaInfo</code> object is returned.<br/> + <p> + The functions only checks if a JRE exists but does not modify any settings. + To make the found JRE the "selected JRE" one has + to call <code>jfw_setSelectedJRE</code>.</p> + + @param pPath + [in] a file URL to a directory. + @param pInfo + [out] the <code>JavaInfo</code> object which represents a JRE found at the + location specified by <code>pPath</code> + + @return + JFW_E_NONE function ran successfully.<br/> + JFW_E_INVALID_ARG at least on of the parameters was NULL<br/> + JFW_E_ERROR an error occurred. <br/> + JFW_E_CONFIGURATION mode was not properly set or their prerequisites + were not met.</br> + JFW_E_NO_PLUGIN a plug-in library could not be found.<br/> + JFW_E_NOT_RECOGNIZED neither plug-in library could detect a JRE. <br/> + JFW_E_FAILED_VERSION a JRE was detected but if failed the version + requirements as determined by the javavendors.xml + */ +javaFrameworkError SAL_CALL jfw_getJavaInfoByPath( + rtl_uString *pPath, JavaInfo **ppInfo); + + +/** starts a Java Virtual Machine (JVM). + + <p>The function uses the current settings to start a JVM. The actual + start-up code, however, is provided by the plug-in libraries. The setting + of the "selected Java" contains the information as to what vendor + the respective JRE comes from. In the javavendors.xml there is a mapping of + vendor names to the respective plug-in libraries.</p> + <p> + The function ultimately calls <code>startJavaVirtualMachine</code> from + the plug-in library.</p> + <p> + The <code>arOptions</code> + argument contains start arguments which are passed in JavaVMOption structures + to the VM during its creation. These + could be things, such as language settings, proxy settings or any other + properties which shall be obtainable by + <code>java.lang.System.getProperties</code>. One can also pass options which + have a certain meaning to the runtime behaviour such as -ea or -X... However, + one must be sure that these options can be interpreted by the VM.<br/> + The class path cannot be set this way. The class path is internally composed by + the paths to archives in a certain directory, which is preconfigured in + the internal data store and the respective user setting (see + <code>jfw_setUserClassPath</code>.</p> + <p> + If a JRE was selected at runtime which was different from the previous + setting and that JRE needs a prepared environment, for example an adapted + <code>LD_LIBRARY_PATH</code> environment variable, then the VM will not be + created and JFW_E_NEED_RESTART error is returned. If a VM is already running + then a JFW_E_RUNNING_JVM is returned.</p> + + @param arOptions + [in] the array containing additional start arguments or NULL. + @param nSize + [in] the size of the array <code>arOptions</code>. + @param ppVM + [out] the <code>JavaVM</code> pointer. + @param ppEnv + [out] the <code>JNIenv</code> pointer. + + @return + JFW_E_NONE function ran successfully.<br/> + JFW_E_INVALID_ARG <code>ppVM</code>, <code>ppEnv</code> are NULL or + <code>arOptions</code> was NULL but <code>nSize</code> was greater 0.<br/> + JFW_E_ERROR an error occurred. <br/> + JFW_E_CONFIGURATION mode was not properly set or their prerequisites + were not met.</br> + JFW_E_NO_PLUGIN the plug-in library responsible for creating the VM + could not be found.<br/> + JFW_E_JAVA_DISABLED the use of Java is currently disabled. <br/> + JFW_E_NO_SELECT there is no JRE selected yet. <br/> + JFW_E_RUNNIN_JVM there is already a VM running.<br/> + JFW_E_INVALID_SETTINGS the javavendors.xml has been changed and no + JRE has been selected afterwards. <br/> + JFW_E_NEED_RESTART in the current process a different JRE has been selected + which needs a prepared environment, which has to be done before the office + process. Therefore the new JRE may not be used until the office was restarted.<br/> + JFW_E_NEED_RESTART is also returned when Java was disabled at the beginning and + then the user enabled it. If then the selected JRE has the requirement + JFW_REQUIRE_NEEDRESTART then this error is returned. </br> + JFW_E_VM_CREATION_FAILED the creation of the JVM failed. The creation is performed + by a plug-in library and not by this API. + JFW_E_FAILED_VERSION the "Default Mode" is active. The JRE determined by + <code>JAVA_HOME</code>does not meet the version requirements. + */ +javaFrameworkError SAL_CALL jfw_startVM(JavaVMOption *arOptions, + sal_Int32 nSize, JavaVM **ppVM, + JNIEnv **ppEnv); + +/** determines the JRE that is to be used. + + <p>When calling <code>jfw_startVM</code> then a VM is startet from + the JRE that is determined by this function.<br/> + It is not verified if the JRE represented by the <code>JavaInfo</code> + argument meets the requirements as specified by the javavendors.xml file. + However, usually one obtains the <code>JavaInfo</code> object from the + functions <code>jfw_findAllJREs</code> or <code>jfw_getJavaInfoByPath</code>, + which do verify the JREs and pass out only <code>JavaInfo</code> objects + which comply with the version requirements.</p> + <p> + If <code>pInfo</code> is NULL then the meaning is that no JRE will be + selected. <code>jfw_startVM</code> will then return + <code>JFW_E_NO_SELECT</code>.</p> + + @param pInfo + [in] pointer to <code>JavaInfo</code> structure, containing data about a + JRE. The caller must still free <code>pInfo</code>. + + @return + JFW_E_NONE function ran successfully.<br/> + JFW_E_ERROR An error occurred.<br/> + JFW_E_CONFIGURATION mode was not properly set or their prerequisites + were not met.<br/> + JFW_E_DIRECT_MODE the function cannot be used in this mode. + */ +javaFrameworkError SAL_CALL jfw_setSelectedJRE(JavaInfo const *pInfo); + + +/** provides information about the JRE that is to be used. + + <p>If no JRE is currently selected then <code>ppInfo</code> will contain + NULL on return.</br> + If the value of the element <updated> in the javavendors.xml file was + changed since the time when the last Java was selected then this + function returns <code>JFW_E_INVALID_SETTINGS</code>. This could happen during + a product patch. Then new version requirements may be introduced, so that + the currently selected JRE may not meet these requirements anymore. + </p> + <p>In direct mode the function returns information about a JRE that was + set by the bootstrap parameter UNO_JAVA_JFW_JREHOME. + </p> + @param ppInfo + [out] on return it contains a pointer to a <code>JavaInfo</code> object + that represents the currently selected JRE. When <code>*ppInfo</code> is not + NULL then the function overwrites the pointer. It is not attempted to free + the pointer. + + @return + JFW_E_NONE function ran successfully.<br/> + JFW_E_INVALIDARG <code>ppInfo</code> is a NULL.<br/> + JFW_E_CONFIGURATION mode was not properly set or their prerequisites + were not met.<br/> + JFW_E_INVALID_SETTINGS the javavendors.xml has been changed and no + JRE has been selected afterwards. <br/> + */ +javaFrameworkError SAL_CALL jfw_getSelectedJRE(JavaInfo **ppInfo); + + +/** determines if Java can be used. + + <p>If <code>bEnabled</code> is <code>sal_False</code> then a call + to jfw_startVM will result in an error with the errorcode + <code>JFW_E_JAVA_DISABLED</code></p> + + @param bEnabled + [in] use of Java enabled/disabled. + + @return + JFW_E_NONE function ran successfully.<br/> + JFW_E_ERROR An error occurred.<br/> + JFW_E_CONFIGURATION mode was not properly set or their prerequisites + were not met.<br/> + JFW_E_DIRECT_MODE the function cannot be used in this mode. + */ +javaFrameworkError SAL_CALL jfw_setEnabled(sal_Bool bEnabled); + +/** provides the information if Java can be used. + + <p>That is if the user enabled or disabled the use of Java. + </p> + + @return + JFW_E_NONE function ran successfully.<br/> + JFW_E_INVALIDARG pbEnabled is NULL<br/> + JFW_E_ERROR An error occurred.<br/> + JFW_E_CONFIGURATION mode was not properly set or their prerequisites + were not met.<br/> + JFW_E_DIRECT_MODE the function cannot be used in this mode. + */ +javaFrameworkError SAL_CALL jfw_getEnabled(sal_Bool *pbEnabled); + +/** determines parameters which are passed to VM during its creation. + + <p>The strings must be exactly as they are passed on the command line. + For example, one could pass<br/> + -Xdebug <br/> + -Xrunjdw:transport=dt_socket,server=y,address=8000<br/> + in order to enable debugging support. + </p> + + @param arParameters + [in] contains the arguments. It can be NULL if nSize is 0. + @param nSize + [i] the size of <code>arArgs</code> + + @return + JFW_E_NONE function ran successfully.<br/> + JFW_E_INVALIDARG arArgs is NULL and nSize is not 0 + JFW_E_ERROR An error occurred.<br/> + JFW_E_CONFIGURATION mode was not properly set or their prerequisites + were not met.<br/> + JFW_E_DIRECT_MODE the function cannot be used in this mode. + */ +javaFrameworkError SAL_CALL jfw_setVMParameters( + rtl_uString ** arArgs, sal_Int32 nSize); + +/** obtains the currently used start parameters. + + <p>The caller needs to free the returned array with + <code>rtl_freeMemory</code>. The contained strings must be released with + <code>rtl_uString_release</code>. + </p> + + @param parParameters + [out] on returns contains a pointer to the array of the start arguments. + If *parParameters is not NULL then the value is overwritten. + @param pSize + [out] on return contains the size of array returned in + <code>parParameters</code> + + @return + JFW_E_NONE function ran successfully.<br/> + JFW_E_INVALIDARG parParameters or pSize are NULL<br/> + JFW_E_ERROR An error occurred.<br/> + JFW_E_CONFIGURATION mode was not properly set or their prerequisites + were not met.<br/> + JFW_E_DIRECT_MODE the function cannot be used in this mode. + */ +javaFrameworkError SAL_CALL jfw_getVMParameters( + rtl_uString *** parParameters, + sal_Int32 * pSize); + +/** sets the user class path. + + <p>When the VM is started then it is passed the class path. The + class path also contains the user class path set by this function. + The paths contained in <code>pCP</code> must be separated with a + system dependent path separator.</p> + + @param pCP + [in] the user class path. + + @return + JFW_E_NONE function ran successfully.<br/> + JFW_E_INVALIDARG pCP is NULL.<br/> + JFW_E_ERROR An error occurred.<br/> + JFW_E_CONFIGURATION mode was not properly set or their prerequisites + were not met.<br/> + JFW_E_DIRECT_MODE the function cannot be used in this mode. + */ +javaFrameworkError SAL_CALL jfw_setUserClassPath(rtl_uString * pCP); +/** provides the value of the current user class path. + + <p>The function returns an empty string if no user class path is set. + </p> + + @param ppCP + [out] contains the user class path on return. If <code>*ppCP</code> was + not NULL then the value is overwritten. No attempt at freeing that string + is made. + + @return + JFW_E_NONE function ran successfully.<br/> + JFW_E_INVALIDARG ppCP is NULL.<br/> + JFW_E_ERROR An error occurred.<br/> + JFW_E_CONFIGURATION mode was not properly set or their prerequisites + were not met.<br/> + JFW_E_DIRECT_MODE the function cannot be used in this mode. + */ +javaFrameworkError SAL_CALL jfw_getUserClassPath(rtl_uString ** ppCP); + +/** saves the location of a JRE. + + <p>When <code>jfw_findAllJREs</code> is called then the paths added by this + function are evaluated. If the location still represents a + JRE then a <code>JavaInfo</code> object is created which is returned along + with all other <code>JavaInfo</code> objects by + <code>jfw_findAllJREs</code>. If the location + cannot be recognized then the location string is ignored. </p> + <p> + A validation if <code>sLocation</code> points to a JRE is not + performed. To do that one has to use <code>jfw_getJavaInfoByPath</code>. + </p> + <p> + Adding a path that is already stored causes no error.</p> + + @param sLocation + [in] file URL to a directory which contains a JRE. + + @return + JFW_E_NONE function ran successfully.<br/> + JFW_E_INVALIDARG sLocation is NULL.<br/> + JFW_E_ERROR An error occurred.<br/> + JFW_E_CONFIGURATION mode was not properly set or their prerequisites + were not met.<br/> + JFW_E_DIRECT_MODE the function cannot be used in this mode. + @see jfw_setJRELocations + */ +javaFrameworkError SAL_CALL jfw_addJRELocation(rtl_uString * sLocation); + +/** saves the locations of a number of JREs. + + <p> + The function does not verify if the paths points to JRE. However, + it makes sure that every path is unique. That is, if the array + contains strings which are the same then only one is stored.</p> + <p> + If <code>arLocations</code> is NULL or it has the length null (nSize = 0) + then all previously stored paths are deleted. Otherwise, + the old values are overwritten.</p> + + @param arLocations + [in] array of paths to locations of JREs. + + @param nSize + [in] the size of the array <code>arLocations</code> + + @return + JFW_E_NONE function ran successfully.<br/> + JFW_E_INVALIDARG arLocation is NULL and nSize is not null.<br/> + JFW_E_ERROR An error occurred.<br/> + JFW_E_CONFIGURATION mode was not properly set or their prerequisites + were not met.<br/> + JFW_E_DIRECT_MODE the function cannot be used in this mode. + @see jfw_addJRELocations + */ +javaFrameworkError SAL_CALL jfw_setJRELocations( + rtl_uString ** arLocations, sal_Int32 nSize); +/** obtains an array containing paths to JRE installations. + + <p> + It is not guaranteed that the returned paths represent + a valid JRE. One can use <code>jfw_getJavaInfoByPath</code> to check this. + </p> + + @param parLocations + [out] on return it contains the array of paths. + @param pSize + [out] on return it contains the size of the array <code>parLocations</code>. + + @return + JFW_E_NONE function ran successfully.<br/> + JFW_E_INVALIDARG parLocation is NULL or pSize is NULL.<br/> + JFW_E_ERROR An error occurred.<br/> + JFW_E_CONFIGURATION mode was not properly set or their prerequisites + were not met.<br/> + JFW_E_DIRECT_MODE the function cannot be used in this mode. + */ +javaFrameworkError SAL_CALL jfw_getJRELocations( + rtl_uString *** parLocations, sal_Int32 * pSize); + + +/** checks if the installation of the jre still exists. + + This function checks if the JRE described by pInfo still + exists. The check must be very quick because it is called by javaldx + (Linux, Solaris) at start up. + + @param pInfo + [in] the JavaInfo object with information about the JRE. + @param pp_exist + [out] the parameter is set to either sal_True or sal_False. The value is + only valid if the function returns JFW_E_NONE. + + @return + JFW_E_NONE the function ran successfully.</br> + JFW_E_ERROR an error occurred during execution.</br> + JFW_E_INVALID_ARG pInfo contains invalid data</br> + JFW_E_NO_PLUGIN a plug-in library could not be found.<br/> + */ +javaFrameworkError SAL_CALL jfw_existJRE(const JavaInfo *pInfo, sal_Bool *exist); + + +/** locks this API so that it cannot be used by other threads. + + <p>If a different thread called this function before then the + current call is blocked until the other thread has called + <code>jfw_unlock()</code>. The function should be called if one + needs an exact snapshot of the current settings. Then the settings + are retrieved one by one without risk that the settings may be changed + by a different thread. Similiary if one needs to make settings which + should become effective at the same time then <code>jfw_lock</code> + should be called. That is, <code>jfw_startVM</code> which uses the + settings cannot be called before all settings have be made.</p> + <p> + The only functions which are not effected by <code>jfw_lock</code> are + <code>jfw_freeJavaInfo</code> and <code>jfw_areEqualJavaInfo</code>. + */ +void SAL_CALL jfw_lock(); + +/** unlocks this API. + + <p>This function is called after <code>jfw_lock</code>. It allows other + threads to use this API concurrently.</p> +*/ +void SAL_CALL jfw_unlock(); + + +#ifdef __cplusplus +} +#endif + + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/jvmfwk/inc/jvmfwk/vendorplugin.h b/jvmfwk/inc/jvmfwk/vendorplugin.h new file mode 100644 index 000000000000..3ccbb0e487f4 --- /dev/null +++ b/jvmfwk/inc/jvmfwk/vendorplugin.h @@ -0,0 +1,268 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +/** @HTML */ +#if !defined INCLUDED_JVMFWK_VENDORPLUGIN_H +#define INCLUDED_JVMFWK_VENDORPLUGIN_H + +#include "jvmfwk/framework.h" +#include "rtl/ustring.h" +#ifdef SOLAR_JAVA +#include "jni.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + @file + <p> + This API shall be implemented if one wants to support a Java Runtime + Environment (JRE) of a particular vendor. Because there is currently no + specification which rules the structure and location of JRE installations + and the format of version strings it is not possible to supply a general + implementation for all possible vendors. If an application determines exactly + what version a JRE must have then it relies on certain features and bug + fixes of that version. Because a version 1.4.2_1 from vendor X may contain + different fixes as the same version from vendor Y it is important to see + version an vendor as one entity. One without the other does not guarantee + the existence of a particular set of features or bug fixes. An implementation + of this API may support multiple vendors. </p> + <p> + Libraries which implement this interface will be dynamically loaded and + unloaded by the java framework (jvmfwk/framework.h). Therefore they must not + keep global variables. + </p> + */ + +typedef enum +{ + JFW_PLUGIN_E_NONE, + JFW_PLUGIN_E_ERROR, + JFW_PLUGIN_E_INVALID_ARG, + JFW_PLUGIN_E_WRONG_VERSION_FORMAT, + JFW_PLUGIN_E_FAILED_VERSION, + JFW_PLUGIN_E_NO_JRE, + JFW_PLUGIN_E_WRONG_VENDOR, + JFW_PLUGIN_E_VM_CREATION_FAILED +} javaPluginError; + + + +/** obtains information about installations of Java Runtime Environments (JREs). + + <p>The function gathers information about available JREs which have the same + vendor as determined by the <code>sVendor</code> parameter. Only information + about those JREs which match the version requirements are returned. These + requirements are specified by the parameters <code>sMinVersion</code>, + <code>sMaxVersion</code> and <code>arExcludeList</code>. + </p> + <p> + The JavaInfo structures returned in <code>parJavaInfo</code> should be ordered + according to their version. The one, representing a JRE with the highest + version should be the first in the array. </p> + <p> + The function allocates memory for an array and all the JavaInfo objects returned + in <code>parJavaInfo</code>. The caller must free each JavaInfo object by calling + <code>jfw_freeJavaInfo</code> (#include "jvmfwk/framework.h"). The array is to be + freed by rtl_freeMemory. + In case an error occurred <code>parJavaInfo</code> need not be freed. + </p> + @param sVendor + [in] only JREs from this vendor are examined. This parameter always contains + a vendor string. That is, the string it is not empty. + @param sMinVersion + [in] represents the minimum version of a JRE. The string can be empty but + a null pointer is not allowed. + @param sMaxVersion + [in] represents the maximum version of a JRE. The string can be empty but + a null pointer is not allowed. + @param arExcludeList + [in] contains a list of "bad" versions. JREs which have one of these + versions must not be returned by this function. It can be NULL. + @param nSizeExcludeList + [in] the number of version strings contained in <code>arExcludeList</code>. + @param parJavaInfo + [out] if the function runs successfully then <code>parJavaInfo</code> contains + on return an array of pointers to <code>JavaInfo</code> objects. + @param nSizeJavaInfo + [out] the number of <code>JavaInfo</code> pointers contained in + <code>parJavaInfo</code>. + + @return + JFW_PLUGIN_E_NONE the function ran successfully.</br> + JFW_PLUGIN_E_ERROR an error occurred during execution.</br> + JFW_PLUGIN_E_INVALID_ARG an argument was not valid. For example + <code>nSizeExcludeList</code> is greater null but <code>arExcludeList</code> + is NULL or NULL pointer were passed for at least on of the strings.</br> + JFW_PLUGIN_E_WRONG_VERSION_FORMAT the version strings in + <code>sMinVersion,sMaxVersion,arExcludeList</code> are not recognized as valid + version strings. + */ +javaPluginError jfw_plugin_getAllJavaInfos( + rtl_uString *sVendor, + rtl_uString *sMinVersion, + rtl_uString *sMaxVersion, + rtl_uString * * arExcludeList, + sal_Int32 nSizeExcludeList, + JavaInfo*** parJavaInfo, + sal_Int32 *nSizeJavaInfo); + +/** obtains information for a JRE at a given location. + + <p>If the given location belongs to a JRE whoose vendor matches the + sVendor argument and the JRE has a version which meets the requirements as + specified by <code>sMinVersion, sMaxVersion, arExcludeList</code> then + this function shall return a JavaInfo object for this JRE if this implementation + supports this vendor.</p> + + @param sLocation + [in] a file URL to the directory of the JRE. + @param sVendor + [in] a name of a vendor. This parameter always contains + a vendor string. That is, the string it is not empty. + @param sMinVersion + [in] represents the minimum version of a JRE. + @param sMaxVersion + [in] represents the maximum version of a JRE. + @param arExcludeList + [in] contains a list of "bad" versions. JREs which have one of these + versions must not be returned by this function. It can be NULL. + @param nSizeExcludeList + [in] the number of version strings contained in <code>arExcludeList</code>. + @param ppInfo + [out] if the function runs successfully then <code>ppInfo</code> contains + on return a pointer to a <code>JavaInfo</code> object. + + @return + JFW_PLUGIN_E_NONE the function ran successfully.</br> + JFW_PLUGIN_E_ERROR an error occurred during execution.</br> + JFW_PLUGIN_E_INVALID_ARG an argument was not valid. For example + <code>nSizeExcludeList</code> is greater null but <code>arExcludeList</code> + is NULL, NULL pointer were passed for at least on of the strings, sLocation + is an empty string.</br> + JFW_PLUGIN_E_WRONG_VERSION_FORMAT the version strings in + <code>sMinVersion,sMaxVersion,arExcludeList</code> are not recognized as valid + version strings. + JFW_PLUGIN_E_FAILED_VERSION there is a JRE at the given location but it does not + meet the version requirements. + JFW_PLUGIN_E_NO_JRE no JRE could be detected at the given location. However, that + does not mean necessarily that there is no JRE. There could be a JRE but it has + a vendor which is not supported by this API implementation. + */ +javaPluginError jfw_plugin_getJavaInfoByPath( + rtl_uString *sLocation, + rtl_uString *sVendor, + rtl_uString *sMinVersion, + rtl_uString *sMaxVersion, + rtl_uString * *arExcludeList, + sal_Int32 nSizeExcludeList, + JavaInfo ** ppInfo); + +/** starts a Java Virtual Machine. + + <p>The caller should provide all essential JavaVMOptions, such as the + class path (-Djava.class.path=xxx). It is assumed that the caller + knows what JRE is used. Hence the implementation does not need to check + the options for validity. If a user configured the application to + use specific options, such as -X..., then it is in his responsibility to + ensure that the application works properly. The function may add or modify + properties. For example, it may add to the class path property. + <p> + The function must ensure, that the VM does not abort the process + during instantiation.</p> + <p> + The function receives a <code>JavaInfo</code> object that was created + by the functions <code>jfw_plugin_getJavaInfoByPath</code> or + <code>jfw_plugin_getAllJavaInfos</code> from the same library. This can be + guaranteed if an application uses exactly one library for one vendor. + Therefore the functions which create the <code>JavaInfo</code> can store all + necessary information which are needed for starting the VM into that + structure. </p> + + @param pInfo + [in] the JavaInfo object with information about the JRE. + @param arOptions + [in] the options which are passed into the JNI_CreateJavaVM function. + Can be NULL. + @param nSizeOptions + [in] the number of elements in <code>arOptions</code>. + @param ppVM + [out] the JavaVM pointer of the created VM. + @param ppEnv + [out] the JNIEnv pointer of the created VM. + + @return + JFW_PLUGIN_E_NONE the function ran successfully.</br> + JFW_PLUGIN_E_ERROR an error occurred during execution.</br> + JFW_PLUGIN_E_WRONG_VENDOR the <code>JavaInfo</code> object was not created + in by this library and the VM cannot be started.</br> + JFW_PLUGIN_E_INVALID_ARG an argument was not valid. For example + <code>pInfo</code> or , <code>ppVM</code> or <code>ppEnv</code> are NULL. + </br> + JFW_PLUGIN_E_VM_CREATION_FAILED a VM could not be created. The error was caused + by the JRE. + */ +javaPluginError jfw_plugin_startJavaVirtualMachine( + const JavaInfo *pInfo, + const JavaVMOption *arOptions, + sal_Int32 nSizeOptions, + JavaVM ** ppVM, + JNIEnv ** ppEnv); + + + +/** checks if the installation of the jre still exists. + + This function checks if the JRE described by pInfo still + exists. The check must be very quick because it is called by javaldx + (Linux, Solaris) at start up. + + @param pInfo + [in] the JavaInfo object with information about the JRE. + @param pp_exist + [out] the parameter is set to either sal_True or sal_False. The value is + only valid if the function returns JFW_E_NONE. + + @return + JFW_PLUGIN_E_NONE the function ran successfully.</br> + JFW_PLUGIN_E_ERROR an error occurred during execution.</br> + JFW_PLUGIN_E_INVALID_ARG pInfo contains invalid data</br> + */ +javaPluginError jfw_plugin_existJRE(const JavaInfo *pInfo, sal_Bool *exist); + +#ifdef __cplusplus +} +#endif + + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/jvmfwk/inc/makefile.mk b/jvmfwk/inc/makefile.mk new file mode 100644 index 000000000000..8acb7b245357 --- /dev/null +++ b/jvmfwk/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=jvmfwk +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/jvmfwk/inc/pch/precompiled_jvmfwk.cxx b/jvmfwk/inc/pch/precompiled_jvmfwk.cxx new file mode 100644 index 000000000000..80c3bb3ee344 --- /dev/null +++ b/jvmfwk/inc/pch/precompiled_jvmfwk.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_jvmfwk.hxx" + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/jvmfwk/inc/pch/precompiled_jvmfwk.hxx b/jvmfwk/inc/pch/precompiled_jvmfwk.hxx new file mode 100644 index 000000000000..8b4018782e42 --- /dev/null +++ b/jvmfwk/inc/pch/precompiled_jvmfwk.hxx @@ -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): Generated on 2006-09-01 17:49:50.576954 + +#ifdef PRECOMPILED_HEADERS +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/jvmfwk/plugins/sunmajor/javaenvsetup/javaldx.cxx b/jvmfwk/plugins/sunmajor/javaenvsetup/javaldx.cxx new file mode 100644 index 000000000000..8567d79f9b0e --- /dev/null +++ b/jvmfwk/plugins/sunmajor/javaenvsetup/javaldx.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. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_jvmfwk.hxx" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "sal/main.h" +#include "sal/types.h" +#include "osl/thread.h" +#include "rtl/ustring.hxx" +#include "rtl/byteseq.hxx" +#include "jvmfwk/framework.h" + +using ::rtl::OUString; +using ::rtl::OUStringToOString; +using ::rtl::OString; +#define OUSTR(x) OUString(RTL_CONSTASCII_USTRINGPARAM( x )) + +static sal_Bool hasOption(char const * szOption, int argc, char** argv); +static rtl::OString getLD_LIBRARY_PATH(const rtl::ByteSequence & vendorData); +static bool findAndSelect(JavaInfo**); + +#define HELP_TEXT \ +"\njavaldx is necessary to make Java work on some UNIX platforms." \ +"It prints a string to std out that consists of directories which " \ +"have to be included into the LD_LIBRARY_PATH variable.The setting of " \ +"the variable usually occurs in a shell script that runs javaldx.\n" \ +"The directories are from the chosen java installation. \n" \ +"Options are: \n"\ +"--help or -h\n" + +SAL_IMPLEMENT_MAIN_WITH_ARGS(argc, argv) +{ + if( hasOption("--help",argc, argv) || hasOption("-h", argc, argv)) + { + fprintf(stdout, HELP_TEXT);// default + return 0; + } + javaFrameworkError errcode = JFW_E_NONE; + sal_Bool bEnabled = sal_False; + errcode = jfw_getEnabled( & bEnabled); + if (errcode == JFW_E_NONE && bEnabled == sal_False) + { + //Do not do any preparation because that may only slow startup time. + return 0; + } + else if (errcode != JFW_E_NONE && errcode != JFW_E_DIRECT_MODE) + { + fprintf(stderr,"javaldx failed! \n"); + return -1; + } + + + JavaInfo * pInfo = NULL; + errcode = jfw_getSelectedJRE( & pInfo); + + if (errcode != JFW_E_NONE && errcode != JFW_E_INVALID_SETTINGS) + { + fprintf(stderr,"javaldx failed! \n"); + return -1; + } + + if (pInfo == NULL) + { + if (false == findAndSelect(&pInfo)) + return -1; + } + else + { + //check if the JRE was not uninstalled + sal_Bool bExist = sal_False; + errcode = jfw_existJRE(pInfo, &bExist); + if (errcode == JFW_E_NONE) + { + if (!bExist && !findAndSelect(&pInfo)) + return -1; + } + else + { + fprintf(stderr, "javaldx: Could not determine if JRE still exist\n"); + return -1; + } + } + + //Only do something if the sunjavaplugin created this JavaInfo + rtl::OUString sVendor1(RTL_CONSTASCII_USTRINGPARAM("Sun Microsystems Inc.")); + rtl::OUString sVendor2(RTL_CONSTASCII_USTRINGPARAM("IBM Corporation")); + rtl::OUString sVendor3(RTL_CONSTASCII_USTRINGPARAM("Blackdown Java-Linux Team")); + rtl::OUString sVendor4(RTL_CONSTASCII_USTRINGPARAM("Apple Inc.")); + rtl::OUString sVendor5(RTL_CONSTASCII_USTRINGPARAM("Apple Computer, Inc.")); + rtl::OUString sVendor6(RTL_CONSTASCII_USTRINGPARAM("BEA Systems, Inc.")); + rtl::OUString sVendor7(RTL_CONSTASCII_USTRINGPARAM("Free Software Foundation, Inc.")); + rtl::OUString sVendor8(RTL_CONSTASCII_USTRINGPARAM("The FreeBSD Foundation")); + if ( ! (sVendor1.equals(pInfo->sVendor) == sal_True + || sVendor2.equals(pInfo->sVendor) == sal_True + || sVendor3.equals(pInfo->sVendor) == sal_True + || sVendor4.equals(pInfo->sVendor) == sal_True + || sVendor5.equals(pInfo->sVendor) == sal_True + || sVendor6.equals(pInfo->sVendor) == sal_True + || sVendor7.equals(pInfo->sVendor) == sal_True + || sVendor8.equals(pInfo->sVendor) == sal_True)) + return 0; + + rtl::OString sPaths = getLD_LIBRARY_PATH(pInfo->arVendorData); + fprintf(stdout, "%s\n", sPaths.getStr()); + jfw_freeJavaInfo(pInfo); + + return 0; +} + +rtl::OString getLD_LIBRARY_PATH(const rtl::ByteSequence & vendorData) +{ + const sal_Unicode* chars = (sal_Unicode*) vendorData.getConstArray(); + sal_Int32 len = vendorData.getLength(); + rtl::OUString sData(chars, len / 2); + //the runtime lib is on the first line + sal_Int32 index = 0; + rtl::OUString aToken = sData.getToken( 1, '\n', index); + + rtl::OString paths = + rtl::OUStringToOString(aToken, osl_getThreadTextEncoding()); + return paths; +} + +static sal_Bool hasOption(char const * szOption, int argc, char** argv) +{ + sal_Bool retVal= sal_False; + for(sal_Int16 i= 1; i < argc; i++) + { + if( ! strcmp(argv[i], szOption)) + { + retVal= sal_True; + break; + } + } + return retVal; +} + +static bool findAndSelect(JavaInfo ** ppInfo) +{ + javaFrameworkError errcode = jfw_findAndSelectJRE(ppInfo); + if (errcode == JFW_E_NO_JAVA_FOUND) + { + fprintf(stderr,"javaldx: Could not find a Java Runtime Environment! \n"); + return false; + } + else if (errcode != JFW_E_NONE && errcode != JFW_E_DIRECT_MODE) + { + fprintf(stderr,"javaldx failed!\n"); + return false; + } + return true; +} + + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/jvmfwk/plugins/sunmajor/javaenvsetup/makefile.mk b/jvmfwk/plugins/sunmajor/javaenvsetup/makefile.mk new file mode 100755 index 000000000000..8e4a79581327 --- /dev/null +++ b/jvmfwk/plugins/sunmajor/javaenvsetup/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=javaldx +TARGET=javaldx +TARGETTYPE=CUI +NO_DEFAULT_STL=TRUE +LIBTARGET=NO +ENABLE_EXCEPTIONS=true + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk + +# --- Files -------------------------------------------------------- + +.IF "$(OS)" != "MACOSX" && "$(SOLAR_JAVA)" != "" + +OBJFILES=$(OBJ)$/javaldx.obj + +APP1TARGET=javaldx +APP1OBJS=$(OBJFILES) +APP1STDLIBS=$(SALLIB) $(JVMFWKLIB) +APP1RPATH=UREBIN + +.ENDIF + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk diff --git a/jvmfwk/plugins/sunmajor/pluginlib/JREProperties.java b/jvmfwk/plugins/sunmajor/pluginlib/JREProperties.java new file mode 100644 index 000000000000..b0930e1c93f3 --- /dev/null +++ b/jvmfwk/plugins/sunmajor/pluginlib/JREProperties.java @@ -0,0 +1,85 @@ +import java.util.*; +import java.awt.*; + +/** This class prints out the system properties. + + We cannot print the strings directly because of encoding issues. Since + about 1.3.1 one can start java with the option -Dfile.encoding=UTF-8, but + unfortunately this works only with later update - versions (for example, + 1.3.1_07). Therefore we use this scheme. The property string has this form: + name=value + + Every character is cast to an integer which value is printed, followed by a + space. If all characters of the string are printed, then a new line is printed. +*/ +public class JREProperties +{ + static public void main(String[] args) + { + try + { + boolean bNoAccess = false; + if(args.length > 0) + { + if (args[0].equals("noaccessibility")) + bNoAccess = true; + } + + //Find out on what operation system we are running. On Windows 98 + //we must not call getDefaultToolkit, because the office may freeze + //#i44608. + boolean bW98 = false; + String os = System.getProperty("os.name"); + + if (os != null) + { + os = os.trim(); + if (os.equalsIgnoreCase("Windows 98") || + os.indexOf("Windows 98") != -1) + bW98 = true; + } + + //We need to be able to switch this part off because + //it causes an exception if the DISPLAY variable has + //a false value. Setting the noaccessibility argument + //can be done by providing a sunjavaplugin.ini with + //the bootstrap parameter JFW_PLUGIN_NO_NOT_CHECK_ACCESSIBILITY + //set to "1" + if (bNoAccess == false && ! bW98) + { + try{ + //This line is needed to get the accessibility properties + Toolkit tk = java.awt.Toolkit.getDefaultToolkit(); + } + catch(Throwable e) + { + System.err.println(e); + } + } + + + Properties p = System.getProperties(); + Enumeration e = p.propertyNames(); + for (; e.hasMoreElements() ;) { + String sProp = (String) e.nextElement(); + String sCompleteProp = sProp + "=" + p.getProperty(sProp); + char[] arChars = new char[sCompleteProp.length()]; + sCompleteProp.getChars(0, sCompleteProp.length(), arChars, 0); + for (int c = 0; c < arChars.length; c++) { + System.out.print(String.valueOf((int) arChars[c])); + System.out.print(" "); + } + System.out.print("\n"); + } + } + catch(Exception e) + { + System.err.println(e); + } + + System.exit(0); + } + + + +} diff --git a/jvmfwk/plugins/sunmajor/pluginlib/diagnostics.h b/jvmfwk/plugins/sunmajor/pluginlib/diagnostics.h new file mode 100644 index 000000000000..6a8ef3232bc4 --- /dev/null +++ b/jvmfwk/plugins/sunmajor/pluginlib/diagnostics.h @@ -0,0 +1,123 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_JFW_PLUGIN_DIAGNOSTICS_HXX +#define INCLUDED_JFW_PLUGIN_DIAGNOSTICS_HXX +#include "osl/diagnose.h" +#include "rtl/ustring.hxx" +#include <stdio.h> + +#if OSL_DEBUG_LEVEL >= 1 +#define JFW_ENSURE(c, m) _JFW_ENSURE(c, OSL_THIS_FILE, __LINE__, m) +#else +#define JFW_ENSURE(c, m) ((void) 0) +#endif + +#if OSL_DEBUG_LEVEL >= 2 +#define JFW_WARNING2(c, m) _JFW_WARNING2(c, OSL_THIS_FILE, __LINE__, m) +#else +#define JFW_WARNING2(c, m) ((void) 0) +#endif + + +#if OSL_DEBUG_LEVEL >= 0 +#define JFW_TRACE0(m) jfw_trace(m) +#else +#define JFW_TRACE0(m) ((void) 0) +#endif + +#if OSL_DEBUG_LEVEL >= 1 +#define JFW_TRACE1(m) jfw_trace(m) +#else +#define JFW_TRACE1(m) ((void) 0) +#endif + +#if OSL_DEBUG_LEVEL >= 2 +#define JFW_TRACE2(m) jfw_trace(m) +#else +#define JFW_TRACE2(m) ((void) 0) +#endif + + + +#define _JFW_ENSURE(c, f, l, m) jfw_ensure(c, f, l, m) +#define _JFW_WARNING(c, f, l, m) jfw_warning2(c, f, l, m); + + +namespace jfw_plugin +{ + +inline void jfw_ensure(bool + #if OSL_DEBUG_LEVEL > 0 /* prevent warning in pro version */ + condition + #endif + , const sal_Char * + #if OSL_DEBUG_LEVEL > 0 /* prevent warning in pro version */ + pzFile + #endif + , sal_Int32 + #if OSL_DEBUG_LEVEL > 0 /* prevent warning in pro version */ + line + #endif + , const rtl::OUString& message ) +{ + rtl::OString oMsg = rtl::OUStringToOString(message, osl_getThreadTextEncoding()); + _OSL_ENSURE(condition, pzFile, line, oMsg.getStr()); +} + +inline void jfw_warning2(bool condition, const sal_Char * pzFile, sal_Int32 line, + sal_Char * pzMessage) +{ + if (! condition) + fprintf( + stderr, "%s\n File: %s\n Line: %ld", pzMessage, pzFile, + sal::static_int_cast< unsigned long >(line)); +} + +inline void jfw_trace(rtl::OUString message) +{ + rtl::OString oMsg = rtl::OUStringToOString(message, osl_getThreadTextEncoding()); + fprintf(stderr,"%s", oMsg.getStr()); +} + +inline void jfw_trace(const sal_Char * pzMessage) +{ + if (pzMessage) + fprintf(stderr,"%s", pzMessage); +} + +inline void jfw_trace(const rtl::OString& message) +{ + if (message.getLength() > 0) + fprintf(stderr,"%s", message.getStr()); +} + +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/jvmfwk/plugins/sunmajor/pluginlib/gnujre.cxx b/jvmfwk/plugins/sunmajor/pluginlib/gnujre.cxx new file mode 100644 index 000000000000..32f2792fbb93 --- /dev/null +++ b/jvmfwk/plugins/sunmajor/pluginlib/gnujre.cxx @@ -0,0 +1,311 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_jvmfwk.hxx" + +#include "osl/file.hxx" +#include "osl/thread.h" +#include "gnujre.hxx" +#include "util.hxx" + +using namespace std; +using namespace osl; +using ::rtl::OUString; +using ::rtl::Reference; + +namespace jfw_plugin +{ + +Reference<VendorBase> GnuInfo::createInstance() +{ + return new GnuInfo; +} + +char const* const* GnuInfo::getJavaExePaths(int * size) +{ + static char const * ar[] = { + "gij", + "bin/gij", + "gij-4.3", + "bin/gij-4.3", + "gij-4.2", + "bin/gij-4.2", + "gij-4.1", + "bin/gij-4.1" + }; + *size = sizeof (ar) / sizeof (char*); + return ar; +} + +#if defined(MIPS) && defined(OSL_LITENDIAN) +#define GCJ_JFW_PLUGIN_ARCH "mipsel" +#else +#define GCJ_JFW_PLUGIN_ARCH JFW_PLUGIN_ARCH +#endif + +char const* const* GnuInfo::getRuntimePaths(int * size) +{ + static char const* ar[]= { + "/libjvm.so", + "/lib/" GCJ_JFW_PLUGIN_ARCH "/client/libjvm.so", + "/gcj-4.1.1/libjvm.so", + "/gcj-4.3-90/libjvm.so", + "/gcj-4.2-81/libjvm.so", + "/gcj-4.2/libjvm.so", + "/gcj-4.2.1/libjvm.so", + "/gcj-4.2.2/libjvm.so", + "/gcj-4.2.3/libjvm.so", + "/gcj-4.1-71/libjvm.so", + "/gcj-4_1/libjvm.so", + "/gcj-4.1/libjvm.so", + "/libgcj.so.81", + "/libgcj.so.80", + "/libgcj.so.8", + "/libgcj.so.71", + "/libgcj.so.70", + "/libgcj.so.7", + "/libgcj.so.6" + }; + *size = sizeof(ar) / sizeof (char*); + return ar; +} + +bool GnuInfo::initialize(vector<pair<OUString, OUString> > props) +{ + //get java.vendor, java.version, java.home, + //javax.accessibility.assistive_technologies from system properties + + OUString sVendor; + OUString sJavaLibraryPath; + typedef vector<pair<OUString, OUString> >::const_iterator it_prop; + OUString sVendorProperty( + RTL_CONSTASCII_USTRINGPARAM("java.vendor")); + OUString sVersionProperty( + RTL_CONSTASCII_USTRINGPARAM("java.version")); + OUString sJavaHomeProperty( + RTL_CONSTASCII_USTRINGPARAM("java.home")); + OUString sJavaLibraryPathProperty( + RTL_CONSTASCII_USTRINGPARAM("java.library.path")); + OUString sGNUHomeProperty( + RTL_CONSTASCII_USTRINGPARAM("gnu.classpath.home.url")); + OUString sAccessProperty( + RTL_CONSTASCII_USTRINGPARAM("javax.accessibility.assistive_technologies")); + + bool bVersion = false; + bool bVendor = false; + bool bHome = false; + bool bJavaHome = false; + bool bJavaLibraryPath = false; + bool bAccess = false; + + typedef vector<pair<OUString, OUString> >::const_iterator it_prop; + for (it_prop i = props.begin(); i != props.end(); ++i) + { + if(! bVendor && sVendorProperty.equals(i->first)) + { + m_sVendor = i->second; + bVendor = true; + } + else if (!bVersion && sVersionProperty.equals(i->first)) + { + m_sVersion = i->second; + bVersion = true; + } + else if (!bHome && sGNUHomeProperty.equals(i->first)) + { + m_sHome = i->second; + bHome = true; + } + else if (!bJavaHome && sJavaHomeProperty.equals(i->first)) + { + OUString fileURL; + if (osl_getFileURLFromSystemPath(i->second.pData,& fileURL.pData) == + osl_File_E_None) + { + //make sure that the drive letter have all the same case + //otherwise file:///c:/jre and file:///C:/jre produce two + //different objects!!! + if (makeDriveLetterSame( & fileURL)) + { + m_sJavaHome = fileURL; + bJavaHome = true; + } + } + } + else if (!bJavaLibraryPath && sJavaLibraryPathProperty.equals(i->first)) + { + sal_Int32 nIndex = 0; + osl_getFileURLFromSystemPath(i->second.getToken(0, ':', nIndex).pData, &sJavaLibraryPath.pData); + bJavaLibraryPath = true; + } + else if (!bAccess && sAccessProperty.equals(i->first)) + { + if (i->second.getLength() > 0) + { + m_bAccessibility = true; + bAccess = true; + } + } + // the javax.accessibility.xxx property may not be set. Therefore we + //must search through all properties. + + } + if (!bVersion || !bVendor || !bHome) + return false; + + if (!m_sJavaHome.getLength()) + m_sJavaHome = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("file:///usr/lib")); + + // init m_sRuntimeLibrary + OSL_ASSERT(m_sHome.getLength()); + //call virtual function to get the possible paths to the runtime library. + + int size = 0; + char const* const* arRtPaths = getRuntimePaths( & size); + vector<OUString> libpaths = getVectorFromCharArray(arRtPaths, size); + + bool bRt = false; + typedef vector<OUString>::const_iterator i_path; + for(i_path ip = libpaths.begin(); ip != libpaths.end(); ++ip) + { + //Construct an absolute path to the possible runtime + OUString usRt= m_sHome + *ip; + DirectoryItem item; + if(DirectoryItem::get(usRt, item) == File::E_None) + { + //found runtime lib + m_sRuntimeLibrary = usRt; + bRt = true; + break; + } + } + + if (!bRt) + { + m_sHome = m_sJavaHome; + for(i_path ip = libpaths.begin(); ip != libpaths.end(); ++ip) + { + //Construct an absolute path to the possible runtime + OUString usRt= m_sHome + *ip; + DirectoryItem item; + if(DirectoryItem::get(usRt, item) == File::E_None) + { + //found runtime lib + m_sRuntimeLibrary = usRt; + bRt = true; + break; + } + } + } + + // try to find it by the java.library.path property + if (!bRt && m_sJavaHome != sJavaLibraryPath) + { + m_sHome = sJavaLibraryPath; + for(i_path ip = libpaths.begin(); ip != libpaths.end(); ++ip) + { + //Construct an absolute path to the possible runtime + OUString usRt= m_sHome + *ip; + DirectoryItem item; + if(DirectoryItem::get(usRt, item) == File::E_None) + { + //found runtime lib + m_sRuntimeLibrary = usRt; + bRt = true; + break; + } + } + } + +#ifdef X86_64 + //Make one last final legacy attempt on x86_64 in case the distro placed it in lib64 instead + if (!bRt && m_sJavaHome != rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("file:///usr/lib"))) + { + m_sHome = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("file:///usr/lib64")); + for(i_path ip = libpaths.begin(); ip != libpaths.end(); ++ip) + { + //Construct an absolute path to the possible runtime + OUString usRt= m_sHome + *ip; + DirectoryItem item; + if(DirectoryItem::get(usRt, item) == File::E_None) + { + //found runtime lib + m_sRuntimeLibrary = usRt; + bRt = true; + break; + } + } + } +#endif + + if (!bRt) + return false; + + // init m_sLD_LIBRARY_PATH + OSL_ASSERT(m_sHome.getLength()); + size = 0; + char const * const * arLDPaths = getLibraryPaths( & size); + vector<OUString> ld_paths = getVectorFromCharArray(arLDPaths, size); + + char arSep[]= {SAL_PATHSEPARATOR, 0}; + OUString sPathSep= OUString::createFromAscii(arSep); + bool bLdPath = true; + int c = 0; + for(i_path il = ld_paths.begin(); il != ld_paths.end(); ++il, ++c) + { + OUString usAbsUrl= m_sHome + *il; + // convert to system path + OUString usSysPath; + if(File::getSystemPathFromFileURL(usAbsUrl, usSysPath) == File::E_None) + { + + if(c > 0) + m_sLD_LIBRARY_PATH+= sPathSep; + m_sLD_LIBRARY_PATH+= usSysPath; + } + else + { + bLdPath = false; + break; + } + } + if (bLdPath == false) + return false; + + return true; +} + +int GnuInfo::compareVersions(const rtl::OUString&) const +{ + return 0; +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/jvmfwk/plugins/sunmajor/pluginlib/gnujre.hxx b/jvmfwk/plugins/sunmajor/pluginlib/gnujre.hxx new file mode 100644 index 000000000000..413ff4bd1c38 --- /dev/null +++ b/jvmfwk/plugins/sunmajor/pluginlib/gnujre.hxx @@ -0,0 +1,58 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_JFW_PLUGIN_GNUJRE_HXX +#define INCLUDED_JFW_PLUGIN_GNUJRE_HXX + +#include "vendorbase.hxx" +#include "vendorlist.hxx" + +namespace jfw_plugin +{ + +class GnuInfo: public VendorBase +{ +private: + rtl::OUString m_sJavaHome; +public: + static char const* const* getJavaExePaths(int * size); + + static rtl::Reference<VendorBase> createInstance(); + + virtual char const* const* getRuntimePaths(int * size); + + virtual bool initialize( + std::vector<std::pair<rtl::OUString, rtl::OUString> > props); + virtual int compareVersions(const rtl::OUString& sSecond) const; + +}; + +} +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/jvmfwk/plugins/sunmajor/pluginlib/makefile.mk b/jvmfwk/plugins/sunmajor/pluginlib/makefile.mk new file mode 100644 index 000000000000..5b09a67952c5 --- /dev/null +++ b/jvmfwk/plugins/sunmajor/pluginlib/makefile.mk @@ -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. +# +#************************************************************************* +PRJ=..$/..$/.. + +PRJNAME= jvmfwk +TARGET = plugin +ENABLE_EXCEPTIONS=TRUE +LIBTARGET=NO +UNOCOMPONENT1=sunjavaplugin + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +DLLPRE = + +# ------------------------------------------------------------------ + +.IF "$(SOLAR_JAVA)"!="" + +SLOFILES= \ + $(SLO)$/sunversion.obj \ + $(SLO)$/sunjavaplugin.obj \ + $(SLO)$/vendorbase.obj \ + $(SLO)$/util.obj \ + $(SLO)$/sunjre.obj \ + $(SLO)$/gnujre.obj \ + $(SLO)$/vendorlist.obj \ + $(SLO)$/otherjre.obj + +LIB1OBJFILES= $(SLOFILES) + +LIB1TARGET=$(SLB)$/$(UNOCOMPONENT1).lib + +SHL1TARGET= $(UNOCOMPONENT1) + + +SHL1STDLIBS= \ + $(CPPUHELPER) \ + $(CPPULIB) \ + $(SALHELPERLIB) \ + $(SALLIB) + + +.IF "$(GUI)" == "WNT" +.IF "$(COM)"!="GCC" +SHL1STDLIBS += uwinapi.lib advapi32.lib +.ELSE +SHL1STDLIBS += -luwinapi -ladvapi32 +.ENDIF # GCC +.ENDIF #WNT + +.IF "$(JVM_ONE_PATH_CHECK)" != "" +CFLAGS += -DJVM_ONE_PATH_CHECK=\"$(JVM_ONE_PATH_CHECK)\" +.ENDIF + +SHL1VERSIONMAP = sunjavaplugin.map +SHL1DEPN= +SHL1IMPLIB= i$(UNOCOMPONENT1) +SHL1LIBS= $(LIB1TARGET) +SHL1DEF= $(MISC)$/$(SHL1TARGET).def +DEF1NAME= $(SHL1TARGET) +SHL1RPATH= URELIB + +JAVACLASSFILES= \ + $(CLASSDIR)$/JREProperties.class + +JAVAFILES = $(subst,$(CLASSDIR)$/, $(subst,.class,.java $(JAVACLASSFILES))) + +.ENDIF # SOLAR_JAVA + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk + +.IF "$(GUI)"=="WNT" +BOOTSTRAPFILE=$(BIN)$/sunjavaplugin.ini +.ELSE +BOOTSTRAPFILE=$(BIN)$/sunjavapluginrc +.ENDIF + + +$(BOOTSTRAPFILE): sunjavapluginrc + -$(COPY) $< $@ + + +ALLTAR: \ + $(BOOTSTRAPFILE) + diff --git a/jvmfwk/plugins/sunmajor/pluginlib/otherjre.cxx b/jvmfwk/plugins/sunmajor/pluginlib/otherjre.cxx new file mode 100644 index 000000000000..63cec34316f8 --- /dev/null +++ b/jvmfwk/plugins/sunmajor/pluginlib/otherjre.cxx @@ -0,0 +1,129 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_jvmfwk.hxx" + +#include "osl/thread.h" +#include "otherjre.hxx" + +using namespace std; + +using ::rtl::OUString; +using ::rtl::Reference; +namespace jfw_plugin +{ + +Reference<VendorBase> OtherInfo::createInstance() +{ + return new OtherInfo; +} + + +char const* const* OtherInfo::getJavaExePaths(int * size) +{ + static char const * ar[] = { +#if defined(WNT) + "bin/java.exe", + "jre/bin/java.exe" +#elif UNX + "bin/java", + "jre/bin/java" +#endif + }; + *size = sizeof (ar) / sizeof (char*); + return ar; +} + +char const* const* OtherInfo::getRuntimePaths(int * size) +{ + static char const* ar[]= { +#if defined(WNT) + "/bin/client/jvm.dll", + "/bin/hotspot/jvm.dll", + "/bin/classic/jvm.dll", + "/bin/jrockit/jvm.dll" +#elif UNX +#ifdef MACOSX + "/../../../../../Frameworks/JavaVM.framework/JavaVM" //as of 1.6.0_22 +#else + "/lib/" JFW_PLUGIN_ARCH "/client/libjvm.so", // for Blackdown PPC + "/lib/" JFW_PLUGIN_ARCH "/server/libjvm.so", // for Blackdown AMD64 + "/lib/" JFW_PLUGIN_ARCH "/classic/libjvm.so", // for Blackdown PPC + "/lib/" JFW_PLUGIN_ARCH "/jrockit/libjvm.so", // for Java of BEA Systems + "/bin/classic/libjvm.so", // fallback for older for IBM Java + "/jre/bin/classic/libjvm.so" // fallback for older for IBM Java +#endif +#endif + + }; + *size = sizeof(ar) / sizeof (char*); + return ar; +} + +char const* const* OtherInfo::getLibraryPaths(int* size) +{ + +#ifdef UNX + static char const * ar[] = { +#ifdef MACOSX + //mac version does not have a ld library path anymore +#else + "/bin", + "/jre/bin", + "/bin/classic", + "/jre/bin/classic", + "/lib/" JFW_PLUGIN_ARCH "/client", + "/lib/" JFW_PLUGIN_ARCH "/server", + "/lib/" JFW_PLUGIN_ARCH "/classic", + "/lib/" JFW_PLUGIN_ARCH "/jrockit", + "/lib/" JFW_PLUGIN_ARCH "/native_threads", + "/lib/" JFW_PLUGIN_ARCH +#endif + }; + + *size = sizeof(ar) / sizeof (char*); + return ar; +#else + size = 0; + return NULL; +#endif +} + +int OtherInfo::compareVersions(const rtl::OUString& /*sSecond*/) const +{ + //Need to provide an own algorithm for comparing version. + //Because this function returns always 0, which means the version of + //this JRE and the provided version "sSecond" are equal, one cannot put + //any excludeVersion entries in the javavendors.xml file. + return 0; +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/jvmfwk/plugins/sunmajor/pluginlib/otherjre.hxx b/jvmfwk/plugins/sunmajor/pluginlib/otherjre.hxx new file mode 100644 index 000000000000..9f54cf0ea5eb --- /dev/null +++ b/jvmfwk/plugins/sunmajor/pluginlib/otherjre.hxx @@ -0,0 +1,56 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_JFW_PLUGIN_OTHERJRE_HXX +#define INCLUDED_JFW_PLUGIN_OTHERJRE_HXX + +#include "vendorbase.hxx" +#include "vendorlist.hxx" + +namespace jfw_plugin +{ +/* Do not forget to put this class in the vendor map in vendorlist.cxx + */ +class OtherInfo: public VendorBase +{ +public: + static char const* const* getJavaExePaths(int * size); + + static rtl::Reference<VendorBase> createInstance(); + + using VendorBase::getLibraryPaths; + virtual char const* const* getRuntimePaths(int * size); + virtual char const* const* getLibraryPaths(int* size); + virtual int compareVersions(const rtl::OUString& sSecond) const; + +}; + +} +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/jvmfwk/plugins/sunmajor/pluginlib/sunjavaplugin.cxx b/jvmfwk/plugins/sunmajor/pluginlib/sunjavaplugin.cxx new file mode 100644 index 000000000000..eaaaf3a35aff --- /dev/null +++ b/jvmfwk/plugins/sunmajor/pluginlib/sunjavaplugin.cxx @@ -0,0 +1,798 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_jvmfwk.hxx" + +#ifdef WNT +# include <stdio.h> +# include <sys/stat.h> +# include <windows.h> +#endif + +#if OSL_DEBUG_LEVEL > 0 +#include <stdio.h> +#endif +#include <string.h> + +#include "boost/scoped_array.hpp" +#include "osl/diagnose.h" +#include "rtl/ustring.hxx" +#include "rtl/ustrbuf.hxx" +#include "osl/module.hxx" +#include "osl/mutex.hxx" +#include "osl/thread.hxx" +#include "osl/file.hxx" +#include "rtl/instance.hxx" +#include "osl/getglobalmutex.hxx" +#include <setjmp.h> +#include <signal.h> +#include <stack> + +#include "jni.h" +#include "rtl/byteseq.hxx" +#include "jvmfwk/vendorplugin.h" +#include "util.hxx" +#include "sunversion.hxx" +#include "vendorlist.hxx" +#include "diagnostics.h" + +#define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) ) +#define SUN_MICRO "Sun Microsystems Inc." + +using namespace osl; +using namespace std; +using namespace jfw_plugin; + +using ::rtl::OUString; +using ::rtl::OUStringBuffer; +using ::rtl::OString; + +namespace { + +struct PluginMutex: public ::rtl::Static<osl::Mutex, PluginMutex> {}; + +#if defined UNX +OString getPluginJarPath( + const OUString & sVendor, + const OUString& sLocation, + const OUString& sVersion) +{ + OString ret; + OUString sName1(RTL_CONSTASCII_USTRINGPARAM("javaplugin.jar")); + OUString sName2(RTL_CONSTASCII_USTRINGPARAM("plugin.jar")); + OUString sPath; + if (sVendor.equals(OUString(RTL_CONSTASCII_USTRINGPARAM(SUN_MICRO)))) + { + SunVersion ver142("1.4.2-ea"); + SunVersion ver150("1.5.0-ea"); + SunVersion ver(sVersion); + OSL_ASSERT(ver142 && ver150 && ver); + + OUString sName; + if (ver < ver142) + { + sName = sName1; + } + else if (ver < ver150) + {//this will cause ea, beta etc. to have plugin.jar in path. + //but this does not harm. 1.5.0-beta < 1.5.0 + sName = sName2; + } + if (sName.getLength()) + { + sName = sLocation + OUSTR("/lib/") + sName; + OSL_VERIFY( + osl_getSystemPathFromFileURL(sName.pData, & sPath.pData) + == osl_File_E_None); + } + } + else + { + char sep[] = {SAL_PATHSEPARATOR, 0}; + OUString sName(sLocation + OUSTR("/lib/") + sName1); + OUString sPath1; + OUString sPath2; + if (osl_getSystemPathFromFileURL(sName.pData, & sPath1.pData) + == osl_File_E_None) + { + sName = sLocation + OUSTR("/lib/") + sName2; + if (osl_getSystemPathFromFileURL(sName.pData, & sPath2.pData) + == osl_File_E_None) + { + sPath = sPath1 + OUString::createFromAscii(sep) + sPath2; + } + } + OSL_ASSERT(sPath.getLength()); + } + ret = rtl::OUStringToOString(sPath, osl_getThreadTextEncoding()); + + return ret; +} +#endif // UNX + + +JavaInfo* createJavaInfo(const rtl::Reference<VendorBase> & info) +{ + JavaInfo* pInfo = (JavaInfo*) rtl_allocateMemory(sizeof(JavaInfo)); + if (pInfo == NULL) + return NULL; + rtl::OUString sVendor = info->getVendor(); + pInfo->sVendor = sVendor.pData; + rtl_uString_acquire(sVendor.pData); + rtl::OUString sHome = info->getHome(); + pInfo->sLocation = sHome.pData; + rtl_uString_acquire(pInfo->sLocation); + rtl::OUString sVersion = info->getVersion(); + pInfo->sVersion = sVersion.pData; + rtl_uString_acquire(pInfo->sVersion); + pInfo->nFeatures = info->supportsAccessibility() ? 1 : 0; + pInfo->nRequirements = info->needsRestart() ? JFW_REQUIRE_NEEDRESTART : 0; + rtl::OUStringBuffer buf(1024); + buf.append(info->getRuntimeLibrary()); + if (info->getLibraryPaths().getLength() > 0) + { + buf.appendAscii("\n"); + buf.append(info->getLibraryPaths()); + buf.appendAscii("\n"); + } + + rtl::OUString sVendorData = buf.makeStringAndClear(); + rtl::ByteSequence byteSeq( (sal_Int8*) sVendorData.pData->buffer, + sVendorData.getLength() * sizeof(sal_Unicode)); + pInfo->arVendorData = byteSeq.get(); + rtl_byte_sequence_acquire(pInfo->arVendorData); + + return pInfo; +} + +rtl::OUString getRuntimeLib(const rtl::ByteSequence & data) +{ + const sal_Unicode* chars = (sal_Unicode*) data.getConstArray(); + sal_Int32 len = data.getLength(); + rtl::OUString sData(chars, len / 2); + //the runtime lib is on the first line + sal_Int32 index = 0; + rtl::OUString aToken = sData.getToken( 0, '\n', index); + + return aToken; +} + +jmp_buf jmp_jvm_abort; +sig_atomic_t g_bInGetJavaVM = 0; + +extern "C" void JNICALL abort_handler() +{ + // If we are within JNI_CreateJavaVM then we jump back into getJavaVM + if( g_bInGetJavaVM != 0 ) + { + fprintf( stderr, "JavaVM: JNI_CreateJavaVM called _exit, caught by abort_handler in javavm.cxx\n"); + longjmp( jmp_jvm_abort, 0); + } +} + +} + +extern "C" +javaPluginError jfw_plugin_getAllJavaInfos( + rtl_uString *sVendor, + rtl_uString *sMinVersion, + rtl_uString *sMaxVersion, + rtl_uString * *arExcludeList, + sal_Int32 nLenList, + JavaInfo*** parJavaInfo, + sal_Int32 *nLenInfoList) +{ + OSL_ASSERT(sVendor); + OSL_ASSERT(sMinVersion); + OSL_ASSERT(sMaxVersion); + OSL_ASSERT(parJavaInfo); + OSL_ASSERT(parJavaInfo); + OSL_ASSERT(nLenInfoList); + if (!sVendor || !sMinVersion || !sMaxVersion || !parJavaInfo || !nLenInfoList) + return JFW_PLUGIN_E_INVALID_ARG; + + //nLenlist contains the number of element in arExcludeList. + //If no exclude list is provided then nLenList must be 0 + OSL_ASSERT( ! (arExcludeList == NULL && nLenList > 0)); + if (arExcludeList == NULL && nLenList > 0) + return JFW_PLUGIN_E_INVALID_ARG; + + OUString ouVendor(sVendor); + OUString ouMinVer(sMinVersion); + OUString ouMaxVer(sMaxVersion); + + OSL_ASSERT(ouVendor.getLength() > 0); + if (ouVendor.getLength() == 0) + return JFW_PLUGIN_E_INVALID_ARG; + + JavaInfo** arInfo = NULL; + + //Find all JREs + vector<rtl::Reference<VendorBase> > vecInfos = + getAllJREInfos(); + vector<rtl::Reference<VendorBase> > vecVerifiedInfos; + + typedef vector<rtl::Reference<VendorBase> >::iterator it; + for (it i= vecInfos.begin(); i != vecInfos.end(); ++i) + { + const rtl::Reference<VendorBase>& cur = *i; + + if (ouVendor.equals(cur->getVendor()) == sal_False) + continue; + + if (ouMinVer.getLength() > 0) + { + try + { + if (cur->compareVersions(sMinVersion) == -1) + continue; + } + catch (MalformedVersionException&) + { + //The minVersion was not recognized as valid for this vendor. + JFW_ENSURE( + 0,OUSTR("[Java framework]sunjavaplugin does not know version: ") + + ouMinVer + OUSTR(" for vendor: ") + cur->getVendor() + + OUSTR(" .Check minimum Version.") ); + return JFW_PLUGIN_E_WRONG_VERSION_FORMAT; + } + } + + if (ouMaxVer.getLength() > 0) + { + try + { + if (cur->compareVersions(sMaxVersion) == 1) + continue; + } + catch (MalformedVersionException&) + { + //The maxVersion was not recognized as valid for this vendor. + JFW_ENSURE( + 0,OUSTR("[Java framework]sunjavaplugin does not know version: ") + + ouMaxVer + OUSTR(" for vendor: ") + cur->getVendor() + + OUSTR(" .Check maximum Version.") ); + return JFW_PLUGIN_E_WRONG_VERSION_FORMAT; + } + } + + if (arExcludeList > 0) + { + bool bExclude = false; + for (int j = 0; j < nLenList; j++) + { + rtl::OUString sExVer(arExcludeList[j]); + try + { + if (cur->compareVersions(sExVer) == 0) + { + bExclude = true; + break; + } + } + catch (MalformedVersionException&) + { + //The excluded version was not recognized as valid for this vendor. + JFW_ENSURE( + 0,OUSTR("[Java framework]sunjavaplugin does not know version: ") + + sExVer + OUSTR(" for vendor: ") + cur->getVendor() + + OUSTR(" .Check excluded versions.") ); + return JFW_PLUGIN_E_WRONG_VERSION_FORMAT; + } + } + if (bExclude == true) + continue; + } + vecVerifiedInfos.push_back(*i); + } + //Now vecVerifiedInfos contains all those JREs which meet the version requirements + //Transfer them into the array that is passed out. + arInfo = (JavaInfo**) rtl_allocateMemory(vecVerifiedInfos.size() * sizeof (JavaInfo*)); + int j = 0; + typedef vector<rtl::Reference<VendorBase> >::const_iterator cit; + for (cit ii = vecVerifiedInfos.begin(); ii != vecVerifiedInfos.end(); ++ii, ++j) + { + arInfo[j] = createJavaInfo(*ii); + } + *nLenInfoList = vecVerifiedInfos.size(); + + + *parJavaInfo = arInfo; + return JFW_PLUGIN_E_NONE; +} + +extern "C" +javaPluginError jfw_plugin_getJavaInfoByPath( + rtl_uString *path, + rtl_uString *sVendor, + rtl_uString *sMinVersion, + rtl_uString *sMaxVersion, + rtl_uString * *arExcludeList, + sal_Int32 nLenList, + JavaInfo ** ppInfo) +{ + javaPluginError errcode = JFW_PLUGIN_E_NONE; + + OSL_ASSERT(path); + OSL_ASSERT(sVendor); + OSL_ASSERT(sMinVersion); + OSL_ASSERT(sMaxVersion); + if (!path || !sVendor || !sMinVersion || !sMaxVersion || !ppInfo) + return JFW_PLUGIN_E_INVALID_ARG; + OUString ouPath(path); + OSL_ASSERT(ouPath.getLength() > 0); + if (ouPath.getLength() == 0) + return JFW_PLUGIN_E_INVALID_ARG; + + //nLenlist contains the number of element in arExcludeList. + //If no exclude list is provided then nLenList must be 0 + OSL_ASSERT( ! (arExcludeList == NULL && nLenList > 0)); + if (arExcludeList == NULL && nLenList > 0) + return JFW_PLUGIN_E_INVALID_ARG; + + OUString ouVendor(sVendor); + OUString ouMinVer(sMinVersion); + OUString ouMaxVer(sMaxVersion); + + OSL_ASSERT(ouVendor.getLength() > 0); + if (ouVendor.getLength() == 0) + return JFW_PLUGIN_E_INVALID_ARG; + + rtl::Reference<VendorBase> aVendorInfo = getJREInfoByPath(ouPath); + if (aVendorInfo.is() == sal_False) + return JFW_PLUGIN_E_NO_JRE; + + //Check if the detected JRE matches the version requirements + if (ouVendor.equals(aVendorInfo->getVendor()) == sal_False) + return JFW_PLUGIN_E_NO_JRE; + + if (ouMinVer.getLength() > 0) + { + int nRes = 0; + try + { + nRes = aVendorInfo->compareVersions(ouMinVer); + } + catch (MalformedVersionException&) + { + //The minVersion was not recognized as valid for this vendor. + JFW_ENSURE( + 0,OUSTR("[Java framework]sunjavaplugin does not know version: ") + + ouMinVer + OUSTR(" for vendor: ") + aVendorInfo->getVendor() + + OUSTR(" .Check minimum Version.") ); + return JFW_PLUGIN_E_WRONG_VERSION_FORMAT; + } + if (nRes < 0) + return JFW_PLUGIN_E_FAILED_VERSION; + } + + if (ouMaxVer.getLength() > 0) + { + int nRes = 0; + try + { + nRes = aVendorInfo->compareVersions(ouMaxVer); + } + catch (MalformedVersionException&) + { + //The maxVersion was not recognized as valid for this vendor. + JFW_ENSURE( + 0,OUSTR("[Java framework]sunjavaplugin does not know version: ") + + ouMaxVer + OUSTR(" for vendor: ") + aVendorInfo->getVendor() + + OUSTR(" .Check maximum Version.") ); + return JFW_PLUGIN_E_WRONG_VERSION_FORMAT; + } + if (nRes > 0) + return JFW_PLUGIN_E_FAILED_VERSION; + } + + if (arExcludeList > 0) + { + for (int i = 0; i < nLenList; i++) + { + rtl::OUString sExVer(arExcludeList[i]); + int nRes = 0; + try + { + nRes = aVendorInfo->compareVersions(sExVer); + } + catch (MalformedVersionException&) + { + //The excluded version was not recognized as valid for this vendor. + JFW_ENSURE( + 0,OUSTR("[Java framework]sunjavaplugin does not know version: ") + + sExVer + OUSTR(" for vendor: ") + aVendorInfo->getVendor() + + OUSTR(" .Check excluded versions.") ); + return JFW_PLUGIN_E_WRONG_VERSION_FORMAT; + } + if (nRes == 0) + return JFW_PLUGIN_E_FAILED_VERSION; + } + } + *ppInfo = createJavaInfo(aVendorInfo); + + return errcode; +} + +#if defined(WNT) + +// Load msvcr71.dll using an explicit full path from where it is +// present as bundled with the JRE. In case it is not found where we +// think it should be, do nothing, and just let the implicit loading +// that happens when loading the JVM take care of it. + +static void load_msvcr71(LPCWSTR jvm_dll) +{ + wchar_t msvcr71_dll[MAX_PATH]; + wchar_t *slash; + + if (wcslen(jvm_dll) > MAX_PATH - 15) + return; + + wcscpy(msvcr71_dll, jvm_dll); + + // First check if msvcr71.dll is in the same folder as jvm.dll. It + // normally isn't, at least up to 1.6.0_22, but who knows if it + // might be in the future. + slash = wcsrchr(msvcr71_dll, L'\\'); + + if (!slash) + { + // Huh, weird path to jvm.dll. Oh well. + return; + } + + wcscpy(slash+1, L"msvcr71.dll"); + if (LoadLibraryW(msvcr71_dll)) + return; + + // Then check if msvcr71.dll is in the parent folder of where + // jvm.dll is. That is currently (1.6.0_22) as far as I know the + // normal case. + *slash = 0; + slash = wcsrchr(msvcr71_dll, L'\\'); + + if (!slash) + return; + + wcscpy(slash+1, L"msvcr71.dll"); + LoadLibraryW(msvcr71_dll); +} + +// Check if the jvm DLL imports msvcr71.dll, and in that case try +// loading it explicitly. In case something goes wrong, do nothing, +// and just let the implicit loading try to take care of it. +static void do_msvcr71_magic(rtl_uString *jvm_dll) +{ + FILE *f; + rtl_uString* Module; + oslFileError nError; + struct stat st; + PIMAGE_DOS_HEADER dos_hdr; + IMAGE_NT_HEADERS *nt_hdr; + IMAGE_IMPORT_DESCRIPTOR *imports; + + nError = osl_getSystemPathFromFileURL(jvm_dll, &Module); + + if ( osl_File_E_None != nError ) + rtl_uString_assign(&Module, jvm_dll); + + f = _wfopen(reinterpret_cast<LPCWSTR>(Module->buffer), L"rb"); + + if (fstat(fileno(f), &st) == -1) + { + fclose(f); + return; + } + + dos_hdr = (PIMAGE_DOS_HEADER) malloc(st.st_size); + + if (fread(dos_hdr, st.st_size, 1, f) != 1 || + memcmp(dos_hdr, "MZ", 2) != 0 || + dos_hdr->e_lfanew < 0 || + dos_hdr->e_lfanew > (LONG) (st.st_size - sizeof(IMAGE_NT_HEADERS))) + { + free(dos_hdr); + fclose(f); + return; + } + + fclose(f); + + nt_hdr = (IMAGE_NT_HEADERS *) ((char *)dos_hdr + dos_hdr->e_lfanew); + + imports = (IMAGE_IMPORT_DESCRIPTOR *) ((char *) dos_hdr + nt_hdr->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress); + + while (imports <= (IMAGE_IMPORT_DESCRIPTOR *) ((char *) dos_hdr + st.st_size - sizeof (IMAGE_IMPORT_DESCRIPTOR)) && + imports->Name != 0 && + imports->Name < (DWORD) st.st_size) + { + // Intentional use of sizeof("msvcr71.dll") here to include the terminating zero byte + if (strnicmp((char *) dos_hdr + imports->Name, "msvcr71.dll", sizeof("msvcr71.dll")) == 0) + { + load_msvcr71(reinterpret_cast<LPCWSTR>(Module->buffer)); + break; + } + imports++; + } + + free(dos_hdr); +} + +#endif + +/** starts a Java Virtual Machine. + <p> + The function shall ensure, that the VM does not abort the process + during instantiation. + </p> + */ +extern "C" +javaPluginError jfw_plugin_startJavaVirtualMachine( + const JavaInfo *pInfo, + const JavaVMOption* arOptions, + sal_Int32 cOptions, + JavaVM ** ppVm, + JNIEnv ** ppEnv) +{ + // unless guard is volatile the following warning occurs on gcc: + // warning: variable 't' might be clobbered by `longjmp' or `vfork' + volatile osl::MutexGuard guard(PluginMutex::get()); + // unless errcode is volatile the following warning occurs on gcc: + // warning: variable 'errcode' might be clobbered by `longjmp' or `vfork' + volatile javaPluginError errcode = JFW_PLUGIN_E_NONE; + if ( pInfo == NULL || ppVm == NULL || ppEnv == NULL) + return JFW_PLUGIN_E_INVALID_ARG; + //Check if the Vendor (pInfo->sVendor) is supported by this plugin + if ( ! isVendorSupported(pInfo->sVendor)) + return JFW_PLUGIN_E_WRONG_VENDOR; + rtl::OUString sRuntimeLib = getRuntimeLib(pInfo->arVendorData); + JFW_TRACE2(OUSTR("[Java framework] Using Java runtime library: ") + + sRuntimeLib + OUSTR(".\n")); + // On linux we load jvm with RTLD_GLOBAL. This is necessary for debugging, because + // libjdwp.so need a symbol (fork1) from libjvm which it only gets if the jvm is loaded + // witd RTLD_GLOBAL. On Solaris libjdwp.so is correctly linked with libjvm.so + oslModule moduleRt = 0; +#if defined(LINUX) + if ((moduleRt = osl_loadModule(sRuntimeLib.pData, + SAL_LOADMODULE_GLOBAL | SAL_LOADMODULE_NOW)) == 0 ) +#else +#if defined(WNT) + do_msvcr71_magic(sRuntimeLib.pData); +#endif + if ((moduleRt = osl_loadModule(sRuntimeLib.pData, SAL_LOADMODULE_DEFAULT)) == 0) +#endif + { + JFW_ENSURE(0, OUSTR("[Java framework]sunjavaplugin" SAL_DLLEXTENSION + " could not load Java runtime library: \n") + + sRuntimeLib + OUSTR("\n")); + JFW_TRACE0(OUSTR("[Java framework]sunjavaplugin" SAL_DLLEXTENSION + " could not load Java runtime library: \n") + + sRuntimeLib + OUSTR("\n")); + return JFW_PLUGIN_E_VM_CREATION_FAILED; + } + +#ifdef UNX + //Setting the JAVA_HOME is needed for awt + rtl::OUString javaHome(RTL_CONSTASCII_USTRINGPARAM("JAVA_HOME=")); + rtl::OUString sPathLocation; + osl_getSystemPathFromFileURL(pInfo->sLocation, & sPathLocation.pData); + javaHome += sPathLocation; + rtl::OString osJavaHome = rtl::OUStringToOString( + javaHome, osl_getThreadTextEncoding()); + putenv(strdup(osJavaHome.getStr())); +#endif + + typedef jint JNICALL JNI_InitArgs_Type(void *); + typedef jint JNICALL JNI_CreateVM_Type(JavaVM **, JNIEnv **, void *); + rtl::OUString sSymbolCreateJava( + RTL_CONSTASCII_USTRINGPARAM("JNI_CreateJavaVM")); + + JNI_CreateVM_Type * pCreateJavaVM = (JNI_CreateVM_Type *) osl_getFunctionSymbol( + moduleRt, sSymbolCreateJava.pData); + if (!pCreateJavaVM) + { + OSL_ASSERT(0); + rtl::OString sLib = rtl::OUStringToOString( + sRuntimeLib, osl_getThreadTextEncoding()); + rtl::OString sSymbol = rtl::OUStringToOString( + sSymbolCreateJava, osl_getThreadTextEncoding()); + fprintf(stderr,"[Java framework]sunjavaplugin"SAL_DLLEXTENSION + "Java runtime library: %s does not export symbol %s !\n", + sLib.getStr(), sSymbol.getStr()); + return JFW_PLUGIN_E_VM_CREATION_FAILED; + } + + // Some testing with Java 1.4 showed that JavaVMOption.optionString has to + // be encoded with the system encoding (i.e., osl_getThreadTextEncoding): + JavaVMInitArgs vm_args; + + boost::scoped_array<JavaVMOption> sarOptions( + new JavaVMOption[cOptions + 1]); + JavaVMOption * options = sarOptions.get(); + + // We set an abort handler which is called when the VM calls _exit during + // JNI_CreateJavaVM. This happens when the LD_LIBRARY_PATH does not contain + // all some directories of the Java installation. This is necessary for + // all versions below 1.5.1 + options[0].optionString= (char *) "abort"; + options[0].extraInfo= (void* )(sal_IntPtr)abort_handler; + rtl::OString sClassPathProp("-Djava.class.path="); + rtl::OString sClassPathOption; + for (int i = 0; i < cOptions; i++) + { +#ifdef UNX + // Until java 1.5 we need to put a plugin.jar or javaplugin.jar (<1.4.2) + // in the class path in order to have applet support. + rtl::OString sClassPath = arOptions[i].optionString; + if (sClassPath.match(sClassPathProp, 0) == sal_True) + { + char sep[] = {SAL_PATHSEPARATOR, 0}; + OString sAddPath = getPluginJarPath(pInfo->sVendor, pInfo->sLocation,pInfo->sVersion); + if (sAddPath.getLength()) + sClassPathOption = sClassPath + rtl::OString(sep) + sAddPath; + else + sClassPathOption = sClassPath; + options[i+1].optionString = (char *) sClassPathOption.getStr(); + options[i+1].extraInfo = arOptions[i].extraInfo; + } + else + { +#endif + options[i+1].optionString = arOptions[i].optionString; + options[i+1].extraInfo = arOptions[i].extraInfo; +#ifdef UNX + } +#endif +#if OSL_DEBUG_LEVEL >= 2 + JFW_TRACE2(OString("VM option: ") + OString(options[i+1].optionString) + + OString("\n")); +#endif + } + +#ifdef MACOSX + vm_args.version= JNI_VERSION_1_4; // issue 88987 +#else + vm_args.version= JNI_VERSION_1_2; +#endif + vm_args.options= options; + vm_args.nOptions= cOptions + 1; + vm_args.ignoreUnrecognized= JNI_TRUE; + + /* We set a global flag which is used by the abort handler in order to + determine whether it is should use longjmp to get back into this function. + That is, the abort handler determines if it is on the same stack as this function + and then jumps back into this function. + */ + g_bInGetJavaVM = 1; + jint err; + JavaVM * pJavaVM = 0; + memset( jmp_jvm_abort, 0, sizeof(jmp_jvm_abort)); + int jmpval= setjmp( jmp_jvm_abort ); + /* If jmpval is not "0" then this point was reached by a longjmp in the + abort_handler, which was called indirectly by JNI_CreateVM. + */ + if( jmpval == 0) + { + //returns negative number on failure + err= pCreateJavaVM(&pJavaVM, ppEnv, &vm_args); + g_bInGetJavaVM = 0; + } + else + // set err to a positive number, so as or recognize that an abort (longjmp) + //occurred + err= 1; + + if(err != 0) + { + rtl::OUString message; + if( err < 0) + { + fprintf(stderr,"[Java framework] sunjavaplugin"SAL_DLLEXTENSION + "Can not create Java Virtual Machine\n"); + errcode = JFW_PLUGIN_E_VM_CREATION_FAILED; + } + else if( err > 0) + { + fprintf(stderr,"[Java framework] sunjavaplugin"SAL_DLLEXTENSION + "Can not create JavaVirtualMachine, abort handler was called.\n"); + errcode = JFW_PLUGIN_E_VM_CREATION_FAILED; + } + } + else + { + *ppVm = pJavaVM; + JFW_TRACE2("[Java framework] sunjavaplugin"SAL_DLLEXTENSION " has created a VM.\n"); + } + + + return errcode; +} + +extern "C" +javaPluginError jfw_plugin_existJRE(const JavaInfo *pInfo, sal_Bool *exist) +{ + javaPluginError ret = JFW_PLUGIN_E_NONE; + if (!pInfo || !exist) + return JFW_PLUGIN_E_INVALID_ARG; + ::rtl::OUString sLocation(pInfo->sLocation); + + if (sLocation.getLength() == 0) + return JFW_PLUGIN_E_INVALID_ARG; + ::osl::DirectoryItem item; + ::osl::File::RC rc_item = ::osl::DirectoryItem::get(sLocation, item); + if (::osl::File::E_None == rc_item) + { + *exist = sal_True; + } + else if (::osl::File::E_NOENT == rc_item) + { + *exist = sal_False; + } + else + { + ret = JFW_PLUGIN_E_ERROR; + } +#ifdef MACOSX + //We can have the situation that the JavaVM runtime library is not + //contained within JAVA_HOME. Then the check for JAVA_HOME would return + //true although the runtime library may not be loadable. + if (ret == JFW_PLUGIN_E_NONE && *exist == sal_True) + { + rtl::OUString sRuntimeLib = getRuntimeLib(pInfo->arVendorData); + JFW_TRACE2(OUSTR("[Java framework] Checking existence of Java runtime library.\n")); + + ::osl::DirectoryItem itemRt; + ::osl::File::RC rc_itemRt = ::osl::DirectoryItem::get(sRuntimeLib, itemRt); + if (::osl::File::E_None == rc_itemRt) + { + *exist = sal_True; + JFW_TRACE2(OUSTR("[Java framework] Java runtime library exist: ") + + sRuntimeLib + OUSTR("\n")); + + } + else if (::osl::File::E_NOENT == rc_itemRt) + { + *exist = sal_False; + JFW_TRACE2(OUSTR("[Java framework] Java runtime library does not exist: ") + + sRuntimeLib + OUSTR("\n")); + } + else + { + ret = JFW_PLUGIN_E_ERROR; + JFW_TRACE2(OUSTR("[Java framework] Error while looking for Java runtime library: ") + + sRuntimeLib + OUSTR(" \n")); + } + } +#endif + return ret; +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/jvmfwk/plugins/sunmajor/pluginlib/sunjavaplugin.map b/jvmfwk/plugins/sunmajor/pluginlib/sunjavaplugin.map new file mode 100644 index 000000000000..901867f0a43d --- /dev/null +++ b/jvmfwk/plugins/sunmajor/pluginlib/sunjavaplugin.map @@ -0,0 +1,13 @@ +UDK_3_0_0 { + global: + jfw_plugin_getAllJavaInfos; + jfw_plugin_getJavaInfoByPath; + jfw_plugin_startJavaVirtualMachine; + local: + *; +}; + +UDK_3.1 { # OOo 3.3 + global: + jfw_plugin_existJRE; +} UDK_3_0_0; diff --git a/jvmfwk/plugins/sunmajor/pluginlib/sunjavapluginrc b/jvmfwk/plugins/sunmajor/pluginlib/sunjavapluginrc new file mode 100755 index 000000000000..0f2fb31eef90 --- /dev/null +++ b/jvmfwk/plugins/sunmajor/pluginlib/sunjavapluginrc @@ -0,0 +1,2 @@ +[Bootstrap] +JFW_PLUGIN_DO_NOT_CHECK_ACCESSIBILITY=1
\ No newline at end of file diff --git a/jvmfwk/plugins/sunmajor/pluginlib/sunjre.cxx b/jvmfwk/plugins/sunmajor/pluginlib/sunjre.cxx new file mode 100644 index 000000000000..975a4c2522c4 --- /dev/null +++ b/jvmfwk/plugins/sunmajor/pluginlib/sunjre.cxx @@ -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. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_jvmfwk.hxx" + +#include "osl/thread.h" +#include "sunjre.hxx" +#include "sunversion.hxx" +#include "diagnostics.h" + +using namespace std; + +using ::rtl::OUString; +using ::rtl::Reference; + +#define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) ) +namespace jfw_plugin +{ + +Reference<VendorBase> SunInfo::createInstance() +{ + return new SunInfo; +} + +char const* const* SunInfo::getJavaExePaths(int * size) +{ + static char const * ar[] = { +#if defined(WNT) + "java.exe", + "bin/java.exe", + "jre/bin/java.exe" +#elif UNX + "java", + "bin/java", + "jre/bin/java" +#endif + }; + *size = sizeof (ar) / sizeof (char*); + return ar; +} + +char const* const* SunInfo::getRuntimePaths(int * size) +{ + static char const* ar[]= { +#if defined(WNT) + "/bin/client/jvm.dll", + "/bin/hotspot/jvm.dll", + "/bin/classic/jvm.dll", + // The 64-bit JRE has the jvm in bin/server + "/bin/server/jvm.dll" +#elif UNX + "/lib/" JFW_PLUGIN_ARCH "/client/libjvm.so", + "/lib/" JFW_PLUGIN_ARCH "/server/libjvm.so", + "/lib/" JFW_PLUGIN_ARCH "/classic/libjvm.so" +#endif + + }; + *size = sizeof(ar) / sizeof (char*); + return ar; +} + +char const* const* SunInfo::getLibraryPaths(int* size) +{ +#ifdef UNX + static char const * ar[] = { + + "/lib/" JFW_PLUGIN_ARCH "/client", + "/lib/" JFW_PLUGIN_ARCH "/server", + "/lib/" JFW_PLUGIN_ARCH "/native_threads", + "/lib/" JFW_PLUGIN_ARCH + + }; + *size = sizeof(ar) / sizeof (char*); + return ar; +#else + size = 0; + return NULL; +#endif +} + +int SunInfo::compareVersions(const rtl::OUString& sSecond) const +{ + OUString sFirst = getVersion(); + + SunVersion version1(sFirst); + JFW_ENSURE(version1, OUSTR("[Java framework] sunjavaplugin"SAL_DLLEXTENSION + " does not know the version: ") + + sFirst + OUSTR(" as valid for a SUN JRE.")); + SunVersion version2(sSecond); + if ( ! version2) + throw MalformedVersionException(); + + if(version1 == version2) + return 0; + if(version1 > version2) + return 1; + else + return -1; +} + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/jvmfwk/plugins/sunmajor/pluginlib/sunjre.hxx b/jvmfwk/plugins/sunmajor/pluginlib/sunjre.hxx new file mode 100644 index 000000000000..5851b16c8143 --- /dev/null +++ b/jvmfwk/plugins/sunmajor/pluginlib/sunjre.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. + * + ************************************************************************/ + +#if !defined INCLUDED_JFW_PLUGIN_SUNJRE_HXX +#define INCLUDED_JFW_PLUGIN_SUNJRE_HXX + +#include "vendorbase.hxx" +#include "vendorlist.hxx" + +namespace jfw_plugin +{ + +class SunInfo: public VendorBase +{ +public: + static char const* const* getJavaExePaths(int * size); + + static rtl::Reference<VendorBase> createInstance(); + + using VendorBase::getLibraryPaths; + virtual char const* const* getRuntimePaths(int * size); + virtual char const* const* getLibraryPaths(int* size); + + virtual int compareVersions(const rtl::OUString& sSecond) const; +}; + +} +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/jvmfwk/plugins/sunmajor/pluginlib/sunversion.cxx b/jvmfwk/plugins/sunmajor/pluginlib/sunversion.cxx new file mode 100644 index 000000000000..bb3e1765a030 --- /dev/null +++ b/jvmfwk/plugins/sunmajor/pluginlib/sunversion.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_jvmfwk.hxx" + +#include "sunversion.hxx" +#include "osl/thread.h" +#include "osl/process.h" +#include "osl/security.hxx" +#include <string.h> +#include <ctype.h> +#include "diagnostics.h" +using namespace osl; + +using ::rtl::OUString; +using ::rtl::OUStringToOString; +using ::rtl::OString; +namespace jfw_plugin { //stoc_javadetect + + +#define OUSTR( x ) ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( x )) + +#if OSL_DEBUG_LEVEL >= 2 +class SelfTest +{ +public: + SelfTest(); +} test; +#endif + +SunVersion::SunVersion(const rtl::OUString &usVer): + m_nUpdateSpecial(0), m_preRelease(Rel_NONE), + usVersion(usVer) +{ + memset(m_arVersionParts, 0, sizeof(m_arVersionParts)); + rtl::OString sVersion= rtl::OUStringToOString(usVer, osl_getThreadTextEncoding()); + m_bValid = init(sVersion.getStr()); +} +SunVersion::SunVersion(const char * szVer): + m_nUpdateSpecial(0), m_preRelease(Rel_NONE) +{ + memset(m_arVersionParts, 0, sizeof(m_arVersionParts)); + m_bValid = init(szVer); + usVersion= rtl::OUString(szVer,strlen(szVer),osl_getThreadTextEncoding()); +} + + +/**Format major.minor.maintainance_update + */ +bool SunVersion::init(const char *szVersion) +{ + if ( ! szVersion || strlen(szVersion) == 0) + return false; + + //first get the major,minor,maintainance + const char * pLast = szVersion; + const char * pCur = szVersion; + //pEnd point to the position after the last character + const char * pEnd = szVersion + strlen(szVersion); + // 0 = major, 1 = minor, 2 = maintainance, 3 = update + int nPart = 0; + // position within part beginning with 0 + int nPartPos = 0; + char buf[128]; + + //char must me a number 0 - 999 and no leading + while (1) + { + if (pCur < pEnd && isdigit(*pCur)) + { + if (pCur < pEnd) + pCur ++; + nPartPos ++; + } + //if correct separator then form integer + else if ( + ! (nPartPos == 0) // prevents: ".4.1", "..1", part must start with digit + && ( + //seperators after maintainance (1.4.1_01, 1.4.1-beta, or1.4.1 + ((pCur == pEnd || *pCur == '_' || *pCur == '-') && (nPart == 2 )) + || + //separators between major-minor and minor-maintainance + (nPart < 2 && *pCur == '.') ) + && ( + //prevent 1.4.0. 1.4.0- + pCur + 1 == pEnd ? isdigit(*(pCur)) : 1) ) + { + int len = pCur - pLast; + if (len >= 127) + return false; + + strncpy(buf, pLast, len); + buf[len] = 0; + pCur ++; + pLast = pCur; + + m_arVersionParts[nPart] = atoi(buf); + nPart ++; + nPartPos = 0; + if (nPart == 3) + break; + + //check next character + if (! ( (pCur < pEnd) + && ( (nPart < 3) && isdigit(*pCur)))) + return false; + } + else + { + return false; + } + } + if (pCur >= pEnd) + return true; + //We have now 1.4.1. This can be followed by _01, -beta, etc. + // _01 (update) According to docu must not be followed by any other + //characters, but on Solaris 9 we have a 1.4.1_01a!! + if (* (pCur - 1) == '_') + {// _01, _02 + // update is the last part _01, _01a, part 0 is the digits parts and 1 the trailing alpha + while (1) + { + if (pCur <= pEnd) + { + if ( ! isdigit(*pCur)) + { + //1.4.1_01-, 1.4.1_01a, the numerical part may only be 2 chars. + int len = pCur - pLast; + if (len > 2) + return false; + //we've got the update: 01, 02 etc + strncpy(buf, pLast, len); + buf[len] = 0; + m_arVersionParts[nPart] = atoi(buf); + if (pCur == pEnd) + { + break; + } + if (*pCur == 'a' && (pCur + 1) == pEnd) + { + //check if it s followed by a simple "a" (not specified) + m_nUpdateSpecial = *pCur; + break; + } + else if (*pCur == '-' && pCur < pEnd) + { + //check 1.5.0_01-ea + PreRelease pr = getPreRelease(++pCur); + if (pr == Rel_NONE) + return false; + //just ignore -ea because its no official release + break; + } + else + { + return false; + } + } + if (pCur < pEnd) + pCur ++; + else + break; + } + } + } + // 1.4.1-ea + else if (*(pCur - 1) == '-') + { + m_preRelease = getPreRelease(pCur); + if (m_preRelease == Rel_NONE) + return false; +#if defined(FREEBSD) + if (m_preRelease == Rel_FreeBSD) + { + pCur++; //elemnate `p' + if (pCur < pEnd && isdigit(*pCur)) + pCur ++; + int len = pCur - pLast -1; //elemenate `p' + if (len >= 127) + return false; + strncpy(buf, (pLast+1), len); //elemenate `p' + buf[len] = 0; + m_nUpdateSpecial = atoi(buf)+100; //hack for FBSD #i56953# + return true; + } +#endif + } + else + { + return false; + } + return true; +} + +SunVersion::PreRelease SunVersion::getPreRelease(const char *szRelease) +{ + if (szRelease == NULL) + return Rel_NONE; + if( ! strcmp(szRelease,"ea")) + return Rel_EA; + else if( ! strcmp(szRelease,"ea1")) + return Rel_EA1; + else if( ! strcmp(szRelease,"ea2")) + return Rel_EA2; + else if( ! strcmp(szRelease,"ea3")) + return Rel_EA3; + else if ( ! strcmp(szRelease,"beta")) + return Rel_BETA; + else if ( ! strcmp(szRelease,"beta1")) + return Rel_BETA1; + else if ( ! strcmp(szRelease,"beta2")) + return Rel_BETA2; + else if ( ! strcmp(szRelease,"beta3")) + return Rel_BETA3; + else if (! strcmp(szRelease, "rc")) + return Rel_RC; + else if (! strcmp(szRelease, "rc1")) + return Rel_RC1; + else if (! strcmp(szRelease, "rc2")) + return Rel_RC2; + else if (! strcmp(szRelease, "rc3")) + return Rel_RC3; +#if defined (FREEBSD) + else if (! strncmp(szRelease, "p", 1)) + return Rel_FreeBSD; +#endif + else + return Rel_NONE; +} + +SunVersion::~SunVersion() +{ + +} + +/* Examples: + a) 1.0 < 1.1 + b) 1.0 < 1.0.0 + c) 1.0 < 1.0_00 + + returns false if both values are equal +*/ +bool SunVersion::operator > (const SunVersion& ver) const +{ + if( &ver == this) + return false; + + //compare major.minor.maintainance + for( int i= 0; i < 4; i ++) + { + // 1.4 > 1.3 + if(m_arVersionParts[i] > ver.m_arVersionParts[i]) + { + return true; + } + else if (m_arVersionParts[i] < ver.m_arVersionParts[i]) + { + return false; + } + } + //major.minor.maintainance_update are equal. test for a trailing char + if (m_nUpdateSpecial > ver.m_nUpdateSpecial) + { + return true; + } + + //Until here the versions are equal + //compare pre -release values + if ((m_preRelease == Rel_NONE && ver.m_preRelease == Rel_NONE) + || + (m_preRelease != Rel_NONE && ver.m_preRelease == Rel_NONE)) + return false; + else if (m_preRelease == Rel_NONE && ver.m_preRelease != Rel_NONE) + return true; + else if (m_preRelease > ver.m_preRelease) + return true; + + return false; +} + +bool SunVersion::operator < (const SunVersion& ver) const +{ + return (! operator > (ver)) && (! operator == (ver)); +} + +bool SunVersion::operator == (const SunVersion& ver) const +{ + bool bRet= true; + for(int i= 0; i < 4; i++) + { + if( m_arVersionParts[i] != ver.m_arVersionParts[i]) + { + bRet= false; + break; + } + } + bRet = m_nUpdateSpecial == ver.m_nUpdateSpecial && bRet; + bRet = m_preRelease == ver.m_preRelease && bRet; + return bRet; +} + +SunVersion::operator bool() +{ + return m_bValid; +} + +#if OSL_DEBUG_LEVEL >= 2 +SelfTest::SelfTest() +{ + bool bRet = true; + + char const * versions[] = {"1.4.0", "1.4.1", "1.0.0", "10.0.0", "10.10.0", + "10.2.2", "10.10.0", "10.10.10", "111.0.999", + "1.4.1_01", "9.90.99_09", "1.4.1_99", + "1.4.1_00a", + "1.4.1-ea", "1.4.1-beta", "1.4.1-rc1", + "1.5.0_01-ea", "1.5.0_01-rc2"}; + char const * badVersions[] = {".4.0", "..1", "", "10.0", "10.10.0.", "10.10.0-", "10.10.0.", + "10.2-2", "10_10.0", "10..10","10.10", "a.0.999", + "1.4b.1_01", "9.90.-99_09", "1.4.1_99-", + "1.4.1_00a2", "1.4.0_z01z", "1.4.1__99A", + "1.4.1-1ea", "1.5.0_010", "1.5.0._01-", "1.5.0_01-eac"}; + char const * orderedVer[] = { "1.3.1-ea", "1.3.1-beta", "1.3.1-rc1", + "1.3.1", "1.3.1_00a", "1.3.1_01", "1.3.1_01a", + "1.3.2", "1.4.0", "1.5.0_01-ea", "2.0.0"}; + + int num = sizeof (versions) / sizeof(char*); + int numBad = sizeof (badVersions) / sizeof(char*); + int numOrdered = sizeof (orderedVer) / sizeof(char*); + //parsing test (positive) + for (int i = 0; i < num; i++) + { + SunVersion ver(versions[i]); + if ( ! ver) + { + bRet = false; + break; + } + } + OSL_ENSURE(bRet, "SunVersion selftest failed"); + //Parsing test (negative) + for ( int i = 0; i < numBad; i++) + { + SunVersion ver(badVersions[i]); + if (ver) + { + bRet = false; + break; + } + } + OSL_ENSURE(bRet, "SunVersion selftest failed"); + + // Ordering test + bRet = true; + int j = 0; + for (int i = 0; i < numOrdered; i ++) + { + SunVersion curVer(orderedVer[i]); + if ( ! curVer) + { + bRet = false; + break; + } + for (j = 0; j < numOrdered; j++) + { + SunVersion compVer(orderedVer[j]); + if (i < j) + { + if ( !(curVer < compVer)) + { + bRet = false; + break; + } + } + else if ( i == j) + { + if (! (curVer == compVer + && ! (curVer > compVer) + && ! (curVer < compVer))) + { + bRet = false; + break; + } + } + else if (i > j) + { + if ( !(curVer > compVer)) + { + bRet = false; + break; + } + } + } + if ( ! bRet) + break; + } + if (bRet) + JFW_TRACE2("[Java framework] sunjavaplugin: Testing class SunVersion succeeded.\n"); + else + OSL_ENSURE(bRet, "[Java framework] sunjavaplugin: SunVersion self test failed.\n"); +} +#endif + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/jvmfwk/plugins/sunmajor/pluginlib/sunversion.hxx b/jvmfwk/plugins/sunmajor/pluginlib/sunversion.hxx new file mode 100644 index 000000000000..4e51f7a0a7a6 --- /dev/null +++ b/jvmfwk/plugins/sunmajor/pluginlib/sunversion.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. + * + ************************************************************************/ + +#if !defined INCLUDED_JVMACCESS_SUNVERSION_HXX +#define INCLUDED_JVMACCESS_SUNVERSION_HXX + +#include "rtl/ustring.hxx" + +namespace jfw_plugin { +// Define OSL_DEBUG_LEVEL >= 2 to run a test when this lib is loaded + +/* SunVersion is used to compare java versions based on a string, as taken + from the registry. The strings look like "1.3", "1.3.1", "1.3.1_02" etc. + Versions such as "1.4.1_01a" are allowed although this is not specified. + 1.4.1_01 < 1.4.1_01a < 1.4.1_01b < 1.4.1_02 + Pre - release versions, such as 1.4.1-ea, 1.4.1-beta, 1.4.1-rc are recognized, + but are treated as minor to release versions: + 1.4.0 > 1.4.2-beta + Pre releases relate this way + 1.4.1-ea < 1.4.1-beta < 1.4.1-rc1 + + This class supports also a FreeBSD Java. This is currently necessary because + it also has the vendor string "Sun Microsystems Inc.". + + An object acts as holder for the version string. That string may be present + even if the version could not be parsed. Then the version may not be compatible + to a SUN Java version. + + An invalid object, that is, operator bool returns false, will always be + the lower version in a comparison. If two invalid objects are compared + then they are considered equal. + + To test if the version is ok, that is this object can be compared to others, + use the bool conversion operator. + */ +class SunVersion +{ +protected: + + enum PreRelease + { + Rel_NONE, + Rel_EA, + Rel_EA1, + Rel_EA2, + Rel_EA3, + Rel_BETA, + Rel_BETA1, + Rel_BETA2, + Rel_BETA3, + Rel_RC, + Rel_RC1, + Rel_RC2, + Rel_RC3 +#if defined(FREEBSD) + , + Rel_FreeBSD +#endif + }; + + //contains major,minor,micro,update + int m_arVersionParts[4]; + // The update can be followed by a char, e.g. 1.4.1_01a + char m_nUpdateSpecial; + + PreRelease m_preRelease; +public: + SunVersion(const char * szVer); + SunVersion(const rtl::OUString& usVer); + ~SunVersion(); + + /** + Pre-release versions are taken into account. + 1.5.0-beta > 1.5.0-ea > 1.4.2 + */ + bool operator > (const SunVersion& ver) const; + bool operator < (const SunVersion& ver) const; + bool operator == (const SunVersion& ver) const; + + /** Test if the version is compatible tu SUN's versioning scheme + */ + operator bool (); + + /** Will always contain a value if the object has been constructed with + a version string. + */ + rtl::OUString usVersion; + +protected: + bool init(const char * szVer); + + bool m_bValid; + + /* Determines if a string constitutes a pre release. For example, if + "ea" is passed then Rel_EA is returned. If the string is no pre release + then Rel_NONE is returned. + */ + PreRelease getPreRelease(const char *szRel); +}; + +} + +#endif // INCLUDED_JVMACCESS_SUNVERSION_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/jvmfwk/plugins/sunmajor/pluginlib/util.cxx b/jvmfwk/plugins/sunmajor/pluginlib/util.cxx new file mode 100644 index 000000000000..00843ec8f03a --- /dev/null +++ b/jvmfwk/plugins/sunmajor/pluginlib/util.cxx @@ -0,0 +1,1284 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_jvmfwk.hxx" + +#include "util.hxx" + +#include "osl/process.h" +#include "osl/security.hxx" +#include "osl/thread.hxx" +#include "osl/file.hxx" +#include "osl/module.hxx" +#include "rtl/byteseq.hxx" +#include "rtl/ustrbuf.hxx" +#include "rtl/instance.hxx" +#include <salhelper/linkhelper.hxx> +#include "boost/scoped_array.hpp" +#include "com/sun/star/uno/Sequence.hxx" +#include <utility> +#include <algorithm> +#include <map> + +#if defined WNT +#if defined _MSC_VER +#pragma warning(push, 1) +#endif +#include <windows.h> +#if defined _MSC_VER +#pragma warning(pop) +#endif +#endif +#include <string.h> + +#include "sunjre.hxx" +#include "vendorlist.hxx" +#include "diagnostics.h" + +using namespace osl; +using namespace std; + +using ::rtl::OUString; +using ::rtl::Reference; +using ::rtl::OString; +using ::rtl::OUStringBuffer; +using ::rtl::OUStringToOString; + +#define CHAR_POINTER(oustr) ::rtl::OUStringToOString(oustr,RTL_TEXTENCODING_UTF8).pData->buffer +#define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) ) +#ifdef WNT +#define HKEY_SUN_JRE L"Software\\JavaSoft\\Java Runtime Environment" +#define HKEY_SUN_SDK L"Software\\JavaSoft\\Java Development Kit" +#endif + +#ifdef UNX +namespace { +char const *g_arJavaNames[] = { + "", + "j2re", + "j2se", + "j2sdk", + "jdk", + "jre", + "java", + "Home", + "IBMJava2-ppc-142" +}; +/* These are directory names which could contain multiple java installations. + */ +char const *g_arCollectDirs[] = { + "", +#ifndef JVM_ONE_PATH_CHECK + "j2re/", + "j2se/", + "j2sdk/", + "jdk/", + "jre/", + "java/", +#endif + "jvm/" +}; + +/* These are directories in which a java installation is + looked for. +*/ +char const *g_arSearchPaths[] = { +#ifdef MACOSX + "", + "System/Library/Frameworks/JavaVM.framework/Versions/1.4.2/" +#else +#ifndef JVM_ONE_PATH_CHECK + "", + "usr/", + "usr/local/", + "usr/local/IBMJava2-ppc-142", + "usr/local/j2sdk1.3.1", +#ifdef X86_64 + "usr/lib64/", +#endif + "usr/lib/", + "usr/bin/" +#else + JVM_ONE_PATH_CHECK +#endif +#endif +}; +} +#endif // UNX + +namespace jfw_plugin +{ +extern VendorSupportMapEntry gVendorMap[]; + +bool getSDKInfoFromRegistry(vector<OUString> & vecHome); +bool getJREInfoFromRegistry(vector<OUString>& vecJavaHome); +bool decodeOutput(const rtl::OString& s, rtl::OUString* out); + + + +namespace +{ + rtl::OUString getLibraryLocation() + { + rtl::OUString libraryFileUrl; + OSL_VERIFY(osl::Module::getUrlFromAddress((void *)(sal_IntPtr)getLibraryLocation, libraryFileUrl)); + return getDirFromFile(libraryFileUrl); + } + + struct InitBootstrap + { + rtl::Bootstrap * operator()(const OUString& sIni) + { + static rtl::Bootstrap aInstance(sIni); + return & aInstance; + + } + }; + + struct InitBootstrapData + { + OUString const & operator()() + { + static OUString sIni; + rtl::OUStringBuffer buf( 255); + buf.append( getLibraryLocation()); + buf.appendAscii( SAL_CONFIGFILE("/sunjavaplugin") ); + sIni = buf.makeStringAndClear(); + JFW_TRACE2(OUSTR("[Java framework] sunjavaplugin: " + "Using configuration file \n") + sIni); + return sIni; + } + }; +} + +rtl::Bootstrap * getBootstrap() +{ + return rtl_Instance< rtl::Bootstrap, InitBootstrap, + ::osl::MutexGuard, ::osl::GetGlobalMutex, + OUString, InitBootstrapData >::create( + InitBootstrap(), ::osl::GetGlobalMutex(), InitBootstrapData()); +} + + + + +class FileHandleGuard +{ +public: + inline FileHandleGuard(oslFileHandle & rHandle) SAL_THROW(()): + m_rHandle(rHandle) {} + + inline ~FileHandleGuard() SAL_THROW(()); + + inline oslFileHandle & getHandle() SAL_THROW(()) { return m_rHandle; } + +private: + oslFileHandle & m_rHandle; + + FileHandleGuard(FileHandleGuard &); // not implemented + void operator =(FileHandleGuard); // not implemented +}; + +inline FileHandleGuard::~FileHandleGuard() SAL_THROW(()) +{ + if (m_rHandle != 0) + { + if (osl_closeFile(m_rHandle) != osl_File_E_None) + { + OSL_FAIL("unexpected situation"); + } + } +} + + +class FileHandleReader +{ +public: + enum Result + { + RESULT_OK, + RESULT_EOF, + RESULT_ERROR + }; + + inline FileHandleReader(oslFileHandle & rHandle) SAL_THROW(()): + m_aGuard(rHandle), m_nSize(0), m_nIndex(0), m_bLf(false) {} + + Result readLine(rtl::OString * pLine) SAL_THROW(()); + +private: + enum { BUFFER_SIZE = 1024 }; + + sal_Char m_aBuffer[BUFFER_SIZE]; + FileHandleGuard m_aGuard; + int m_nSize; + int m_nIndex; + bool m_bLf; +}; + +FileHandleReader::Result +FileHandleReader::readLine(rtl::OString * pLine) + SAL_THROW(()) +{ + OSL_ENSURE(pLine, "specification violation"); + + for (bool bEof = true;; bEof = false) + { + if (m_nIndex == m_nSize) + { + sal_uInt64 nRead = 0; + switch (osl_readFile( + m_aGuard.getHandle(), m_aBuffer, sizeof(m_aBuffer), &nRead)) + { + case osl_File_E_PIPE: //HACK! for windows + nRead = 0; + case osl_File_E_None: + if (nRead == 0) + { + m_bLf = false; + return bEof ? RESULT_EOF : RESULT_OK; + } + m_nIndex = 0; + m_nSize = static_cast< int >(nRead); + break; + case osl_File_E_INTR: + continue; + + default: + return RESULT_ERROR; + } + } + + if (m_bLf && m_aBuffer[m_nIndex] == 0x0A) + ++m_nIndex; + m_bLf = false; + + int nStart = m_nIndex; + while (m_nIndex != m_nSize) + switch (m_aBuffer[m_nIndex++]) + { + case 0x0D: + m_bLf = true; + case 0x0A: + *pLine += rtl::OString(m_aBuffer + nStart, + m_nIndex - 1 - nStart); + //TODO! check for overflow, and not very efficient + return RESULT_OK; + } + + *pLine += rtl::OString(m_aBuffer + nStart, m_nIndex - nStart); + //TODO! check for overflow, and not very efficient + } +} + +class AsynchReader: public Thread +{ + size_t m_nDataSize; + boost::scoped_array<sal_Char> m_arData; + + bool m_bError; + bool m_bDone; + FileHandleGuard m_aGuard; + + void SAL_CALL run(); +public: + + AsynchReader(oslFileHandle & rHandle); +#if OSL_DEBUG_LEVEL >= 2 + /** only call this function after this thread has finished. + + That is, call join on this instance and then call getData. + + */ + OString getData(); +#endif +}; + +AsynchReader::AsynchReader(oslFileHandle & rHandle): + m_nDataSize(0), m_bError(false), m_bDone(false), m_aGuard(rHandle) +{ +} + +#if OSL_DEBUG_LEVEL >= 2 +OString AsynchReader::getData() +{ + OSL_ASSERT(isRunning() == sal_False ); + return OString(m_arData.get(), m_nDataSize); +} +#endif + +void AsynchReader::run() +{ + const sal_uInt64 BUFFER_SIZE = 4096; + sal_Char aBuffer[BUFFER_SIZE]; + while (true) + { + sal_uInt64 nRead; + //the function blocks until something could be read or the pipe closed. + switch (osl_readFile( + m_aGuard.getHandle(), aBuffer, BUFFER_SIZE, &nRead)) + { + case osl_File_E_PIPE: //HACK! for windows + nRead = 0; + case osl_File_E_None: + break; + default: + m_bError = true; + return; + } + + if (nRead == 0) + { + m_bDone = true; + break; + } + else if (nRead <= BUFFER_SIZE) + { + //Save the data we have in m_arData into a temporary array + boost::scoped_array<sal_Char> arTmp( new sal_Char[m_nDataSize]); + memcpy(arTmp.get(), m_arData.get(), m_nDataSize); + //Enlarge m_arData to hold the newly read data + m_arData.reset(new sal_Char[(size_t)(m_nDataSize + nRead)]); + //Copy back the data that was already in m_arData + memcpy(m_arData.get(), arTmp.get(), m_nDataSize); + //Add the newly read data to m_arData + memcpy(m_arData.get() + m_nDataSize, aBuffer, (size_t) nRead); + m_nDataSize += (size_t) nRead; + } + } +} + + +bool getJavaProps(const OUString & exePath, +#ifdef JVM_ONE_PATH_CHECK + const OUString & homePath, +#endif + std::vector<std::pair<rtl::OUString, rtl::OUString> >& props, + bool * bProcessRun) +{ + bool ret = false; + + OSL_ASSERT( exePath.getLength() > 0); + OUString usStartDir; + //We need to set the CLASSPATH in case the office is started from + //a different directory. The JREProperties.class is expected to reside + //next to the plugin. + rtl::OUString sThisLib; + if (osl_getModuleURLFromAddress((void *) (sal_IntPtr)& getJavaProps, + & sThisLib.pData) == sal_False) + return false; + sThisLib = getDirFromFile(sThisLib); + OUString sClassPath; + if (osl_getSystemPathFromFileURL(sThisLib.pData, & sClassPath.pData) + != osl_File_E_None) + return false; + + //check if we shall examine a Java for accessibility support + //If the bootstrap variable is "1" then we pass the argument + //"noaccessibility" to JREProperties.class. This will prevent + //that it calls java.awt.Toolkit.getDefaultToolkit(); + OUString sValue; + getBootstrap()->getFrom(OUSTR("JFW_PLUGIN_DO_NOT_CHECK_ACCESSIBILITY"), sValue); + + //prepare the arguments + sal_Int32 cArgs = 3; + OUString arg1 = OUString(RTL_CONSTASCII_USTRINGPARAM("-classpath"));// + sClassPath; + OUString arg2 = sClassPath; + OUString arg3(RTL_CONSTASCII_USTRINGPARAM("JREProperties")); + OUString arg4 = OUSTR("noaccessibility"); + rtl_uString *args[4] = {arg1.pData, arg2.pData, arg3.pData}; + + // Only add the fourth param if the bootstrap parameter is set. + if (sValue.equals(OUString::valueOf((sal_Int32) 1))) + { + args[3] = arg4.pData; + cArgs = 4; + } + + oslProcess javaProcess= 0; + oslFileHandle fileOut= 0; + oslFileHandle fileErr= 0; + + FileHandleReader stdoutReader(fileOut); + AsynchReader stderrReader(fileErr); + + JFW_TRACE2(OUSTR("\n[Java framework] Executing: ") + exePath + OUSTR(".\n")); + oslProcessError procErr = + osl_executeProcess_WithRedirectedIO( exePath.pData,//usExe.pData, + args, + cArgs, //sal_uInt32 nArguments, + osl_Process_HIDDEN, //oslProcessOption Options, + NULL, //oslSecurity Security, + usStartDir.pData,//usStartDir.pData,//usWorkDir.pData, //rtl_uString *strWorkDir, + NULL, //rtl_uString *strEnvironment[], + 0, // sal_uInt32 nEnvironmentVars, + &javaProcess, //oslProcess *pProcess, + NULL,//oslFileHandle *pChildInputWrite, + &fileOut,//oslFileHandle *pChildOutputRead, + &fileErr);//oslFileHandle *pChildErrorRead); + + if( procErr != osl_Process_E_None) + { + JFW_TRACE2("[Java framework] Execution failed. \n"); + *bProcessRun = false; + return ret; + } + else + { + JFW_TRACE2("[Java framework] Java executed successfully.\n"); + *bProcessRun = true; + } + + //Start asynchronous reading (different thread) of error stream + stderrReader.create(); + + //Use this thread to read output stream + FileHandleReader::Result rs = FileHandleReader::RESULT_OK; + while (1) + { + OString aLine; + rs = stdoutReader.readLine( & aLine); + if (rs != FileHandleReader::RESULT_OK) + break; + OUString sLine; + if (!decodeOutput(aLine, &sLine)) + continue; + JFW_TRACE2(OString("[Java framework]:\" ") + + OString( CHAR_POINTER(sLine)) + OString(" \".\n")); + sLine = sLine.trim(); + if (sLine.getLength() == 0) + continue; + //The JREProperties class writes key value pairs, separated by '=' + sal_Int32 index = sLine.indexOf('=', 0); + OSL_ASSERT(index != -1); + OUString sKey = sLine.copy(0, index); + OUString sVal = sLine.copy(index + 1); + +#ifdef JVM_ONE_PATH_CHECK + //replace absolute path by linux distro link + OUString sHomeProperty(RTL_CONSTASCII_USTRINGPARAM("java.home")); + if(sHomeProperty.equals(sKey)) + { + sVal = homePath + OUString::createFromAscii("/jre"); + } +#endif + + props.push_back(std::make_pair(sKey, sVal)); + } + + if (rs != FileHandleReader::RESULT_ERROR && !props.empty()) + ret = true; + + //process error stream data + stderrReader.join(); + JFW_TRACE2(OString("[Java framework] Java wrote to stderr:\" ") + + stderrReader.getData() + OString(" \".\n")); + + TimeValue waitMax= {5 ,0}; + procErr = osl_joinProcessWithTimeout(javaProcess, &waitMax); + OSL_ASSERT(procErr == osl_Process_E_None); + osl_freeProcessHandle(javaProcess); + return ret; +} + +/* converts the properties printed by JREProperties.class into + readable strings. The strings are encoded as integer values separated + by spaces. + */ +bool decodeOutput(const rtl::OString& s, rtl::OUString* out) +{ + OSL_ASSERT(out != 0); + OUStringBuffer buff(512); + sal_Int32 nIndex = 0; + do + { + OString aToken = s.getToken( 0, ' ', nIndex ); + if (aToken.getLength()) + { + for (sal_Int32 i = 0; i < aToken.getLength(); ++i) + { + if (aToken[i] < '0' || aToken[i] > '9') + return false; + } + sal_Unicode value = (sal_Unicode)(aToken.toInt32()); + buff.append(value); + } + } while (nIndex >= 0); + + *out = buff.makeStringAndClear(); + return true; +} + + +#if defined WNT +void createJavaInfoFromWinReg(std::vector<rtl::Reference<VendorBase> > & vecInfos) +{ + // Get Java s from registry + std::vector<OUString> vecJavaHome; + if(getSDKInfoFromRegistry(vecJavaHome)) + { + // create impl objects + typedef std::vector<OUString>::iterator ItHome; + for(ItHome it_home= vecJavaHome.begin(); it_home != vecJavaHome.end(); + it_home++) + { + getJREInfoByPath(*it_home, vecInfos); + } + } + + vecJavaHome.clear(); + if(getJREInfoFromRegistry(vecJavaHome)) + { + typedef std::vector<OUString>::iterator ItHome; + for(ItHome it_home= vecJavaHome.begin(); it_home != vecJavaHome.end(); + it_home++) + { + getJREInfoByPath(*it_home, vecInfos); + } + } +} + + +bool getJavaInfoFromRegistry(const wchar_t* szRegKey, + vector<OUString>& vecJavaHome) +{ + HKEY hRoot; + if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, szRegKey, 0, KEY_ENUMERATE_SUB_KEYS, &hRoot) + == ERROR_SUCCESS) + { + DWORD dwIndex = 0; + const DWORD BUFFSIZE = 1024; + wchar_t bufVersion[BUFFSIZE]; + DWORD nNameLen = BUFFSIZE; + FILETIME fileTime; + nNameLen = sizeof(bufVersion); + + // Iterate over all subkeys of HKEY_LOCAL_MACHINE\Software\JavaSoft\Java Runtime Environment + while (RegEnumKeyExW(hRoot, dwIndex, bufVersion, &nNameLen, NULL, NULL, NULL, &fileTime) != ERROR_NO_MORE_ITEMS) + { + HKEY hKey; + // Open a Java Runtime Environment sub key, e.g. "1.4.0" + if (RegOpenKeyExW(hRoot, bufVersion, 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS) + { + DWORD dwType; + DWORD dwTmpPathLen= 0; + // Get the path to the JavaHome every JRE entry + // Find out how long the string for JavaHome is and allocate memory to hold the path + if( RegQueryValueExW(hKey, L"JavaHome", 0, &dwType, NULL, &dwTmpPathLen)== ERROR_SUCCESS) + { + char* szTmpPath= (char *) malloc( dwTmpPathLen); + // Get the path for the runtime lib + if(RegQueryValueExW(hKey, L"JavaHome", 0, &dwType, (unsigned char*) szTmpPath, &dwTmpPathLen) == ERROR_SUCCESS) + { + // There can be several version entries refering with the same JavaHome,e.g 1.4 and 1.4.1 + OUString usHome((sal_Unicode*) szTmpPath); + // check if there is already an entry with the same JavaHomeruntime lib + // if so, we use the one with the more accurate version + bool bAppend= true; + OUString usHomeUrl; + if (osl_getFileURLFromSystemPath(usHome.pData, & usHomeUrl.pData) == + osl_File_E_None) + { + //iterate over the vector with java home strings + typedef vector<OUString>::iterator ItHome; + for(ItHome itHome= vecJavaHome.begin(); + itHome != vecJavaHome.end(); itHome++) + { + if(usHomeUrl.equals(*itHome)) + { + bAppend= false; + break; + } + } + // Save the home dir + if(bAppend) + { + vecJavaHome.push_back(usHomeUrl); + } + } + } + free( szTmpPath); + RegCloseKey(hKey); + } + } + dwIndex ++; + nNameLen = BUFFSIZE; + } + RegCloseKey(hRoot); + } + return true; +} + + + +bool getSDKInfoFromRegistry(vector<OUString> & vecHome) +{ + return getJavaInfoFromRegistry(HKEY_SUN_SDK, vecHome); +} + +bool getJREInfoFromRegistry(vector<OUString>& vecJavaHome) +{ + return getJavaInfoFromRegistry(HKEY_SUN_JRE, vecJavaHome); +} + +#endif // WNT + +void bubbleSortVersion(vector<rtl::Reference<VendorBase> >& vec) +{ + if(vec.empty()) + return; + int size= vec.size() - 1; + int cIter= 0; + // sort for version + for(int i= 0; i < size; i++) + { + for(int j= size; j > 0 + cIter; j--) + { + rtl::Reference<VendorBase>& cur= vec.at(j); + rtl::Reference<VendorBase>& next= vec.at(j-1); + + int nCmp = 0; + // comparing invalid SunVersion s is possible, they will be less than a + // valid version + + //check if version of current is recognized, by comparing it with itself + try + { + cur->compareVersions(cur->getVersion()); + } + catch (MalformedVersionException &) + { + nCmp = -1; // current < next + } + //The version of cur is valid, now compare with the second version + if (nCmp == 0) + { + try + { + nCmp = cur->compareVersions(next->getVersion()); + } + catch (MalformedVersionException & ) + { + //The second version is invalid, therefor it is regardes less. + nCmp = 1; + } + } + if(nCmp == 1) // cur > next + { + rtl::Reference<VendorBase> less = next; + vec.at(j-1)= cur; + vec.at(j)= less; + } + } + ++cIter; + } +} + + +bool getJREInfoFromBinPath( + const rtl::OUString& path, vector<rtl::Reference<VendorBase> > & vecInfos) +{ + // file:///c:/jre/bin + //map: jre/bin/java.exe + bool ret = false; + vector<pair<OUString, OUString> > props; + + for ( sal_Int32 pos = 0; + gVendorMap[pos].sVendorName != NULL; ++pos ) + { + vector<OUString> vecPaths; + getJavaExePaths_func pFunc = gVendorMap[pos].getJavaFunc; + + int size = 0; + char const* const* arExePaths = (*pFunc)(&size); + vecPaths = getVectorFromCharArray(arExePaths, size); + + //make sure argument path does not end with '/' + OUString sBinPath = path; + if (path.lastIndexOf('/') == (path.getLength() - 1)) + sBinPath = path.copy(0, path.getLength() - 1); + + typedef vector<OUString>::const_iterator c_it; + for (c_it i = vecPaths.begin(); i != vecPaths.end(); ++i) + { + //the map contains e.g. jre/bin/java.exe + //get the directory where the executable is contained + OUString sHome; + sal_Int32 index = i->lastIndexOf('/'); + if (index == -1) + { + //map contained only : "java.exe, then the argument + //path is already the home directory + sHome = sBinPath; + } + else + { + // jre/bin/jre -> jre/bin + OUString sMapPath(i->getStr(), index); + index = sBinPath.lastIndexOf(sMapPath); + if (index != -1 + && (index + sMapPath.getLength() == sBinPath.getLength()) + && sBinPath[index - 1] == '/') + { + sHome = OUString(sBinPath.getStr(), index - 1); + } + } + if (sHome.getLength() > 0) + { + ret = getJREInfoByPath(sHome, vecInfos); + if (ret) + break; + } + } + if (ret) + break; + } + return ret; +} + +vector<Reference<VendorBase> > getAllJREInfos() +{ + vector<Reference<VendorBase> > vecInfos; + +#if defined WNT + // Get Javas from the registry + createJavaInfoFromWinReg(vecInfos); +#endif // WNT + +#ifndef JVM_ONE_PATH_CHECK + createJavaInfoFromJavaHome(vecInfos); + //this function should be called after createJavaInfoDirScan. + //Otherwise in SDKs Java may be started twice + createJavaInfoFromPath(vecInfos); +#endif + +#ifdef UNX + createJavaInfoDirScan(vecInfos); +#endif + + bubbleSortVersion(vecInfos); + return vecInfos; +} + + +vector<OUString> getVectorFromCharArray(char const * const * ar, int size) +{ + vector<OUString> vec; + for( int i = 0; i < size; i++) + { + OUString s(ar[i], strlen(ar[i]), RTL_TEXTENCODING_UTF8); + vec.push_back(s); + } + return vec; +} +bool getJREInfoByPath(const rtl::OUString& path, + std::vector<rtl::Reference<VendorBase> > & vecInfos) +{ + bool ret = false; + + rtl::Reference<VendorBase> aInfo = getJREInfoByPath(path); + if (aInfo.is()) + { + ret = true; + vector<rtl::Reference<VendorBase> >::const_iterator it_impl= std::find_if( + vecInfos.begin(),vecInfos.end(), InfoFindSame(aInfo->getHome())); + if(it_impl == vecInfos.end()) + { + vecInfos.push_back(aInfo); + } + } + return ret; +} + +/** Checks if the path is a directory. Links are resolved. + In case of an error the returned string has the length 0. + Otherwise the returned string is the "resolved" file URL. + */ +OUString resolveDirPath(const OUString & path) +{ + OUString ret; + salhelper::LinkResolver aResolver(osl_FileStatus_Mask_Type | + osl_FileStatus_Mask_FileURL); + if (aResolver.fetchFileStatus(path) == osl::FileBase::E_None) + { + //check if this is a directory + if (aResolver.m_aStatus.getFileType() == FileStatus::Directory) + { +#ifndef JVM_ONE_PATH_CHECK + ret = aResolver.m_aStatus.getFileURL(); +#else + ret = path; +#endif + } + } + return ret; +} +/** Checks if the path is a file. If it is a link to a file than + it is resolved. + */ +OUString resolveFilePath(const OUString & path) +{ + OUString ret; + salhelper::LinkResolver aResolver(osl_FileStatus_Mask_Type | + osl_FileStatus_Mask_FileURL); + if (aResolver.fetchFileStatus(path) == osl::FileBase::E_None) + { + //check if this is a file + if (aResolver.m_aStatus.getFileType() == FileStatus::Regular) + { +#ifndef JVM_ONE_PATH_CHECK + ret = aResolver.m_aStatus.getFileURL(); +#else + ret = path; +#endif + } + } + return ret; +} + +rtl::Reference<VendorBase> getJREInfoByPath( + const OUString& path) +{ + rtl::Reference<VendorBase> ret; + static vector<OUString> vecBadPaths; + + static map<OUString, rtl::Reference<VendorBase> > mapJREs; + typedef map<OUString, rtl::Reference<VendorBase> >::const_iterator MapIt; + typedef map<OUString, rtl::Reference<VendorBase> > MAPJRE; + OUString sFilePath; + typedef vector<OUString>::const_iterator cit_path; + vector<pair<OUString, OUString> > props; + + OUString sResolvedDir = resolveDirPath(path); + // If this path is invalid then there is no chance to find a JRE here + if (sResolvedDir.getLength() == 0) + return 0; + + //check if the directory path is good, that is a JRE was already recognized. + //Then we need not detect it again + //For example, a sun JKD contains <jdk>/bin/java and <jdk>/jre/bin/java. + //When <jdk>/bin/java has been found then we need not find <jdk>/jre/bin/java. + //Otherwise we would execute java two times for evers JDK found. + MapIt entry2 = find_if(mapJREs.begin(), mapJREs.end(), + SameOrSubDirJREMap(sResolvedDir)); + if (entry2 != mapJREs.end()) + { + JFW_TRACE2(OUSTR("[Java framework] sunjavaplugin"SAL_DLLEXTENSION ": ") + + OUSTR("JRE found again (detected before): ") + sResolvedDir + + OUSTR(".\n")); + return entry2->second; + } + + for ( sal_Int32 pos = 0; + gVendorMap[pos].sVendorName != NULL; ++pos ) + { + vector<OUString> vecPaths; + getJavaExePaths_func pFunc = gVendorMap[pos].getJavaFunc; + + int size = 0; + char const* const* arExePaths = (*pFunc)(&size); + vecPaths = getVectorFromCharArray(arExePaths, size); + + bool bBreak = false; + typedef vector<OUString>::const_iterator c_it; + for (c_it i = vecPaths.begin(); i != vecPaths.end(); ++i) + { + //if the path is a link, then resolve it + //check if the executable exists at all + + //path can be only "file:///". Then do not append a '/' + //sizeof counts the terminating 0 + OUString sFullPath; + if (path.getLength() == sizeof("file:///") - 1) + sFullPath = sResolvedDir + (*i); + else + sFullPath = sResolvedDir + + OUString(RTL_CONSTASCII_USTRINGPARAM("/")) + (*i); + + + sFilePath = resolveFilePath(sFullPath); + + if (sFilePath.getLength() == 0) + { + //The file path (to java exe) is not valid + cit_path ifull = find(vecBadPaths.begin(), vecBadPaths.end(), sFullPath); + if (ifull == vecBadPaths.end()) + vecBadPaths.push_back(sFullPath); + continue; + } + + cit_path ifile = find(vecBadPaths.begin(), vecBadPaths.end(), sFilePath); + if (ifile != vecBadPaths.end()) + continue; + + MapIt entry = mapJREs.find(sFilePath); + if (entry != mapJREs.end()) + { + JFW_TRACE2(OUSTR("[Java framework] sunjavaplugin"SAL_DLLEXTENSION ": ") + + OUSTR("JRE found again (detected before): ") + sFilePath + + OUSTR(".\n")); + + return entry->second; + } + + bool bProcessRun= false; + if (getJavaProps(sFilePath, +#ifdef JVM_ONE_PATH_CHECK + sResolvedDir, +#endif + props, & bProcessRun) == false) + { + //The java executable could not be run or the system properties + //could not be retrieved. We can assume that this java is corrupt. + vecBadPaths.push_back(sFilePath); + //If there was a java executable, that could be run but we did not get + //the system properties, then we also assume that the whole Java installation + //does not work. In a jdk there are two executables. One in jdk/bin and the other + //in jdk/jre/bin. We do not search any further, because we assume that if one java + //does not work then the other does not work as well. This saves us to run java + //again which is quite costly. + if (bProcessRun == true) + { + // 1.3.1 special treatment: jdk/bin/java and /jdk/jre/bin/java are links to + //a script, named .java_wrapper. The script starts jdk/bin/sparc/native_threads/java + //or jdk/jre/bin/sparc/native_threads/java. The script uses the name with which it was + //invoked to build the path to the executable. It we start the script directy as .java_wrapper + //then it tries to start a jdk/.../native_threads/.java_wrapper. Therefore the link, which + //is named java, must be used to start the script. + getJavaProps(sFullPath, +#ifdef JVM_ONE_PATH_CHECK + sResolvedDir, +#endif + props, & bProcessRun); + // Either we found a working 1.3.1 + //Or the java is broken. In both cases we stop searchin under this "root" directory + bBreak = true; + break; + } + //sFilePath is no working java executable. We continue with another possible + //path. + else + { + continue; + } + } + //sFilePath is a java and we could get the system properties. We proceed with this + //java. + else + { + bBreak = true; + break; + } + } + if (bBreak) + break; + } + + if (props.empty()) + return rtl::Reference<VendorBase>(); + + //find java.vendor property + typedef vector<pair<OUString, OUString> >::const_iterator c_ip; + OUString sVendor(RTL_CONSTASCII_USTRINGPARAM("java.vendor")); + OUString sVendorName; + + for (c_ip i = props.begin(); i != props.end(); ++i) + { + if (sVendor.equals(i->first)) + { + sVendorName = i->second; + break; + } + } + + if (sVendorName.getLength() > 0) + { + //find the creator func for the respective vendor name + for ( sal_Int32 c = 0; + gVendorMap[c].sVendorName != NULL; ++c ) + { + OUString sNameMap(gVendorMap[c].sVendorName, strlen(gVendorMap[c].sVendorName), + RTL_TEXTENCODING_ASCII_US); + if (sNameMap.equals(sVendorName)) + { + ret = createInstance(gVendorMap[c].createFunc, props); + break; + } + } + } + if (ret.is() == false) + vecBadPaths.push_back(sFilePath); + else + { + JFW_TRACE2(OUSTR("[Java framework] sunjavaplugin"SAL_DLLEXTENSION ": ") + + OUSTR("Found JRE: ") + sResolvedDir + + OUSTR(" \n at: ") + path + OUSTR(".\n")); + + mapJREs.insert(MAPJRE::value_type(sResolvedDir, ret)); + mapJREs.insert(MAPJRE::value_type(sFilePath, ret)); + } + + return ret; +} + +Reference<VendorBase> createInstance(createInstance_func pFunc, + vector<pair<OUString, OUString> > properties) +{ + + Reference<VendorBase> aBase = (*pFunc)(); + if (aBase.is()) + { + if (aBase->initialize(properties) == false) + aBase = 0; + } + return aBase; +} + +inline OUString getDirFromFile(const OUString& usFilePath) +{ + sal_Int32 index= usFilePath.lastIndexOf('/'); + return OUString(usFilePath.getStr(), index); +} + +void createJavaInfoFromPath(vector<rtl::Reference<VendorBase> >& vecInfos) +{ +// Get Java from PATH environment variable + static OUString sCurDir(RTL_CONSTASCII_USTRINGPARAM(".")); + static OUString sParentDir(RTL_CONSTASCII_USTRINGPARAM("..")); + char *szPath= getenv("PATH"); + if(szPath) + { + OUString usAllPath(szPath, strlen(szPath), osl_getThreadTextEncoding()); + sal_Int32 nIndex = 0; + do + { + OUString usToken = usAllPath.getToken( 0, SAL_PATHSEPARATOR, nIndex ); + OUString usTokenUrl; + if(File::getFileURLFromSystemPath(usToken, usTokenUrl) == File::E_None) + { + if(usTokenUrl.getLength()) + { + OUString usBin; + // "." + if(usTokenUrl.equals(sCurDir)) + { + OUString usWorkDirUrl; + if(osl_Process_E_None == osl_getProcessWorkingDir(&usWorkDirUrl.pData)) + usBin= usWorkDirUrl; + } + // ".." + else if(usTokenUrl.equals(sParentDir)) + { + OUString usWorkDir; + if(osl_Process_E_None == osl_getProcessWorkingDir(&usWorkDir.pData)) + usBin= getDirFromFile(usWorkDir); + } + else + { + usBin = usTokenUrl; + } + if(usBin.getLength()) + { + getJREInfoFromBinPath(usBin, vecInfos); + } + } + } + } + while ( nIndex >= 0 ); + } +} + +void createJavaInfoFromJavaHome(vector<rtl::Reference<VendorBase> >& vecInfos) +{ + // Get Java from JAVA_HOME environment + char *szJavaHome= getenv("JAVA_HOME"); + if(szJavaHome) + { + OUString sHome(szJavaHome,strlen(szJavaHome),osl_getThreadTextEncoding()); + OUString sHomeUrl; + if(File::getFileURLFromSystemPath(sHome, sHomeUrl) == File::E_None) + { + getJREInfoByPath(sHomeUrl, vecInfos); + } + } +} + +bool makeDriveLetterSame(OUString * fileURL) +{ + bool ret = false; + DirectoryItem item; + if (DirectoryItem::get(*fileURL, item) == File::E_None) + { + FileStatus status(osl_FileStatus_Mask_FileURL); + if (item.getFileStatus(status) == File::E_None) + { + *fileURL = status.getFileURL(); + ret = true; + } + } + return ret; +} + +#ifdef UNX +#ifdef SOLARIS + +void createJavaInfoDirScan(vector<rtl::Reference<VendorBase> >& vecInfos) +{ + JFW_TRACE2(OUSTR("\n[Java framework] Checking \"/usr/jdk/latest\"\n")); + getJREInfoByPath(OUSTR("file:////usr/jdk/latest"), vecInfos); +} + +#else +void createJavaInfoDirScan(vector<rtl::Reference<VendorBase> >& vecInfos) +{ + OUString excMessage = OUSTR("[Java framework] sunjavaplugin: " + "Error in function createJavaInfoDirScan in util.cxx."); + int cJavaNames= sizeof(g_arJavaNames) / sizeof(char*); + boost::scoped_array<OUString> sarJavaNames(new OUString[cJavaNames]); + OUString *arNames = sarJavaNames.get(); + for(int i= 0; i < cJavaNames; i++) + arNames[i] = OUString(g_arJavaNames[i], strlen(g_arJavaNames[i]), + RTL_TEXTENCODING_UTF8); + + int cSearchPaths= sizeof(g_arSearchPaths) / sizeof(char*); + boost::scoped_array<OUString> sarPathNames(new OUString[cSearchPaths]); + OUString *arPaths = sarPathNames.get(); + for(int c = 0; c < cSearchPaths; c++) + arPaths[c] = OUString(g_arSearchPaths[c], strlen(g_arSearchPaths[c]), + RTL_TEXTENCODING_UTF8); + + int cCollectDirs = sizeof(g_arCollectDirs) / sizeof(char*); + boost::scoped_array<OUString> sarCollectDirs(new OUString[cCollectDirs]); + OUString *arCollectDirs = sarCollectDirs.get(); + for(int d = 0; d < cCollectDirs; d++) + arCollectDirs[d] = OUString(g_arCollectDirs[d], strlen(g_arCollectDirs[d]), + RTL_TEXTENCODING_UTF8); + + + + OUString usFile(RTL_CONSTASCII_USTRINGPARAM("file:///")); + for( int ii = 0; ii < cSearchPaths; ii ++) + { + OUString usDir1(usFile + arPaths[ii]); + DirectoryItem item; + if(DirectoryItem::get(usDir1, item) == File::E_None) + { + for(int j= 0; j < cCollectDirs; j++) + { + OUString usDir2(usDir1 + arCollectDirs[j]); + // prevent that we scan the whole /usr, /usr/lib, etc directories + if (arCollectDirs[j] != OUString()) + { + //usr/java/xxx + //Examin every subdirectory + Directory aCollectionDir(usDir2); + + Directory::RC openErr = aCollectionDir.open(); + switch (openErr) + { + case File::E_None: + break; + case File::E_NOENT: + case File::E_NOTDIR: + continue; + case File::E_ACCES: + JFW_TRACE2(OUSTR("[Java framework] sunjavaplugin: " + "Could not read directory ") + usDir2 + + OUSTR(" because of missing access rights.")); + continue; + default: + JFW_TRACE2(OUSTR("[Java framework] sunjavaplugin: " + "Could not read directory ") + + usDir2 + OUSTR(". Osl file error: ") + + OUString::valueOf((sal_Int32) openErr)); + continue; + } + + DirectoryItem curIt; + File::RC errNext = File::E_None; + while( (errNext = aCollectionDir.getNextItem(curIt)) == File::E_None) + { + FileStatus aStatus(osl_FileStatus_Mask_FileURL); + File::RC errStatus = File::E_None; + if ((errStatus = curIt.getFileStatus(aStatus)) != File::E_None) + { + JFW_TRACE2(excMessage + OUSTR("getFileStatus failed with error ") + + OUString::valueOf((sal_Int32) errStatus)); + continue; + } + JFW_TRACE2(OUSTR("[Java framework] sunjavaplugin: " + "Checking if directory: ") + aStatus.getFileURL() + + OUSTR(" is a Java. \n")); + + getJREInfoByPath(aStatus.getFileURL(),vecInfos); + } + + JFW_ENSURE(errNext == File::E_None || errNext == File::E_NOENT, + OUSTR("[Java framework] sunjavaplugin: " + "Error while iterating over contens of ") + + usDir2 + OUSTR(". Osl file error: ") + + OUString::valueOf((sal_Int32) openErr)); + } + else + { + //usr/java + //When we look directly into a dir like /usr, /usr/lib, etc. then we only + //look for certain java directories, such as jre, jdk, etc. Whe do not want + //to examine the whole directory because of performance reasons. + DirectoryItem item2; + if(DirectoryItem::get(usDir2, item2) == File::E_None) + { + for( int k= 0; k < cJavaNames; k++) + { + // /usr/java/j2re1.4.0 + OUString usDir3(usDir2 + arNames[k]); + + DirectoryItem item3; + if(DirectoryItem::get(usDir3, item) == File::E_None) + { + //remove trailing '/' + sal_Int32 islash = usDir3.lastIndexOf('/'); + if (islash == usDir3.getLength() - 1 + && (islash + > RTL_CONSTASCII_LENGTH("file://"))) + usDir3 = usDir3.copy(0, islash); + getJREInfoByPath(usDir3,vecInfos); + } + } + } + } + } + } + } +} +#endif // ifdef SOLARIS +#endif // ifdef UNX +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/jvmfwk/plugins/sunmajor/pluginlib/util.hxx b/jvmfwk/plugins/sunmajor/pluginlib/util.hxx new file mode 100644 index 000000000000..891ad63a58bc --- /dev/null +++ b/jvmfwk/plugins/sunmajor/pluginlib/util.hxx @@ -0,0 +1,136 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_JFW_PLUGIN_UTIL_HXX +#define INCLUDED_JFW_PLUGIN_UTIL_HXX + +#include "rtl/ustring.hxx" +#include "rtl/bootstrap.hxx" +#include <vector> +#include "vendorbase.hxx" + +namespace jfw_plugin +{ + +class VendorBase; +std::vector<rtl::OUString> getVectorFromCharArray(char const * const * ar, int size); + +/* The function uses the relative paths, such as "bin/java.exe" as provided by + VendorBase::getJavaExePaths and the provided path to derive the the home directory. + The home directory is then used as argument to getJREInfoByPath. For example + usBinDir is file:///c:/j2sdk/jre/bin then file:///c:/j2sdk/jre would be derived. + */ +bool getJREInfoFromBinPath( + const rtl::OUString& path, std::vector<rtl::Reference<VendorBase> > & vecInfos); +inline rtl::OUString getDirFromFile(const rtl::OUString& usFilePath); +void createJavaInfoFromPath(std::vector<rtl::Reference<VendorBase> >& vecInfos); +void createJavaInfoFromJavaHome(std::vector<rtl::Reference<VendorBase> > &vecInfos); +void createJavaInfoDirScan(std::vector<rtl::Reference<VendorBase> >& vecInfos); +#ifdef WNT +void createJavaInfoFromWinReg(std::vector<rtl::Reference<VendorBase> >& vecInfos); +#endif + +bool makeDriveLetterSame(rtl::OUString * fileURL); + + +/* for std::find_if + Used to find a JavaInfo::Impl object in a std::vector<Impl*> which has a member usJavaHome + as the specified string in the constructor. +*/ +struct InfoFindSame +{ + rtl::OUString sJava; + InfoFindSame(const rtl::OUString& sJavaHome):sJava(sJavaHome){} + + bool operator () (const rtl::Reference<VendorBase> & aVendorInfo) + { + return aVendorInfo->getHome().equals(sJava) == sal_True ? true : false; + } +}; + +struct SameOrSubDirJREMap +{ + rtl::OUString s1; + SameOrSubDirJREMap(const rtl::OUString& s):s1(s){ + } + + bool operator () (const std::pair<const rtl::OUString, rtl::Reference<VendorBase> > & s2) + { + if (s1 == s2.first) + return true; + rtl::OUString sSub; + sSub = s2.first + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/")); + if (s1.match(sSub) == sal_True) + return true; + return false; + } +}; + + +/* Creates a VendorBase object if a JRE could be found at the specified path. + + This depends if there is a JRE at all and if it is from a vendor that + is supported by this plugin. + */ +rtl::Reference<VendorBase> getJREInfoByPath(const rtl::OUString& path); + +/* Creates a VendorBase object if a JRE could be found at the specified path. + + The difference to the other getJREInfoByPath is that this function checks + first if the path corresponds to one of the VendorBase::getHome path already + contained in vecInfo. Only if there is no such entry, then the other + getJREInfoByPath is called. Again the created VendorBase is compared to + those contained in vecInfos. If it it not in there then it's added. + + @return + true a VendorBase was created and added to the end of vecInfos. + false - no VendorBase has been created. Either the path did not represent a + supported JRE installation or there was already a VendorBase in vecInfos. + */ +bool getJREInfoByPath(const rtl::OUString& path, + std::vector<rtl::Reference<VendorBase> > & vecInfos); + +std::vector<rtl::Reference<VendorBase> > getAllJREInfos(); + +bool getJavaProps( + const rtl::OUString & exePath, +#ifdef JVM_ONE_PATH_CHECK + const rtl::OUString & homePath, +#endif + std::vector<std::pair<rtl::OUString, rtl::OUString> >& props, + bool * bProcessRun); + +void createJavaInfoFromWinReg(std::vector<rtl::Reference<VendorBase> > & vecInfos); + +void bubbleSortVersion(std::vector<rtl::Reference<VendorBase> >& vec); + +rtl::Bootstrap* getBootstrap(); +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/jvmfwk/plugins/sunmajor/pluginlib/vendorbase.cxx b/jvmfwk/plugins/sunmajor/pluginlib/vendorbase.cxx new file mode 100644 index 000000000000..fa7210854aa4 --- /dev/null +++ b/jvmfwk/plugins/sunmajor/pluginlib/vendorbase.cxx @@ -0,0 +1,285 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_jvmfwk.hxx" + +#include "osl/file.hxx" + +#include "vendorbase.hxx" +#include "util.hxx" +#include "sunjre.hxx" + +using namespace std; +using namespace osl; + +using ::rtl::OUString; + +namespace jfw_plugin +{ +rtl::Reference<VendorBase> createInstance(createInstance_func pFunc, + vector<pair<OUString, OUString> > properties); + + + + + + + +//############################################################################## + +MalformedVersionException::MalformedVersionException() +{} +MalformedVersionException::MalformedVersionException( + const MalformedVersionException & ) +{} +MalformedVersionException::~MalformedVersionException() +{} +MalformedVersionException & +MalformedVersionException::operator =( + const MalformedVersionException &) +{ + return *this; +} +//############################################################################## + + +VendorBase::VendorBase(): m_bAccessibility(false) +{ +} + +char const* const * VendorBase::getJavaExePaths(int* size) +{ + static char const * ar[] = { +#if defined(WNT) + "java.exe", + "bin/java.exe" +#elif UNX + "java", + "bin/java" +#endif + }; + *size = sizeof(ar) / sizeof(char*); + return ar; +} + + +rtl::Reference<VendorBase> VendorBase::createInstance() +{ + VendorBase *pBase = new VendorBase(); + return rtl::Reference<VendorBase>(pBase); +} + +bool VendorBase::initialize(vector<pair<OUString, OUString> > props) +{ + //get java.vendor, java.version, java.home, + //javax.accessibility.assistive_technologies from system properties + + OUString sVendor; + typedef vector<pair<OUString, OUString> >::const_iterator it_prop; + OUString sVendorProperty( + RTL_CONSTASCII_USTRINGPARAM("java.vendor")); + OUString sVersionProperty( + RTL_CONSTASCII_USTRINGPARAM("java.version")); + OUString sHomeProperty( + RTL_CONSTASCII_USTRINGPARAM("java.home")); + OUString sAccessProperty( + RTL_CONSTASCII_USTRINGPARAM("javax.accessibility.assistive_technologies")); + + bool bVersion = false; + bool bVendor = false; + bool bHome = false; + bool bAccess = false; + + typedef vector<pair<OUString, OUString> >::const_iterator it_prop; + for (it_prop i = props.begin(); i != props.end(); ++i) + { + if(! bVendor && sVendorProperty.equals(i->first)) + { + m_sVendor = i->second; + bVendor = true; + } + else if (!bVersion && sVersionProperty.equals(i->first)) + { + m_sVersion = i->second; + bVersion = true; + } + else if (!bHome && sHomeProperty.equals(i->first)) + { +#ifndef JVM_ONE_PATH_CHECK + OUString fileURL; + if (osl_getFileURLFromSystemPath(i->second.pData,& fileURL.pData) == + osl_File_E_None) + { + //make sure that the drive letter have all the same case + //otherwise file:///c:/jre and file:///C:/jre produce two + //different objects!!! + if (makeDriveLetterSame( & fileURL)) + { + m_sHome = fileURL; + bHome = true; + } + } +#else + m_sHome = i->second; + bHome = true; +#endif + } + else if (!bAccess && sAccessProperty.equals(i->first)) + { + if (i->second.getLength() > 0) + { + m_bAccessibility = true; + bAccess = true; + } + } + // the javax.accessibility.xxx property may not be set. Therefore we + //must search through all properties. + + } + if (!bVersion || !bVendor || !bHome) + return false; + + // init m_sRuntimeLibrary + OSL_ASSERT(m_sHome.getLength()); + //call virtual function to get the possible paths to the runtime library. + + int size = 0; + char const* const* arRtPaths = getRuntimePaths( & size); + vector<OUString> libpaths = getVectorFromCharArray(arRtPaths, size); + + bool bRt = false; + typedef vector<OUString>::const_iterator i_path; + for(i_path ip = libpaths.begin(); ip != libpaths.end(); ++ip) + { + //Construct an absolute path to the possible runtime + OUString usRt= m_sHome + *ip; + DirectoryItem item; + if(DirectoryItem::get(usRt, item) == File::E_None) + { + //found runtime lib + m_sRuntimeLibrary = usRt; + bRt = true; + break; + } + } + if (!bRt) + return false; + + // init m_sLD_LIBRARY_PATH + OSL_ASSERT(m_sHome.getLength()); + size = 0; + char const * const * arLDPaths = getLibraryPaths( & size); + vector<OUString> ld_paths = getVectorFromCharArray(arLDPaths, size); + + char arSep[]= {SAL_PATHSEPARATOR, 0}; + OUString sPathSep= OUString::createFromAscii(arSep); + bool bLdPath = true; + int c = 0; + for(i_path il = ld_paths.begin(); il != ld_paths.end(); ++il, ++c) + { + OUString usAbsUrl= m_sHome + *il; + // convert to system path + OUString usSysPath; + if(File::getSystemPathFromFileURL(usAbsUrl, usSysPath) == File::E_None) + { + + if(c > 0) + m_sLD_LIBRARY_PATH+= sPathSep; + m_sLD_LIBRARY_PATH+= usSysPath; + } + else + { + bLdPath = false; + break; + } + } + if (bLdPath == false) + return false; + + return true; +} + +char const* const* VendorBase::getRuntimePaths(int* /*size*/) +{ + return NULL; +} + +char const* const* VendorBase::getLibraryPaths(int* /*size*/) +{ + return NULL; +} + +const OUString & VendorBase::getVendor() const +{ + return m_sVendor; +} +const OUString & VendorBase::getVersion() const +{ + return m_sVersion; +} + +const OUString & VendorBase::getHome() const +{ + return m_sHome; +} + +const OUString & VendorBase::getLibraryPaths() const +{ + return m_sLD_LIBRARY_PATH; +} + +const OUString & VendorBase::getRuntimeLibrary() const +{ + return m_sRuntimeLibrary; +} +bool VendorBase::supportsAccessibility() const +{ + return m_bAccessibility; +} + +bool VendorBase::needsRestart() const +{ + if (getLibraryPaths().getLength() > 0) + return true; + return false; +} + +int VendorBase::compareVersions(const rtl::OUString& /*sSecond*/) const +{ + OSL_FAIL("[Java framework] VendorBase::compareVersions must be " + "overridden in derived class."); + return 0; +} + + + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/jvmfwk/plugins/sunmajor/pluginlib/vendorbase.hxx b/jvmfwk/plugins/sunmajor/pluginlib/vendorbase.hxx new file mode 100644 index 000000000000..37b12b9ab6c5 --- /dev/null +++ b/jvmfwk/plugins/sunmajor/pluginlib/vendorbase.hxx @@ -0,0 +1,188 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_JFW_PLUGIN_VENDORBASE_HXX +#define INCLUDED_JFW_PLUGIN_VENDORBASE_HXX + +#include "rtl/ustring.hxx" +#include "rtl/ref.hxx" +#include "osl/endian.h" +#include "salhelper/simplereferenceobject.hxx" +#include <vector> + +namespace jfw_plugin +{ + + +//Used by subclasses of VendorBase to build paths to Java runtime +#if defined(__sparcv9) +#define JFW_PLUGIN_ARCH "sparcv9" +#elif defined SPARC +#define JFW_PLUGIN_ARCH "sparc" +#elif defined X86_64 +#define JFW_PLUGIN_ARCH "amd64" +#elif defined INTEL +#define JFW_PLUGIN_ARCH "i386" +#elif defined POWERPC64 +#define JFW_PLUGIN_ARCH "ppc64" +#elif defined POWERPC +#define JFW_PLUGIN_ARCH "ppc" +#elif defined MIPS +#ifdef OSL_BIGENDIAN +# define JFW_PLUGIN_ARCH "mips" +#else +# define JFW_PLUGIN_ARCH "mips32" +#endif +#elif defined S390X +#define JFW_PLUGIN_ARCH "s390x" +#elif defined S390 +#define JFW_PLUGIN_ARCH "s390" +#elif defined ARM +#define JFW_PLUGIN_ARCH "arm" +#elif defined IA64 +#define JFW_PLUGIN_ARCH "ia64" +#elif defined M68K +#define JFW_PLUGIN_ARCH "m68k" +#elif defined HPPA +#define JFW_PLUGIN_ARCH "parisc" +#elif defined AXP +#define JFW_PLUGIN_ARCH "alpha" +#else // SPARC, INTEL, POWERPC, MIPS, ARM, IA64, M68K, HPPA, ALPHA +#error unknown plattform +#endif // SPARC, INTEL, POWERPC, MIPS, ARM, IA64, M68K, HPPA, ALPHA + + +class MalformedVersionException +{ +public: + MalformedVersionException(); + + MalformedVersionException(const MalformedVersionException &); + + virtual ~MalformedVersionException(); + + MalformedVersionException & operator =(const MalformedVersionException &); +}; + +class VendorBase: public salhelper::SimpleReferenceObject +{ +public: + VendorBase(); + /* returns relative paths to the java executable as + file URLs. + + For example "bin/java.exe". You need + to implement this function in a derived class, if + the paths differ. this implmentation provides for + Windows "bin/java.exe" and for Unix "bin/java". + The paths are relative file URLs. That is, they always + contain '/' even on windows. The paths are relative + to the installation directory of a JRE. + + + The signature of this function must correspond to + getJavaExePaths_func. + */ + static char const* const * getJavaExePaths(int* size); + + /* creates an instance of this class. MUST be overridden + in a derived class. + #################################################### + OVERRIDE in derived class + ################################################### + @param + Key - value pairs of the system properties of the JRE. + */ + static rtl::Reference<VendorBase> createInstance(); + + /* called automatically on the instance created by createInstance. + + @return + true - the object could completely initialize. + false - the object could not completly initialize. In this case + it will be discarded by the caller. + */ + virtual bool initialize( + std::vector<std::pair<rtl::OUString, rtl::OUString> > props); + + /* returns relative file URLs to the runtime library. + For example "/bin/client/jvm.dll" + */ + virtual char const* const* getRuntimePaths(int* size); + + virtual char const* const* getLibraryPaths(int* size); + + virtual const rtl::OUString & getVendor() const; + virtual const rtl::OUString & getVersion() const; + virtual const rtl::OUString & getHome() const; + virtual const rtl::OUString & getRuntimeLibrary() const; + virtual const rtl::OUString & getLibraryPaths() const; + virtual bool supportsAccessibility() const; + /* determines if prior to running java something has to be done, + like setting the LD_LIBRARY_PATH. This implementation checks + if an LD_LIBRARY_PATH (getLD_LIBRARY_PATH) needs to be set and + if so, needsRestart returns true. + */ + virtual bool needsRestart() const; + + /* compares versions of this vendor. MUST be overridden + in a derived class. + #################################################### + OVERRIDE in derived class + ################################################### + @return + 0 this.version == sSecond + 1 this.version > sSecond + -1 this.version < sSEcond + + @throw + MalformedVersionException if the version string was not recognized. + */ + virtual int compareVersions(const rtl::OUString& sSecond) const; + +protected: + + rtl::OUString m_sVendor; + rtl::OUString m_sVersion; + rtl::OUString m_sHome; + rtl::OUString m_sRuntimeLibrary; + rtl::OUString m_sLD_LIBRARY_PATH; + bool m_bAccessibility; + + + typedef rtl::Reference<VendorBase> (* createInstance_func) (); + friend rtl::Reference<VendorBase> createInstance( + createInstance_func pFunc, + std::vector<std::pair<rtl::OUString, rtl::OUString> > properties); +}; + +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/jvmfwk/plugins/sunmajor/pluginlib/vendorlist.cxx b/jvmfwk/plugins/sunmajor/pluginlib/vendorlist.cxx new file mode 100644 index 000000000000..f24b6ff166e4 --- /dev/null +++ b/jvmfwk/plugins/sunmajor/pluginlib/vendorlist.cxx @@ -0,0 +1,98 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_jvmfwk.hxx" + +#include "vendorlist.hxx" +#include "gnujre.hxx" +#include "sunjre.hxx" +#include "otherjre.hxx" +#include "osl/thread.h" +#include <stdio.h> + +using namespace com::sun::star::uno; + +using ::rtl::OUString; +using ::rtl::OUStringToOString; +using ::rtl::OStringToOUString; +using ::rtl::OString; + +namespace jfw_plugin +{ + +/* Note: The vendor strings must be UTF-8. For example, if + the string contains an a umlaut then it must be expressed + by "\xXX\xXX" + */ +BEGIN_VENDOR_MAP() + VENDOR_MAP_ENTRY("Sun Microsystems Inc.", SunInfo) + VENDOR_MAP_ENTRY("IBM Corporation", OtherInfo) + VENDOR_MAP_ENTRY("Blackdown Java-Linux Team", OtherInfo) + VENDOR_MAP_ENTRY("Apple Inc.", OtherInfo) + VENDOR_MAP_ENTRY("Apple Computer, Inc.", OtherInfo) + VENDOR_MAP_ENTRY("BEA Systems, Inc.", OtherInfo) + VENDOR_MAP_ENTRY("Free Software Foundation, Inc.", GnuInfo) + VENDOR_MAP_ENTRY("The FreeBSD Foundation", OtherInfo) +END_VENDOR_MAP() + + +Sequence<OUString> getVendorNames() +{ + const size_t count = sizeof(gVendorMap) / sizeof (VendorSupportMapEntry) - 1; + OUString arNames[count]; + for ( size_t pos = 0; pos < count; ++pos ) + { + OString sVendor(gVendorMap[pos].sVendorName); + arNames[pos] = OStringToOUString(sVendor, RTL_TEXTENCODING_UTF8); + } + return Sequence<OUString>(arNames, count); +} + +bool isVendorSupported(const rtl::OUString& sVendor) +{ + Sequence<OUString> seqNames = getVendorNames(); + const OUString * arNames = seqNames.getConstArray(); + sal_Int32 count = seqNames.getLength(); + + for (int i = 0; i < count; i++) + { + if (sVendor.equals(arNames[i])) + return true; + } +#if OSL_DEBUG_LEVEL >= 2 + OString sVendorName = OUStringToOString(sVendor, osl_getThreadTextEncoding()); + fprintf(stderr, "[Java frameworksunjavaplugin.so]sunjavaplugin does not support vendor: %s.\n", + sVendorName.getStr()); +#endif + return false; +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/jvmfwk/plugins/sunmajor/pluginlib/vendorlist.hxx b/jvmfwk/plugins/sunmajor/pluginlib/vendorlist.hxx new file mode 100644 index 000000000000..7edc5fa00735 --- /dev/null +++ b/jvmfwk/plugins/sunmajor/pluginlib/vendorlist.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. + * + ************************************************************************/ +#if !defined INCLUDED_JFW_PLUGIN_VENDORLIST_HXX +#define INCLUDED_JFW_PLUGIN_VENDORLIST_HXX + +#include "rtl/ref.hxx" +#include "vendorbase.hxx" +#include "com/sun/star/uno/Sequence.hxx" + +namespace jfw_plugin +{ + +typedef char const * const * (* getJavaExePaths_func)(int*); +typedef rtl::Reference<VendorBase> (* createInstance_func) (); + +struct VendorSupportMapEntry +{ + char const * sVendorName; + getJavaExePaths_func getJavaFunc; + createInstance_func createFunc; +}; + +#define BEGIN_VENDOR_MAP() \ +VendorSupportMapEntry gVendorMap[] ={ + +#define VENDOR_MAP_ENTRY(x,y) \ + {x, & y::getJavaExePaths, & y::createInstance}, + +#define END_VENDOR_MAP() \ + {NULL, NULL, NULL} }; + + +com::sun::star::uno::Sequence<rtl::OUString> getVendorNames(); + +/* Examines if the vendor supplied in parameter sVendor is part of the + list of supported vendors. That is the arry of VendorSupportMapEntry + is search for an respective entry. +*/ +bool isVendorSupported(const rtl::OUString & sVendor); +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/jvmfwk/prj/build.lst b/jvmfwk/prj/build.lst new file mode 100644 index 000000000000..1a8d67401648 --- /dev/null +++ b/jvmfwk/prj/build.lst @@ -0,0 +1,6 @@ +jvmf jvmfwk : cppu cppuhelper sal comphelper LIBXML2:libxml2 NULL +jvmf jvmfwk\inc nmake - all jvmf_inc NULL +jvmf jvmfwk\source nmake - all jvmf_framework jvmf_inc NULL +jvmf jvmfwk\plugins\sunmajor\pluginlib nmake - all jvmf_sunmajorlib jvmf_inc NULL +jvmf jvmfwk\plugins\sunmajor\javaenvsetup nmake - u jvmf_sunjavaldx jvmf_framework jvmf_inc NULL +jvmf jvmfwk\distributions\OpenOfficeorg nmake - all jvmf_openoffice jvmf_framework jvmf_inc NULL diff --git a/jvmfwk/prj/d.lst b/jvmfwk/prj/d.lst new file mode 100644 index 000000000000..09bc295ddb40 --- /dev/null +++ b/jvmfwk/prj/d.lst @@ -0,0 +1,22 @@ +mkdir: %_DEST%\inc\jvmfwk +..\inc\jvmfwk\framework.h %_DEST%\inc\jvmfwk\framework.h +..\inc\jvmfwk\vendorplugin.h %_DEST%\inc\jvmfwk\vendorplugin.h +..\%__SRC%\lib\ijvmfwk.lib %_DEST%\lib\ijvmfwk.lib +..\%__SRC%\lib\libjvmfwk.* %_DEST%\lib\* +..\%__SRC%\bin\jvmfwk*.dll %_DEST%\bin\* +..\%__SRC%\bin\sunjavap*.dll %_DEST%\bin\* +..\%__SRC%\lib\sunjavaplugin*.so %_DEST%\lib\* +..\%__SRC%\lib\sunjavaplugin*.dylib %_DEST%\lib\* +..\%__SRC%\class\JREProperties.class %_DEST%\bin\JREProperties.class +..\%__SRC%\class\JREProperties.class %_DEST%\lib\JREProperties.class +..\%__SRC%\bin\javaldx %_DEST%\bin\javaldx +..\source\javasettingsunopkginstall.xml %_DEST%\bin\javasettingsunopkginstall.xml +..\%__SRC%\bin\javavendors.xml %_DEST%\bin\javavendors.xml +..\%__SRC%\bin\javavendors.xml %_DEST%\lib\javavendors.xml +..\%__SRC%\bin\jvmfwk3rc %_DEST%\lib\jvmfwk3rc +..\%__SRC%\bin\jvmfwk3.ini %_DEST%\bin\jvmfwk3.ini +..\%__SRC%\bin\sunjavapluginrc %_DEST%\lib\sunjavapluginrc +..\%__SRC%\bin\sunjavaplugin.ini %_DEST%\bin\sunjavaplugin.ini + +linklib: libjvmfwk.*.* +linklib: libjvmfwk*.dylib.*.*.* diff --git a/jvmfwk/source/elements.cxx b/jvmfwk/source/elements.cxx new file mode 100644 index 000000000000..bb5cf62ba952 --- /dev/null +++ b/jvmfwk/source/elements.cxx @@ -0,0 +1,1294 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_jvmfwk.hxx" +#include "elements.hxx" +#include "osl/mutex.hxx" +#include "osl/file.hxx" +#include "osl/time.h" +#include "fwkutil.hxx" +#include "fwkbase.hxx" +#include "framework.hxx" +#include "libxmlutil.hxx" +#include "osl/thread.hxx" +#include <algorithm> +#include "libxml/parser.h" +#include "libxml/xpath.h" +#include "libxml/xpathInternals.h" +#include "rtl/bootstrap.hxx" +#include "boost/optional.hpp" +#include <string.h> + + +using namespace osl; +namespace jfw +{ + +rtl::OString getElement(::rtl::OString const & docPath, + xmlChar const * pathExpression, bool bThrowIfEmpty) +{ + //Prepare the xml document and context + OSL_ASSERT(docPath.getLength() > 0); + jfw::CXmlDocPtr doc(xmlParseFile(docPath.getStr())); + if (doc == NULL) + throw FrameworkException( + JFW_E_ERROR, + rtl::OString("[Java framework] Error in function getElement " + "(elements.cxx)")); + + jfw::CXPathContextPtr context(xmlXPathNewContext(doc)); + if (xmlXPathRegisterNs(context, (xmlChar*) "jf", + (xmlChar*) NS_JAVA_FRAMEWORK) == -1) + throw FrameworkException( + JFW_E_ERROR, + rtl::OString("[Java framework] Error in function getElement " + "(elements.cxx)")); + + CXPathObjectPtr pathObj; + pathObj = xmlXPathEvalExpression(pathExpression, context); + rtl::OString sValue; + if (xmlXPathNodeSetIsEmpty(pathObj->nodesetval)) + { + if (bThrowIfEmpty) + throw FrameworkException( + JFW_E_ERROR, + rtl::OString("[Java framework] Error in function getElement " + "(elements.cxx)")); + } + else + { + sValue = (sal_Char*) pathObj->nodesetval->nodeTab[0]->content; + } + return sValue; +} + +rtl::OString getElementUpdated() +{ + return getElement(jfw::getVendorSettingsPath(), + (xmlChar*)"/jf:javaSelection/jf:updated/text()", true); +} + +// Use only in INSTALL mode !!! +rtl::OString getElementModified() +{ + //The modified element is only written in INSTALL mode. + //That is NodeJava::m_layer = INSTALL + return getElement(jfw::getInstallSettingsPath(), + (xmlChar*)"/jf:java/jf:modified/text()", false); +} + + +void createSettingsStructure(xmlDoc * document, bool * bNeedsSave) +{ + rtl::OString sExcMsg("[Java framework] Error in function createSettingsStructure " + "(elements.cxx)."); + xmlNode * root = xmlDocGetRootElement(document); + if (root == NULL) + throw FrameworkException(JFW_E_ERROR, sExcMsg); + bool bFound = false; + xmlNode * cur = root->children; + while (cur != NULL) + { + if (xmlStrcmp(cur->name, (xmlChar*) "enabled") == 0) + { + bFound = true; + break; + } + cur = cur->next; + } + if (bFound) + { + bNeedsSave = false; + return; + } + //We will modify this document + *bNeedsSave = true; + // Now we create the child elements ------------------ + //Get xsi:nil namespace + xmlNs* nsXsi = xmlSearchNsByHref( + document, root,(xmlChar*) NS_SCHEMA_INSTANCE); + + //<enabled xsi:nil="true" + xmlNode * nodeEn = xmlNewTextChild( + root,NULL, (xmlChar*) "enabled", (xmlChar*) ""); + if (nodeEn == NULL) + throw FrameworkException(JFW_E_ERROR, sExcMsg); + xmlSetNsProp(nodeEn,nsXsi,(xmlChar*) "nil",(xmlChar*) "true"); + //add a new line + xmlNode * nodeCrLf = xmlNewText((xmlChar*) "\n"); + xmlAddChild(root, nodeCrLf); + + //<userClassPath xsi:nil="true"> + xmlNode * nodeUs = xmlNewTextChild( + root,NULL, (xmlChar*) "userClassPath", (xmlChar*) ""); + if (nodeUs == NULL) + throw FrameworkException(JFW_E_ERROR, sExcMsg); + xmlSetNsProp(nodeUs,nsXsi,(xmlChar*) "nil",(xmlChar*) "true"); + //add a new line + nodeCrLf = xmlNewText((xmlChar*) "\n"); + xmlAddChild(root, nodeCrLf); + + //<vmParameters xsi:nil="true"> + xmlNode * nodeVm = xmlNewTextChild( + root,NULL, (xmlChar*) "vmParameters", (xmlChar*) ""); + if (nodeVm == NULL) + throw FrameworkException(JFW_E_ERROR, sExcMsg); + xmlSetNsProp(nodeVm,nsXsi,(xmlChar*) "nil",(xmlChar*) "true"); + //add a new line + nodeCrLf = xmlNewText((xmlChar*) "\n"); + xmlAddChild(root, nodeCrLf); + + //<jreLocations xsi:nil="true"> + xmlNode * nodeJre = xmlNewTextChild( + root,NULL, (xmlChar*) "jreLocations", (xmlChar*) ""); + if (nodeJre == NULL) + throw FrameworkException(JFW_E_ERROR, sExcMsg); + xmlSetNsProp(nodeJre,nsXsi,(xmlChar*) "nil",(xmlChar*) "true"); + //add a new line + nodeCrLf = xmlNewText((xmlChar*) "\n"); + xmlAddChild(root, nodeCrLf); + + //<javaInfo xsi:nil="true"> + xmlNode * nodeJava = xmlNewTextChild( + root,NULL, (xmlChar*) "javaInfo", (xmlChar*) ""); + if (nodeJava == NULL) + throw FrameworkException(JFW_E_ERROR, sExcMsg); + xmlSetNsProp(nodeJava,nsXsi,(xmlChar*) "nil",(xmlChar*) "true"); + //add a new line + nodeCrLf = xmlNewText((xmlChar*) "\n"); + xmlAddChild(root, nodeCrLf); +} + + +//==================================================================== +VersionInfo::VersionInfo(): arVersions(NULL) +{ +} + +VersionInfo::~VersionInfo() +{ + delete [] arVersions; +} + +void VersionInfo::addExcludeVersion(const rtl::OUString& sVersion) +{ + vecExcludeVersions.push_back(sVersion); +} + +rtl_uString** VersionInfo::getExcludeVersions() +{ + osl::MutexGuard guard(FwkMutex::get()); + if (arVersions != NULL) + return arVersions; + + arVersions = new rtl_uString*[vecExcludeVersions.size()]; + int j=0; + typedef std::vector<rtl::OUString>::const_iterator it; + for (it i = vecExcludeVersions.begin(); i != vecExcludeVersions.end(); + ++i, ++j) + { + arVersions[j] = vecExcludeVersions[j].pData; + } + return arVersions; +} + +sal_Int32 VersionInfo::getExcludeVersionSize() +{ + return vecExcludeVersions.size(); +} +//================================================================== + +NodeJava::NodeJava(Layer layer): + m_layer(layer) +{ + //This class reads and write to files which should only be done in + //application mode + if (getMode() == JFW_MODE_DIRECT) + throw FrameworkException( + JFW_E_DIRECT_MODE, + "[Java framework] Trying to access settings files in direct mode."); + + if (USER_OR_INSTALL == m_layer) + { + if (BootParams::getInstallData().getLength() > 0) + m_layer = INSTALL; + else + m_layer = USER; + } + else + { + m_layer = layer; + } +} + + +void NodeJava::load() +{ + const rtl::OString sExcMsg("[Java framework] Error in function NodeJava::load" + "(elements.cxx)."); + if (SHARED == m_layer) + { + //we do not support yet to write into the shared installation + + //check if shared settings exist at all. + jfw::FileStatus s = checkFileURL(BootParams::getSharedData()); + if (s == FILE_INVALID) + throw FrameworkException( + JFW_E_ERROR, + "[Java framework] Invalid file for shared Java settings."); + else if (s == FILE_DOES_NOT_EXIST) + //Writing shared data is not supported yet. + return; + } + else if (USER == m_layer || INSTALL == m_layer) + { + prepareSettingsDocument(); + } + else + { + OSL_FAIL("[Java framework] Unknown enum used."); + } + + + //Read the user elements + rtl::OString sSettingsPath = getSettingsPath(); + //There must not be a share settings file + CXmlDocPtr docUser(xmlParseFile(sSettingsPath.getStr())); + if (docUser == NULL) + throw FrameworkException(JFW_E_ERROR, sExcMsg); + + xmlNode * cur = xmlDocGetRootElement(docUser); + if (cur == NULL || cur->children == NULL) + throw FrameworkException(JFW_E_ERROR, sExcMsg); + + CXmlCharPtr sNil; + cur = cur->children; + while (cur != NULL) + { + if (xmlStrcmp(cur->name, (xmlChar*) "enabled") == 0) + { + //only overwrite share settings if xsi:nil="false" + sNil = xmlGetNsProp( + cur, (xmlChar*) "nil", (xmlChar*) NS_SCHEMA_INSTANCE); + if (sNil == NULL) + throw FrameworkException(JFW_E_ERROR, sExcMsg);; + if (xmlStrcmp(sNil, (xmlChar*) "false") == 0) + { + CXmlCharPtr sEnabled( xmlNodeListGetString( + docUser, cur->children, 1)); + if (xmlStrcmp(sEnabled, (xmlChar*) "true") == 0) + m_enabled = boost::optional<sal_Bool>(sal_True); + else if (xmlStrcmp(sEnabled, (xmlChar*) "false") == 0) + m_enabled = boost::optional<sal_Bool>(sal_False); + } + } + else if (xmlStrcmp(cur->name, (xmlChar*) "userClassPath") == 0) + { + sNil = xmlGetNsProp( + cur, (xmlChar*) "nil", (xmlChar*) NS_SCHEMA_INSTANCE); + if (sNil == NULL) + throw FrameworkException(JFW_E_ERROR, sExcMsg); + if (xmlStrcmp(sNil, (xmlChar*) "false") == 0) + { + CXmlCharPtr sUser(xmlNodeListGetString( + docUser, cur->children, 1)); + m_userClassPath = boost::optional<rtl::OUString>(rtl::OUString(sUser)); + } + } + else if (xmlStrcmp(cur->name, (xmlChar*) "javaInfo") == 0) + { + sNil = xmlGetNsProp( + cur, (xmlChar*) "nil", (xmlChar*) NS_SCHEMA_INSTANCE); + if (sNil == NULL) + throw FrameworkException(JFW_E_ERROR, sExcMsg); + + if (xmlStrcmp(sNil, (xmlChar*) "false") == 0) + { + if (! m_javaInfo) + m_javaInfo = boost::optional<CNodeJavaInfo>(CNodeJavaInfo()); + m_javaInfo->loadFromNode(docUser, cur); + } + } + else if (xmlStrcmp(cur->name, (xmlChar*) "vmParameters") == 0) + { + sNil = xmlGetNsProp( + cur, (xmlChar*) "nil", (xmlChar*) NS_SCHEMA_INSTANCE); + if (sNil == NULL) + throw FrameworkException(JFW_E_ERROR, sExcMsg); + if (xmlStrcmp(sNil, (xmlChar*) "false") == 0) + { + if ( ! m_vmParameters) + m_vmParameters = boost::optional<std::vector<rtl::OUString> >( + std::vector<rtl::OUString> ()); + + xmlNode * pOpt = cur->children; + while (pOpt != NULL) + { + if (xmlStrcmp(pOpt->name, (xmlChar*) "param") == 0) + { + CXmlCharPtr sOpt; + sOpt = xmlNodeListGetString( + docUser, pOpt->children, 1); + m_vmParameters->push_back(sOpt); + } + pOpt = pOpt->next; + } + } + } + else if (xmlStrcmp(cur->name, (xmlChar*) "jreLocations") == 0) + { + sNil = xmlGetNsProp( + cur, (xmlChar*) "nil", (xmlChar*) NS_SCHEMA_INSTANCE); + if (sNil == NULL) + throw FrameworkException(JFW_E_ERROR, sExcMsg); + if (xmlStrcmp(sNil, (xmlChar*) "false") == 0) + { + if (! m_JRELocations) + m_JRELocations = boost::optional<std::vector<rtl::OUString> >( + std::vector<rtl::OUString>()); + + xmlNode * pLoc = cur->children; + while (pLoc != NULL) + { + if (xmlStrcmp(pLoc->name, (xmlChar*) "location") == 0) + { + CXmlCharPtr sLoc; + sLoc = xmlNodeListGetString( + docUser, pLoc->children, 1); + m_JRELocations->push_back(sLoc); + } + pLoc = pLoc->next; + } + } + } + cur = cur->next; + } +} + +::rtl::OString NodeJava::getSettingsPath() const +{ + ::rtl::OString ret; + switch (m_layer) + { + case USER: ret = getUserSettingsPath(); break; + case INSTALL: ret = getInstallSettingsPath(); break; + case SHARED: ret = getSharedSettingsPath(); break; + default: + OSL_FAIL("[Java framework] NodeJava::getSettingsPath()"); + } + return ret; +} + +::rtl::OUString NodeJava::getSettingsURL() const +{ + ::rtl::OUString ret; + switch (m_layer) + { + case USER: ret = BootParams::getUserData(); break; + case INSTALL: ret = BootParams::getInstallData(); break; + case SHARED: ret = BootParams::getSharedData(); break; + default: + OSL_FAIL("[Java framework] NodeJava::getSettingsURL()"); + } + return ret; +} + +void NodeJava::prepareSettingsDocument() const +{ + rtl::OString sExcMsg( + "[Java framework] Error in function prepareSettingsDocument" + " (elements.cxx)."); + createSettingsDocument(); + rtl::OString sSettings = getSettingsPath(); + CXmlDocPtr doc(xmlParseFile(sSettings.getStr())); + if (!doc) + throw FrameworkException(JFW_E_ERROR, sExcMsg); + + bool bNeedsSave = false; + createSettingsStructure(doc, & bNeedsSave); + if (bNeedsSave) + { + if (xmlSaveFormatFileEnc( + sSettings.getStr(), doc,"UTF-8", 1) == -1) + throw FrameworkException(JFW_E_ERROR, sExcMsg); + } +} + +void NodeJava::write() const +{ + rtl::OString sExcMsg("[Java framework] Error in function NodeJava::writeSettings " + "(elements.cxx)."); + CXmlDocPtr docUser; + CXPathContextPtr contextUser; + CXPathObjectPtr pathObj; + + prepareSettingsDocument(); + + //Read the user elements + rtl::OString sSettingsPath = getSettingsPath(); + docUser = xmlParseFile(sSettingsPath.getStr()); + if (docUser == NULL) + throw FrameworkException(JFW_E_ERROR, sExcMsg); + contextUser = xmlXPathNewContext(docUser); + if (xmlXPathRegisterNs(contextUser, (xmlChar*) "jf", + (xmlChar*) NS_JAVA_FRAMEWORK) == -1) + throw FrameworkException(JFW_E_ERROR, sExcMsg); + + xmlNode * root = xmlDocGetRootElement(docUser); + //Get xsi:nil namespace + xmlNs* nsXsi = xmlSearchNsByHref(docUser, + root, + (xmlChar*) NS_SCHEMA_INSTANCE); + + //set the <enabled> element + //The element must exist + if (m_enabled) + { + rtl::OString sExpression= rtl::OString( + "/jf:java/jf:enabled"); + pathObj = xmlXPathEvalExpression((xmlChar*) sExpression.getStr(), + contextUser); + if ( ! pathObj || xmlXPathNodeSetIsEmpty(pathObj->nodesetval)) + throw FrameworkException(JFW_E_ERROR, sExcMsg); + + xmlNode * nodeEnabled = pathObj->nodesetval->nodeTab[0]; + xmlSetNsProp(nodeEnabled, + nsXsi, + (xmlChar*) "nil", + (xmlChar*) "false"); + + if (m_enabled == boost::optional<sal_Bool>(sal_True)) + xmlNodeSetContent(nodeEnabled,(xmlChar*) "true"); + else + xmlNodeSetContent(nodeEnabled,(xmlChar*) "false"); + } + + //set the <userClassPath> element + //The element must exist + if (m_userClassPath) + { + rtl::OString sExpression= rtl::OString( + "/jf:java/jf:userClassPath"); + pathObj = xmlXPathEvalExpression((xmlChar*) sExpression.getStr(), + contextUser); + if ( ! pathObj || xmlXPathNodeSetIsEmpty(pathObj->nodesetval)) + throw FrameworkException(JFW_E_ERROR, sExcMsg); + + xmlNode * nodeEnabled = pathObj->nodesetval->nodeTab[0]; + xmlSetNsProp(nodeEnabled, nsXsi, (xmlChar*) "nil",(xmlChar*) "false"); + xmlNodeSetContent(nodeEnabled,(xmlChar*) CXmlCharPtr(*m_userClassPath)); + } + + //set <javaInfo> element + if (m_javaInfo) + { + rtl::OString sExpression= rtl::OString( + "/jf:java/jf:javaInfo"); + pathObj = xmlXPathEvalExpression((xmlChar*) sExpression.getStr(), + contextUser); + if ( ! pathObj || xmlXPathNodeSetIsEmpty(pathObj->nodesetval)) + throw FrameworkException(JFW_E_ERROR, sExcMsg); + m_javaInfo->writeToNode( + docUser, pathObj->nodesetval->nodeTab[0]); + } + + //set <vmParameters> element + if (m_vmParameters) + { + rtl::OString sExpression= rtl::OString( + "/jf:java/jf:vmParameters"); + pathObj = xmlXPathEvalExpression((xmlChar*) sExpression.getStr(), + contextUser); + if ( ! pathObj || xmlXPathNodeSetIsEmpty(pathObj->nodesetval)) + throw FrameworkException(JFW_E_ERROR, sExcMsg); + xmlNode* vmParameters = pathObj->nodesetval->nodeTab[0]; + //set xsi:nil = false; + xmlSetNsProp(vmParameters, nsXsi,(xmlChar*) "nil", + (xmlChar*) "false"); + + //remove option elements + xmlNode* cur = vmParameters->children; + while (cur != NULL) + { + xmlNode* lastNode = cur; + cur = cur->next; + xmlUnlinkNode(lastNode); + xmlFreeNode(lastNode); + } + //add a new line after <vmParameters> + if (m_vmParameters->size() > 0) + { + xmlNode * nodeCrLf = xmlNewText((xmlChar*) "\n"); + xmlAddChild(vmParameters, nodeCrLf); + } + + typedef std::vector<rtl::OUString>::const_iterator cit; + for (cit i = m_vmParameters->begin(); i != m_vmParameters->end(); ++i) + { + xmlNewTextChild(vmParameters, NULL, (xmlChar*) "param", + CXmlCharPtr(*i)); + //add a new line + xmlNode * nodeCrLf = xmlNewText((xmlChar*) "\n"); + xmlAddChild(vmParameters, nodeCrLf); + } + } + + //set <jreLocations> element + if (m_JRELocations) + { + rtl::OString sExpression= rtl::OString( + "/jf:java/jf:jreLocations"); + pathObj = xmlXPathEvalExpression((xmlChar*) sExpression.getStr(), + contextUser); + if ( ! pathObj || xmlXPathNodeSetIsEmpty(pathObj->nodesetval)) + throw FrameworkException(JFW_E_ERROR, sExcMsg); + xmlNode* jreLocationsNode = pathObj->nodesetval->nodeTab[0]; + //set xsi:nil = false; + xmlSetNsProp(jreLocationsNode, nsXsi,(xmlChar*) "nil", + (xmlChar*) "false"); + + //remove option elements + xmlNode* cur = jreLocationsNode->children; + while (cur != NULL) + { + xmlNode* lastNode = cur; + cur = cur->next; + xmlUnlinkNode(lastNode); + xmlFreeNode(lastNode); + } + //add a new line after <vmParameters> + if (m_JRELocations->size() > 0) + { + xmlNode * nodeCrLf = xmlNewText((xmlChar*) "\n"); + xmlAddChild(jreLocationsNode, nodeCrLf); + } + + typedef std::vector<rtl::OUString>::const_iterator cit; + for (cit i = m_JRELocations->begin(); i != m_JRELocations->end(); ++i) + { + xmlNewTextChild(jreLocationsNode, NULL, (xmlChar*) "location", + CXmlCharPtr(*i)); + //add a new line + xmlNode * nodeCrLf = xmlNewText((xmlChar*) "\n"); + xmlAddChild(jreLocationsNode, nodeCrLf); + } + } + + if (INSTALL == m_layer) + { + //now write the current system time + ::TimeValue curTime = {0,0}; + if (::osl_getSystemTime(& curTime)) + { + rtl::OUString sSeconds = + rtl::OUString::valueOf((sal_Int64) curTime.Seconds); + xmlNewTextChild( + root,NULL, (xmlChar*) "modified", CXmlCharPtr(sSeconds)); + xmlNode * nodeCrLf = xmlNewText((xmlChar*) "\n"); + xmlAddChild(root, nodeCrLf); + } + } + if (xmlSaveFormatFile(sSettingsPath.getStr(), docUser, 1) == -1) + throw FrameworkException(JFW_E_ERROR, sExcMsg); +} + +void NodeJava::setEnabled(sal_Bool bEnabled) +{ + m_enabled = boost::optional<sal_Bool>(bEnabled); +} + + +void NodeJava::setUserClassPath(const rtl::OUString & sClassPath) +{ + m_userClassPath = boost::optional<rtl::OUString>(sClassPath); +} + +void NodeJava::setJavaInfo(const JavaInfo * pInfo, bool bAutoSelect) +{ + if (!m_javaInfo) + m_javaInfo = boost::optional<CNodeJavaInfo>(CNodeJavaInfo()); + m_javaInfo->bAutoSelect = bAutoSelect; + m_javaInfo->bNil = false; + + if (pInfo != NULL) + { + m_javaInfo->m_bEmptyNode = false; + m_javaInfo->sVendor = pInfo->sVendor; + m_javaInfo->sLocation = pInfo->sLocation; + m_javaInfo->sVersion = pInfo->sVersion; + m_javaInfo->nFeatures = pInfo->nFeatures; + m_javaInfo->nRequirements = pInfo->nRequirements; + m_javaInfo->arVendorData = pInfo->arVendorData; + } + else + { + m_javaInfo->m_bEmptyNode = true; + rtl::OUString sEmpty; + m_javaInfo->sVendor = sEmpty; + m_javaInfo->sLocation = sEmpty; + m_javaInfo->sVersion = sEmpty; + m_javaInfo->nFeatures = 0; + m_javaInfo->nRequirements = 0; + m_javaInfo->arVendorData = rtl::ByteSequence(); + } +} + +void NodeJava::setVmParameters(rtl_uString * * arOptions, sal_Int32 size) +{ + OSL_ASSERT( !(arOptions == 0 && size != 0)); + if ( ! m_vmParameters) + m_vmParameters = boost::optional<std::vector<rtl::OUString> >( + std::vector<rtl::OUString>()); + m_vmParameters->clear(); + if (arOptions != NULL) + { + for (int i = 0; i < size; i++) + { + const rtl::OUString sOption(static_cast<rtl_uString*>(arOptions[i])); + m_vmParameters->push_back(sOption); + } + } +} + +void NodeJava::setJRELocations(rtl_uString * * arLocations, sal_Int32 size) +{ + OSL_ASSERT( !(arLocations == 0 && size != 0)); + if (! m_JRELocations) + m_JRELocations = boost::optional<std::vector<rtl::OUString> > ( + std::vector<rtl::OUString>()); + m_JRELocations->clear(); + if (arLocations != NULL) + { + for (int i = 0; i < size; i++) + { + const rtl::OUString & sLocation = static_cast<rtl_uString*>(arLocations[i]); + + //only add the path if not already present + std::vector<rtl::OUString>::const_iterator it = + std::find(m_JRELocations->begin(), m_JRELocations->end(), + sLocation); + if (it == m_JRELocations->end()) + m_JRELocations->push_back(sLocation); + } + } +} + +void NodeJava::addJRELocation(rtl_uString * sLocation) +{ + OSL_ASSERT( sLocation); + if (!m_JRELocations) + m_JRELocations = boost::optional<std::vector<rtl::OUString> >( + std::vector<rtl::OUString> ()); + //only add the path if not already present + std::vector<rtl::OUString>::const_iterator it = + std::find(m_JRELocations->begin(), m_JRELocations->end(), + rtl::OUString(sLocation)); + if (it == m_JRELocations->end()) + m_JRELocations->push_back(rtl::OUString(sLocation)); +} + +const boost::optional<sal_Bool> & NodeJava::getEnabled() const +{ + return m_enabled; +} + +const boost::optional<std::vector<rtl::OUString> >& +NodeJava::getJRELocations() const +{ + return m_JRELocations; +} + +const boost::optional<rtl::OUString> & NodeJava::getUserClassPath() const +{ + return m_userClassPath; +} + +const boost::optional<std::vector<rtl::OUString> > & NodeJava::getVmParameters() const +{ + return m_vmParameters; +} + +const boost::optional<CNodeJavaInfo> & NodeJava::getJavaInfo() const +{ + return m_javaInfo; +} + +jfw::FileStatus NodeJava::checkSettingsFileStatus() const +{ + jfw::FileStatus ret = FILE_DOES_NOT_EXIST; + + const rtl::OUString sURL = getSettingsURL(); + //check the file time + ::osl::DirectoryItem item; + File::RC rc = ::osl::DirectoryItem::get(sURL, item); + if (File::E_None == rc) + { + ::osl::FileStatus stat( + osl_FileStatus_Mask_Validate + | osl_FileStatus_Mask_CreationTime + | osl_FileStatus_Mask_ModifyTime); + File::RC rc_stat = item.getFileStatus(stat); + if (File::E_None == rc_stat) + { + // This + //function may be called multiple times when a java is started. + //If the expiretime is too small then we may loop because everytime + //the file is deleted and we need to search for a java again. + if (INSTALL == m_layer) + { + //file exists. Check if it is too old + //Do not use the creation time. On Windows 2003 server I noticed + //that after removing the file and shortly later creating it again + //did not change the creation time. That is the newly created file + //had the creation time of the former file. + ::TimeValue curTime = {0,0}; + ret = FILE_OK; + if (sal_True == ::osl_getSystemTime(& curTime)) + { + //get the modified time recorded in the <modified> element + sal_uInt32 modified = getModifiedTime(); + OSL_ASSERT(modified <= curTime.Seconds); + //Only if modified has a valued then NodeJava::write was called, + //then the xml structure was filled with data. + + if ( modified && curTime.Seconds - modified > + BootParams::getInstallDataExpiration()) + { +#if OSL_DEBUG_LEVEL >=2 + fprintf(stderr, "[Java framework] Settings file is %d seconds old. \n", + (int)( curTime.Seconds - modified)); + rtl::OString s = rtl::OUStringToOString(sURL, osl_getThreadTextEncoding()); + fprintf(stderr, "[Java framework] Settings file is exspired. Deleting settings file at \n%s\n", s.getStr()); +#endif + //delete file + File f(sURL); + if (File::E_None == f.open(osl_File_OpenFlag_Write | osl_File_OpenFlag_Read) + && File::E_None == f.setPos(0, 0) + && File::E_None == f.setSize(0)) + ret = FILE_DOES_NOT_EXIST; + else + ret = FILE_INVALID; + } + else + { + ret = FILE_OK; + } + } + else // osl_getSystemTime + { + ret = FILE_INVALID; + } + } + else // INSTALL == m_layer + { + ret = FILE_OK; + } + } + else if (File::E_NOENT == rc_stat) + { + ret = FILE_DOES_NOT_EXIST; + } + else + { + ret = FILE_INVALID; + } + } + else if(File::E_NOENT == rc) + { + ret = FILE_DOES_NOT_EXIST; + } + else + { + ret = FILE_INVALID; + } + return ret; +} + +void NodeJava::createSettingsDocument() const +{ + const rtl::OUString sURL = getSettingsURL(); + //make sure there is a user directory + rtl::OString sExcMsg("[Java framework] Error in function createSettingsDocument " + "(elements.cxx)."); + // check if javasettings.xml already exist + if (FILE_OK == checkSettingsFileStatus()) + return; + + //make sure that the directories are created in case they do not exist + FileBase::RC rcFile = Directory::createPath(getDirFromFile(sURL)); + if (rcFile != FileBase::E_EXIST && rcFile != FileBase::E_None) + throw FrameworkException(JFW_E_ERROR, sExcMsg); + + //javasettings.xml does not exist yet + CXmlDocPtr doc(xmlNewDoc((xmlChar *)"1.0")); + if (! doc) + throw FrameworkException(JFW_E_ERROR, sExcMsg); + //Create a comment + xmlNewDocComment( + doc, (xmlChar *) "This is a generated file. Do not alter this file!"); + + //Create the root element and name spaces + xmlNodePtr root = xmlNewDocNode( + doc, NULL, (xmlChar *) "java", (xmlChar *) "\n"); + + if (root == NULL) + throw FrameworkException(JFW_E_ERROR, sExcMsg); + + if (xmlNewNs(root, (xmlChar *) NS_JAVA_FRAMEWORK,NULL) == NULL) + throw FrameworkException(JFW_E_ERROR, sExcMsg); + if (xmlNewNs(root,(xmlChar*) NS_SCHEMA_INSTANCE,(xmlChar*)"xsi") == NULL) + throw FrameworkException(JFW_E_ERROR, sExcMsg); + xmlDocSetRootElement(doc, root); + + //Create a comment + xmlNodePtr com = xmlNewComment( + (xmlChar *) "This is a generated file. Do not alter this file!"); + if (com == NULL) + throw FrameworkException(JFW_E_ERROR, sExcMsg); + + if (xmlAddPrevSibling(root, com) == NULL) + throw FrameworkException(JFW_E_ERROR, sExcMsg); + + const rtl::OString path = getSettingsPath(); + if (xmlSaveFormatFileEnc(path.getStr(), doc,"UTF-8", 1) == -1) + throw FrameworkException(JFW_E_ERROR, sExcMsg); +} + +//===================================================================== +CNodeJavaInfo::CNodeJavaInfo() : + m_bEmptyNode(false), bNil(true), bAutoSelect(true), + nFeatures(0), nRequirements(0) +{ +} + +CNodeJavaInfo::~CNodeJavaInfo() +{ +} + +void CNodeJavaInfo::loadFromNode(xmlDoc * pDoc, xmlNode * pJavaInfo) +{ + rtl::OString sExcMsg("[Java framework] Error in function NodeJavaInfo::loadFromNode " + "(elements.cxx)."); + + OSL_ASSERT(pJavaInfo && pDoc); + if (pJavaInfo->children == NULL) + return; + //Get the xsi:nil attribute; + CXmlCharPtr sNil; + sNil = xmlGetNsProp( + pJavaInfo, (xmlChar*) "nil", (xmlChar*) NS_SCHEMA_INSTANCE); + if ( ! sNil) + throw FrameworkException(JFW_E_ERROR, sExcMsg); + + if (xmlStrcmp(sNil, (xmlChar*) "true") == 0) + bNil = true; + else if (xmlStrcmp(sNil, (xmlChar*) "false") == 0) + bNil = false; + else + throw FrameworkException(JFW_E_ERROR, sExcMsg); + if (bNil == true) + return; + + //Get javaInfo@manuallySelected attribute + CXmlCharPtr sAutoSelect; + sAutoSelect = xmlGetProp( + pJavaInfo, (xmlChar*) "autoSelect"); + if ( ! sAutoSelect) + throw FrameworkException(JFW_E_ERROR, sExcMsg); + + if (xmlStrcmp(sAutoSelect, (xmlChar*) "true") == 0) + bAutoSelect = true; + else if (xmlStrcmp(sAutoSelect, (xmlChar*) "false") == 0) + bAutoSelect = false; + else + throw FrameworkException(JFW_E_ERROR, sExcMsg); + + xmlNode * cur = pJavaInfo->children; + + while (cur != NULL) + { + if (xmlStrcmp(cur->name, (xmlChar*) "vendor") == 0) + { + CXmlCharPtr xmlVendor; + xmlVendor = xmlNodeListGetString( + pDoc, cur->children, 1); + if (! xmlVendor) + return; + sVendor = xmlVendor; + } + else if (xmlStrcmp(cur->name, (xmlChar*) "location") == 0) + { + CXmlCharPtr xmlLocation; + xmlLocation = xmlNodeListGetString( + pDoc, cur->children, 1); + sLocation = xmlLocation; + } + else if (xmlStrcmp(cur->name, (xmlChar*) "version") == 0) + { + CXmlCharPtr xmlVersion; + xmlVersion = xmlNodeListGetString( + pDoc, cur->children, 1); + sVersion = xmlVersion; + } + else if (xmlStrcmp(cur->name, (xmlChar*) "features")== 0) + { + CXmlCharPtr xmlFeatures; + xmlFeatures = xmlNodeListGetString( + pDoc, cur->children, 1); + rtl::OUString sFeatures = xmlFeatures; + nFeatures = sFeatures.toInt64(16); + } + else if (xmlStrcmp(cur->name, (xmlChar*) "requirements") == 0) + { + CXmlCharPtr xmlRequire; + xmlRequire = xmlNodeListGetString( + pDoc, cur->children, 1); + rtl::OUString sRequire = xmlRequire; + nRequirements = sRequire.toInt64(16); +#ifdef MACOSX + //javaldx is not used anymore in the mac build. In case the Java + //corresponding to the saved settings does not exist anymore the + //javavm services will look for an existing Java after creation of + //the JVM failed. See stoc/source/javavm/javavm.cxx. Only if + //nRequirements does not have the flag JFW_REQUIRE_NEEDRESTART the + //jvm of the new selected JRE will be started. Old settings (before + //OOo 3.3) still contain the flag which can be safely ignored. + nRequirements &= ~JFW_REQUIRE_NEEDRESTART; +#endif + } + else if (xmlStrcmp(cur->name, (xmlChar*) "vendorData") == 0) + { + CXmlCharPtr xmlData; + xmlData = xmlNodeListGetString( + pDoc, cur->children, 1); + xmlChar* _data = (xmlChar*) xmlData; + if (_data) + { + rtl::ByteSequence seq((sal_Int8*) _data, strlen((char*)_data)); + arVendorData = decodeBase16(seq); + } + } + cur = cur->next; + } + + if (sVendor.getLength() == 0) + m_bEmptyNode = true; + //Get the javainfo attributes + CXmlCharPtr sVendorUpdate; + sVendorUpdate = xmlGetProp(pJavaInfo, + (xmlChar*) "vendorUpdate"); + if ( ! sVendorUpdate) + throw FrameworkException(JFW_E_ERROR, sExcMsg); + sAttrVendorUpdate = sVendorUpdate; +} + + +void CNodeJavaInfo::writeToNode(xmlDoc* pDoc, + xmlNode* pJavaInfoNode) const + +{ + OSL_ASSERT(pJavaInfoNode && pDoc); + rtl::OString sExcMsg("[Java framework] Error in function NodeJavaInfo::writeToNode " + "(elements.cxx)."); + + //write the attribute vendorSettings + + //javaInfo@vendorUpdate + //creates the attribute if necessary + rtl::OString sUpdated = getElementUpdated(); + + xmlSetProp(pJavaInfoNode, (xmlChar*)"vendorUpdate", + (xmlChar*) sUpdated.getStr()); + + //javaInfo@autoSelect + xmlSetProp(pJavaInfoNode, (xmlChar*)"autoSelect", + (xmlChar*) (bAutoSelect == true ? "true" : "false")); + + //Set xsi:nil in javaInfo element to false + //the xmlNs pointer must not be destroyed + xmlNs* nsXsi = xmlSearchNsByHref((xmlDoc*) pDoc, + pJavaInfoNode, + (xmlChar*) NS_SCHEMA_INSTANCE); + + xmlSetNsProp(pJavaInfoNode, + nsXsi, + (xmlChar*) "nil", + (xmlChar*) "false"); + + //Delete the children of JavaInfo + xmlNode* cur = pJavaInfoNode->children; + while (cur != NULL) + { + xmlNode* lastNode = cur; + cur = cur->next; + xmlUnlinkNode(lastNode); + xmlFreeNode(lastNode); + } + + //If the JavaInfo was set with an empty value, + //then we are done. + if (m_bEmptyNode) + return; + + //add a new line after <javaInfo> + xmlNode * nodeCrLf = xmlNewText((xmlChar*) "\n"); + xmlAddChild(pJavaInfoNode, nodeCrLf); + + //Create the vendor element + xmlNewTextChild(pJavaInfoNode, NULL, (xmlChar*) "vendor", + CXmlCharPtr(sVendor)); + //add a new line for better readability + nodeCrLf = xmlNewText((xmlChar*) "\n"); + xmlAddChild(pJavaInfoNode, nodeCrLf); + + //Create the location element + xmlNewTextChild(pJavaInfoNode, NULL, (xmlChar*) "location", + CXmlCharPtr(sLocation)); + //add a new line for better readability + nodeCrLf = xmlNewText((xmlChar*) "\n"); + xmlAddChild(pJavaInfoNode, nodeCrLf); + + //Create the version element + xmlNewTextChild(pJavaInfoNode, NULL, (xmlChar*) "version", + CXmlCharPtr(sVersion)); + //add a new line for better readability + nodeCrLf = xmlNewText((xmlChar*) "\n"); + xmlAddChild(pJavaInfoNode, nodeCrLf); + + //Create the features element + rtl::OUString sFeatures = rtl::OUString::valueOf( + (sal_Int64)nFeatures, 16); + xmlNewTextChild(pJavaInfoNode, NULL, (xmlChar*) "features", + CXmlCharPtr(sFeatures)); + //add a new line for better readability + nodeCrLf = xmlNewText((xmlChar*) "\n"); + xmlAddChild(pJavaInfoNode, nodeCrLf); + + + //Create the requirements element + rtl::OUString sRequirements = rtl::OUString::valueOf( + (sal_Int64) nRequirements, 16); + xmlNewTextChild(pJavaInfoNode, NULL, (xmlChar*) "requirements", + CXmlCharPtr(sRequirements)); + //add a new line for better readability + nodeCrLf = xmlNewText((xmlChar*) "\n"); + xmlAddChild(pJavaInfoNode, nodeCrLf); + + + //Create the features element + rtl::ByteSequence data = encodeBase16(arVendorData); + xmlNode* dataNode = xmlNewChild(pJavaInfoNode, NULL, + (xmlChar*) "vendorData", + (xmlChar*) ""); + xmlNodeSetContentLen(dataNode, + (xmlChar*) data.getArray(), data.getLength()); + //add a new line for better readability + nodeCrLf = xmlNewText((xmlChar*) "\n"); + xmlAddChild(pJavaInfoNode, nodeCrLf); +} + +JavaInfo * CNodeJavaInfo::makeJavaInfo() const +{ + if (bNil == true || m_bEmptyNode == true) + return NULL; + JavaInfo * pInfo = (JavaInfo*) rtl_allocateMemory(sizeof(JavaInfo)); + if (pInfo == NULL) + return NULL; + memset(pInfo, 0, sizeof(JavaInfo)); + pInfo->sVendor = sVendor.pData; + rtl_uString_acquire(pInfo->sVendor); + pInfo->sLocation = sLocation.pData; + rtl_uString_acquire(pInfo->sLocation); + pInfo->sVersion = sVersion.pData; + rtl_uString_acquire(pInfo->sVersion); + pInfo->nFeatures = nFeatures; + pInfo->nRequirements = nRequirements; + pInfo->arVendorData = arVendorData.getHandle(); + rtl_byte_sequence_acquire(pInfo->arVendorData); + return pInfo; +} + +sal_uInt32 NodeJava::getModifiedTime() const +{ + if (m_layer != INSTALL) + { + OSL_ASSERT(0); + return 0; + } + rtl::OString modTimeSeconds = getElementModified(); + return (sal_uInt32) modTimeSeconds.toInt64(); +} + +//================================================================================ +MergedSettings::MergedSettings(): + m_bEnabled(sal_False), + m_sClassPath(), + m_vmParams(), + m_JRELocations(), + m_javaInfo() +{ + NodeJava settings(NodeJava::USER_OR_INSTALL); + settings.load(); + + //Check if UNO_JAVA_JFW_INSTALL_DATA is set. If so, then we need not use user and + //shared data. + const ::rtl::OUString sInstall = BootParams::getInstallData(); + + if (sInstall.getLength() == 0) + { + NodeJava sharedSettings(NodeJava::SHARED); + sharedSettings.load(); + merge(sharedSettings, settings); + } + else + { + merge(NodeJava(), settings); + } +} + +MergedSettings::~MergedSettings() +{ +} + +void MergedSettings::merge(const NodeJava & share, const NodeJava & user) +{ + if (user.getEnabled()) + m_bEnabled = * user.getEnabled(); + else if (share.getEnabled()) + m_bEnabled = * share.getEnabled(); + else + m_bEnabled = sal_True; + + if (user.getUserClassPath()) + m_sClassPath = * user.getUserClassPath(); + else if (share.getUserClassPath()) + m_sClassPath = * share.getUserClassPath(); + + if (user.getJavaInfo()) + m_javaInfo = * user.getJavaInfo(); + else if (share.getJavaInfo()) + m_javaInfo = * share.getJavaInfo(); + + if (user.getVmParameters()) + m_vmParams = * user.getVmParameters(); + else if (share.getVmParameters()) + m_vmParams = * share.getVmParameters(); + + if (user.getJRELocations()) + m_JRELocations = * user.getJRELocations(); + else if (share.getJRELocations()) + m_JRELocations = * share.getJRELocations(); +} + +sal_Bool MergedSettings::getEnabled() const +{ + return m_bEnabled; +} +const rtl::OUString& MergedSettings::getUserClassPath() const +{ + return m_sClassPath; +} + +::std::vector< ::rtl::OString> MergedSettings::getVmParametersUtf8() const +{ + ::std::vector< ::rtl::OString> ret; + typedef ::std::vector< ::rtl::OUString>::const_iterator cit; + for (cit i = m_vmParams.begin(); i < m_vmParams.end(); i++) + { + ret.push_back( ::rtl::OUStringToOString(*i, RTL_TEXTENCODING_UTF8)); + } + return ret; +} + +const ::rtl::OString & MergedSettings::getJavaInfoAttrVendorUpdate() const +{ + return m_javaInfo.sAttrVendorUpdate; +} + + +JavaInfo * MergedSettings::createJavaInfo() const +{ + return m_javaInfo.makeJavaInfo(); +} +#ifdef WNT +bool MergedSettings::getJavaInfoAttrAutoSelect() const +{ + return m_javaInfo.bAutoSelect; +} +#endif +void MergedSettings::getVmParametersArray( + rtl_uString *** parParams, sal_Int32 * size) const +{ + osl::MutexGuard guard(FwkMutex::get()); + OSL_ASSERT(parParams != NULL && size != NULL); + + *parParams = (rtl_uString **) + rtl_allocateMemory(sizeof(rtl_uString*) * m_vmParams.size()); + if (*parParams == NULL) + return; + + int j=0; + typedef std::vector<rtl::OUString>::const_iterator it; + for (it i = m_vmParams.begin(); i != m_vmParams.end(); + ++i, ++j) + { + (*parParams)[j] = i->pData; + rtl_uString_acquire(i->pData); + } + *size = m_vmParams.size(); +} + +void MergedSettings::getJRELocations( + rtl_uString *** parLocations, sal_Int32 * size) const +{ + osl::MutexGuard guard(FwkMutex::get()); + OSL_ASSERT(parLocations != NULL && size != NULL); + + *parLocations = (rtl_uString **) + rtl_allocateMemory(sizeof(rtl_uString*) * m_JRELocations.size()); + if (*parLocations == NULL) + return; + + int j=0; + typedef std::vector<rtl::OUString>::const_iterator it; + for (it i = m_JRELocations.begin(); i != m_JRELocations.end(); + ++i, ++j) + { + (*parLocations)[j] = i->pData; + rtl_uString_acquire(i->pData); + } + *size = m_JRELocations.size(); +} +const std::vector<rtl::OUString> & MergedSettings::getJRELocations() const +{ + return m_JRELocations; +} +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/jvmfwk/source/elements.hxx b/jvmfwk/source/elements.hxx new file mode 100644 index 000000000000..6efedbf96647 --- /dev/null +++ b/jvmfwk/source/elements.hxx @@ -0,0 +1,422 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_JVMFWK_ELEMENTS_HXX +#define INCLUDED_JVMFWK_ELEMENTS_HXX + +#include <vector> +#include "jvmfwk/framework.h" +#include "fwkutil.hxx" +#include "rtl/ustring.hxx" +#include "rtl/byteseq.hxx" +#include "libxml/parser.h" +#include "boost/optional.hpp" + +#define NS_JAVA_FRAMEWORK "http://openoffice.org/2004/java/framework/1.0" +#define NS_SCHEMA_INSTANCE "http://www.w3.org/2001/XMLSchema-instance" + +namespace jfw +{ + +/** gets the value of the updated element from the javavendors.xml. + */ +rtl::OString getElementUpdated(); + +/** create the child elements within the root structure for each platform. + + @param bNeedsSave + [out]If true then the respective structure of elements was added and the + document needs to be saved. + */ +void createSettingsStructure( + xmlDoc * document, bool * bNeedsSave); + + +/** represents the settings saved in the /java/javaInfo element. + It is used within class NodeJava which determines the settings + file. +*/ +class CNodeJavaInfo +{ +public: + CNodeJavaInfo(); + ~CNodeJavaInfo(); + + /** if true, then javaInfo is empty. When writeToNode is called + then all child elements are deleted. + */ + bool m_bEmptyNode; + /** Contains the value of the <updated> element of + the javavendors.xml after loadFromNode was called. + It is not used, when the javaInfo node is written. + see writeToNode + */ + ::rtl::OString sAttrVendorUpdate; + /** contains the nil value of the /java/javaInfo@xsi:nil attribute. + Default is true; + */ + bool bNil; + /** contains the value of the /java/javaInfo@autoSelect attribute. + Default is true. If it is false then the user has modified the JRE + selection by actively choosing a JRE from the options dialog. That is, + the function jfw_setSelectedJRE was called. Contrary, the function + jfw_findAndSelectJRE sets the attribute to true. + */ + bool bAutoSelect; + ::rtl::OUString sVendor; + ::rtl::OUString sLocation; + ::rtl::OUString sVersion; + sal_uInt64 nFeatures; + sal_uInt64 nRequirements; + ::rtl::ByteSequence arVendorData; + + /** reads the node /java/javaInfo. + If javaInfo@xsi:nil = true then member bNil is set to true + an no further elements are read. + */ + void loadFromNode(xmlDoc * pDoc,xmlNode * pJavaInfo); + /** The attribut nil will be set to false. The function gets the value + javaSettings/updated from the javavendors.xml and writes it to + javaInfo@vendorUpdate in javasettings.xml + */ + void writeToNode(xmlDoc * pDoc, xmlNode * pJavaInfo) const; + + /** returns NULL if javaInfo is nil. + */ + JavaInfo * makeJavaInfo() const; +}; + +/** this class represents the java settings based on a particular + settings file. + + Which settings file is used is determined by the value passed into the + constructo and the values of the bootstrap parameters UNO_JAVA_JFW_USER_DATA, + UNO_JAVA_JFW_SHARED_DATA,_JAVA_JFW_INSTALL_DATA. + + If the value is USER_OR_INSTALL then it depends of the bootstrap parameter + UNO_JAVA_JFW_INSTALL_DATA. If it has as value then it is used. Otherwise the + value from UNO_JAVA_JFW_USER_DATA is used. + + The method load reads the data from the settings file. + The method write stores the data into the settings file. + */ +class NodeJava +{ +public: + enum Layer { USER_OR_INSTALL, USER, SHARED, INSTALL }; +private: + + /** creates settings file and fills it with default values. + + When this function is called then it creates the + settings file at the possition determined by the bootstrap parameters + (UNO_JAVA_JFW_USER_DATA, UNO_JAVA_JFW_SHARED_DATA, + UNO_JAVA_JFW_INSTALL_DATA) and m_layer, unless the file already exists + (see createSettingsDocument). + + @return + JFW_E_CONFIG_READWRITE + */ + void prepareSettingsDocument() const; + + /** helper function for prepareSettingsDocument. + */ + void createSettingsDocument() const; + + /** returns the system path to the data file which is to be used. The value + depends on + the the member m_layer and the bootstrap paramters UNO_JAVA_JFW_USER_DATA, + UNO_JAVA_JFW_SHARED_DATA and UNO_JAVA_JFW_INSTALL_DATA which this may be. + */ + ::rtl::OString getSettingsPath() const; + + /** returns the file URL to the data file which is to be used. See getSettingsPath. + */ + ::rtl::OUString getSettingsURL() const; + + /** Verifies if the respective settings file exist. In case UNO_JAVA_JFW_INSTALL_DATA + is used, the age is checked. If the file is too old then we assume that it does not + exist and wipe its contents. Then still FILE_DOES_NOT_EXIST is returned. + */ + jfw::FileStatus checkSettingsFileStatus() const; + + /** Determines the layer for which the instance the loads and writes the + data. + */ + Layer m_layer; + + /** User configurable option. /java/enabled + If /java/enabled@xsi:nil == true then the value will be uninitialized + after a call to load(). + */ + boost::optional<sal_Bool> m_enabled; + + /** User configurable option. /java/userClassPath + If /java/userClassPath@xsi:nil == true then the value is uninitialized + after a call to load(). + */ + boost::optional< ::rtl::OUString> m_userClassPath; + /** User configurable option. /java/javaInfo + If /java/javaInfo@xsi:nil == true then the value is uninitialized + after a call to load. + */ + boost::optional<CNodeJavaInfo> m_javaInfo; + /** User configurable option. /java/vmParameters + If /java/vmParameters@xsi:nil == true then the value is uninitialized + after a call to load. + */ + boost::optional< ::std::vector< ::rtl::OUString> > m_vmParameters; + /** User configurable option. /java/jreLocations + If /java/jreLocaltions@xsi:nil == true then the value is uninitialized + after a call to load. + */ + boost::optional< ::std::vector< ::rtl::OUString> > m_JRELocations; + + /** Only in INSTALL mode. Then NodeJava.write writes a <modified> element + which contains the seconds value of the TimeValue (osl/time.h), obtained + with osl_getSystemTime. + It returns 0 if the value cannot be obtained. + This is used to fix the problem that the modified time of the settings + file is incorrect because it resides on an NFS volume where the NFS + server and NFS client do not have the same system time. For example if + the server time is ahead of the client time then checkSettingsFileStatus + deleted the settings. So even if javaldx determined a Java + (jfw_findAndSelectJRE) then jfw_startVM returned a JFW_E_NO_SELECT. Then + it looked again for a java by calling jfw_findAndSelectJRE, which + returned a JFW_E_NONE. But the following jfw_startVM returned again + JFW_E_NO_SELECT. So it looped. (see issue i114509) + + NFS server and NFS client should have the same time. It is common + practise to enforce this in networks. We actually should not work + around a malconfigured network. We must however, make sure that we do + not loop. Maybe a better approach is, that: + - assume that mtime and system time are reliable + - checkSettingsFile uses system time and mtime of the settings file, + instset of using getModifiedTime. + - allow a small error margin + - jfw_startVM must return a JFW_E_EXPIRED_SETTINGS + - XJavaVM::startVM should prevent the loop by processing the new return+ value + + */ + sal_uInt32 getModifiedTime() const; + +public: + + NodeJava(Layer theLayer = USER_OR_INSTALL); + + /** sets m_enabled. + /java/enabled@xsi:nil will be set to false when write is called. + */ + void setEnabled(sal_Bool bEnabled); + + /** sets m_sUserClassPath. See setEnabled. + */ + void setUserClassPath(const ::rtl::OUString & sClassPath); + + /** sets m_aInfo. See setEnabled. + @param bAutoSelect + true- called by jfw_setSelectedJRE + false called by jfw_findAndSelectJRE + */ + void setJavaInfo(const JavaInfo * pInfo, bool bAutoSelect); + + /** sets the /java/vmParameters/param elements. + When this method all previous values are removed and replaced + by those in arParameters. + /java/vmParameters@xsi:nil will be set to true when write() is + called. + */ + void setVmParameters(rtl_uString * * arParameters, sal_Int32 size); + + /** sets the /java/jreLocations/location elements. + When this method is called then all previous values are removed + and replaced by those in arParamters. + /java/jreLocations@xsi:nil will be set to true write() is called. + */ + void setJRELocations(rtl_uString * * arParameters, sal_Int32 size); + + /** adds a location to the already existing locations. + Note: call load() before, then add the location and then call write(). + */ + void addJRELocation(rtl_uString * sLocation); + + /** writes the data to user settings. + */ + void write() const; + + /** load the values of the settings file. + */ + void load(); + + /** returns the value of the element /java/enabled + */ + const boost::optional<sal_Bool> & getEnabled() const; + /** returns the value of the element /java/userClassPath. + */ + const boost::optional< ::rtl::OUString> & getUserClassPath() const; + + /** returns the value of the element /java/javaInfo. + */ + const boost::optional<CNodeJavaInfo> & getJavaInfo() const; + + /** returns the parameters from the element /java/vmParameters/param. + */ + const boost::optional< ::std::vector< ::rtl::OUString> > & getVmParameters() const; + + /** returns the parameters from the element /java/jreLocations/location. + */ + const boost::optional< ::std::vector< ::rtl::OUString> > & getJRELocations() const; +}; + +/** merges the settings for shared, user and installation during construction. + The class uses a simple merge mechanism for the javasettings.xml files in share and + user. The following elements completly overwrite the corresponding elements + from share: + /java/enabled + /java/userClassPath + /java/vmParameters + /java/jreLocations + /java/javaInfo + + In case of an installation, the shared and user settings are completely + disregarded. + + The locations of the different settings files is obtained through the + bootstrap variables: + UNO_JAVA_JFW_USER_DATA + UNO_JAVA_JFW_SHARED_DATA + UNO_JAVA_JFW_INSTALL_DATA + + The class also determines useful default values for settings which have not been made. +*/ +class MergedSettings +{ +private: + const MergedSettings& operator = (MergedSettings&); + MergedSettings(MergedSettings&); + + void merge(const NodeJava & share, const NodeJava & user); + + sal_Bool m_bEnabled; + + ::rtl::OUString m_sClassPath; + + ::std::vector< ::rtl::OUString> m_vmParams; + + ::std::vector< ::rtl::OUString> m_JRELocations; + + CNodeJavaInfo m_javaInfo; + +public: + MergedSettings(); + virtual ~MergedSettings(); + + /** the default is true. + */ + sal_Bool getEnabled() const; + + const ::rtl::OUString & getUserClassPath() const; + + ::std::vector< ::rtl::OString> getVmParametersUtf8() const; + /** returns a JavaInfo structure representing the node + /java/javaInfo. Every time a new JavaInfo structure is created + which needs to be freed by the caller. + If both, user and share settings are nil, then NULL is returned. + */ + JavaInfo * createJavaInfo() const; + + /** returns the value of the attribute /java/javaInfo[@vendorUpdate]. + */ + ::rtl::OString const & getJavaInfoAttrVendorUpdate() const; + +#ifdef WNT + /** returns the javaInfo@autoSelect attribute. + Before calling this function loadFromSettings must be called. + It uses the javaInfo@autoSelect attribute to determine + the return value; + */ + bool getJavaInfoAttrAutoSelect() const; +#endif + + /** returns an array. + Caller must free the strings and the array. + */ + void getVmParametersArray(rtl_uString *** parParameters, sal_Int32 * size) const; + + /** returns an array. + Caller must free the strings and the array. + */ + void getJRELocations(rtl_uString *** parLocations, sal_Int32 * size) const; + + const ::std::vector< ::rtl::OUString> & getJRELocations() const; +}; + + +class VersionInfo +{ + ::std::vector< ::rtl::OUString> vecExcludeVersions; + rtl_uString ** arVersions; + +public: + VersionInfo(); + ~VersionInfo(); + + void addExcludeVersion(const ::rtl::OUString& sVersion); + + ::rtl::OUString sMinVersion; + ::rtl::OUString sMaxVersion; + + /** The caller DOES NOT get ownership of the strings. That is he + does not need to release the strings. + The array exists as long as this object exists. + */ + + rtl_uString** getExcludeVersions(); + sal_Int32 getExcludeVersionSize(); +}; + +struct PluginLibrary +{ + PluginLibrary() + { + } + PluginLibrary(rtl::OUString vendor,::rtl::OUString path) : + sVendor(vendor), sPath(path) + { + } + /** contains the vendor string which is later userd in the xml API + */ + ::rtl::OUString sVendor; + /** File URL the plug-in library + */ + ::rtl::OUString sPath; +}; + +} //end namespace +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/jvmfwk/source/framework.cxx b/jvmfwk/source/framework.cxx new file mode 100644 index 000000000000..9cf2c4985932 --- /dev/null +++ b/jvmfwk/source/framework.cxx @@ -0,0 +1,1284 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_jvmfwk.hxx" +#include "boost/scoped_array.hpp" +#include "rtl/ustring.hxx" +#include "rtl/bootstrap.hxx" +#include "osl/thread.hxx" +#include "osl/file.hxx" +#include "osl/module.hxx" +#include "jvmfwk/framework.h" +#include "jvmfwk/vendorplugin.h" +#include <vector> +#include <functional> +#include <algorithm> +#include "framework.hxx" +#include "fwkutil.hxx" +#include "elements.hxx" +#include "fwkbase.hxx" + +#ifdef WNT +/** The existence of the file useatjava.txt decides if a Java should be used + that supports accessibility tools. + */ +#define USE_ACCESSIBILITY_FILE "useatjava.txt" +#endif + +#define UNO_JAVA_JFW_JREHOME "UNO_JAVA_JFW_JREHOME" +namespace { +JavaVM * g_pJavaVM = NULL; + +bool g_bEnabledSwitchedOn = false; + +sal_Bool areEqualJavaInfo( + JavaInfo const * pInfoA,JavaInfo const * pInfoB) +{ + return jfw_areEqualJavaInfo(pInfoA, pInfoB); +} +} + +javaFrameworkError SAL_CALL jfw_findAllJREs(JavaInfo ***pparInfo, sal_Int32 *pSize) +{ + javaFrameworkError retVal = JFW_E_NONE; + try + { + osl::MutexGuard guard(jfw::FwkMutex::get()); + javaFrameworkError errcode = JFW_E_NONE; + if (pparInfo == NULL || pSize == NULL) + return JFW_E_INVALID_ARG; + + jfw::VendorSettings aVendorSettings; + //Get a list of plugins which provide Java information + std::vector<jfw::PluginLibrary> vecPlugins = + aVendorSettings.getPluginData(); + + //Create a vector that holds the libraries, which will be later + //dynamically loaded; + boost::scoped_array<osl::Module> sarModules; + sarModules.reset(new osl::Module[vecPlugins.size()]); + osl::Module * arModules = sarModules.get(); + //Add the JavaInfos found by jfw_plugin_getAllJavaInfos to the vector + //Make sure that the contents are destroyed if this + //function returns with an error + std::vector<jfw::CJavaInfo> vecInfo; + //Add the JavaInfos found by jfw_plugin_getJavaInfoByPath to this vector + //Make sure that the contents are destroyed if this + //function returns with an error + std::vector<jfw::CJavaInfo> vecInfoManual; + typedef std::vector<jfw::CJavaInfo>::iterator it_info; + //get the list of paths to jre locations which have been + //added manually + const jfw::MergedSettings settings; + const std::vector<rtl::OUString>& vecJRELocations = + settings.getJRELocations(); + //Use every plug-in library to get Java installations. + typedef std::vector<jfw::PluginLibrary>::const_iterator ci_pl; + int cModule = 0; + for (ci_pl i = vecPlugins.begin(); i != vecPlugins.end(); ++i, ++cModule) + { + const jfw::PluginLibrary & library = *i; + jfw::VersionInfo versionInfo = + aVendorSettings.getVersionInformation(library.sVendor); + arModules[cModule].load(library.sPath); + osl::Module & pluginLib = arModules[cModule]; + + if (pluginLib.is() == sal_False) + { + rtl::OString msg = rtl::OUStringToOString( + library.sPath, osl_getThreadTextEncoding()); + fprintf(stderr,"[jvmfwk] Could not load plugin %s\n" \ + "Modify the javavendors.xml accordingly!\n", msg.getStr()); + return JFW_E_NO_PLUGIN; + } + jfw_plugin_getAllJavaInfos_ptr getAllJavaFunc = + (jfw_plugin_getAllJavaInfos_ptr) pluginLib.getFunctionSymbol( + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("jfw_plugin_getAllJavaInfos"))); + + OSL_ASSERT(getAllJavaFunc); + if (getAllJavaFunc == NULL) + return JFW_E_ERROR; + + //get all installations of one vendor according to minVersion, + //maxVersion and excludeVersions + sal_Int32 cInfos = 0; + JavaInfo** arInfos = NULL; + javaPluginError plerr = (*getAllJavaFunc)( + library.sVendor.pData, + versionInfo.sMinVersion.pData, + versionInfo.sMaxVersion.pData, + versionInfo.getExcludeVersions(), + versionInfo.getExcludeVersionSize(), + & arInfos, + & cInfos); + + if (plerr != JFW_PLUGIN_E_NONE) + return JFW_E_ERROR; + + for (int j = 0; j < cInfos; j++) + vecInfo.push_back(jfw::CJavaInfo::createWrapper(arInfos[j])); + + rtl_freeMemory(arInfos); + + //Check if the current plugin can detect JREs at the location + // of the paths added by jfw_setJRELocations or jfw_addJRELocation + //get the function from the plugin + jfw_plugin_getJavaInfoByPath_ptr jfw_plugin_getJavaInfoByPathFunc = + (jfw_plugin_getJavaInfoByPath_ptr) pluginLib.getFunctionSymbol( + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("jfw_plugin_getJavaInfoByPath"))); + + OSL_ASSERT(jfw_plugin_getJavaInfoByPathFunc); + if (jfw_plugin_getJavaInfoByPathFunc == NULL) + return JFW_E_ERROR; + + typedef std::vector<rtl::OUString>::const_iterator citLoc; + //Check every manually added location + for (citLoc ii = vecJRELocations.begin(); + ii != vecJRELocations.end(); ++ii) + { + jfw::CJavaInfo aInfo; + plerr = (*jfw_plugin_getJavaInfoByPathFunc)( + ii->pData, + library.sVendor.pData, + versionInfo.sMinVersion.pData, + versionInfo.sMaxVersion.pData, + versionInfo.getExcludeVersions(), + versionInfo.getExcludeVersionSize(), + & aInfo.pInfo); + if (plerr == JFW_PLUGIN_E_NO_JRE) + continue; + if (plerr == JFW_PLUGIN_E_FAILED_VERSION) + continue; + else if (plerr !=JFW_PLUGIN_E_NONE) + return JFW_E_ERROR; + + if (aInfo) + { + //Was this JRE already added?. Different plugins could detect + //the same JRE + it_info it_duplicate = + std::find_if(vecInfoManual.begin(), vecInfoManual.end(), + std::bind2nd(std::ptr_fun(areEqualJavaInfo), aInfo)); + if (it_duplicate == vecInfoManual.end()) + vecInfoManual.push_back(aInfo); + } + } + } + //Make sure vecInfoManual contains only JavaInfos for the vendors for which + //there is a javaSelection/plugins/library entry in the javavendors.xml + //To obtain the JavaInfos for the manually added JRE locations the function + //jfw_getJavaInfoByPath is called which can return a JavaInfo of any vendor. + std::vector<jfw::CJavaInfo> vecInfoManual2; + for (it_info ivm = vecInfoManual.begin(); ivm != vecInfoManual.end(); ++ivm) + { + for (ci_pl ii = vecPlugins.begin(); ii != vecPlugins.end(); ++ii) + { + if ( ii->sVendor.equals((*ivm)->sVendor)) + { + vecInfoManual2.push_back(*ivm); + break; + } + } + } + //Check which JavaInfo from vector vecInfoManual2 is already + //contained in vecInfo. If it already exists then remove it from + //vecInfoManual2 + for (it_info j = vecInfo.begin(); j != vecInfo.end(); ++j) + { + it_info it_duplicate = + std::find_if(vecInfoManual2.begin(), vecInfoManual2.end(), + std::bind2nd(std::ptr_fun(areEqualJavaInfo), *j)); + if (it_duplicate != vecInfoManual2.end()) + vecInfoManual2.erase(it_duplicate); + } + //create an fill the array of JavaInfo* + sal_Int32 nSize = vecInfo.size() + vecInfoManual2.size(); + *pparInfo = (JavaInfo**) rtl_allocateMemory( + nSize * sizeof(JavaInfo*)); + if (*pparInfo == NULL) + return JFW_E_ERROR; + + typedef std::vector<jfw::CJavaInfo>::iterator it; + int index = 0; + //Add the automatically detected JREs + for (it k = vecInfo.begin(); k != vecInfo.end(); ++k) + (*pparInfo)[index++] = k->detach(); + //Add the manually detected JREs + for (it l = vecInfoManual2.begin(); l != vecInfoManual2.end(); ++l) + (*pparInfo)[index++] = l->detach(); + + *pSize = nSize; + return errcode; + } + catch (jfw::FrameworkException& e) + { + retVal = e.errorCode; + fprintf(stderr, "%s\n", e.message.getStr()); + OSL_FAIL(e.message.getStr()); + } + return retVal; +} + +javaFrameworkError SAL_CALL jfw_startVM(JavaVMOption *arOptions, sal_Int32 cOptions, + JavaVM **ppVM, JNIEnv **ppEnv) +{ +#ifndef SOLAR_JAVA + return JFW_E_ERROR; +#else + javaFrameworkError errcode = JFW_E_NONE; + if (cOptions > 0 && arOptions == NULL) + return JFW_E_INVALID_ARG; + + try + { + osl::MutexGuard guard(jfw::FwkMutex::get()); + + //We keep this pointer so we can determine if a VM has already + //been created. + if (g_pJavaVM != NULL) + return JFW_E_RUNNING_JVM; + + if (ppVM == NULL) + return JFW_E_INVALID_ARG; + + std::vector<rtl::OString> vmParams; + rtl::OString sUserClassPath; + jfw::CJavaInfo aInfo; + jfw::JFW_MODE mode = jfw::getMode(); + if (mode == jfw::JFW_MODE_APPLICATION) + { + const jfw::MergedSettings settings; + if (sal_False == settings.getEnabled()) + return JFW_E_JAVA_DISABLED; + aInfo.attach(settings.createJavaInfo()); + //check if a Java has ever been selected + if (aInfo == NULL) + return JFW_E_NO_SELECT; + +#ifdef WNT + //Because on Windows there is no system setting that we can use to determine + //if Assistive Technology Tool support is needed, we ship a .reg file that the + //user can use to create a registry setting. When the user forgets to set + //the key before he starts the office then a JRE may be selected without access bridge. + //When he later sets the key then we select a JRE with accessibility support but + //only if the user has not manually changed the selected JRE in the options dialog. + if (jfw::isAccessibilitySupportDesired()) + { + // If no JRE has been selected then we do not select one. This function shall then + //return JFW_E_NO_SELECT + if (aInfo != NULL && + (aInfo->nFeatures & JFW_FEATURE_ACCESSBRIDGE) == 0) + { + //has the user manually selected a JRE? + if (settings.getJavaInfoAttrAutoSelect() == true) + { + // if not then the automatism has previously selected a JRE + //without accessibility support. We return JFW_E_NO_SELECT + //to cause that we search for another JRE. The search code will + //then prefer a JRE with accessibility support. + return JFW_E_NO_SELECT; + } + } + } +#endif + //check if the javavendors.xml has changed after a Java was selected + rtl::OString sVendorUpdate = jfw::getElementUpdated(); + + if (sVendorUpdate != settings.getJavaInfoAttrVendorUpdate()) + return JFW_E_INVALID_SETTINGS; + + //check if JAVA is disabled + //If Java is enabled, but it was disabled when this process was started + // then no preparational work, such as setting the LD_LIBRARY_PATH, was + //done. Therefore if a JRE needs it it must not be started. + if (g_bEnabledSwitchedOn && + (aInfo->nRequirements & JFW_REQUIRE_NEEDRESTART)) + return JFW_E_NEED_RESTART; + + //Check if the selected Java was set in this process. If so it + //must not have the requirments flag JFW_REQUIRE_NEEDRESTART + if ((aInfo->nRequirements & JFW_REQUIRE_NEEDRESTART) + && + (jfw::wasJavaSelectedInSameProcess() == true)) + return JFW_E_NEED_RESTART; + + vmParams = settings.getVmParametersUtf8(); + sUserClassPath = jfw::makeClassPathOption(settings.getUserClassPath()); + } // end mode FWK_MODE_OFFICE + else if (mode == jfw::JFW_MODE_DIRECT) + { + errcode = jfw_getSelectedJRE(&aInfo.pInfo); + if (errcode != JFW_E_NONE) + return errcode; + //In direct mode the options are specified by bootstrap variables + //of the form UNO_JAVA_JFW_PARAMETER_1 .. UNO_JAVA_JFW_PARAMETER_n + vmParams = jfw::BootParams::getVMParameters(); + sUserClassPath = + "-Djava.class.path=" + jfw::BootParams::getClasspath(); + } + else + OSL_ASSERT(0); + + //get the function jfw_plugin_startJavaVirtualMachine + jfw::VendorSettings aVendorSettings; + rtl::OUString sLibPath = aVendorSettings.getPluginLibrary(aInfo.getVendor()); + + osl::Module modulePlugin(sLibPath); + if ( ! modulePlugin) + return JFW_E_NO_PLUGIN; + + rtl::OUString sFunctionName( + RTL_CONSTASCII_USTRINGPARAM("jfw_plugin_startJavaVirtualMachine")); + jfw_plugin_startJavaVirtualMachine_ptr pFunc = + (jfw_plugin_startJavaVirtualMachine_ptr) + osl_getFunctionSymbol(modulePlugin, sFunctionName.pData); + if (pFunc == NULL) + return JFW_E_ERROR; + + // create JavaVMOptions array that is passed to the plugin + // it contains the classpath and all options set in the + //options dialog + boost::scoped_array<JavaVMOption> sarJOptions( + new JavaVMOption[cOptions + 2 + vmParams.size()]); + JavaVMOption * arOpt = sarJOptions.get(); + if (! arOpt) + return JFW_E_ERROR; + + //The first argument is the classpath + arOpt[0].optionString= (char*) sUserClassPath.getStr(); + arOpt[0].extraInfo = NULL; + // Set a flag that this JVM has been created via the JNI Invocation API + // (used, for example, by UNO remote bridges to share a common thread pool + // factory among Java and native bridge implementations): + arOpt[1].optionString = (char *) "-Dorg.openoffice.native="; + arOpt[1].extraInfo = 0; + + //add the options set by options dialog + int index = 2; + typedef std::vector<rtl::OString>::const_iterator cit; + for (cit i = vmParams.begin(); i != vmParams.end(); ++i) + { + arOpt[index].optionString = const_cast<sal_Char*>(i->getStr()); + arOpt[index].extraInfo = 0; + index ++; + } + //add all options of the arOptions argument + for (int ii = 0; ii < cOptions; ii++) + { + arOpt[index].optionString = arOptions[ii].optionString; + arOpt[index].extraInfo = arOptions[ii].extraInfo; + index++; + } + + //start Java + JavaVM *pVm = NULL; + javaPluginError plerr = (*pFunc)(aInfo, arOpt, index, & pVm, ppEnv); + if (plerr == JFW_PLUGIN_E_VM_CREATION_FAILED) + { + errcode = JFW_E_VM_CREATION_FAILED; + } + else if (plerr != JFW_PLUGIN_E_NONE ) + { + errcode = JFW_E_ERROR; + } + else + { + g_pJavaVM = pVm; + *ppVM = pVm; + } + OSL_ASSERT(plerr != JFW_PLUGIN_E_WRONG_VENDOR); + } + catch (jfw::FrameworkException& e) + { + errcode = e.errorCode; + fprintf(stderr, "%s\n", e.message.getStr()); + OSL_FAIL(e.message.getStr()); + } + + return errcode; +#endif +} + +/** We do not use here jfw_findAllJREs and then check if a JavaInfo + meets the requirements, because that means using all plug-ins, which + may take quite a while. The implementation uses one plug-in and if + it already finds a suitable JRE then it is done and does not need to + load another plug-in + */ +javaFrameworkError SAL_CALL jfw_findAndSelectJRE(JavaInfo **pInfo) +{ + javaFrameworkError errcode = JFW_E_NONE; + try + { + osl::MutexGuard guard(jfw::FwkMutex::get()); + if (jfw::getMode() == jfw::JFW_MODE_DIRECT) + return JFW_E_DIRECT_MODE; + sal_uInt64 nFeatureFlags = 0; + jfw::CJavaInfo aCurrentInfo; +//Determine if accessibility support is needed + bool bSupportAccessibility = jfw::isAccessibilitySupportDesired(); + nFeatureFlags = bSupportAccessibility ? + JFW_FEATURE_ACCESSBRIDGE : 0L; + + //Get a list of services which provide Java information + jfw::VendorSettings aVendorSettings; + std::vector<jfw::PluginLibrary> vecPlugins = + aVendorSettings.getPluginData(); + //Create a vector that holds the libraries, which will be later + //dynamically loaded; + boost::scoped_array<osl::Module> sarModules; + sarModules.reset(new osl::Module[vecPlugins.size()]); + osl::Module * arModules = sarModules.get(); + + //Use every plug-in library to get Java installations. At the first usable + //Java the loop will break + typedef std::vector<jfw::PluginLibrary>::const_iterator ci_pl; + int cModule = 0; + for (ci_pl i = vecPlugins.begin(); i != vecPlugins.end(); ++i, ++cModule) + { + const jfw::PluginLibrary & library = *i; + jfw::VersionInfo versionInfo = + aVendorSettings.getVersionInformation(library.sVendor); + + arModules[cModule].load(library.sPath); + osl::Module & pluginLib = arModules[cModule]; + if (pluginLib.is() == sal_False) + return JFW_E_NO_PLUGIN; + + jfw_plugin_getAllJavaInfos_ptr getAllJavaFunc = + (jfw_plugin_getAllJavaInfos_ptr) pluginLib.getFunctionSymbol( + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("jfw_plugin_getAllJavaInfos"))); + + OSL_ASSERT(getAllJavaFunc); + if (getAllJavaFunc == NULL) + continue; + + //get all installations of one vendor according to minVersion, + //maxVersion and excludeVersions + sal_Int32 cInfos = 0; + JavaInfo** arInfos = NULL; + javaPluginError plerr = (*getAllJavaFunc)( + library.sVendor.pData, + versionInfo.sMinVersion.pData, + versionInfo.sMaxVersion.pData, + versionInfo.getExcludeVersions(), + versionInfo.getExcludeVersionSize(), + & arInfos, + & cInfos); + + if (plerr != JFW_PLUGIN_E_NONE) + continue; + //iterate over all installations to find the best which has + //all features + if (cInfos == 0) + { + rtl_freeMemory(arInfos); + continue; + } + bool bInfoFound = false; + for (int ii = 0; ii < cInfos; ii++) + { + JavaInfo* pJInfo = arInfos[ii]; + + //We remember the very first installation in aCurrentInfo + if (aCurrentInfo.getLocation().getLength() == 0) + aCurrentInfo = pJInfo; + // compare features + // If the user does not require any features (nFeatureFlags = 0) + // then the first installation is used + if ((pJInfo->nFeatures & nFeatureFlags) == nFeatureFlags) + { + //the just found Java implements all required features + //currently there is only accessibility!!! + aCurrentInfo = pJInfo; + bInfoFound = true; + break; + } + } + //The array returned by jfw_plugin_getAllJavaInfos must be freed as well as + //its contents + for (int j = 0; j < cInfos; j++) + jfw_freeJavaInfo(arInfos[j]); + rtl_freeMemory(arInfos); + + if (bInfoFound == true) + break; + //All Java installations found by the current plug-in lib + //do not provide the required features. Try the next plug-in + } + if ((JavaInfo*) aCurrentInfo == NULL) + {//The plug-ins did not find a suitable Java. Now try the paths which have been + //added manually. + //get the list of paths to jre locations which have been added manually + const jfw::MergedSettings settings; + //node.loadFromSettings(); + const std::vector<rtl::OUString> & vecJRELocations = + settings.getJRELocations(); + //use every plug-in to determine the JavaInfo objects + bool bInfoFound = false; + for (ci_pl i = vecPlugins.begin(); i != vecPlugins.end(); ++i) + { + const jfw::PluginLibrary & library = *i; + jfw::VersionInfo versionInfo = + aVendorSettings.getVersionInformation(library.sVendor); + + osl::Module pluginLib(library.sPath); + if (pluginLib.is() == sal_False) + return JFW_E_NO_PLUGIN; + //Check if the current plugin can detect JREs at the location + // of the paths added by jfw_setJRELocations or jfw_addJRELocation + //get the function from the plugin + jfw_plugin_getJavaInfoByPath_ptr jfw_plugin_getJavaInfoByPathFunc = + (jfw_plugin_getJavaInfoByPath_ptr) pluginLib.getFunctionSymbol( + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("jfw_plugin_getJavaInfoByPath"))); + + OSL_ASSERT(jfw_plugin_getJavaInfoByPathFunc); + if (jfw_plugin_getJavaInfoByPathFunc == NULL) + return JFW_E_ERROR; + + typedef std::vector<rtl::OUString>::const_iterator citLoc; + for (citLoc it = vecJRELocations.begin(); + it != vecJRELocations.end(); ++it) + { + jfw::CJavaInfo aInfo; + javaPluginError err = (*jfw_plugin_getJavaInfoByPathFunc)( + it->pData, + library.sVendor.pData, + versionInfo.sMinVersion.pData, + versionInfo.sMaxVersion.pData, + versionInfo.getExcludeVersions(), + versionInfo.getExcludeVersionSize(), + & aInfo.pInfo); + if (err == JFW_PLUGIN_E_NO_JRE) + continue; + if (err == JFW_PLUGIN_E_FAILED_VERSION) + continue; + else if (err !=JFW_PLUGIN_E_NONE) + return JFW_E_ERROR; + + if (aInfo) + { + //We remember the very first installation in aCurrentInfo + if (aCurrentInfo.getLocation().getLength() == 0) + aCurrentInfo = aInfo; + // compare features + // If the user does not require any features (nFeatureFlags = 0) + // then the first installation is used + if ((aInfo.getFeatures() & nFeatureFlags) == nFeatureFlags) + { + //the just found Java implements all required features + //currently there is only accessibility!!! + aCurrentInfo = aInfo; + bInfoFound = true; + break; + } + } + }//end iterate over paths + if (bInfoFound == true) + break; + }// end iterate plug-ins + } + if ((JavaInfo*) aCurrentInfo) + { + jfw::NodeJava javaNode; + javaNode.setJavaInfo(aCurrentInfo,true); + javaNode.write(); + + if (pInfo !=NULL) + { + //copy to out param + *pInfo = aCurrentInfo.cloneJavaInfo(); + //remember that this JRE was selected in this process + jfw::setJavaSelected(); + } + } + else + { + errcode = JFW_E_NO_JAVA_FOUND; + } + } + catch (jfw::FrameworkException& e) + { + errcode = e.errorCode; + fprintf(stderr, "%s\n", e.message.getStr()); + OSL_FAIL(e.message.getStr()); + } + + return errcode; +} +sal_Bool SAL_CALL jfw_areEqualJavaInfo( + JavaInfo const * pInfoA,JavaInfo const * pInfoB) +{ + if (pInfoA == pInfoB) + return sal_True; + if (pInfoA == NULL || pInfoB == NULL) + return sal_False; + rtl::OUString sVendor(pInfoA->sVendor); + rtl::OUString sLocation(pInfoA->sLocation); + rtl::OUString sVersion(pInfoA->sVersion); + rtl::ByteSequence sData(pInfoA->arVendorData); + if (sVendor.equals(pInfoB->sVendor) == sal_True + && sLocation.equals(pInfoB->sLocation) == sal_True + && sVersion.equals(pInfoB->sVersion) == sal_True + && pInfoA->nFeatures == pInfoB->nFeatures + && pInfoA->nRequirements == pInfoB->nRequirements + && sData == pInfoB->arVendorData) + { + return sal_True; + } + return sal_False; +} + + +void SAL_CALL jfw_freeJavaInfo(JavaInfo *pInfo) +{ + if (pInfo == NULL) + return; + rtl_uString_release(pInfo->sVendor); + rtl_uString_release(pInfo->sLocation); + rtl_uString_release(pInfo->sVersion); + rtl_byte_sequence_release(pInfo->arVendorData); + rtl_freeMemory(pInfo); +} + +javaFrameworkError SAL_CALL jfw_getSelectedJRE(JavaInfo **ppInfo) +{ + javaFrameworkError errcode = JFW_E_NONE; + try + { + osl::MutexGuard guard(jfw::FwkMutex::get()); + if (ppInfo == NULL) + return JFW_E_INVALID_ARG; + + if (jfw::getMode() == jfw::JFW_MODE_DIRECT) + { + rtl::OUString sJRE = jfw::BootParams::getJREHome(); + + jfw::CJavaInfo aInfo; + if ((errcode = jfw_getJavaInfoByPath(sJRE.pData, & aInfo.pInfo)) + != JFW_E_NONE) + throw jfw::FrameworkException( + JFW_E_CONFIGURATION, + rtl::OString( + "[Java framework] The JRE specified by the bootstrap " + "variable UNO_JAVA_JFW_JREHOME or UNO_JAVA_JFW_ENV_JREHOME " + " could not be recognized. Check the values and make sure that you " + "use a plug-in library that can recognize that JRE.")); + + *ppInfo = aInfo.detach(); + return JFW_E_NONE; + } + + const jfw::MergedSettings settings; + jfw::CJavaInfo aInfo; + aInfo.attach(settings.createJavaInfo()); + if (! aInfo) + { + *ppInfo = NULL; + return JFW_E_NONE; + } + //If the javavendors.xml has changed, then the current selected + //Java is not valid anymore + // /java/javaInfo/@vendorUpdate != javaSelection/updated (javavendors.xml) + rtl::OString sUpdated = jfw::getElementUpdated(); + + if (sUpdated.equals(settings.getJavaInfoAttrVendorUpdate()) == sal_False) + return JFW_E_INVALID_SETTINGS; + *ppInfo = aInfo.detach(); + } + catch (jfw::FrameworkException& e) + { + errcode = e.errorCode; + fprintf(stderr, "%s\n", e.message.getStr()); + OSL_FAIL(e.message.getStr()); + } + return errcode; +} + +javaFrameworkError SAL_CALL jfw_isVMRunning(sal_Bool *bRunning) +{ + osl::MutexGuard guard(jfw::FwkMutex::get()); + if (bRunning == NULL) + return JFW_E_INVALID_ARG; + if (g_pJavaVM == NULL) + *bRunning = sal_False; + else + *bRunning = sal_True; + return JFW_E_NONE; +} + +javaFrameworkError SAL_CALL jfw_getJavaInfoByPath( + rtl_uString *pPath, JavaInfo **ppInfo) +{ + javaFrameworkError errcode = JFW_E_NONE; + try + { + osl::MutexGuard guard(jfw::FwkMutex::get()); + if (pPath == NULL || ppInfo == NULL) + return JFW_E_INVALID_ARG; + + jfw::VendorSettings aVendorSettings; + //Get a list of plugins which provide Java information + std::vector<jfw::PluginLibrary> vecPlugins = + aVendorSettings.getPluginData(); + //Create a vector that holds the libraries, which will be later + //dynamically loaded; + boost::scoped_array<osl::Module> sarModules; + sarModules.reset(new osl::Module[vecPlugins.size()]); + osl::Module * arModules = sarModules.get(); + + typedef std::vector<rtl::OUString>::const_iterator CIT_VENDOR; + std::vector<rtl::OUString> vecVendors = + aVendorSettings.getSupportedVendors(); + + //Use every plug-in library to determine if the path represents a + //JRE. If a plugin recognized it then the loop will break + typedef std::vector<jfw::PluginLibrary>::const_iterator ci_pl; + int cModule = 0; + for (ci_pl i = vecPlugins.begin(); i != vecPlugins.end(); + ++i, ++cModule) + { + const jfw::PluginLibrary & library = *i; + jfw::VersionInfo versionInfo = + aVendorSettings.getVersionInformation(library.sVendor); + arModules[cModule].load(library.sPath); + osl::Module & pluginLib = arModules[cModule]; + if (pluginLib.is() == sal_False) + { + rtl::OString msg = rtl::OUStringToOString( + library.sPath, osl_getThreadTextEncoding()); + fprintf(stderr,"[jvmfwk] Could not load plugin %s\n" \ + "Modify the javavendors.xml accordingly!\n", msg.getStr()); + return JFW_E_NO_PLUGIN; + } + + jfw_plugin_getJavaInfoByPath_ptr jfw_plugin_getJavaInfoByPathFunc = + (jfw_plugin_getJavaInfoByPath_ptr) pluginLib.getFunctionSymbol( + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("jfw_plugin_getJavaInfoByPath"))); + + OSL_ASSERT(jfw_plugin_getJavaInfoByPathFunc); + if (jfw_plugin_getJavaInfoByPathFunc == NULL) + continue; + + //ask the plugin if this is a JRE. + //If so check if it meets the version requirements. + //Only if it does return a JavaInfo + JavaInfo* pInfo = NULL; + javaPluginError plerr = (*jfw_plugin_getJavaInfoByPathFunc)( + pPath, + library.sVendor.pData, + versionInfo.sMinVersion.pData, + versionInfo.sMaxVersion.pData, + versionInfo.getExcludeVersions(), + versionInfo.getExcludeVersionSize(), + & pInfo); + + if (plerr == JFW_PLUGIN_E_NONE) + { + //check if the vendor of the found JRE is supported + if (vecVendors.empty()) + { + //vendor does not matter + *ppInfo = pInfo; + break; + } + else + { + rtl::OUString sVendor(pInfo->sVendor); + CIT_VENDOR ivendor = std::find(vecVendors.begin(), vecVendors.end(), + sVendor); + if (ivendor != vecVendors.end()) + { + *ppInfo = pInfo; + } + else + { + *ppInfo = NULL; + errcode = JFW_E_NOT_RECOGNIZED; + } + break; + } + } + else if(plerr == JFW_PLUGIN_E_FAILED_VERSION) + {//found JRE but it has the wrong version + *ppInfo = NULL; + errcode = JFW_E_FAILED_VERSION; + break; + } + else if (plerr == JFW_PLUGIN_E_NO_JRE) + {// plugin does not recognize this path as belonging to JRE + continue; + } + OSL_ASSERT(0); + } + if (*ppInfo == NULL && errcode != JFW_E_FAILED_VERSION) + errcode = JFW_E_NOT_RECOGNIZED; + } + catch (jfw::FrameworkException& e) + { + errcode = e.errorCode; + fprintf(stderr, "%s\n", e.message.getStr()); + OSL_FAIL(e.message.getStr()); + } + + return errcode; +} + + +javaFrameworkError SAL_CALL jfw_setSelectedJRE(JavaInfo const *pInfo) +{ + javaFrameworkError errcode = JFW_E_NONE; + try + { + osl::MutexGuard guard(jfw::FwkMutex::get()); + if (jfw::getMode() == jfw::JFW_MODE_DIRECT) + return JFW_E_DIRECT_MODE; + //check if pInfo is the selected JRE + JavaInfo *currentInfo = NULL; + errcode = jfw_getSelectedJRE( & currentInfo); + if (errcode != JFW_E_NONE && errcode != JFW_E_INVALID_SETTINGS) + return errcode; + + if (jfw_areEqualJavaInfo(currentInfo, pInfo) == sal_False) + { + jfw::NodeJava node; + node.setJavaInfo(pInfo, false); + node.write(); + //remember that the JRE was selected in this process + jfw::setJavaSelected(); + } + } + catch (jfw::FrameworkException& e) + { + errcode = e.errorCode; + fprintf(stderr, "%s\n", e.message.getStr()); + OSL_FAIL(e.message.getStr()); + } + return errcode; +} +javaFrameworkError SAL_CALL jfw_setEnabled(sal_Bool bEnabled) +{ + javaFrameworkError errcode = JFW_E_NONE; + try + { + osl::MutexGuard guard(jfw::FwkMutex::get()); + if (jfw::getMode() == jfw::JFW_MODE_DIRECT) + return JFW_E_DIRECT_MODE; + + if (g_bEnabledSwitchedOn == false && bEnabled == sal_True) + { + //When the process started then Enabled was false. + //This is first time enabled is set to true. + //That means, no preparational work has been done, such as setting the + //LD_LIBRARY_PATH, etc. + + //check if Enabled is false; + const jfw::MergedSettings settings; + if (settings.getEnabled() == sal_False) + g_bEnabledSwitchedOn = true; + } + jfw::NodeJava node; + node.setEnabled(bEnabled); + node.write(); + } + catch (jfw::FrameworkException& e) + { + errcode = e.errorCode; + fprintf(stderr, "%s\n", e.message.getStr()); + OSL_FAIL(e.message.getStr()); + } + return errcode; +} + +javaFrameworkError SAL_CALL jfw_getEnabled(sal_Bool *pbEnabled) +{ + javaFrameworkError errcode = JFW_E_NONE; + try + { + if (jfw::getMode() == jfw::JFW_MODE_DIRECT) + return JFW_E_DIRECT_MODE; + osl::MutexGuard guard(jfw::FwkMutex::get()); + if (pbEnabled == NULL) + return JFW_E_INVALID_ARG; + jfw::MergedSettings settings; + *pbEnabled = settings.getEnabled(); + } + catch (jfw::FrameworkException& e) + { + errcode = e.errorCode; + fprintf(stderr, "%s\n", e.message.getStr()); + OSL_FAIL(e.message.getStr()); + } + return errcode; +} + + +javaFrameworkError SAL_CALL jfw_setVMParameters( + rtl_uString * * arOptions, sal_Int32 nLen) +{ + javaFrameworkError errcode = JFW_E_NONE; + try + { + osl::MutexGuard guard(jfw::FwkMutex::get()); + if (jfw::getMode() == jfw::JFW_MODE_DIRECT) + return JFW_E_DIRECT_MODE; + jfw::NodeJava node; + if (arOptions == NULL && nLen != 0) + return JFW_E_INVALID_ARG; + node.setVmParameters(arOptions, nLen); + node.write(); + } + catch (jfw::FrameworkException& e) + { + errcode = e.errorCode; + fprintf(stderr, "%s\n", e.message.getStr()); + OSL_FAIL(e.message.getStr()); + } + + return errcode; +} + +javaFrameworkError SAL_CALL jfw_getVMParameters( + rtl_uString *** parOptions, sal_Int32 * pLen) +{ + javaFrameworkError errcode = JFW_E_NONE; + try + { + osl::MutexGuard guard(jfw::FwkMutex::get()); + if (jfw::getMode() == jfw::JFW_MODE_DIRECT) + return JFW_E_DIRECT_MODE; + + if (parOptions == NULL || pLen == NULL) + return JFW_E_INVALID_ARG; + const jfw::MergedSettings settings; + settings.getVmParametersArray(parOptions, pLen); + } + catch (jfw::FrameworkException& e) + { + errcode = e.errorCode; + fprintf(stderr, "%s\n", e.message.getStr()); + OSL_FAIL(e.message.getStr()); + } + return errcode; +} + +javaFrameworkError SAL_CALL jfw_setUserClassPath(rtl_uString * pCp) +{ + javaFrameworkError errcode = JFW_E_NONE; + try + { + osl::MutexGuard guard(jfw::FwkMutex::get()); + if (jfw::getMode() == jfw::JFW_MODE_DIRECT) + return JFW_E_DIRECT_MODE; + jfw::NodeJava node; + if (pCp == NULL) + return JFW_E_INVALID_ARG; + node.setUserClassPath(pCp); + node.write(); + } + catch (jfw::FrameworkException& e) + { + errcode = e.errorCode; + fprintf(stderr, "%s\n", e.message.getStr()); + OSL_FAIL(e.message.getStr()); + } + return errcode; +} + +javaFrameworkError SAL_CALL jfw_getUserClassPath(rtl_uString ** ppCP) +{ + javaFrameworkError errcode = JFW_E_NONE; + try + { + osl::MutexGuard guard(jfw::FwkMutex::get()); + if (jfw::getMode() == jfw::JFW_MODE_DIRECT) + return JFW_E_DIRECT_MODE; + if (ppCP == NULL) + return JFW_E_INVALID_ARG; + const jfw::MergedSettings settings; + *ppCP = settings.getUserClassPath().pData; + rtl_uString_acquire(*ppCP); + } + catch (jfw::FrameworkException& e) + { + errcode = e.errorCode; + fprintf(stderr, "%s\n", e.message.getStr()); + OSL_FAIL(e.message.getStr()); + } + return errcode; +} + +javaFrameworkError SAL_CALL jfw_addJRELocation(rtl_uString * sLocation) +{ + javaFrameworkError errcode = JFW_E_NONE; + try + { + osl::MutexGuard guard(jfw::FwkMutex::get()); + if (jfw::getMode() == jfw::JFW_MODE_DIRECT) + return JFW_E_DIRECT_MODE; + jfw::NodeJava node; + if (sLocation == NULL) + return JFW_E_INVALID_ARG; + node.load(); + node.addJRELocation(sLocation); + node.write(); + } + catch (jfw::FrameworkException& e) + { + errcode = e.errorCode; + fprintf(stderr, "%s\n", e.message.getStr()); + OSL_FAIL(e.message.getStr()); + } + + return errcode; + +} + +javaFrameworkError SAL_CALL jfw_setJRELocations( + rtl_uString ** arLocations, sal_Int32 nLen) +{ + javaFrameworkError errcode = JFW_E_NONE; + try + { + osl::MutexGuard guard(jfw::FwkMutex::get()); + if (jfw::getMode() == jfw::JFW_MODE_DIRECT) + return JFW_E_DIRECT_MODE; + jfw::NodeJava node; + if (arLocations == NULL && nLen != 0) + return JFW_E_INVALID_ARG; + node.setJRELocations(arLocations, nLen); + node.write(); + } + catch (jfw::FrameworkException& e) + { + errcode = e.errorCode; + fprintf(stderr, "%s\n", e.message.getStr()); + OSL_FAIL(e.message.getStr()); + } + return errcode; + +} + +javaFrameworkError SAL_CALL jfw_getJRELocations( + rtl_uString *** parLocations, sal_Int32 *pLen) +{ + javaFrameworkError errcode = JFW_E_NONE; + try + { + osl::MutexGuard guard(jfw::FwkMutex::get()); + if (jfw::getMode() == jfw::JFW_MODE_DIRECT) + return JFW_E_DIRECT_MODE; + + if (parLocations == NULL || pLen == NULL) + return JFW_E_INVALID_ARG; + const jfw::MergedSettings settings; + settings.getJRELocations(parLocations, pLen); + } + catch (jfw::FrameworkException& e) + { + errcode = e.errorCode; + fprintf(stderr, "%s\n", e.message.getStr()); + OSL_FAIL(e.message.getStr()); + } + + return errcode; +} + + +javaFrameworkError jfw_existJRE(const JavaInfo *pInfo, sal_Bool *exist) +{ + //get the function jfw_plugin_existJRE + jfw::VendorSettings aVendorSettings; + jfw::CJavaInfo aInfo; + aInfo = (const ::JavaInfo*) pInfo; //makes a copy of pInfo + rtl::OUString sLibPath = aVendorSettings.getPluginLibrary(aInfo.getVendor()); + osl::Module modulePlugin(sLibPath); + if ( ! modulePlugin) + return JFW_E_NO_PLUGIN; + rtl::OUString sFunctionName( + RTL_CONSTASCII_USTRINGPARAM("jfw_plugin_existJRE")); + jfw_plugin_existJRE_ptr pFunc = + (jfw_plugin_existJRE_ptr) + osl_getFunctionSymbol(modulePlugin, sFunctionName.pData); + if (pFunc == NULL) + return JFW_E_ERROR; + + javaPluginError plerr = (*pFunc)(pInfo, exist); + + javaFrameworkError ret = JFW_E_NONE; + switch (plerr) + { + case JFW_PLUGIN_E_NONE: + ret = JFW_E_NONE; + break; + case JFW_PLUGIN_E_INVALID_ARG: + ret = JFW_E_INVALID_ARG; + break; + case JFW_PLUGIN_E_ERROR: + ret = JFW_E_ERROR; + break; + default: + ret = JFW_E_ERROR; + } + return ret; +} + +void SAL_CALL jfw_lock() +{ + jfw::FwkMutex::get().acquire(); +} + +void SAL_CALL jfw_unlock() +{ + jfw::FwkMutex::get().release(); +} + + +namespace jfw +{ +CJavaInfo::CJavaInfo(): pInfo(0) +{ +} + +CJavaInfo::CJavaInfo(const CJavaInfo & info) +{ + pInfo = copyJavaInfo(info.pInfo); +} + +CJavaInfo::CJavaInfo(::JavaInfo * info, _transfer_ownership) +{ + pInfo = info; +} +CJavaInfo CJavaInfo::createWrapper(::JavaInfo* info) +{ + return CJavaInfo(info, TRANSFER); +} +void CJavaInfo::attach(::JavaInfo * info) +{ + jfw_freeJavaInfo(pInfo); + pInfo = info; +} +::JavaInfo * CJavaInfo::detach() +{ + JavaInfo * tmp = pInfo; + pInfo = NULL; + return tmp; +} + +CJavaInfo::~CJavaInfo() +{ + jfw_freeJavaInfo(pInfo); +} + +CJavaInfo::operator ::JavaInfo* () +{ + return pInfo; +} + +JavaInfo * CJavaInfo::copyJavaInfo(const JavaInfo * pInfo) +{ + if (pInfo == NULL) + return NULL; + JavaInfo* newInfo = + (JavaInfo*) rtl_allocateMemory(sizeof(JavaInfo)); + if (newInfo) + { + rtl_copyMemory(newInfo, pInfo, sizeof(JavaInfo)); + rtl_uString_acquire(pInfo->sVendor); + rtl_uString_acquire(pInfo->sLocation); + rtl_uString_acquire(pInfo->sVersion); + rtl_byte_sequence_acquire(pInfo->arVendorData); + } + return newInfo; +} + + +JavaInfo* CJavaInfo::cloneJavaInfo() const +{ + if (pInfo == NULL) + return NULL; + return copyJavaInfo(pInfo); +} + +CJavaInfo & CJavaInfo::operator = (const CJavaInfo& info) +{ + if (&info == this) + return *this; + + jfw_freeJavaInfo(pInfo); + pInfo = copyJavaInfo(info.pInfo); + return *this; +} +CJavaInfo & CJavaInfo::operator = (const ::JavaInfo* info) +{ + if (info == pInfo) + return *this; + + jfw_freeJavaInfo(pInfo); + pInfo = copyJavaInfo(info); + return *this; +} + +const ::JavaInfo* CJavaInfo::operator ->() const +{ + return pInfo; +} + +CJavaInfo::operator JavaInfo const * () const +{ + return pInfo; +} + +rtl::OUString CJavaInfo::getVendor() const +{ + if (pInfo) + return rtl::OUString(pInfo->sVendor); + else + return rtl::OUString(); +} + +rtl::OUString CJavaInfo::getLocation() const +{ + if (pInfo) + return rtl::OUString(pInfo->sLocation); + else + return rtl::OUString(); +} + +sal_uInt64 CJavaInfo::getFeatures() const +{ + if (pInfo) + return pInfo->nFeatures; + else + return 0l; +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/jvmfwk/source/framework.hxx b/jvmfwk/source/framework.hxx new file mode 100644 index 000000000000..0ba8c6b29583 --- /dev/null +++ b/jvmfwk/source/framework.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. + * + ************************************************************************/ +#if !defined INCLUDED_JVMFWK_LOCAL_FRAMEWORK_HXX +#define INCLUDED_JVMFWK_LOCAL_FRAMEWORK_HXX +#include "rtl/ustring.hxx" +#include "rtl/byteseq.hxx" +#include "jvmfwk/framework.h" +#include "jvmfwk/vendorplugin.h" + +/** typedefs for functions from vendorplugin.h + */ +typedef javaPluginError (*jfw_plugin_getAllJavaInfos_ptr)( + rtl_uString * sVendor, + rtl_uString * sMinVersion, + rtl_uString * sMaxVersion, + rtl_uString * * arExcludeList, + sal_Int32 nLenList, + JavaInfo*** parJavaInfo, + sal_Int32 *nLenInfoList); + +typedef javaPluginError (*jfw_plugin_getJavaInfoByPath_ptr)( + rtl_uString * sPath, + rtl_uString * sVendor, + rtl_uString * sMinVersion, + rtl_uString * sMaxVersion, + rtl_uString * * arExcludeList, + sal_Int32 nLenList, + JavaInfo** ppInfo); + +/** starts a Java Virtual Machine. + <p> + The function shall ensure, that the VM does not abort the process + during instantiation. + </p> + */ +typedef javaPluginError (*jfw_plugin_startJavaVirtualMachine_ptr)( + const JavaInfo *info, + const JavaVMOption* options, + sal_Int32 cOptions, + JavaVM ** ppVM, + JNIEnv ** ppEnv); + +typedef javaPluginError (*jfw_plugin_existJRE_ptr)( + const JavaInfo *info, + sal_Bool *exist); + + +namespace jfw +{ + +class CJavaInfo +{ + static JavaInfo * copyJavaInfo(const JavaInfo * pInfo); + + enum _transfer_ownership {TRANSFER}; + /*Attaching the pointer to this class. The argument pInfo must not + be freed afterwards. + */ + CJavaInfo(::JavaInfo * info, _transfer_ownership); + +public: + ::JavaInfo * pInfo; + + + + CJavaInfo(); + CJavaInfo(const CJavaInfo &); + ~CJavaInfo(); + CJavaInfo& operator =(const ::JavaInfo* info); + CJavaInfo & operator = (const CJavaInfo& info); + + /* The returned class takes ownership of the argument info. info + must not been freed afterwards. + */ + static CJavaInfo createWrapper(::JavaInfo* info); + /*Attaching the pointer to this class. The argument pInfo must not + be freed afterwards. + */ + void attach(::JavaInfo* pInfo); + ::JavaInfo * detach(); + const ::JavaInfo* operator ->() const; + operator ::JavaInfo* (); + operator ::JavaInfo const * () const; + ::JavaInfo* cloneJavaInfo() const; + + rtl::OUString getVendor() const; + rtl::OUString getLocation() const; + sal_uInt64 getFeatures() const; +}; + +class FrameworkException +{ +public: + + FrameworkException(javaFrameworkError err, const rtl::OString& msg): + errorCode(err), message(msg) + { + } + javaFrameworkError errorCode; + rtl::OString message; +}; +} +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/jvmfwk/source/framework.map b/jvmfwk/source/framework.map new file mode 100644 index 000000000000..c95cc83aa826 --- /dev/null +++ b/jvmfwk/source/framework.map @@ -0,0 +1,31 @@ +UDK_3_0_0 { + global: + # jvmfwk/framework.h: + jfw_freeJavaInfo; + jfw_areEqualJavaInfo; + jfw_findAllJREs; + jfw_findAndSelectJRE; + jfw_startVM; + jfw_isVMRunning; + jfw_getJavaInfoByPath; + jfw_setSelectedJRE; + jfw_getSelectedJRE; + jfw_setEnabled; + jfw_getEnabled; + jfw_setVMParameters; + jfw_getVMParameters; + jfw_setUserClassPath; + jfw_getUserClassPath; + jfw_setJRELocations; + jfw_getJRELocations; + jfw_addJRELocation; + jfw_lock; + jfw_unlock; + local: + *; +}; + +UDK_3.1 { # OOo 3.1.0 + global: + jfw_existJRE; +} UDK_3_0_0; diff --git a/jvmfwk/source/fwkbase.cxx b/jvmfwk/source/fwkbase.cxx new file mode 100644 index 000000000000..3b3f4087e610 --- /dev/null +++ b/jvmfwk/source/fwkbase.cxx @@ -0,0 +1,726 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_jvmfwk.hxx" +#include "rtl/ustring.hxx" +#include "rtl/ustrbuf.hxx" +#include "rtl/uri.hxx" +#include "osl/thread.hxx" +#include "osl/process.h" +#include "libxml/xpathInternals.h" +#include "osl/file.hxx" +#include "osl/module.hxx" +#include "framework.hxx" +#include "fwkutil.hxx" +#include "elements.hxx" +#include "fwkbase.hxx" + +using namespace osl; + +using ::rtl::OUString; +using ::rtl::OUStringBuffer; +using ::rtl::OString; +using ::rtl::OUStringToOString; +using ::rtl::OStringToOUString; +#define JAVASETTINGS "javasettings" +#define JAVASETTINGS_XML "javasettings.xml" +#define VENDORSETTINGS "javavendors.xml" + +#define UNO_JAVA_JFW_PARAMETER "UNO_JAVA_JFW_PARAMETER_" +#define UNO_JAVA_JFW_JREHOME "UNO_JAVA_JFW_JREHOME" +#define UNO_JAVA_JFW_ENV_JREHOME "UNO_JAVA_JFW_ENV_JREHOME" +#define UNO_JAVA_JFW_CLASSPATH "UNO_JAVA_JFW_CLASSPATH" +#define UNO_JAVA_JFW_ENV_CLASSPATH "UNO_JAVA_JFW_ENV_CLASSPATH" +#define UNO_JAVA_JFW_CLASSPATH_URLS "UNO_JAVA_JFW_CLASSPATH_URLS" +#define UNO_JAVA_JFW_PARAMETERS "UNO_JAVA_JFW_PARAMETERS" +#define UNO_JAVA_JFW_VENDOR_SETTINGS "UNO_JAVA_JFW_VENDOR_SETTINGS" +#define UNO_JAVA_JFW_USER_DATA "UNO_JAVA_JFW_USER_DATA" +#define UNO_JAVA_JFW_SHARED_DATA "UNO_JAVA_JFW_SHARED_DATA" +#define UNO_JAVA_JFW_INSTALL_DATA "UNO_JAVA_JFW_INSTALL_DATA" +#define UNO_JAVA_JFW_INSTALL_EXPIRE "UNO_JAVA_JFW_INSTALL_EXPIRE" +#define DEFAULT_INSTALL_EXPIRATION 3600 + +namespace jfw +{ +bool g_bJavaSet = false; + +namespace { + +rtl::OString getVendorSettingsPath(rtl::OUString const & sURL) +{ + if (sURL.getLength() == 0) + return rtl::OString(); + rtl::OUString sSystemPathSettings; + if (osl_getSystemPathFromFileURL(sURL.pData, + & sSystemPathSettings.pData) != osl_File_E_None) + throw FrameworkException( + JFW_E_ERROR, + rtl::OString("[Java framework] Error in function " + "getVendorSettingsPath (fwkbase.cxx) ")); + rtl::OString osSystemPathSettings = + rtl::OUStringToOString(sSystemPathSettings,osl_getThreadTextEncoding()); + return osSystemPathSettings; +} + +rtl::OUString getParam(const char * name) +{ + rtl::OUString retVal; + if (Bootstrap::get()->getFrom(rtl::OUString::createFromAscii(name), retVal)) + { +#if OSL_DEBUG_LEVEL >=2 + rtl::OString sValue = rtl::OUStringToOString(retVal, osl_getThreadTextEncoding()); + fprintf(stderr,"[Java framework] Using bootstrap parameter %s = %s.\n", + name, sValue.getStr()); +#endif + } + return retVal; +} + +rtl::OUString getParamFirstUrl(const char * name) +{ + // Some parameters can consist of multiple URLs (separated by space + // characters, although trim() harmlessly also removes other white-space), + // of which only the first is used: + sal_Int32 i = 0; + return getParam(name).trim().getToken(0, ' ', i); +} + +}//blind namespace + + +VendorSettings::VendorSettings(): + m_xmlDocVendorSettingsFileUrl(BootParams::getVendorSettings()) +{ + OString sMsgExc("[Java framework] Error in constructor " + "VendorSettings::VendorSettings() (fwkbase.cxx)"); + //Prepare the xml document and context + OString sSettingsPath = getVendorSettingsPath(m_xmlDocVendorSettingsFileUrl); + if (sSettingsPath.getLength() == 0) + { + OString sMsg("[Java framework] A vendor settings file was not specified." + "Check the bootstrap parameter " UNO_JAVA_JFW_VENDOR_SETTINGS "."); + OSL_FAIL(sMsg.getStr()); + throw FrameworkException(JFW_E_CONFIGURATION, sMsg); + } + if (sSettingsPath.getLength() > 0) + { + m_xmlDocVendorSettings = xmlParseFile(sSettingsPath.getStr()); + if (m_xmlDocVendorSettings == NULL) + throw FrameworkException( + JFW_E_ERROR, + OString("[Java framework] Error while parsing file: ") + + sSettingsPath + OString(".")); + + m_xmlPathContextVendorSettings = xmlXPathNewContext(m_xmlDocVendorSettings); + int res = xmlXPathRegisterNs( + m_xmlPathContextVendorSettings, (xmlChar*) "jf", + (xmlChar*) NS_JAVA_FRAMEWORK); + if (res == -1) + throw FrameworkException(JFW_E_ERROR, sMsgExc); + } +} + +std::vector<PluginLibrary> VendorSettings::getPluginData() +{ + OString sExcMsg("[Java framework] Error in function VendorSettings::getVendorPluginURLs " + "(fwkbase.cxx)."); + std::vector<PluginLibrary> vecPlugins; + CXPathObjectPtr result(xmlXPathEvalExpression( + (xmlChar*)"/jf:javaSelection/jf:plugins/jf:library", + m_xmlPathContextVendorSettings)); + if (xmlXPathNodeSetIsEmpty(result->nodesetval)) + throw FrameworkException(JFW_E_ERROR, sExcMsg); + + //get the values of the library elements + vendor attribute + xmlNode* cur = result->nodesetval->nodeTab[0]; + + while (cur != NULL) + { + //between library elements are also text elements + if (cur->type == XML_ELEMENT_NODE) + { + CXmlCharPtr sAttrVendor(xmlGetProp(cur, (xmlChar*) "vendor")); + CXmlCharPtr sTextLibrary( + xmlNodeListGetString(m_xmlDocVendorSettings, + cur->xmlChildrenNode, 1)); + PluginLibrary plugin; + OString osVendor((sal_Char*)(xmlChar*) sAttrVendor); + plugin.sVendor = OStringToOUString(osVendor, RTL_TEXTENCODING_UTF8); + + //create the file URL to the library + OUString sUrl = findPlugin( + m_xmlDocVendorSettingsFileUrl, sTextLibrary); + if (sUrl.getLength() == 0) + { + OString sPlugin = OUStringToOString( + sTextLibrary, osl_getThreadTextEncoding()); + throw FrameworkException( + JFW_E_CONFIGURATION, + "[Java framework] The file: " + sPlugin + " does not exist."); + } + plugin.sPath = sUrl; + + vecPlugins.push_back(plugin); + } + cur = cur->next; + } + return vecPlugins; +} + +VersionInfo VendorSettings::getVersionInformation(const rtl::OUString & sVendor) +{ + OSL_ASSERT(sVendor.getLength() > 0); + VersionInfo aVersionInfo; + OString osVendor = OUStringToOString(sVendor, RTL_TEXTENCODING_UTF8); + //Get minVersion + OString sExpresion = OString( + "/jf:javaSelection/jf:vendorInfos/jf:vendor[@name=\"") + + osVendor + OString("\"]/jf:minVersion"); + + CXPathObjectPtr xPathObjectMin; + xPathObjectMin = + xmlXPathEvalExpression((xmlChar*) sExpresion.getStr(), + m_xmlPathContextVendorSettings); + if (xmlXPathNodeSetIsEmpty(xPathObjectMin->nodesetval)) + { + aVersionInfo.sMinVersion = OUString(); + } + else + { + CXmlCharPtr sVersion; + sVersion = xmlNodeListGetString( + m_xmlDocVendorSettings, + xPathObjectMin->nodesetval->nodeTab[0]->xmlChildrenNode, 1); + OString osVersion((sal_Char*)(xmlChar*) sVersion); + aVersionInfo.sMinVersion = OStringToOUString( + osVersion, RTL_TEXTENCODING_UTF8); + } + + //Get maxVersion + sExpresion = OString("/jf:javaSelection/jf:vendorInfos/jf:vendor[@name=\"") + + osVendor + OString("\"]/jf:maxVersion"); + CXPathObjectPtr xPathObjectMax; + xPathObjectMax = xmlXPathEvalExpression( + (xmlChar*) sExpresion.getStr(), + m_xmlPathContextVendorSettings); + if (xmlXPathNodeSetIsEmpty(xPathObjectMax->nodesetval)) + { + aVersionInfo.sMaxVersion = OUString(); + } + else + { + CXmlCharPtr sVersion; + sVersion = xmlNodeListGetString( + m_xmlDocVendorSettings, + xPathObjectMax->nodesetval->nodeTab[0]->xmlChildrenNode, 1); + OString osVersion((sal_Char*) (xmlChar*) sVersion); + aVersionInfo.sMaxVersion = OStringToOUString( + osVersion, RTL_TEXTENCODING_UTF8); + } + + //Get excludeVersions + sExpresion = OString("/jf:javaSelection/jf:vendorInfos/jf:vendor[@name=\"") + + osVendor + OString("\"]/jf:excludeVersions/jf:version"); + CXPathObjectPtr xPathObjectVersions; + xPathObjectVersions = + xmlXPathEvalExpression((xmlChar*) sExpresion.getStr(), + m_xmlPathContextVendorSettings); + if (!xmlXPathNodeSetIsEmpty(xPathObjectVersions->nodesetval)) + { + xmlNode* cur = xPathObjectVersions->nodesetval->nodeTab[0]; + while (cur != NULL) + { + if (cur->type == XML_ELEMENT_NODE ) + { + if (xmlStrcmp(cur->name, (xmlChar*) "version") == 0) + { + CXmlCharPtr sVersion; + sVersion = xmlNodeListGetString( + m_xmlDocVendorSettings, cur->xmlChildrenNode, 1); + OString osVersion((sal_Char*)(xmlChar*) sVersion); + OUString usVersion = OStringToOUString( + osVersion, RTL_TEXTENCODING_UTF8); + aVersionInfo.addExcludeVersion(usVersion); + } + } + cur = cur->next; + } + } + return aVersionInfo; +} + +std::vector<OUString> VendorSettings::getSupportedVendors() +{ + std::vector<rtl::OUString> vecVendors; + //get the nodeset for the library elements + jfw::CXPathObjectPtr result; + result = xmlXPathEvalExpression( + (xmlChar*)"/jf:javaSelection/jf:plugins/jf:library", + m_xmlPathContextVendorSettings); + if (xmlXPathNodeSetIsEmpty(result->nodesetval)) + throw FrameworkException( + JFW_E_ERROR, + rtl::OString("[Java framework] Error in function getSupportedVendors (fwkbase.cxx).")); + + //get the values of the library elements + vendor attribute + xmlNode* cur = result->nodesetval->nodeTab[0]; + while (cur != NULL) + { + //between library elements are also text elements + if (cur->type == XML_ELEMENT_NODE) + { + jfw::CXmlCharPtr sAttrVendor(xmlGetProp(cur, (xmlChar*) "vendor")); + vecVendors.push_back(sAttrVendor); + } + cur = cur->next; + } + return vecVendors; +} + +OUString VendorSettings::getPluginLibrary(const OUString& sVendor) +{ + OSL_ASSERT(sVendor.getLength() > 0); + + OString sExcMsg("[Java framework] Error in function getPluginLibrary (fwkbase.cxx)."); + OString sVendorsPath = getVendorSettingsPath(m_xmlDocVendorSettingsFileUrl); + OUStringBuffer usBuffer(256); + usBuffer.appendAscii("/jf:javaSelection/jf:plugins/jf:library[@vendor=\""); + usBuffer.append(sVendor); + usBuffer.appendAscii("\"]/text()"); + OUString ouExpr = usBuffer.makeStringAndClear(); + OString sExpression = + OUStringToOString(ouExpr, osl_getThreadTextEncoding()); + CXPathObjectPtr pathObjVendor; + pathObjVendor = xmlXPathEvalExpression( + (xmlChar*) sExpression.getStr(), m_xmlPathContextVendorSettings); + if (xmlXPathNodeSetIsEmpty(pathObjVendor->nodesetval)) + throw FrameworkException(JFW_E_ERROR, sExcMsg); + + CXmlCharPtr xmlCharPlugin; + xmlCharPlugin = + xmlNodeListGetString( + m_xmlDocVendorSettings,pathObjVendor->nodesetval->nodeTab[0], 1); + + //make an absolute file url from the relative plugin URL + OUString sUrl = findPlugin(m_xmlDocVendorSettingsFileUrl, xmlCharPlugin); + if (sUrl.getLength() == 0) + { + OString sPlugin = OUStringToOString( + xmlCharPlugin, osl_getThreadTextEncoding()); + throw FrameworkException( + JFW_E_CONFIGURATION, + "[Java framework] The file: " + sPlugin + " does not exist."); + } + return sUrl; +} + +::std::vector<OString> BootParams::getVMParameters() +{ + ::std::vector<OString> vecParams; + + for (sal_Int32 i = 1; ; i++) + { + OUString sName = + OUString(RTL_CONSTASCII_USTRINGPARAM(UNO_JAVA_JFW_PARAMETER)) + + OUString::valueOf(i); + OUString sValue; + if (Bootstrap::get()->getFrom(sName, sValue) == sal_True) + { + OString sParam = + OUStringToOString(sValue, osl_getThreadTextEncoding()); + vecParams.push_back(sParam); +#if OSL_DEBUG_LEVEL >=2 + rtl::OString sParamName = rtl::OUStringToOString(sName, osl_getThreadTextEncoding()); + fprintf(stderr,"[Java framework] Using bootstrap parameter %s" + " = %s.\n", sParamName.getStr(), sParam.getStr()); +#endif + } + else + break; + } + return vecParams; +} + +rtl::OUString BootParams::getUserData() +{ + return getParamFirstUrl(UNO_JAVA_JFW_USER_DATA); +} + +rtl::OUString BootParams::getSharedData() +{ + return getParamFirstUrl(UNO_JAVA_JFW_SHARED_DATA); +} + +rtl::OUString BootParams::getInstallData() +{ + return getParam(UNO_JAVA_JFW_INSTALL_DATA); +} + + +rtl::OString BootParams::getClasspath() +{ + rtl::OString sClassPath; + rtl::OUString sCP; + char szSep[] = {SAL_PATHSEPARATOR,0}; + if (Bootstrap::get()->getFrom( + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(UNO_JAVA_JFW_CLASSPATH)), + sCP) == sal_True) + { + sClassPath = rtl::OUStringToOString( + sCP, osl_getThreadTextEncoding()); +#if OSL_DEBUG_LEVEL >=2 + fprintf(stderr,"[Java framework] Using bootstrap parameter " + UNO_JAVA_JFW_CLASSPATH " = %s.\n", sClassPath.getStr()); +#endif + } + + rtl::OUString sEnvCP; + if (Bootstrap::get()->getFrom( + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(UNO_JAVA_JFW_ENV_CLASSPATH)), + sEnvCP) == sal_True) + { + char * pCp = getenv("CLASSPATH"); + if (pCp) + { + sClassPath += rtl::OString(szSep) + rtl::OString(pCp); + } +#if OSL_DEBUG_LEVEL >=2 + fprintf(stderr,"[Java framework] Using bootstrap parameter " + UNO_JAVA_JFW_ENV_CLASSPATH " and class path is:\n %s.\n", pCp ? pCp : ""); +#endif + } + + return sClassPath; +} + +rtl::OUString BootParams::getVendorSettings() +{ + rtl::OUString sVendor; + rtl::OUString sName( + RTL_CONSTASCII_USTRINGPARAM(UNO_JAVA_JFW_VENDOR_SETTINGS)); + if (Bootstrap::get()->getFrom(sName ,sVendor) == sal_True) + { + //check the value of the bootstrap variable + jfw::FileStatus s = checkFileURL(sVendor); + if (s != FILE_OK) + { + //This bootstrap parameter can contain a relative URL + rtl::OUString sAbsoluteUrl; + rtl::OUString sBaseDir = getLibraryLocation(); + if (File::getAbsoluteFileURL(sBaseDir, sVendor, sAbsoluteUrl) + != File::E_None) + throw FrameworkException( + JFW_E_CONFIGURATION, + rtl::OString("[Java framework] Invalid value for bootstrap variable: " + UNO_JAVA_JFW_VENDOR_SETTINGS)); + sVendor = sAbsoluteUrl; + s = checkFileURL(sVendor); + if (s == jfw::FILE_INVALID || s == jfw::FILE_DOES_NOT_EXIST) + { + throw FrameworkException( + JFW_E_CONFIGURATION, + rtl::OString("[Java framework] Invalid value for bootstrap variable: " + UNO_JAVA_JFW_VENDOR_SETTINGS)); + } + } +#if OSL_DEBUG_LEVEL >=2 + rtl::OString sValue = rtl::OUStringToOString(sVendor, osl_getThreadTextEncoding()); + fprintf(stderr,"[Java framework] Using bootstrap parameter " + UNO_JAVA_JFW_VENDOR_SETTINGS" = %s.\n", sValue.getStr()); +#endif + } + return sVendor; +} + +rtl::OUString BootParams::getJREHome() +{ + rtl::OUString sJRE; + rtl::OUString sEnvJRE; + sal_Bool bJRE = Bootstrap::get()->getFrom( + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(UNO_JAVA_JFW_JREHOME)) ,sJRE); + sal_Bool bEnvJRE = Bootstrap::get()->getFrom( + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(UNO_JAVA_JFW_ENV_JREHOME)) ,sEnvJRE); + + if (bJRE == sal_True && bEnvJRE == sal_True) + { + throw FrameworkException( + JFW_E_CONFIGURATION, + rtl::OString("[Java framework] Both bootstrap parameter " + UNO_JAVA_JFW_JREHOME" and " + UNO_JAVA_JFW_ENV_JREHOME" are set. However only one of them can be set." + "Check bootstrap parameters: environment variables, command line " + "arguments, rc/ini files for executable and java framework library.")); + } + else if (bEnvJRE == sal_True) + { + const char * pJRE = getenv("JAVA_HOME"); + if (pJRE == NULL) + { + throw FrameworkException( + JFW_E_CONFIGURATION, + rtl::OString("[Java framework] Both bootstrap parameter " + UNO_JAVA_JFW_ENV_JREHOME" is set, but the environment variable " + "JAVA_HOME is not set.")); + } + rtl::OString osJRE(pJRE); + rtl::OUString usJRE = rtl::OStringToOUString(osJRE, osl_getThreadTextEncoding()); + if (File::getFileURLFromSystemPath(usJRE, sJRE) != File::E_None) + throw FrameworkException( + JFW_E_ERROR, + rtl::OString("[Java framework] Error in function BootParams::getJREHome() " + "(fwkbase.cxx).")); +#if OSL_DEBUG_LEVEL >=2 + fprintf(stderr,"[Java framework] Using bootstrap parameter " + UNO_JAVA_JFW_ENV_JREHOME" with JAVA_HOME = %s.\n", pJRE); +#endif + } + else if (getMode() == JFW_MODE_DIRECT + && bEnvJRE == sal_False + && bJRE == sal_False) + { + throw FrameworkException( + JFW_E_CONFIGURATION, + rtl::OString("[Java framework] The bootstrap parameter " + UNO_JAVA_JFW_ENV_JREHOME" or " UNO_JAVA_JFW_JREHOME + " must be set in direct mode.")); + } + +#if OSL_DEBUG_LEVEL >=2 + if (bJRE == sal_True) + { + rtl::OString sValue = rtl::OUStringToOString(sJRE, osl_getThreadTextEncoding()); + fprintf(stderr,"[Java framework] Using bootstrap parameter " + UNO_JAVA_JFW_JREHOME" = %s.\n", sValue.getStr()); + } +#endif + return sJRE; +} + +rtl::OUString BootParams::getClasspathUrls() +{ + rtl::OUString sParams; + Bootstrap::get()->getFrom( + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(UNO_JAVA_JFW_CLASSPATH_URLS)), + sParams); +#if OSL_DEBUG_LEVEL >=2 + rtl::OString sValue = rtl::OUStringToOString(sParams, osl_getThreadTextEncoding()); + fprintf(stderr,"[Java framework] Using bootstrap parameter " + UNO_JAVA_JFW_CLASSPATH_URLS " = %s.\n", sValue.getStr()); +#endif + return sParams; +} + +::sal_uInt32 BootParams::getInstallDataExpiration() +{ + rtl::OUString sValue; + Bootstrap::get()->getFrom( + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(UNO_JAVA_JFW_INSTALL_EXPIRE)), + sValue); + +#if OSL_DEBUG_LEVEL >=2 + rtl::OString osValue = rtl::OUStringToOString(sValue, osl_getThreadTextEncoding()); + fprintf(stderr,"[Java framework] Using bootstrap parameter " + UNO_JAVA_JFW_INSTALL_EXPIRE " = %s.\n", osValue.getStr()); +#endif + + sal_Int64 nVal = sValue.toInt64(); + if (0 == nVal) + { +#if OSL_DEBUG_LEVEL >=2 + fprintf(stderr,"[Java framework] Using default value for " + "UNO_JAVA_JFW_INSTALL_EXPIRE: %d \n", DEFAULT_INSTALL_EXPIRATION); +#endif + return DEFAULT_INSTALL_EXPIRATION; + } + else + { + return static_cast<sal_uInt32>(nVal); + } +} + +JFW_MODE getMode() +{ + static bool g_bMode = false; + static JFW_MODE g_mode = JFW_MODE_APPLICATION; + + if (g_bMode == false) + { + //check if either of the "direct mode" bootstrap variables is set + bool bDirectMode = true; + rtl::OUString sValue; + const rtl::Bootstrap * aBoot = Bootstrap::get(); + rtl::OUString sJREHome( + RTL_CONSTASCII_USTRINGPARAM(UNO_JAVA_JFW_JREHOME)); + if (aBoot->getFrom(sJREHome, sValue) == sal_False) + { + rtl::OUString sEnvJRE( + RTL_CONSTASCII_USTRINGPARAM(UNO_JAVA_JFW_ENV_JREHOME)); + if (aBoot->getFrom(sEnvJRE, sValue) == sal_False) + { + rtl::OUString sClasspath( + RTL_CONSTASCII_USTRINGPARAM(UNO_JAVA_JFW_CLASSPATH)); + if (aBoot->getFrom(sClasspath, sValue) == sal_False) + { + rtl::OUString sEnvClasspath( + RTL_CONSTASCII_USTRINGPARAM(UNO_JAVA_JFW_ENV_CLASSPATH)); + if (aBoot->getFrom(sEnvClasspath, sValue) == sal_False) + { + rtl::OUString sParams = rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM(UNO_JAVA_JFW_PARAMETER)) + + rtl::OUString::valueOf((sal_Int32)1); + if (aBoot->getFrom(sParams, sValue) == sal_False) + { + bDirectMode = false; + } + } + } + } + } + + if (bDirectMode) + g_mode = JFW_MODE_DIRECT; + else + g_mode = JFW_MODE_APPLICATION; + g_bMode = true; + } + + return g_mode; +} + +rtl::OUString getApplicationClassPath() +{ + OSL_ASSERT(getMode() == JFW_MODE_APPLICATION); + rtl::OUString retVal; + rtl::OUString sParams = BootParams::getClasspathUrls(); + if (sParams.getLength() == 0) + return retVal; + + rtl::OUStringBuffer buf; + sal_Int32 index = 0; + char szClassPathSep[] = {SAL_PATHSEPARATOR,0}; + do + { + ::rtl::OUString token( sParams.getToken( 0, ' ', index ).trim() ); + if (token.getLength()) + { + ::rtl::OUString systemPathElement; + oslFileError rc = osl_getSystemPathFromFileURL( + token.pData, &systemPathElement.pData ); + OSL_ASSERT( rc == osl_File_E_None ); + if (rc == osl_File_E_None && systemPathElement.getLength() > 0) + { + if (buf.getLength() > 0) + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( + szClassPathSep) ); + buf.append( systemPathElement ); + } + } + } + while (index >= 0); + return buf.makeStringAndClear(); +} + +rtl::OString makeClassPathOption(OUString const & sUserClassPath) +{ + //Compose the class path + rtl::OString sPaths; + rtl::OUStringBuffer sBufCP(4096); + char szSep[] = {SAL_PATHSEPARATOR,0}; + + // append all user selected jars to the class path + if (sUserClassPath.getLength() > 0) + sBufCP.append(sUserClassPath); + + //append all jar libraries and components to the class path + OUString sAppCP = getApplicationClassPath(); + if (sAppCP.getLength()) + { + if (sUserClassPath.getLength()) + sBufCP.appendAscii(szSep); + sBufCP.append(sAppCP); + } + + sPaths = rtl::OUStringToOString( + sBufCP.makeStringAndClear(), osl_getThreadTextEncoding()); + + rtl::OString sOptionClassPath("-Djava.class.path="); + sOptionClassPath += sPaths; + return sOptionClassPath; +} + +rtl::OString getUserSettingsPath() +{ + return getSettingsPath(BootParams::getUserData()); +} + +rtl::OString getSharedSettingsPath() +{ + return getSettingsPath(BootParams::getSharedData()); +} + +rtl::OString getInstallSettingsPath() +{ + return getSettingsPath(BootParams::getInstallData()); +} + +rtl::OString getSettingsPath( const rtl::OUString & sURL) +{ + if (sURL.getLength() == 0) + return rtl::OString(); + rtl::OUString sPath; + if (osl_getSystemPathFromFileURL(sURL.pData, + & sPath.pData) != osl_File_E_None) + throw FrameworkException( + JFW_E_ERROR, rtl::OString( + "[Java framework] Error in function ::getSettingsPath (fwkbase.cxx).")); + return rtl::OUStringToOString(sPath,osl_getThreadTextEncoding()); +} + +rtl::OString getVendorSettingsPath() +{ + return getVendorSettingsPath(BootParams::getVendorSettings()); +} + +void setJavaSelected() +{ + g_bJavaSet = true; +} + +bool wasJavaSelectedInSameProcess() +{ + //g_setJavaProcId not set means no Java selected + if (g_bJavaSet == true) + return true; + return false; +} + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/jvmfwk/source/fwkbase.hxx b/jvmfwk/source/fwkbase.hxx new file mode 100644 index 000000000000..0a15f7628e8e --- /dev/null +++ b/jvmfwk/source/fwkbase.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_JVMFWK_FWKBASE_HXX +#define INCLUDED_JVMFWK_FWKBASE_HXX +#include "rtl/ustring.hxx" +#include "libxmlutil.hxx" +namespace jfw +{ + +class VendorSettings +{ + ::rtl::OUString m_xmlDocVendorSettingsFileUrl; + CXmlDocPtr m_xmlDocVendorSettings; + CXPathContextPtr m_xmlPathContextVendorSettings; + +public: + VendorSettings(); + + /** Gets all plugin library URLs with the corresponding vendor name. + + It uses the /javaSelection/plugins/library element from the javavendors.xml + to locate the library. + Is is verified that the plug-in exist. If a plug-in does not exist then an + exception is thrown containing the error JFW_E_CONFIGURATION + */ + ::std::vector<PluginLibrary> getPluginData(); + + /* returns the file URL to the plugin. + */ + ::rtl::OUString getPluginLibrary(const ::rtl::OUString& sVendor); + + VersionInfo getVersionInformation(const ::rtl::OUString & sVendor); + + ::std::vector< ::rtl::OUString> getSupportedVendors(); +}; + +/* The class offers functions to retrieve verified bootstrap parameters. + */ +namespace BootParams +{ + +/* Gets the file URL to the JRE which has been determined by the + bootstrap parameter UNO_JAVA_JFW_JREHOME or UNO_JAVA_JFW_ENV_JREHOME. + + In direct mode either of them must be set. If not an exception is thrown. +*/ +::rtl::OUString getJREHome(); + +::std::vector< ::rtl::OString> getVMParameters(); + +::rtl::OUString getUserData(); + +::rtl::OUString getSharedData(); + +::rtl::OUString getInstallData(); +/* returns the file URL to the vendor settings xml file. + */ +::rtl::OUString getVendorSettings(); + +/* User the parameter UNO_JAVA_JFW_CLASSPATH and UNO_JAVA_JFW_ENV_CLASSPATH + to compose a classpath + */ +::rtl::OString getClasspath(); + +::rtl::OUString getClasspathUrls(); + +/** returns the content of UNO_JAVA_JFW_INSTALL_EXPIRE or a pretermined + value. If the bootstrap variable contains a string that cannot be + converted by OUString then it returns the predetermined value. +*/ +::sal_uInt32 getInstallDataExpiration(); + +} //end namespace + + + +enum JFW_MODE +{ + JFW_MODE_APPLICATION, + + JFW_MODE_DIRECT +}; + +JFW_MODE getMode(); + +/** creates the -Djava.class.path option with the complete classpath, including + the paths which are set by UNO_JAVA_JFW_CLASSPATH_URLS. + */ +::rtl::OString makeClassPathOption(::rtl::OUString const & sUserClassPath); + +::rtl::OString getSettingsPath( const ::rtl::OUString & sURL); + +/** Get the system path to the javasettings.xml + Converts the URL returned from getUserSettingsURL to a + Systempath. An empty string is returned if the file + does not exist. + @throws FrameworkException + */ +::rtl::OString getUserSettingsPath(); + +::rtl::OString getInstallSettingsPath(); + +/** Returns the system path of the share settings file. + Returns a valid string or throws an exception. + @throws FrameworkException + */ +::rtl::OString getSharedSettingsPath(); + +/* returns a valid string or throws an exception. + @throws FrameworkException + */ +::rtl::OString getVendorSettingsPath(); + +::rtl::OUString buildClassPathFromDirectory(const ::rtl::OUString & relPath); + +/** Called from writeJavaInfoData. It sets the process identifier. When +java is to be started, then the current id is compared to the one set by +this function. If they are identical then the Java was selected in the +same process. If that Java needs a prepared environment, such as a +LD_LIBRARY_PATH, then it must not be started in this process. +*/ +void setJavaSelected(); + +/** Determines if the currently selected Java was set in this process. + + @see setProcessId() + */ +bool wasJavaSelectedInSameProcess(); +/* Only for application mode. + */ +::rtl::OUString getApplicationClassPath(); +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/jvmfwk/source/fwkutil.cxx b/jvmfwk/source/fwkutil.cxx new file mode 100644 index 000000000000..8b700922d3aa --- /dev/null +++ b/jvmfwk/source/fwkutil.cxx @@ -0,0 +1,362 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_jvmfwk.hxx" + +#if defined WNT +#if defined _MSC_VER +#pragma warning(push, 1) +#endif +#include <windows.h> +#if defined _MSC_VER +#pragma warning(pop) +#endif +#endif + +#include <string> +#include <string.h> +#include "osl/mutex.hxx" +#include "osl/module.hxx" +#include "osl/thread.hxx" +#include "rtl/ustring.hxx" +#include "rtl/ustrbuf.hxx" +#include "rtl/bootstrap.hxx" +#include "osl/file.hxx" +#include "osl/process.h" +#include "rtl/instance.hxx" +#include "rtl/uri.hxx" +#include "osl/getglobalmutex.hxx" +#include "com/sun/star/lang/IllegalArgumentException.hpp" +#include "cppuhelper/bootstrap.hxx" + +#include "framework.hxx" +#include "fwkutil.hxx" + +using namespace osl; + +using ::rtl::OUString; +using ::rtl::OUStringToOString; +using ::rtl::OString; + +namespace jfw +{ + +bool isAccessibilitySupportDesired() +{ + OUString sValue; + if ((sal_True == ::rtl::Bootstrap::get( + OUString(RTL_CONSTASCII_USTRINGPARAM("JFW_PLUGIN_DO_NOT_CHECK_ACCESSIBILITY")), sValue)) + && sValue.equals(OUString(RTL_CONSTASCII_USTRINGPARAM("1"))) + ) + return false; + + bool retVal = false; +#ifdef WNT + HKEY hKey = 0; + if (RegOpenKeyEx(HKEY_CURRENT_USER, + "Software\\OpenOffice.org\\Accessibility\\AtToolSupport", + 0, KEY_READ, &hKey) == ERROR_SUCCESS) + { + DWORD dwType = 0; + DWORD dwLen = 16; + unsigned char arData[16]; + if( RegQueryValueEx(hKey, "SupportAssistiveTechnology", NULL, &dwType, arData, + & dwLen)== ERROR_SUCCESS) + { + if (dwType == REG_SZ) + { + if (strcmp((char*) arData, "true") == 0 + || strcmp((char*) arData, "1") == 0) + retVal = true; + else if (strcmp((char*) arData, "false") == 0 + || strcmp((char*) arData, "0") == 0) + retVal = false; +#if OSL_DEBUG_LEVEL > 1 + else + OSL_ASSERT(0); +#endif + } + else if (dwType == REG_DWORD) + { + if (arData[0] == 1) + retVal = true; + else if (arData[0] == 0) + retVal = false; +#if OSL_DEBUG_LEVEL > 1 + else + OSL_ASSERT(0); +#endif + } + } + } + RegCloseKey(hKey); + +#elif UNX + char buf[16]; + // use 2 shells to suppress the eventual "gcontool-2 not found" message + // of the shell trying to execute the command + FILE* fp = popen( "/bin/sh 2>/dev/null -c \"gconftool-2 -g /desktop/gnome/interface/accessibility\"", "r" ); + if( fp ) + { + if( fgets( buf, sizeof(buf), fp ) ) + { + int nCompare = strncasecmp( buf, "true", 4 ); + retVal = (nCompare == 0 ? true : false); + } + pclose( fp ); + } +#endif + return retVal; +} + + +rtl::ByteSequence encodeBase16(const rtl::ByteSequence& rawData) +{ + static char EncodingTable[] = + {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; + sal_Int32 lenRaw = rawData.getLength(); + char* pBuf = new char[lenRaw * 2]; + const sal_Int8* arRaw = rawData.getConstArray(); + + char* pCurBuf = pBuf; + for (int i = 0; i < lenRaw; i++) + { + unsigned char curChar = arRaw[i]; + curChar >>= 4; + + *pCurBuf = EncodingTable[curChar]; + pCurBuf++; + + curChar = arRaw[i]; + curChar &= 0x0F; + + *pCurBuf = EncodingTable[curChar]; + pCurBuf++; + } + + rtl::ByteSequence ret((sal_Int8*) pBuf, lenRaw * 2); + delete [] pBuf; + return ret; +} + +rtl::ByteSequence decodeBase16(const rtl::ByteSequence& data) +{ + static char decodingTable[] = + {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; + sal_Int32 lenData = data.getLength(); + sal_Int32 lenBuf = lenData / 2; //always divisable by two + unsigned char* pBuf = new unsigned char[lenBuf]; + const sal_Int8* pData = data.getConstArray(); + for (sal_Int32 i = 0; i < lenBuf; i++) + { + sal_Int8 curChar = *pData++; + //find the index of the first 4bits + // TODO What happens if text is not valid Hex characters? + unsigned char nibble = 0; + for (unsigned char j = 0; j < 16; j++) + { + if (curChar == decodingTable[j]) + { + nibble = j; + break; + } + } + nibble <<= 4; + curChar = *pData++; + //find the index for the next 4bits + for (unsigned char j = 0; j < 16; j++) + { + if (curChar == decodingTable[j]) + { + nibble |= j; + break; + } + } + pBuf[i] = nibble; + } + rtl::ByteSequence ret((sal_Int8*) pBuf, lenBuf ); + delete [] pBuf; + return ret; +} + +rtl::OUString getDirFromFile(const rtl::OUString& usFilePath) +{ + sal_Int32 index= usFilePath.lastIndexOf('/'); + return rtl::OUString(usFilePath.getStr(), index); +} + +rtl::OUString getExecutableDirectory() +{ + rtl_uString* sExe = NULL; + if (osl_getExecutableFile( & sExe) != osl_Process_E_None) + throw FrameworkException( + JFW_E_ERROR, + "[Java framework] Error in function getExecutableDirectory (fwkutil.cxx)"); + + rtl::OUString ouExe(sExe, SAL_NO_ACQUIRE); + return getDirFromFile(ouExe); +} + +rtl::OUString findPlugin( + const rtl::OUString & baseUrl, const rtl::OUString & plugin) +{ + rtl::OUString expandedPlugin; + try + { + expandedPlugin = cppu::bootstrap_expandUri(plugin); + } + catch (com::sun::star::lang::IllegalArgumentException & e) + { + throw FrameworkException( + JFW_E_ERROR, + (rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "[Java framework] IllegalArgumentException in" + " findPlugin: ")) + + rtl::OUStringToOString(e.Message, osl_getThreadTextEncoding()))); + } + rtl::OUString sUrl; + try + { + sUrl = rtl::Uri::convertRelToAbs(baseUrl, expandedPlugin); + } + catch (rtl::MalformedUriException & e) + { + throw FrameworkException( + JFW_E_ERROR, + (rtl::OString( + RTL_CONSTASCII_STRINGPARAM( + "[Java framework] rtl::MalformedUriException in" + " findPlugin: ")) + + rtl::OUStringToOString( + e.getMessage(), osl_getThreadTextEncoding()))); + } + if (checkFileURL(sUrl) == jfw::FILE_OK) + { + return sUrl; + } + rtl::OUString retVal; + rtl::OUString sProgDir = getExecutableDirectory(); + sUrl = sProgDir + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/")) + + plugin; + jfw::FileStatus s = checkFileURL(sUrl); + if (s == jfw::FILE_INVALID || s == jfw::FILE_DOES_NOT_EXIST) + { + //If only the name of the library is given, then + //use PATH, LD_LIBRARY_PATH etc. to locate the plugin + if (plugin.indexOf('/') == -1) + { + rtl::OUString url; +#ifdef UNX +#if defined(MACOSX) + rtl::OUString path = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("DYLD_LIBRARY_PATH")); +#elif defined(AIX) + rtl::OUString path = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("LIBPATH")); +#else + rtl::OUString path = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("LD_LIBRARY_PATH")); +#endif + rtl::OUString env_path; + oslProcessError err = osl_getEnvironment(path.pData, &env_path.pData); + if (err != osl_Process_E_None && err != osl_Process_E_NotFound) + throw FrameworkException( + JFW_E_ERROR, + "[Java framework] Error in function findPlugin (fwkutil.cxx)."); + if (err == osl_Process_E_NotFound) + return retVal; + if (osl_searchFileURL(plugin.pData, env_path.pData, &url.pData) + == osl_File_E_None) +#else + if (osl_searchFileURL(plugin.pData, NULL, &url.pData) + == osl_File_E_None) +#endif + retVal = url; + else + throw FrameworkException( + JFW_E_ERROR, + "[Java framework] Error in function findPlugin (fwkutil.cxx)."); + } + } + else + { + retVal = sUrl; + } + return retVal; +} + +rtl::OUString getLibraryLocation() +{ + rtl::OString sExcMsg("[Java framework] Error in function getLibraryLocation " + "(fwkutil.cxx)."); + rtl::OUString libraryFileUrl; + + if (!osl::Module::getUrlFromAddress( + reinterpret_cast< oslGenericFunction >(getLibraryLocation), + libraryFileUrl)) + throw FrameworkException(JFW_E_ERROR, sExcMsg); + + return getDirFromFile(libraryFileUrl); +} + +jfw::FileStatus checkFileURL(const rtl::OUString & sURL) +{ + jfw::FileStatus ret = jfw::FILE_OK; + DirectoryItem item; + File::RC rc_item = DirectoryItem::get(sURL, item); + if (File::E_None == rc_item) + { + osl::FileStatus status(osl_FileStatus_Mask_Validate); + + File::RC rc_stat = item.getFileStatus(status); + if (File::E_None == rc_stat) + { + ret = FILE_OK; + } + else if (File::E_NOENT == rc_stat) + { + ret = FILE_DOES_NOT_EXIST; + } + else + { + ret = FILE_INVALID; + } + } + else if (File::E_NOENT == rc_item) + { + ret = FILE_DOES_NOT_EXIST; + } + else + { + ret = FILE_INVALID; + } + return ret; +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/jvmfwk/source/fwkutil.hxx b/jvmfwk/source/fwkutil.hxx new file mode 100644 index 000000000000..9e241cf92efe --- /dev/null +++ b/jvmfwk/source/fwkutil.hxx @@ -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. + * + ************************************************************************/ +#if !defined INCLUDED_JVMFWK_FWKUTIL_HXX +#define INCLUDED_JVMFWK_FWKUTIL_HXX + +#include "sal/config.h" +#include "osl/mutex.hxx" +#include "rtl/bootstrap.hxx" +#include "rtl/instance.hxx" +#include "rtl/ustrbuf.hxx" +#include "rtl/byteseq.hxx" +#include "osl/thread.hxx" +#if OSL_DEBUG_LEVEL >=2 +#include <stdio.h> +#endif + + +namespace jfw +{ + +/** Returns the file URL of the directory where the framework library + (this library) resides. +*/ +rtl::OUString getLibraryLocation(); + +/** provides a bootstrap class which already knows the values from the + jvmfkwrc file. +*/ +struct Bootstrap : + public ::rtl::StaticWithInit< const rtl::Bootstrap *, Bootstrap > { + const rtl::Bootstrap * operator () () { + ::rtl::OUStringBuffer buf(256); + buf.append(getLibraryLocation()); + buf.appendAscii(SAL_CONFIGFILE("/jvmfwk3")); + ::rtl::OUString sIni = buf.makeStringAndClear(); + ::rtl::Bootstrap * bootstrap = new ::rtl::Bootstrap(sIni); +#if OSL_DEBUG_LEVEL >=2 + rtl::OString o = rtl::OUStringToOString( sIni , osl_getThreadTextEncoding() ); + fprintf(stderr, "[Java framework] Using configuration file %s\n" , o.getStr() ); +#endif + return bootstrap; + } +}; + +struct FwkMutex: public ::rtl::Static<osl::Mutex, FwkMutex> {}; + +rtl::ByteSequence encodeBase16(const rtl::ByteSequence& rawData); +rtl::ByteSequence decodeBase16(const rtl::ByteSequence& data); + +rtl::OUString getPlatform(); + + +rtl::OUString getDirFromFile(const rtl::OUString& usFilePath); + +/** Returns the file URL of the folder where the executable resides. + */ +rtl::OUString getExecutableDirectory(); +/** Locates the plugin library and returns the file URL. + + First tries to locate plugin relative to baseUrl (if relative); + vnd.sun.star.expand URLs are supported. If that fails, tries to + locate plugin relative to the executable. If that fails, and plugin + contains no slashes, tries to locate plugin in a platform-specific way + (e.g., LD_LIBRARY_PATH). + + @param baseUrl + The base file URL relative to which the plugin argument is interpreted. + + @param plugin + The argument is an absolute or relative URL or just the name of the plugin. + */ +rtl::OUString findPlugin( + const rtl::OUString & baseUrl, const rtl::OUString & plugin); + + +enum FileStatus +{ + FILE_OK, + FILE_DOES_NOT_EXIST, + FILE_INVALID +}; + +/** checks if the URL is a file. + + If it is a link to a file than + it is resolved. Assuming that the argument + represents a relative URL then FILE_INVALID + is returned. + + + @return + one of the values of FileStatus. + + @exception + Errors occurred during determining if the file exists + */ +FileStatus checkFileURL(const rtl::OUString & path); + + +struct PluginLibrary; +class VersionInfo; +class CJavaInfo; + +bool isAccessibilitySupportDesired(); + +rtl::OUString buildClassPathFromDirectory(const rtl::OUString & relPath); + +rtl::OUString retrieveClassPath( ::rtl::OUString const & macro ); +} +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/jvmfwk/source/javasettings.xsd b/jvmfwk/source/javasettings.xsd new file mode 100644 index 000000000000..3b3b28f2192e --- /dev/null +++ b/jvmfwk/source/javasettings.xsd @@ -0,0 +1,54 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<!-- + Document : javasettings.xsd + Created on : 25. März 2004, 16:16 + Author : jl97489 + Description: + Purpose of XML Schema document follows. +--> + +<schema targetNamespace="http://openoffice.org/2004/java/framework/1.0" + xmlns:jf="http://openoffice.org/2004/java/framework/1.0" + xmlns="http://www.w3.org/2001/XMLSchema" + elementFormDefault="qualified"> + +<element name="java"> + <complexType> + <sequence> + <element name="enabled" nillable="true" default="true" type="boolean"/> + <element name="userClassPath" nillable="true" type="string"/> + <element name="vmParameters" nillable="true" type="jf:vmParametersType"/> + <element name="jreLocations" nillable="true" type="jf:jreLocationsType"/> + <element name="javaInfo" nillable="true" type="jf:javaInfoType"/> + </sequence> + </complexType> + +</element> + +<complexType name="javaInfoType"> + <sequence> + <element name="vendor" type="string"/> + <element name="location" type="string"/> + <element name="version" type="string"/> + <element name="features" default="0" type="unsignedLong"/> + <element name="requirements" default="0" type="unsignedLong"/> + <element name="vendorData" type="base64Binary"/> + </sequence> + <attribute name="vendorUpdate" type="date"/> +</complexType> + + +<complexType name="vmParametersType"> + <sequence> + <element name="param" minOccurs="0" maxOccurs="unbounded" type="string"/> + </sequence> +</complexType> + +<complexType name="jreLocationsType"> + <sequence> + <element name="location" minOccurs="0" maxOccurs="unbounded" type="string"/> + </sequence> +</complexType> + +</schema> diff --git a/jvmfwk/source/javasettings_template.xml b/jvmfwk/source/javasettings_template.xml new file mode 100644 index 000000000000..3512501d3ee4 --- /dev/null +++ b/jvmfwk/source/javasettings_template.xml @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<!-- +This file shows what elements the javasettings_platform.xml can contain. +The children of javaInfo are only created when a JRE is selected. The children of +vmParameters are only created when parameters are added and the children of +jreLocations are only created when the paths are added. +See CNodeJava::loadFromSettings and CNodeJava::writeSettings for details. +When extending the javavendors.xml then use the schema to verify it. +--> + +<java xmlns='http://openoffice.org/2004/java/framework/1.0' + xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' + xsi:schemaLocation='http://openoffice.org/2004/java/framework/1.0 file:/D:/cws-jl6/jvmfwk/source/javasettings.xsd'> + <classesDirectory>program/classes</classesDirectory> + <enabled xsi:nil="true"></enabled> + <userClassPath xsi:nil="true"></userClassPath> + <vmParameters xsi:nil="true"/> + <!--param>-Xdebug</param--> + <!--</vmParameters>--> + <jreLocations xsi:nil="true"/> + <!--location></location--> + <!--</jreLocations>--> + <javaInfo xsi:nil="true"/> + <!--javaInfo vendorUpdate="2004-03-27" xsi:nil="false"--> + <!--vendor></vendor> + <location></location> + <version></version> + <features></features> + <requirements></requirements> + <vendorData></vendorData> + </javaInfo--> + </java> + + diff --git a/jvmfwk/source/javasettingsunopkginstall.xml b/jvmfwk/source/javasettingsunopkginstall.xml new file mode 100644 index 000000000000..3efc8e87fc62 --- /dev/null +++ b/jvmfwk/source/javasettingsunopkginstall.xml @@ -0,0 +1,3 @@ +<?xml version="1.0" encoding="UTF-8"?> +<java xmlns="http://openoffice.org/2004/java/framework/1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> +</java> diff --git a/jvmfwk/source/jvmfwk3rc b/jvmfwk/source/jvmfwk3rc new file mode 100644 index 000000000000..048b16e7ab3b --- /dev/null +++ b/jvmfwk/source/jvmfwk3rc @@ -0,0 +1,4 @@ +[Bootstrap] +UNO_JAVA_JFW_ENV_JREHOME=true +UNO_JAVA_JFW_ENV_CLASSPATH=true +UNO_JAVA_JFW_VENDOR_SETTINGS=javavendors.xml
\ No newline at end of file diff --git a/jvmfwk/source/libxmlutil.cxx b/jvmfwk/source/libxmlutil.cxx new file mode 100644 index 000000000000..43d90d686dfd --- /dev/null +++ b/jvmfwk/source/libxmlutil.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_jvmfwk.hxx" +#include "libxmlutil.hxx" + +namespace jfw +{ + +CXPathObjectPtr::CXPathObjectPtr(xmlXPathObject* aObject) + : _object(aObject) +{ +} + +CXPathObjectPtr::CXPathObjectPtr():_object(NULL) +{ +} + +CXPathObjectPtr::~CXPathObjectPtr() +{ + xmlXPathFreeObject(_object); +} +CXPathObjectPtr & CXPathObjectPtr::operator = (xmlXPathObject* pObj) +{ + if (_object == pObj) + return *this; + + xmlXPathFreeObject(_object); + _object = pObj; + return *this; +} +xmlXPathObject* CXPathObjectPtr::operator ->() + +{ + return _object; +} +CXPathObjectPtr::operator xmlXPathObject*() const +{ + return _object; +} +//=========================================================== +CXPathContextPtr::CXPathContextPtr(xmlXPathContextPtr aContext) + : _object(aContext) +{ +} + +CXPathContextPtr::CXPathContextPtr():_object(NULL) +{ +} + +CXPathContextPtr::~CXPathContextPtr() +{ + xmlXPathFreeContext(_object); +} + +CXPathContextPtr & CXPathContextPtr::operator = (xmlXPathContextPtr pObj) +{ + if (_object == pObj) + return *this; + xmlXPathFreeContext(_object); + _object = pObj; + return *this; +} +xmlXPathContext* CXPathContextPtr::operator ->() +{ + return _object; +} + +CXPathContextPtr::operator xmlXPathContext*() const +{ + return _object; +} +//=========================================================== +CXmlDocPtr::CXmlDocPtr(xmlDoc* aDoc) + : _object(aDoc) +{ +} + +CXmlDocPtr::CXmlDocPtr():_object(NULL) +{ +} + +CXmlDocPtr::~CXmlDocPtr() +{ + xmlFreeDoc(_object); +} +CXmlDocPtr & CXmlDocPtr::operator = (xmlDoc* pObj) +{ + if (_object == pObj) + return *this; + xmlFreeDoc(_object); + _object = pObj; + return *this; +} + +xmlDoc* CXmlDocPtr::operator ->() +{ + return _object; +} + +CXmlDocPtr::operator xmlDoc*() const +{ + return _object; +} + +//=========================================================== +CXmlCharPtr::CXmlCharPtr(xmlChar * aChar) + : _object(aChar) +{ +} + +CXmlCharPtr::CXmlCharPtr(const ::rtl::OUString & s): + _object(NULL) +{ + ::rtl::OString o = ::rtl::OUStringToOString(s, RTL_TEXTENCODING_UTF8); + _object = xmlCharStrdup(o.getStr()); +} +CXmlCharPtr::CXmlCharPtr():_object(NULL) +{ +} + +CXmlCharPtr::~CXmlCharPtr() +{ + xmlFree(_object); +} + +CXmlCharPtr & CXmlCharPtr::operator = (xmlChar* pObj) +{ + if (pObj == _object) + return *this; + xmlFree(_object); + _object = pObj; + return *this; +} + +CXmlCharPtr::operator xmlChar*() const +{ + return _object; +} + +CXmlCharPtr::operator ::rtl::OUString() +{ + ::rtl::OUString ret; + if (_object != NULL) + { + ::rtl::OString aOStr((sal_Char*)_object); + ret = ::rtl::OStringToOUString(aOStr, RTL_TEXTENCODING_UTF8); + } + return ret; +} + +CXmlCharPtr::operator ::rtl::OString() +{ + return ::rtl::OString((sal_Char*) _object); +} + + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/jvmfwk/source/libxmlutil.hxx b/jvmfwk/source/libxmlutil.hxx new file mode 100644 index 000000000000..ccc20a233773 --- /dev/null +++ b/jvmfwk/source/libxmlutil.hxx @@ -0,0 +1,112 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_JVMFWK_LIBXMLUTIL_HXX +#define INCLUDED_JVMFWK_LIBXMLUTIL_HXX + + +#include "libxml/parser.h" +#include "libxml/xpath.h" +#include "rtl/ustring.hxx" +namespace jfw +{ +class CXPathObjectPtr +{ + xmlXPathObject* _object; + CXPathObjectPtr & operator = (const CXPathObjectPtr&); + CXPathObjectPtr(const CXPathObjectPtr&); +public: + CXPathObjectPtr(); + /** Takes ownership of xmlXPathObject + */ + CXPathObjectPtr(xmlXPathObject* aObject); + ~CXPathObjectPtr(); + /** Takes ownership of xmlXPathObject + */ + CXPathObjectPtr & operator = (xmlXPathObject* pObj); + xmlXPathObject* operator -> (); + operator xmlXPathObject* () const; +}; + +//=========================================================== +class CXPathContextPtr +{ + xmlXPathContext* _object; + + CXPathContextPtr(const jfw::CXPathContextPtr&); + CXPathContextPtr & operator = (const CXPathContextPtr&); +public: + CXPathContextPtr(); + CXPathContextPtr(xmlXPathContextPtr aContext); + CXPathContextPtr & operator = (xmlXPathContextPtr pObj); + ~CXPathContextPtr(); + xmlXPathContext* operator -> (); + operator xmlXPathContext* () const; +}; + +//=========================================================== +class CXmlDocPtr +{ + xmlDoc* _object; + + CXmlDocPtr(const CXmlDocPtr&); + +public: + CXmlDocPtr & operator = (const CXmlDocPtr&); + CXmlDocPtr(); + CXmlDocPtr(xmlDoc* aDoc); + /** Takes ownership of xmlDoc + */ + CXmlDocPtr & operator = (xmlDoc* pObj); + ~CXmlDocPtr(); + xmlDoc* operator -> (); + operator xmlDoc* () const; +}; + +//=========================================================== +class CXmlCharPtr +{ + xmlChar* _object; + + CXmlCharPtr(const CXmlCharPtr&); + CXmlCharPtr & operator = (const CXmlCharPtr&); +public: + CXmlCharPtr(); + CXmlCharPtr(xmlChar* aDoc); + CXmlCharPtr(const ::rtl::OUString &); + ~CXmlCharPtr(); + CXmlCharPtr & operator = (xmlChar* pObj); + operator xmlChar* () const; + operator ::rtl::OUString (); + operator ::rtl::OString (); +}; + + +} +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/jvmfwk/source/makefile.mk b/jvmfwk/source/makefile.mk new file mode 100644 index 000000000000..76ae22de6a44 --- /dev/null +++ b/jvmfwk/source/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 = jvmfwk +FRAMEWORKLIB=jvmfwk +TARGET = $(FRAMEWORKLIB) +ENABLE_EXCEPTIONS = TRUE + +.IF "$(OS)" != "WNT" +UNIXVERSIONNAMES = UDK +.ENDIF # WNT + +.INCLUDE: settings.mk + +.IF "$(SYSTEM_LIBXML)" == "YES" +CFLAGS+=-DSYSTEM_LIBXML $(LIBXML_CFLAGS) +.ENDIF + +UNOUCROUT = $(OUT)$/inc + +SLOFILES = \ + $(SLO)$/framework.obj \ + $(SLO)$/libxmlutil.obj \ + $(SLO)$/fwkutil.obj \ + $(SLO)$/elements.obj \ + $(SLO)$/fwkbase.obj + + +.IF "$(UNIXVERSIONNAMES)" == "" +SHL1TARGET = $(FRAMEWORKLIB)$(UDK_MAJOR) +.ELSE # UNIXVERSIONNAMES +SHL1TARGET = $(FRAMEWORKLIB) +.ENDIF # UNIXVERSIONNAMES + +SHL1DEPN= +.IF "$(COM)" == "MSC" +SHL1IMPLIB = i$(FRAMEWORKLIB) +.ELSE +SHL1IMPLIB = $(FRAMEWORKLIB) +.ENDIF +SHL1LIBS = $(SLB)$/$(TARGET).lib +SHL1STDLIBS = $(CPPUHELPERLIB) $(SALLIB) $(LIBXML2LIB) +SHL1RPATH = URELIB + +.IF "$(OS)" == "WNT" +SHL1STDLIBS += $(ADVAPI32LIB) +.ENDIF # WNT + +SHL1VERSIONMAP = framework.map +SHL1DEF=$(MISC)$/$(SHL1TARGET).def +DEF1NAME = $(SHL1TARGET) + +.IF "$(GUI)"=="UNX" +RCFILE=$(BIN)$/jvmfwk3rc +.ELIF "$(GUI)"=="WNT" +RCFILE=$(BIN)$/jvmfwk3.ini +.END + + +.INCLUDE: target.mk +$(RCFILE): jvmfwk3rc + -$(COPY) $< $@ + +ALLTAR: \ + $(RCFILE) + diff --git a/jvmfwk/source/readme.txt b/jvmfwk/source/readme.txt new file mode 100644 index 000000000000..f4e822513de5 --- /dev/null +++ b/jvmfwk/source/readme.txt @@ -0,0 +1,9 @@ +The file jvfwk3rc is intended for providing bootstrap parameter for the java +framework within the build environment. It is not part of a product. Tools +which are started in the environment, such as regcomp.exe and uno.exe, use +this rc file when Java is needed. + +The file javasettingsunopkginstall.xml only contains the root element of +a settings file (<java ...>). It is a dummy which will be installed into +office/share/config/. Bundled extensions will used this file to store its +java settings. See framework.h bootstrap variable UNO_JAVA_JFW_INSTALL_DATA |