blob: 2c8476e71f88ed134fd2a409b7eec1367cdf1b1e [file] [log] [blame]
/*
* Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.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.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.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".
*/
private 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;
Locale locale = getDefaultLocale();
if (!locale.equals(Locale.ENGLISH) && supportedLocales.contains(locale)) {
// if the locale is not English and is supported by JDK
// set to the appropriate offline registration page;
// otherwise,set to register.html.
name = REGISTRATION_HTML_NAME + "_" + locale.toString();
}
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 Locale getDefaultLocale() {
List<Locale> candidateLocales = getCandidateLocales(Locale.getDefault());
for (Locale l : candidateLocales) {
if (supportedLocales.contains(l)) {
return l;
}
}
return Locale.getDefault();
}
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();
// Make sure it uses the canonical path before getting the URI.
File img = new File(svcTagDir.getCanonicalPath(), "jdk_header.png");
String headerImageSrc = img.toURI().toString();
// Format the registration data in one single line
StringBuilder payload = new StringBuilder();
String xml = regData.toString().replaceAll("\"", "%22");
BufferedReader reader = new BufferedReader(new StringReader(xml));
try {
String line = null;
while ((line = reader.readLine()) != null) {
payload.append(line.trim());
}
} finally {
reader.close();
}
String resourceFilename = "/com/sun/servicetag/resources/register";
for (Locale locale : supportedLocales) {
String name = REGISTRATION_HTML_NAME;
String resource = resourceFilename;
if (!locale.equals(Locale.ENGLISH)) {
name += "_" + locale.toString();
resource += "_" + locale.toString();
}
File f = new File(parent, name + ".html");
InputStream in = null;
BufferedReader br = null;
PrintWriter pw = null;
String registerURL = SunConnection.
getRegistrationURL(regData.getRegistrationURN(),
locale,
String.valueOf(version)).toString();
try {
in = Installer.class.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");
}
try {
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 {
// It's safe for this finally block to have two close statements
// consecutively as PrintWriter.close doesn't throw IOException.
if (pw != null) {
pw.close();
}
if (br!= null) {
br.close();
}
}
} finally {
if (in != null) {
in.close();
}
}
}
}
private static final int MAX_SOURCE_LEN = 63;
/**
* 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 ";
String runtimeName = System.getProperty("java.runtime.name");
if (runtimeName.startsWith("OpenJDK")) {
source = "OpenJDK ";
}
source += System.getProperty("java.runtime.version");
if (source.length() > MAX_SOURCE_LEN) {
source = source.substring(0, MAX_SOURCE_LEN);
}
// 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,
getDefaultLocale(),
String.valueOf(Util.getJdkVersion()));
}
}
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");
}
}