summaryrefslogtreecommitdiff
path: root/setup_native/source/registration/com/sun/star/servicetag/Installer.java
diff options
context:
space:
mode:
authorRĂ¼diger Timm <rt@openoffice.org>2008-08-01 07:59:23 +0000
committerRĂ¼diger Timm <rt@openoffice.org>2008-08-01 07:59:23 +0000
commit485a56ffb2aeaaf85ab8a22b7866df2b109138c3 (patch)
treeb5af32739055f40f0732bccb007e73f6c4f1f69d /setup_native/source/registration/com/sun/star/servicetag/Installer.java
parent87f540e87ed84f8d38e0ba924abc6b1d7c6d5e5c (diff)
INTEGRATION: CWS register30 (1.1.2); FILE ADDED
2008/07/30 08:02:32 obr 1.1.2.1: #158122# new style registration service
Diffstat (limited to 'setup_native/source/registration/com/sun/star/servicetag/Installer.java')
-rw-r--r--setup_native/source/registration/com/sun/star/servicetag/Installer.java947
1 files changed, 947 insertions, 0 deletions
diff --git a/setup_native/source/registration/com/sun/star/servicetag/Installer.java b/setup_native/source/registration/com/sun/star/servicetag/Installer.java
new file mode 100644
index 000000000000..02825dfec69d
--- /dev/null
+++ b/setup_native/source/registration/com/sun/star/servicetag/Installer.java
@@ -0,0 +1,947 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: Installer.java,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+package com.sun.star.servicetag;
+
+import java.io.*;
+import java.util.HashSet;
+import java.util.Locale;
+import java.util.Properties;
+import java.util.Set;
+import java.util.List;
+import java.util.ArrayList;
+import static com.sun.star.servicetag.Util.*;
+
+/**
+ * Service Tag Installer for Java SE.
+ */
+public class Installer {
+ // System properties for testing
+ private static String SVCTAG_DIR_PATH =
+ "servicetag.dir.path";
+ private static String SVCTAG_ENABLE_REGISTRATION =
+ "servicetag.registration.enabled";
+ private final static String SUN_VENDOR = "Sun Microsystems";
+ private final static String REGISTRATION_XML = "registration.xml";
+ private final static String SERVICE_TAG_FILE = "servicetag";
+ private final static String REGISTRATION_HTML_NAME = "register";
+
+ private final static Locale[] knownSupportedLocales =
+ new Locale[] { Locale.ENGLISH,
+ Locale.JAPANESE,
+ Locale.SIMPLIFIED_CHINESE};
+
+ private final static String javaHome = System.getProperty("java.home");
+ private static File svcTagDir;
+ private static File serviceTagFile;
+ private static File regXmlFile;
+ private static RegistrationData registration;
+ private static boolean supportRegistration;
+ private static String registerHtmlParent;
+ private static Set<Locale> supportedLocales = new HashSet<Locale>();
+ private static Properties swordfishProps = null;
+ private static String[] jreArchs = null;
+ static {
+ String dir = System.getProperty(SVCTAG_DIR_PATH);
+ if (dir == null) {
+ svcTagDir = new File(getJrePath(), "lib" + File.separator + SERVICE_TAG_FILE);
+ } else {
+ svcTagDir = new File(dir);
+ }
+ serviceTagFile = new File(svcTagDir, SERVICE_TAG_FILE);
+ regXmlFile = new File(svcTagDir, REGISTRATION_XML);
+ if (System.getProperty(SVCTAG_ENABLE_REGISTRATION) == null) {
+ supportRegistration = isJdk();
+ } else {
+ supportRegistration = true;
+ }
+ }
+
+ private Installer() {
+ }
+
+ // Implementation of ServiceTag.getJavaServiceTag(String) method
+ static ServiceTag getJavaServiceTag(String source) throws IOException {
+ if (!System.getProperty("java.vendor").startsWith(SUN_VENDOR)) {
+ // Products bundling this implementation may run on
+ // Mac OS which is not a Sun JDK
+ return null;
+ }
+ boolean cleanup = false;
+ try {
+ // Check if we have the swordfish entries for this JRE version
+ if (loadSwordfishEntries() == null) {
+ return null;
+ }
+
+ ServiceTag st = getJavaServiceTag();
+ // Check if the service tag created by this bundle owner
+ if (st != null && st.getSource().equals(source)) {
+ // Install the system service tag if supported
+ // stclient may be installed after the service tag creation
+ if (Registry.isSupported()) {
+ installSystemServiceTag();
+ }
+ return st;
+ }
+
+ // in case any exception thrown during the cleanup
+ cleanup = true;
+
+ // re-create a new one for this bundle owner
+ // first delete the registration data
+ deleteRegistrationData();
+ cleanup = false;
+
+ // create service tag and generate new register.html pages
+ return createServiceTag(source);
+ } finally {
+ if (cleanup) {
+ if (regXmlFile.exists()) {
+ regXmlFile.delete();
+ }
+ if (serviceTagFile.exists()) {
+ serviceTagFile.delete();
+ }
+ }
+ }
+ }
+
+ /**
+ * Returns the Java SE registration data located in
+ * the <JRE>/lib/servicetag/registration.xml by default.
+ *
+ * @throws IllegalArgumentException if the registration data
+ * is of invalid format.
+ */
+ private static synchronized RegistrationData getRegistrationData()
+ throws IOException {
+ if (registration != null) {
+ return registration;
+ }
+ if (regXmlFile.exists()) {
+ BufferedInputStream in = null;
+ try {
+ in = new BufferedInputStream(new FileInputStream(regXmlFile));
+ registration = RegistrationData.loadFromXML(in);
+ } catch (IllegalArgumentException ex) {
+ System.err.println("Error: Bad registration data \"" +
+ regXmlFile + "\":" + ex.getMessage());
+ throw ex;
+ } finally {
+ if (in != null) {
+ in.close();
+ }
+ }
+ } else {
+ registration = new RegistrationData();
+ }
+ return registration;
+ }
+
+ /**
+ * Write the registration data to the registration.xml file.
+ *
+ * The offline registration page has to be regenerated with
+ * the new registration data.
+ *
+ * @throws java.io.IOException
+ */
+ private static synchronized void writeRegistrationXml()
+ throws IOException {
+ if (!svcTagDir.exists()) {
+ // This check is for NetBeans or other products that
+ // bundles this com.sun.servicetag implementation for
+ // pre-6u5 release.
+ if (!svcTagDir.mkdir()) {
+ throw new IOException("Failed to create directory: " + svcTagDir);
+ }
+ }
+
+ // regenerate the new offline registration page
+ deleteRegistrationHtmlPage();
+ getRegistrationHtmlPage();
+
+ BufferedOutputStream out = null;
+ try {
+ out = new BufferedOutputStream(new FileOutputStream(regXmlFile));
+ getRegistrationData().storeToXML(out);
+ } catch (IllegalArgumentException ex) {
+ System.err.println("Error: Bad registration data \"" +
+ regXmlFile + "\":" + ex.getMessage());
+ throw ex;
+ } finally {
+ if (out != null) {
+ out.close();
+ }
+ }
+ }
+
+ /**
+ * Returns the instance urn(s) stored in the servicetag file
+ * or empty set if file not exists.
+ */
+ private static Set<String> getInstalledURNs() throws IOException {
+ Set<String> urnSet = new HashSet<String>();
+ if (serviceTagFile.exists()) {
+ BufferedReader in = null;
+ try {
+ in = new BufferedReader(new FileReader(serviceTagFile));
+ String urn;
+ while ((urn = in.readLine()) != null) {
+ urn = urn.trim();
+ if (urn.length() > 0) {
+ urnSet.add(urn);
+ }
+ }
+ } finally {
+ if (in != null) {
+ in.close();
+ }
+ }
+ }
+ return urnSet;
+ }
+
+ /**
+ * Return the Java SE service tag(s) if it exists.
+ * Typically only one Java SE service tag but it could have two for
+ * Solaris 32-bit and 64-bit on the same install directory.
+ *
+ * @return the service tag(s) for Java SE
+ */
+ private static ServiceTag[] getJavaServiceTagArray() throws IOException {
+ RegistrationData regData = getRegistrationData();
+ Set<ServiceTag> svcTags = regData.getServiceTags();
+ Set<ServiceTag> result = new HashSet<ServiceTag>();
+
+ Properties props = loadSwordfishEntries();
+ String jdkUrn = props.getProperty("servicetag.jdk.urn");
+ String jreUrn = props.getProperty("servicetag.jre.urn");
+ for (ServiceTag st : svcTags) {
+ if (st.getProductURN().equals(jdkUrn) ||
+ st.getProductURN().equals(jreUrn)) {
+ result.add(st);
+ }
+ }
+ return result.toArray(new ServiceTag[0]);
+ }
+
+ /**
+ * Returns the Java SE service tag for this running platform;
+ * or null if not exist.
+ * This method will return the 64-bit service tag if the JDK
+ * supports both 32-bit and 64-bit if already created.
+ */
+ private static ServiceTag getJavaServiceTag() throws IOException {
+ String definedId = getProductDefinedId();
+ for (ServiceTag st : getJavaServiceTagArray()) {
+ if (st.getProductDefinedInstanceID().equals(definedId)) {
+ return st;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Create a service tag for Java SE and install in the system
+ * service tag registry if supported.
+ *
+ * A registration data <JRE>/lib/servicetag/registration.xml
+ * will be created to storeToXML the XML entry for Java SE service tag.
+ * If the system supports service tags, this method will install
+ * the Java SE service tag in the system service tag registry and
+ * its <tt>instance_urn</tt> will be stored to <JRE>/lib/servicetag/servicetag.
+ *
+ * If <JRE>/lib/servicetag/registration.xml exists but is not installed
+ * in the system service tag registry (i.e. servicetag doesn't exist),
+ * this method will install it as described above.
+ *
+ * If the system supports service tag, stclient will be used
+ * to create the Java SE service tag.
+ *
+ * A Solaris 32-bit and 64-bit JDK will be installed in the same
+ * directory but the registration.xml will have 2 service tags.
+ * The servicetag file will also contain 2 instance_urns for that case.
+ */
+ private static ServiceTag createServiceTag(String svcTagSource)
+ throws IOException {
+ // determine if a new service tag is needed to be created
+ ServiceTag newSvcTag = null;
+ if (getJavaServiceTag() == null) {
+ newSvcTag = newServiceTag(svcTagSource);
+ }
+
+ // Add the new service tag in the registration data
+ if (newSvcTag != null) {
+ RegistrationData regData = getRegistrationData();
+
+ // Add the service tag to the registration data in JDK/JRE
+ newSvcTag = regData.addServiceTag(newSvcTag);
+
+ // add if there is a service tag for the OS
+ ServiceTag osTag = SolarisServiceTag.getServiceTag();
+ if (osTag != null && regData.getServiceTag(osTag.getInstanceURN()) == null) {
+ regData.addServiceTag(osTag);
+ }
+ // write to the registration.xml
+ writeRegistrationXml();
+ }
+
+ // Install the system service tag if supported
+ if (Registry.isSupported()) {
+ installSystemServiceTag();
+ }
+ return newSvcTag;
+ }
+
+ private static void installSystemServiceTag() throws IOException {
+ // only install the service tag in the registry if
+ // it has permission to write the servicetag file.
+ if ((!serviceTagFile.exists() && !svcTagDir.canWrite()) ||
+ (serviceTagFile.exists() && !serviceTagFile.canWrite())) {
+ return;
+ }
+
+ Set<String> urns = getInstalledURNs();
+ ServiceTag[] javaSvcTags = getJavaServiceTagArray();
+ if (urns.size() < javaSvcTags.length) {
+ for (ServiceTag st : javaSvcTags) {
+ // Add the service tag in the system service tag registry
+ // if not installed
+ String instanceURN = st.getInstanceURN();
+ if (!urns.contains(instanceURN)) {
+ Registry.getSystemRegistry().addServiceTag(st);
+ }
+ }
+ }
+ writeInstalledUrns();
+ }
+
+ private static ServiceTag newServiceTag(String svcTagSource) throws IOException {
+ // Load the swoRDFish information for the service tag creation
+ Properties props = loadSwordfishEntries();
+
+ // Determine the product URN and name
+ String productURN;
+ String productName;
+
+ if (isJdk()) {
+ // <HOME>/jre exists which implies it's a JDK
+ productURN = props.getProperty("servicetag.jdk.urn");
+ productName = props.getProperty("servicetag.jdk.name");
+ } else {
+ // Otherwise, it's a JRE
+ productURN = props.getProperty("servicetag.jre.urn");
+ productName = props.getProperty("servicetag.jre.name");
+ }
+
+ return ServiceTag.newInstance(ServiceTag.generateInstanceURN(),
+ productName,
+ System.getProperty("java.version"),
+ productURN,
+ props.getProperty("servicetag.parent.name"),
+ props.getProperty("servicetag.parent.urn"),
+ getProductDefinedId(),
+ SUN_VENDOR,
+ System.getProperty("os.arch"),
+ getZoneName(),
+ svcTagSource);
+ }
+
+ /**
+ * Delete the registration data, the offline registration pages and
+ * the service tags in the system service tag registry if installed.
+ *
+ * The registration.xml and servicetag file will be removed.
+ */
+ private static synchronized void deleteRegistrationData()
+ throws IOException {
+ try {
+ // delete the offline registration page
+ deleteRegistrationHtmlPage();
+
+ // Remove the service tag from the system ST registry if exists
+ Set<String> urns = getInstalledURNs();
+ if (urns.size() > 0 && Registry.isSupported()) {
+ for (String u : urns) {
+ Registry.getSystemRegistry().removeServiceTag(u);
+ }
+ }
+ registration = null;
+ } finally {
+ // Delete the registration.xml and servicetag files if exists
+ if (regXmlFile.exists()) {
+ if (!regXmlFile.delete()) {
+ throw new IOException("Failed to delete " + regXmlFile);
+ }
+ }
+ if (serviceTagFile.exists()) {
+ if (!serviceTagFile.delete()) {
+ throw new IOException("Failed to delete " + serviceTagFile);
+ }
+ }
+ }
+ }
+
+ /**
+ * Updates the registration data to contain one single service tag
+ * for the running Java runtime.
+ */
+ private static synchronized void updateRegistrationData(String svcTagSource)
+ throws IOException {
+ RegistrationData regData = getRegistrationData();
+ ServiceTag curSvcTag = newServiceTag(svcTagSource);
+
+ ServiceTag[] javaSvcTags = getJavaServiceTagArray();
+ Set<String> urns = getInstalledURNs();
+ for (ServiceTag st : javaSvcTags) {
+ if (!st.getProductDefinedInstanceID().equals(curSvcTag.getProductDefinedInstanceID())) {
+ String instanceURN = st.getInstanceURN();
+ regData.removeServiceTag(instanceURN);
+
+ // remove it from the system service tag registry if exists
+ if (urns.contains(instanceURN) && Registry.isSupported()) {
+ Registry.getSystemRegistry().removeServiceTag(instanceURN);
+ }
+ }
+ }
+ writeRegistrationXml();
+ writeInstalledUrns();
+ }
+
+ private static void writeInstalledUrns() throws IOException {
+ // if the Registry is not supported,
+ // remove the servicetag file
+ if (!Registry.isSupported() && serviceTagFile.exists()) {
+ serviceTagFile.delete();
+ return;
+ }
+
+ PrintWriter out = null;
+ try {
+ out = new PrintWriter(serviceTagFile);
+
+ ServiceTag[] javaSvcTags = getJavaServiceTagArray();
+ for (ServiceTag st : javaSvcTags) {
+ // Write the instance_run to the servicetag file
+ String instanceURN = st.getInstanceURN();
+ out.println(instanceURN);
+ }
+ } finally {
+ if (out != null) {
+ out.close();
+ }
+ }
+ }
+
+ /**
+ * Load the values associated with the swoRDFish metadata entries
+ * for Java SE. The swoRDFish metadata entries are different for
+ * different release.
+ *
+ * @param version Version of Java SE
+ */
+ private static synchronized Properties loadSwordfishEntries() throws IOException {
+ if (swordfishProps != null) {
+ return swordfishProps;
+ }
+
+ // The version string for Java SE 6 is 1.6.0
+ // We just need the minor number in the version string
+ int version = Util.getJdkVersion();
+
+ String filename = "/com/sun/servicetag/resources/javase_" +
+ version + "_swordfish.properties";
+ InputStream in = Installer.class.getClass().getResourceAsStream(filename);
+ if (in == null) {
+ return null;
+ }
+ swordfishProps = new Properties();
+ try {
+ swordfishProps.load(in);
+ } finally {
+ in.close();
+ }
+ return swordfishProps;
+ }
+
+ /**
+ * Returns the product defined instance ID for Java SE.
+ * It is a list of comma-separated name/value pairs:
+ * "id=<full-version> <arch> [<arch>]*"
+ * "dir=<java.home system property value>"
+ *
+ * where <full-version> is the full version string of the JRE,
+ * <arch> is the architecture that the runtime supports
+ * (i.e. "sparc", "sparcv9", "i386", "amd64" (ISA list))
+ *
+ * For Solaris, it can be dual mode that can support both
+ * 32-bit and 64-bit. the "id" will be set to
+ * "1.6.0_03-b02 sparc sparcv9"
+ *
+ * The "dir" property is included in the service tag to enable
+ * the Service Tag software to determine if a service tag for
+ * Java SE is invalid and perform appropriate service tag
+ * cleanup if necessary. See RFE# 6574781 Service Tags Enhancement.
+ *
+ */
+ private static String getProductDefinedId() {
+ StringBuilder definedId = new StringBuilder();
+ definedId.append("id=");
+ definedId.append(System.getProperty("java.runtime.version"));
+
+ String[] archs = getJreArchs();
+ for (String name : archs) {
+ definedId.append(" " + name);
+ }
+
+ String location = ",dir=" + javaHome;
+ if ((definedId.length() + location.length()) < 256) {
+ definedId.append(",dir=");
+ definedId.append(javaHome);
+ } else {
+ // if it exceeds the limit, we will not include the location
+ if (isVerbose()) {
+ System.err.println("Warning: Product defined instance ID exceeds the field limit:");
+ }
+ }
+
+ return definedId.toString();
+ }
+
+ /**
+ * Returns the architectures that the runtime supports
+ * (i.e. "sparc", "sparcv9", "i386", "amd64" (ISA list))
+ * The directory name where libjava.so is located.
+ *
+ * On Windows, returns the "os.arch" system property value.
+ */
+ private synchronized static String[] getJreArchs() {
+ if (jreArchs != null) {
+ return jreArchs;
+ }
+
+ Set<String> archs = new HashSet<String>();
+
+ String os = System.getProperty("os.name");
+ if (os.equals("SunOS") || os.equals("Linux")) {
+ // Traverse the directories under <JRE>/lib.
+ // If <JRE>/lib/<arch>/libjava.so exists, add <arch>
+ // to the product defined ID
+ File dir = new File(getJrePath() + File.separator + "lib");
+ if (dir.isDirectory()) {
+ String[] children = dir.list();
+ for (String name : children) {
+ File f = new File(dir, name + File.separator + "libjava.so");
+ if (f.exists()) {
+ archs.add(name);
+ }
+ }
+ }
+ } else {
+ // Windows - append the os.arch
+ archs.add(System.getProperty("os.arch"));
+ }
+ jreArchs = archs.toArray(new String[0]);
+ return jreArchs;
+ }
+
+ /**
+ * Return the zonename if zone is supported; otherwise, return
+ * "global".
+ */
+ public static String getZoneName() throws IOException {
+ String zonename = "global";
+
+ String command = "/usr/bin/zonename";
+ File f = new File(command);
+ // com.sun.servicetag package has to be compiled with JDK 5 as well
+ // JDK 5 doesn't support the File.canExecute() method.
+ // Risk not checking isExecute() for the zonename command is very low.
+ if (f.exists()) {
+ ProcessBuilder pb = new ProcessBuilder(command);
+ Process p = pb.start();
+ String output = commandOutput(p);
+ if (p.exitValue() == 0) {
+ zonename = output.trim();
+ }
+
+ }
+ return zonename;
+ }
+
+ private synchronized static String getRegisterHtmlParent() throws IOException {
+ if (registerHtmlParent == null) {
+ File htmlDir; // register.html is put under the JDK directory
+ if (getJrePath().endsWith(File.separator + "jre")) {
+ htmlDir = new File(getJrePath(), "..");
+ } else {
+ // j2se non-image build
+ htmlDir = new File(getJrePath());
+ }
+
+ // initialize the supported locales
+ initSupportedLocales(htmlDir);
+
+ // Determine the location of the offline registration page
+ String path = System.getProperty(SVCTAG_DIR_PATH);
+ if (path == null) {
+ // Default is <JDK>/register.html
+ registerHtmlParent = htmlDir.getCanonicalPath();
+ } else {
+ File f = new File(path);
+ registerHtmlParent = f.getCanonicalPath();
+ if (!f.isDirectory()) {
+ throw new InternalError("Path " + path + " set in \"" +
+ SVCTAG_DIR_PATH + "\" property is not a directory");
+ }
+ }
+ }
+ return registerHtmlParent;
+ }
+
+ /**
+ * Returns the File object of the offline registration page localized
+ * for the default locale in the JDK directory.
+ */
+ static synchronized File getRegistrationHtmlPage() throws IOException {
+ if (!supportRegistration) {
+ // No register.html page generated if JRE
+ return null;
+ }
+
+ String parent = getRegisterHtmlParent();
+
+ // check if the offline registration page is already generated
+ File f = new File(parent, REGISTRATION_HTML_NAME + ".html");
+ if (!f.exists()) {
+ // Generate the localized version of the offline registration Page
+ generateRegisterHtml(parent);
+ }
+
+ String name = REGISTRATION_HTML_NAME;
+ List<Locale> candidateLocales = getCandidateLocales(Locale.getDefault());
+ for (Locale l : candidateLocales) {
+ if (supportedLocales.contains(l)) {
+ name = REGISTRATION_HTML_NAME + "_" + l.toString();
+ break;
+ }
+ }
+ File htmlFile = new File(parent, name + ".html");
+ if (isVerbose()) {
+ System.out.print("Offline registration page: " + htmlFile);
+ System.out.println((htmlFile.exists() ?
+ "" : " not exist. Use register.html"));
+ }
+ if (htmlFile.exists()) {
+ return htmlFile;
+ } else {
+ return new File(parent,
+ REGISTRATION_HTML_NAME + ".html");
+ }
+ }
+
+ private static List<Locale> getCandidateLocales(Locale locale) {
+ String language = locale.getLanguage();
+ String country = locale.getCountry();
+ String variant = locale.getVariant();
+
+ List<Locale> locales = new ArrayList<Locale>(3);
+ if (variant.length() > 0) {
+ locales.add(locale);
+ }
+ if (country.length() > 0) {
+ locales.add((locales.size() == 0) ?
+ locale : new Locale(language, country, ""));
+ }
+ if (language.length() > 0) {
+ locales.add((locales.size() == 0) ?
+ locale : new Locale(language, "", ""));
+ }
+ return locales;
+ }
+
+ // Remove the offline registration pages
+ private static void deleteRegistrationHtmlPage() throws IOException {
+ String parent = getRegisterHtmlParent();
+ if (parent == null) {
+ return;
+ }
+
+ for (Locale locale : supportedLocales) {
+ String name = REGISTRATION_HTML_NAME;
+ if (!locale.equals(Locale.ENGLISH)) {
+ name += "_" + locale.toString();
+ }
+ File f = new File(parent, name + ".html");
+ if (f.exists()) {
+ if (!f.delete()) {
+ throw new IOException("Failed to delete " + f);
+ }
+ }
+ }
+ }
+
+ private static void initSupportedLocales(File jdkDir) {
+ if (supportedLocales.isEmpty()) {
+ // initialize with the known supported locales
+ for (Locale l : knownSupportedLocales) {
+ supportedLocales.add(l);
+ }
+ }
+
+ // Determine unknown supported locales if any
+ // by finding the localized version of README.html
+ // This prepares if a new locale in JDK is supported in
+ // e.g. in the OpenSource world
+ FilenameFilter ff = new FilenameFilter() {
+ public boolean accept(File dir, String name) {
+ String fname = name.toLowerCase();
+ if (fname.startsWith("readme") && fname.endsWith(".html")) {
+ return true;
+ }
+ return false;
+ }
+ };
+
+ String[] readmes = jdkDir.list(ff);
+ for (String name : readmes) {
+ String basename = name.substring(0, name.length() - ".html".length());
+ String[] ss = basename.split("_");
+ switch (ss.length) {
+ case 1:
+ // English version
+ break;
+ case 2:
+ supportedLocales.add(new Locale(ss[1]));
+ break;
+ case 3:
+ supportedLocales.add(new Locale(ss[1], ss[2]));
+ break;
+ default:
+ // ignore
+ break;
+ }
+ }
+ if (isVerbose()) {
+ System.out.println("Supported locales: ");
+ for (Locale l : supportedLocales) {
+ System.out.println(l);
+ }
+ }
+ }
+
+ private static final String JDK_HEADER_PNG_KEY = "@@JDK_HEADER_PNG@@";
+ private static final String JDK_VERSION_KEY = "@@JDK_VERSION@@";
+ private static final String REGISTRATION_URL_KEY = "@@REGISTRATION_URL@@";
+ private static final String REGISTRATION_PAYLOAD_KEY = "@@REGISTRATION_PAYLOAD@@";
+
+ @SuppressWarnings("unchecked")
+ private static void generateRegisterHtml(String parent) throws IOException {
+ int version = Util.getJdkVersion();
+ int update = Util.getUpdateVersion();
+ String jdkVersion = "Version " + version;
+ if (update > 0) {
+ // product name is not translated
+ jdkVersion += " Update " + update;
+ }
+ RegistrationData regData = getRegistrationData();
+ String registerURL = SunConnection.getRegistrationURL(
+ regData.getRegistrationURN()).toString();
+ // Make sure it uses the canonical path before getting the URI.
+ File img = new File(svcTagDir.getCanonicalPath(), "jdk_header.png");
+ String headerImageSrc = img.toURI().toString();
+
+ // Format the registration data in one single line
+ StringBuilder payload = new StringBuilder();
+ String xml = regData.toString().replaceAll("\"", "%22");
+ BufferedReader reader = new BufferedReader(new StringReader(xml));
+ try {
+ String line = null;
+ while ((line = reader.readLine()) != null) {
+ payload.append(line.trim());
+ }
+ } finally {
+ reader.close();
+ }
+
+ String resourceFilename = "/com/sun/star/servicetag/resources/register";
+ for (Locale locale : supportedLocales) {
+ String name = REGISTRATION_HTML_NAME;
+ String resource = resourceFilename;
+ if (!locale.equals(Locale.ENGLISH)) {
+ name += "_" + locale.toString();
+ resource += "_" + locale.toString();
+ }
+ File f = new File(parent, name + ".html");
+ InputStream in = null;
+ BufferedReader br = null;
+ PrintWriter pw = null;
+ try {
+ in = Installer.class.getClass().getResourceAsStream(resource + ".html");
+ if (in == null) {
+ // if the resource file is missing
+ if (isVerbose()) {
+ System.out.println("Missing resouce file: " + resource + ".html");
+ }
+ continue;
+ }
+ if (isVerbose()) {
+ System.out.println("Generating " + f + " from " + resource + ".html");
+ }
+
+ br = new BufferedReader(new InputStreamReader(in, "UTF-8"));
+ pw = new PrintWriter(f, "UTF-8");
+ String line = null;
+ while ((line = br.readLine()) != null) {
+ String output = line;
+ if (line.contains(JDK_VERSION_KEY)) {
+ output = line.replace(JDK_VERSION_KEY, jdkVersion);
+ } else if (line.contains(JDK_HEADER_PNG_KEY)) {
+ output = line.replace(JDK_HEADER_PNG_KEY, headerImageSrc);
+ } else if (line.contains(REGISTRATION_URL_KEY)) {
+ output = line.replace(REGISTRATION_URL_KEY, registerURL);
+ } else if (line.contains(REGISTRATION_PAYLOAD_KEY)) {
+ output = line.replace(REGISTRATION_PAYLOAD_KEY, payload.toString());
+ }
+ pw.println(output);
+ }
+ f.setReadOnly();
+ pw.flush();
+ } finally {
+ if (pw != null) {
+ pw.close();
+ }
+ if (in != null) {
+ in.close();
+ }
+ if (br!= null) {
+ br.close();
+ }
+ }
+ }
+ }
+
+ /**
+ * A utility class to create a service tag for Java SE.
+ * <p>
+ * <b>Usage:</b><br>
+ * <blockquote><tt>
+ * &lt;JAVA_HOME&gt;/bin/java com.sun.servicetag.Installer
+ * </tt></blockquote>
+ * <p>
+ */
+ public static void main(String[] args) {
+ String source = "Manual";
+
+ // Parse the options (arguments starting with "-" )
+ boolean delete = false;
+ boolean update = false;
+ boolean register = false;
+ int count = 0;
+ while (count < args.length) {
+ String arg = args[count];
+ if (arg.trim().length() == 0) {
+ // skip empty arguments
+ count++;
+ continue;
+ }
+
+ if (arg.equals("-source")) {
+ source = args[++count];
+ } else if (arg.equals("-delete")) {
+ delete = true;
+ } else if (arg.equals("-register")) {
+ register = true;
+ } else {
+ usage();
+ return;
+ }
+ count++;
+ }
+ try {
+ if (delete) {
+ deleteRegistrationData();
+ } else {
+ ServiceTag[] javaSvcTags = getJavaServiceTagArray();
+ String[] archs = getJreArchs();
+ if (javaSvcTags.length > archs.length) {
+ // 64-bit has been uninstalled
+ // so remove the service tag
+ updateRegistrationData(source);
+ } else {
+ // create the service tag
+ createServiceTag(source);
+ }
+ }
+
+ if (register) {
+ // Registration is only supported by JDK
+ // For testing purpose, override with a "servicetag.enable.registration" property
+
+ RegistrationData regData = getRegistrationData();
+ if (supportRegistration && !regData.getServiceTags().isEmpty()) {
+ SunConnection.register(regData);
+ }
+ }
+ System.exit(0);
+ } catch (IOException e) {
+ System.err.println("I/O Error: " + e.getMessage());
+ if (isVerbose()) {
+ e.printStackTrace();
+ }
+ } catch (IllegalArgumentException ex) {
+ if (isVerbose()) {
+ ex.printStackTrace();
+ }
+ } catch (Exception e) {
+ System.err.println("Error: " + e.getMessage());
+ if (isVerbose()) {
+ e.printStackTrace();
+ }
+ }
+ System.exit(1);
+ }
+
+ private static void usage() {
+ System.out.println("Usage:");
+ System.out.print(" " + Installer.class.getName());
+ System.out.println(" [-delete|-source <source>|-register]");
+ System.out.println(" to create a service tag for the Java platform");
+ System.out.println("");
+ System.out.println("Internal Options:");
+ System.out.println(" -source: to specify the source of the service tag to be created");
+ System.out.println(" -delete: to delete the service tag ");
+ System.out.println(" -register: to register the JDK");
+ System.out.println(" -help: to print this help message");
+ }
+}