blob: 4794f8d0de1f2c9143f91ab00179f1592a3df59f [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.util.Date;
import java.io.IOException;
import static com.sun.servicetag.RegistrationDocument.*;
/**
* A service tag is an XML-based data structure that identifies a product or
* a component on a system. The service tag schema is defined by the
* Service Tags Technology. The location of the DTD file is platform dependent.
* On Solaris, see <tt>/usr/share/lib/xml/dtd/servicetag.dtd</tt>.
* <p>
* A valid {@code ServiceTag} instance must comply to the service tag schema
* and contain the following fields:
* <ul>
* <li>{@link #getInstanceURN <tt>instance_urn</tt>}</li>
* <li>{@link #getProductName <tt>product_name</tt>}</li>
* <li>{@link #getProductVersion <tt>product_version</tt>}</li>
* <li>{@link #getProductURN <tt>product_urn</tt>}</li>
* <li>{@link #getProductParent <tt>product_parent</tt>}</li>
* <li>{@link #getProductParentURN <tt>product_parent_urn</tt>}</li>
* <li>{@link #getProductDefinedInstanceID <tt>product_defined_inst_id</tt>}</li>
* <li>{@link #getProductVendor <tt>product_vendor</tt>}</li>
* <li>{@link #getPlatformArch <tt>platform_arch</tt>}</li>
* <li>{@link #getContainer <tt>container</tt>}</li>
* <li>{@link #getSource <tt>source</tt>}</li>
* <li>{@link #getInstallerUID <tt>installer_uid</tt>}</li>
* <li>{@link #getTimestamp <tt>timestamp</tt>}</li>
* </ul>
*
* The <tt>instance_urn</tt> can be specified when a {@code ServiceTag}
* object is created, or it can be generated when it is added to
* a {@link RegistrationData} object, or {@link Registry
* system service tag registry}. The <tt>installer_uid</tt> and
* <tt>timestamp</tt> are set when a {@code ServiceTag} object
* is added to a {@link RegistrationData} object, or {@link Registry
* system service tag registry}.
*
* @see <a href="https://sunconnection.sun.com/FAQ/sc_faq.html">Service Tags FAQ</a>
*/
public class ServiceTag {
private String instanceURN;
private String productName;
private String productVersion;
private String productURN;
private String productParent;
private String productParentURN;
private String productDefinedInstanceID;
private String productVendor;
private String platformArch;
private String container;
private String source;
private int installerUID;
private Date timestamp;
// Service Tag Field Lengths (defined in sthelper.h)
// Since the constants defined in sthelper.h includes the null-terminated
// character, so minus 1 from the sthelper.h defined values.
private final int MAX_URN_LEN = 256 - 1;
private final int MAX_PRODUCT_NAME_LEN = 256 - 1;
private final int MAX_PRODUCT_VERSION_LEN = 64 - 1;
private final int MAX_PRODUCT_PARENT_LEN = 256 - 1;
private final int MAX_PRODUCT_VENDOR_LEN = 64 - 1;
private final int MAX_PLATFORM_ARCH_LEN = 64 - 1;
private final int MAX_CONTAINER_LEN = 64 - 1;
private final int MAX_SOURCE_LEN = 64 - 1;
// private constructors
private ServiceTag() {
}
// package private
ServiceTag(String instanceURN,
String productName,
String productVersion,
String productURN,
String productParent,
String productParentURN,
String productDefinedInstanceID,
String productVendor,
String platformArch,
String container,
String source,
int installerUID,
Date timestamp) {
setInstanceURN(instanceURN);
setProductName(productName);
setProductVersion(productVersion);
setProductURN(productURN);
setProductParentURN(productParentURN);
setProductParent(productParent);
setProductDefinedInstanceID(productDefinedInstanceID);
setProductVendor(productVendor);
setPlatformArch(platformArch);
setContainer(container);
setSource(source);
setInstallerUID(installerUID);
setTimestamp(timestamp);
}
/**
* Creates a service tag object with no <tt>instance_urn</tt>.
*
* @param productName the name of the product.
* @param productVersion the version of the product.
* @param productURN the uniform resource name of the product
* @param productParent the name of the product's parent.
* @param productParentURN the uniform resource name of the product's parent.
* @param productDefinedInstanceID the instance identifier.
* @param productVendor the vendor of the product.
* @param platformArch the operating system architecture.
* @param container the container of the product.
* @param source the source of the product.
*
* @throws IllegalArgumentException if any value of the input fields
* does not conform to the service tag XML schema.
*/
public static ServiceTag newInstance(String productName,
String productVersion,
String productURN,
String productParent,
String productParentURN,
String productDefinedInstanceID,
String productVendor,
String platformArch,
String container,
String source) {
return new ServiceTag("", /* empty instance_urn */
productName,
productVersion,
productURN,
productParent,
productParentURN,
productDefinedInstanceID,
productVendor,
platformArch,
container,
source,
-1,
null);
}
/**
* Creates a service tag object with a specified <tt>instance_urn</tt>.
*
* @param instanceURN the uniform resource name of this instance.
* @param productName the name of the product.
* @param productVersion the version of the product.
* @param productURN the uniform resource name of the product
* @param productParent the name of the product's parent.
* @param productParentURN the uniform resource name of the product's parent.
* @param productDefinedInstanceID the instance identifier.
* @param productVendor the vendor of the product.
* @param platformArch the operating system architecture.
* @param container the container of the product.
* @param source the source of the product.
*
* @throws IllegalArgumentException if any value of the input fields
* does not conform to the service tag XML schema.
*/
public static ServiceTag newInstance(String instanceURN,
String productName,
String productVersion,
String productURN,
String productParent,
String productParentURN,
String productDefinedInstanceID,
String productVendor,
String platformArch,
String container,
String source) {
return new ServiceTag(instanceURN,
productName,
productVersion,
productURN,
productParent,
productParentURN,
productDefinedInstanceID,
productVendor,
platformArch,
container,
source,
-1,
null);
}
// Creates a copy of the ServiceTag instance
// with instance_urn and timestamp initialized
static ServiceTag newInstanceWithUrnTimestamp(ServiceTag st) {
String instanceURN =
(st.getInstanceURN().length() == 0 ? Util.generateURN() :
st.getInstanceURN());
ServiceTag svcTag = new ServiceTag(instanceURN,
st.getProductName(),
st.getProductVersion(),
st.getProductURN(),
st.getProductParent(),
st.getProductParentURN(),
st.getProductDefinedInstanceID(),
st.getProductVendor(),
st.getPlatformArch(),
st.getContainer(),
st.getSource(),
st.getInstallerUID(),
new Date());
return svcTag;
}
/**
* Returns a uniform resource name (URN) in this format:
* <blockquote>
* "<tt>urn:st:<32-char {@link java.util.UUID uuid}></tt>"
* </blockquote>
* @return a URN.
*/
public static String generateInstanceURN() {
return Util.generateURN();
}
/**
* Returns the uniform resource name of this service tag instance.
*
* @return the <tt>instance_urn</tt> of this service tag.
*/
public String getInstanceURN() {
return instanceURN;
}
/**
* Returns the name of the product.
*
* @return the product name.
*/
public String getProductName() {
return productName;
}
/**
* Returns the version of the product.
*
* @return the product version.
*/
public String getProductVersion() {
return productVersion;
}
/**
* Returns the uniform resource name of the product.
*
* @return the product URN.
*/
public String getProductURN() {
return productURN;
}
/**
* Returns the uniform resource name of the product's parent.
*
* @return the product's parent URN.
*/
public String getProductParentURN() {
return productParentURN;
}
/**
* Returns the name of the product's parent.
*
* @return the product's parent name.
*/
public String getProductParent() {
return productParent;
}
/**
* Returns the identifier defined for this product instance.
*
* @return the identifier defined for this product instance.
*/
public String getProductDefinedInstanceID() {
return productDefinedInstanceID;
}
/**
* Returns the vendor of the product.
*
* @return the product vendor.
*/
public String getProductVendor() {
return productVendor;
}
/**
* Returns the platform architecture on which the product
* is running on.
*
* @return the platform architecture on which the product is running on.
*/
public String getPlatformArch() {
return platformArch;
}
/**
* Returns the timestamp. This timestamp is set when this service tag
* is added to or updated in a {@code RegistrationData} object or
* the system service tag registry.
* This method may return {@code null}.
*
* @return timestamp when this service tag
* is added to or updated in a {@code RegistrationData} object or
* the system service tag registry, or {@code null}.
*/
public Date getTimestamp() {
if (timestamp != null) {
return (Date) timestamp.clone();
} else {
return null;
}
}
/**
* Returns the container of the product.
*
* @return the container of the product.
*/
public String getContainer() {
return container;
}
/**
* Returns the source of this service tag.
*
* @return source of this service tag.
*/
public String getSource() {
return source;
}
/**
* Returns the UID. The UID is set when this service tag
* is added to or updated in the system service tag registry.
* This is platform dependent whose default value is {@code -1}.
* When this service tag is added to a {@code RegistrationData},
* the UID is not set.
*
* @return the UID of whom this service tag
* is added to or updated in the system service tag registry,
* or {@code -1}.
*/
public int getInstallerUID() {
return installerUID;
}
// The following setter methods are used to validate the
// input field when constructing a ServiceTag instance
private void setInstanceURN(String instanceURN) {
if (instanceURN == null) {
throw new NullPointerException("Parameter instanceURN cannot be null");
}
if (instanceURN.length() > MAX_URN_LEN) {
throw new IllegalArgumentException("instanceURN \"" + instanceURN +
"\" exceeds maximum length " + MAX_URN_LEN);
}
this.instanceURN = instanceURN;
}
private void setProductName(String productName) {
if (productName == null) {
throw new NullPointerException("Parameter productName cannot be null");
}
if (productName.length() == 0) {
throw new IllegalArgumentException("product name cannot be empty");
}
if (productName.length() > MAX_PRODUCT_NAME_LEN) {
throw new IllegalArgumentException("productName \"" + productName +
"\" exceeds maximum length " + MAX_PRODUCT_NAME_LEN);
}
this.productName = productName;
}
private void setProductVersion(String productVersion) {
if (productVersion == null) {
throw new NullPointerException("Parameter productVersion cannot be null");
}
if (productVersion.length() == 0) {
throw new IllegalArgumentException("product version cannot be empty");
}
if (productVersion.length() > MAX_PRODUCT_VERSION_LEN) {
throw new IllegalArgumentException("productVersion \"" +
productVersion + "\" exceeds maximum length " +
MAX_PRODUCT_VERSION_LEN);
}
this.productVersion = productVersion;
}
private void setProductURN(String productURN) {
if (productURN == null) {
throw new NullPointerException("Parameter productURN cannot be null");
}
if (productURN.length() == 0) {
throw new IllegalArgumentException("product URN cannot be empty");
}
if (productURN.length() > MAX_URN_LEN) {
throw new IllegalArgumentException("productURN \"" + productURN +
"\" exceeds maximum length " + MAX_URN_LEN);
}
this.productURN = productURN;
}
private void setProductParentURN(String productParentURN) {
if (productParentURN == null) {
throw new NullPointerException("Parameter productParentURN cannot be null");
}
// optional field - can be empty
if (productParentURN.length() > MAX_URN_LEN) {
throw new IllegalArgumentException("productParentURN \"" +
productParentURN + "\" exceeds maximum length " +
MAX_URN_LEN);
}
this.productParentURN = productParentURN;
}
private void setProductParent(String productParent) {
if (productParent == null) {
throw new NullPointerException("Parameter productParent cannot be null");
}
if (productParent.length() == 0) {
throw new IllegalArgumentException("product parent cannot be empty");
}
if (productParent.length() > MAX_PRODUCT_PARENT_LEN) {
throw new IllegalArgumentException("productParent \"" +
productParent + "\" exceeds maximum length " +
MAX_PRODUCT_PARENT_LEN);
}
this.productParent = productParent;
}
void setProductDefinedInstanceID(String productDefinedInstanceID) {
if (productDefinedInstanceID == null) {
throw new NullPointerException("Parameter productDefinedInstanceID cannot be null");
}
if (productDefinedInstanceID.length() > MAX_URN_LEN) {
throw new IllegalArgumentException("productDefinedInstanceID \"" +
productDefinedInstanceID + "\" exceeds maximum length " +
MAX_URN_LEN);
}
// optional field - can be empty
this.productDefinedInstanceID = productDefinedInstanceID;
}
private void setProductVendor(String productVendor) {
if (productVendor == null) {
throw new NullPointerException("Parameter productVendor cannot be null");
}
if (productVendor.length() == 0) {
throw new IllegalArgumentException("product vendor cannot be empty");
}
if (productVendor.length() > MAX_PRODUCT_VENDOR_LEN) {
throw new IllegalArgumentException("productVendor \"" +
productVendor + "\" exceeds maximum length " +
MAX_PRODUCT_VENDOR_LEN);
}
this.productVendor = productVendor;
}
private void setPlatformArch(String platformArch) {
if (platformArch == null) {
throw new NullPointerException("Parameter platformArch cannot be null");
}
if (platformArch.length() == 0) {
throw new IllegalArgumentException("platform architecture cannot be empty");
}
if (platformArch.length() > MAX_PLATFORM_ARCH_LEN) {
throw new IllegalArgumentException("platformArch \"" +
platformArch + "\" exceeds maximum length " +
MAX_PLATFORM_ARCH_LEN);
}
this.platformArch = platformArch;
}
private void setTimestamp(Date timestamp) {
// can be null
this.timestamp = timestamp;
}
private void setContainer(String container) {
if (container == null) {
throw new NullPointerException("Parameter container cannot be null");
}
if (container.length() == 0) {
throw new IllegalArgumentException("container cannot be empty");
}
if (container.length() > MAX_CONTAINER_LEN) {
throw new IllegalArgumentException("container \"" +
container + "\" exceeds maximum length " +
MAX_CONTAINER_LEN);
}
this.container = container;
}
private void setSource(String source) {
if (source == null) {
throw new NullPointerException("Parameter source cannot be null");
}
if (source.length() == 0) {
throw new IllegalArgumentException("source cannot be empty");
}
if (source.length() > MAX_SOURCE_LEN) {
throw new IllegalArgumentException("source \"" + source +
"\" exceeds maximum length " + MAX_SOURCE_LEN);
}
this.source = source;
}
private void setInstallerUID(int installerUID) {
this.installerUID = installerUID;
}
/**
* Compares this service tag to the specified object.
* The result is {@code true} if and only if the argument is
* not {@code null} and is a {@code ServiceTag} object whose
* <tt>instance_urn</tt> is the same as the
* <tt>instance_urn</tt> of this service tag.
*
* @return {@code true} if this service tag is the same as
* the specified object.
*/
@Override
public boolean equals(Object obj) {
if (obj == null || !(obj instanceof ServiceTag)) {
return false;
}
ServiceTag st = (ServiceTag) obj;
if (st == this) {
return true;
}
return st.getInstanceURN().equals(getInstanceURN());
}
/**
* Returns the hash code value for this service tag.
* @return the hash code value for this service tag.
*/
@Override
public int hashCode() {
int hash = 7;
hash = 19 * hash + (this.instanceURN != null ? this.instanceURN.hashCode() : 0);
return hash;
}
/**
* Returns the string representation of this service tag.
* The format is implementation specific.
*
* @return the string representation of this service tag.
*/
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(ST_NODE_INSTANCE_URN).append("=").append(instanceURN).append("\n");
sb.append(ST_NODE_PRODUCT_NAME).append("=").append(productName).append("\n");
sb.append(ST_NODE_PRODUCT_VERSION).append("=").append(productVersion).append("\n");
sb.append(ST_NODE_PRODUCT_URN).append("=").append(productURN).append("\n");
sb.append(ST_NODE_PRODUCT_PARENT_URN).append("=").append(productParentURN).append("\n");
sb.append(ST_NODE_PRODUCT_PARENT).append("=").append(productParent).append("\n");
sb.append(ST_NODE_PRODUCT_DEFINED_INST_ID).append("=").append(productDefinedInstanceID).append("\n");
sb.append(ST_NODE_PRODUCT_VENDOR).append("=").append(productVendor).append("\n");
sb.append(ST_NODE_PLATFORM_ARCH).append("=").append(platformArch).append("\n");
sb.append(ST_NODE_TIMESTAMP).append("=").append(Util.formatTimestamp(timestamp)).append("\n");
sb.append(ST_NODE_CONTAINER).append("=").append(container).append("\n");
sb.append(ST_NODE_SOURCE).append("=").append(source).append("\n");
sb.append(ST_NODE_INSTALLER_UID).append("=").append(String.valueOf(installerUID)).append("\n");
return sb.toString();
}
/**
* Returns the {@link ServiceTag} instance for the running Java
* platform. The {@link ServiceTag#setSource source} field
* of the {@code ServiceTag} will be set to the given {@code source}.
* This method will return {@code null} if there is no service tag
* for the running Java platform.
* <p>
* This method is designed for Sun software that bundles the JDK
* or the JRE to use. It is recommended that the {@code source}
* string contains information about the bundling software
* such as the name and the version of the software bundle,
* for example,
* <blockquote>
* <tt>NetBeans IDE 6.0 with JDK 6 Update 5 Bundle</tt>
* </blockquote>
* in a NetBeans/JDK bundle.
* <p>
* At the first time to call this method the application
* is required to have the write permission to the installed
* directory of this running JDK or JRE instance.
*
* @param source the source that bundles the JDK or the JRE.
* @return a {@code ServiceTag} object for the Java platform,
* or {@code null} if not supported.
* @throws IOException if an error occurs in this operation.
*/
public static ServiceTag getJavaServiceTag(String source) throws IOException {
return Installer.getJavaServiceTag(source);
}
}