001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package com.sun.servicetag;
043:
044: import java.util.Date;
045: import java.io.IOException;
046: import static com.sun.servicetag.RegistrationDocument.*;
047:
048: /**
049: * A service tag is an XML-based data structure that identifies a product or
050: * a component on a system. The service tag schema is defined by the
051: * Service Tags Technology. The location of the DTD file is platform dependent.
052: * On Solaris, see <tt>/usr/share/lib/xml/dtd/servicetag.dtd</tt>.
053: * <p>
054: * A valid {@code ServiceTag} instance must comply to the service tag schema
055: * and contain the following fields:
056: * <ul>
057: * <li>{@link #getInstanceURN <tt>instance_urn</tt>}</li>
058: * <li>{@link #getProductName <tt>product_name</tt>}</li>
059: * <li>{@link #getProductVersion <tt>product_version</tt>}</li>
060: * <li>{@link #getProductURN <tt>product_urn</tt>}</li>
061: * <li>{@link #getProductParent <tt>product_parent</tt>}</li>
062: * <li>{@link #getProductParentURN <tt>product_parent_urn</tt>}</li>
063: * <li>{@link #getProductDefinedInstanceID <tt>product_defined_inst_id</tt>}</li>
064: * <li>{@link #getProductVendor <tt>product_vendor</tt>}</li>
065: * <li>{@link #getPlatformArch <tt>platform_arch</tt>}</li>
066: * <li>{@link #getContainer <tt>container</tt>}</li>
067: * <li>{@link #getSource <tt>source</tt>}</li>
068: * <li>{@link #getInstallerUID <tt>installer_uid</tt>}</li>
069: * <li>{@link #getTimestamp <tt>timestamp</tt>}</li>
070: * </ul>
071: *
072: * The <tt>instance_urn</tt> can be specified when a {@code ServiceTag}
073: * object is created, or it can be generated when it is added to
074: * a {@link RegistrationData} object, or {@link Registry
075: * system service tag registry}. The <tt>installer_uid</tt> and
076: * <tt>timestamp</tt> are set when a {@code ServiceTag} object
077: * is added to a {@link RegistrationData} object, or {@link Registry
078: * system service tag registry}.
079: *
080: * @see <a href="https://sunconnection.sun.com/FAQ/sc_faq.html">Service Tags FAQ</a>
081: */
082: public class ServiceTag {
083:
084: private String instanceURN;
085: private String productName;
086: private String productVersion;
087: private String productURN;
088: private String productParent;
089: private String productParentURN;
090: private String productDefinedInstanceID;
091: private String productVendor;
092: private String platformArch;
093: private String container;
094: private String source;
095: private int installerUID;
096: private Date timestamp;
097:
098: // Service Tag Field Lengths (defined in sthelper.h)
099: // Since the constants defined in sthelper.h includes the null-terminated
100: // character, so minus 1 from the sthelper.h defined values.
101: private final int MAX_URN_LEN = 256 - 1;
102: private final int MAX_PRODUCT_NAME_LEN = 256 - 1;
103: private final int MAX_PRODUCT_VERSION_LEN = 64 - 1;
104: private final int MAX_PRODUCT_PARENT_LEN = 256 - 1;
105: private final int MAX_PRODUCT_VENDOR_LEN = 64 - 1;
106: private final int MAX_PLATFORM_ARCH_LEN = 64 - 1;
107: private final int MAX_CONTAINER_LEN = 64 - 1;
108: private final int MAX_SOURCE_LEN = 64 - 1;
109:
110: // private constructors
111: private ServiceTag() {
112: }
113:
114: // package private
115: ServiceTag(String instanceURN, String productName,
116: String productVersion, String productURN,
117: String productParent, String productParentURN,
118: String productDefinedInstanceID, String productVendor,
119: String platformArch, String container, String source,
120: int installerUID, Date timestamp) {
121: setInstanceURN(instanceURN);
122: setProductName(productName);
123: setProductVersion(productVersion);
124: setProductURN(productURN);
125: setProductParentURN(productParentURN);
126: setProductParent(productParent);
127: setProductDefinedInstanceID(productDefinedInstanceID);
128: setProductVendor(productVendor);
129: setPlatformArch(platformArch);
130: setContainer(container);
131: setSource(source);
132: setInstallerUID(installerUID);
133: setTimestamp(timestamp);
134: }
135:
136: /**
137: * Creates a service tag object with no <tt>instance_urn</tt>.
138: *
139: * @param productName the name of the product.
140: * @param productVersion the version of the product.
141: * @param productURN the uniform resource name of the product
142: * @param productParent the name of the product's parent.
143: * @param productParentURN the uniform resource name of the product's parent.
144: * @param productDefinedInstanceID the instance identifier.
145: * @param productVendor the vendor of the product.
146: * @param platformArch the operating system architecture.
147: * @param container the container of the product.
148: * @param source the source of the product.
149: *
150: * @throws IllegalArgumentException if any value of the input fields
151: * does not conform to the service tag XML schema.
152: */
153: public static ServiceTag newInstance(String productName,
154: String productVersion, String productURN,
155: String productParent, String productParentURN,
156: String productDefinedInstanceID, String productVendor,
157: String platformArch, String container, String source) {
158: return new ServiceTag("", /* empty instance_urn */
159: productName, productVersion, productURN, productParent,
160: productParentURN, productDefinedInstanceID,
161: productVendor, platformArch, container, source, -1,
162: null);
163: }
164:
165: /**
166: * Creates a service tag object with a specified <tt>instance_urn</tt>.
167: *
168: * @param instanceURN the uniform resource name of this instance.
169: * @param productName the name of the product.
170: * @param productVersion the version of the product.
171: * @param productURN the uniform resource name of the product
172: * @param productParent the name of the product's parent.
173: * @param productParentURN the uniform resource name of the product's parent.
174: * @param productDefinedInstanceID the instance identifier.
175: * @param productVendor the vendor of the product.
176: * @param platformArch the operating system architecture.
177: * @param container the container of the product.
178: * @param source the source of the product.
179: *
180: * @throws IllegalArgumentException if any value of the input fields
181: * does not conform to the service tag XML schema.
182: */
183: public static ServiceTag newInstance(String instanceURN,
184: String productName, String productVersion,
185: String productURN, String productParent,
186: String productParentURN, String productDefinedInstanceID,
187: String productVendor, String platformArch,
188: String container, String source) {
189: return new ServiceTag(instanceURN, productName, productVersion,
190: productURN, productParent, productParentURN,
191: productDefinedInstanceID, productVendor, platformArch,
192: container, source, -1, null);
193: }
194:
195: // Creates a copy of the ServiceTag instance
196: // with instance_urn and timestamp initialized
197: static ServiceTag newInstanceWithUrnTimestamp(ServiceTag st) {
198: String instanceURN = (st.getInstanceURN().length() == 0 ? Util
199: .generateURN() : st.getInstanceURN());
200: ServiceTag svcTag = new ServiceTag(instanceURN, st
201: .getProductName(), st.getProductVersion(), st
202: .getProductURN(), st.getProductParent(), st
203: .getProductParentURN(), st
204: .getProductDefinedInstanceID(), st.getProductVendor(),
205: st.getPlatformArch(), st.getContainer(),
206: st.getSource(), st.getInstallerUID(), new Date());
207: return svcTag;
208: }
209:
210: /**
211: * Returns a uniform resource name (URN) in this format:
212: * <blockquote>
213: * "<tt>urn:st:<32-char {@link java.util.UUID uuid}></tt>"
214: * </blockquote>
215: * @return a URN.
216: */
217: public static String generateInstanceURN() {
218: return Util.generateURN();
219: }
220:
221: /**
222: * Returns the uniform resource name of this service tag instance.
223: *
224: * @return the <tt>instance_urn</tt> of this service tag.
225: */
226: public String getInstanceURN() {
227: return instanceURN;
228: }
229:
230: /**
231: * Returns the name of the product.
232: *
233: * @return the product name.
234: */
235: public String getProductName() {
236: return productName;
237: }
238:
239: /**
240: * Returns the version of the product.
241: *
242: * @return the product version.
243: */
244: public String getProductVersion() {
245: return productVersion;
246: }
247:
248: /**
249: * Returns the uniform resource name of the product.
250: *
251: * @return the product URN.
252: */
253: public String getProductURN() {
254: return productURN;
255: }
256:
257: /**
258: * Returns the uniform resource name of the product's parent.
259: *
260: * @return the product's parent URN.
261: */
262: public String getProductParentURN() {
263: return productParentURN;
264: }
265:
266: /**
267: * Returns the name of the product's parent.
268: *
269: * @return the product's parent name.
270: */
271: public String getProductParent() {
272: return productParent;
273: }
274:
275: /**
276: * Returns the identifier defined for this product instance.
277: *
278: * @return the identifier defined for this product instance.
279: */
280: public String getProductDefinedInstanceID() {
281: return productDefinedInstanceID;
282: }
283:
284: /**
285: * Returns the vendor of the product.
286: *
287: * @return the product vendor.
288: */
289: public String getProductVendor() {
290: return productVendor;
291: }
292:
293: /**
294: * Returns the platform architecture on which the product
295: * is running on.
296: *
297: * @return the platform architecture on which the product is running on.
298: */
299: public String getPlatformArch() {
300: return platformArch;
301: }
302:
303: /**
304: * Returns the timestamp. This timestamp is set when this service tag
305: * is added to or updated in a {@code RegistrationData} object or
306: * the system service tag registry.
307: * This method may return {@code null}.
308: *
309: * @return timestamp when this service tag
310: * is added to or updated in a {@code RegistrationData} object or
311: * the system service tag registry, or {@code null}.
312: */
313: public Date getTimestamp() {
314: if (timestamp != null) {
315: return (Date) timestamp.clone();
316: } else {
317: return null;
318: }
319: }
320:
321: /**
322: * Returns the container of the product.
323: *
324: * @return the container of the product.
325: */
326: public String getContainer() {
327: return container;
328: }
329:
330: /**
331: * Returns the source of this service tag.
332: *
333: * @return source of this service tag.
334: */
335: public String getSource() {
336: return source;
337: }
338:
339: /**
340: * Returns the UID. The UID is set when this service tag
341: * is added to or updated in the system service tag registry.
342: * This is platform dependent whose default value is {@code -1}.
343: * When this service tag is added to a {@code RegistrationData},
344: * the UID is not set.
345: *
346: * @return the UID of whom this service tag
347: * is added to or updated in the system service tag registry,
348: * or {@code -1}.
349: */
350: public int getInstallerUID() {
351: return installerUID;
352: }
353:
354: // The following setter methods are used to validate the
355: // input field when constructing a ServiceTag instance
356:
357: private void setInstanceURN(String instanceURN) {
358: if (instanceURN == null) {
359: throw new NullPointerException(
360: "Parameter instanceURN cannot be null");
361: }
362: if (instanceURN.length() > MAX_URN_LEN) {
363: throw new IllegalArgumentException("instanceURN \""
364: + instanceURN + "\" exceeds maximum length "
365: + MAX_URN_LEN);
366: }
367: this .instanceURN = instanceURN;
368: }
369:
370: private void setProductName(String productName) {
371: if (productName == null) {
372: throw new NullPointerException(
373: "Parameter productName cannot be null");
374: }
375: if (productName.length() == 0) {
376: throw new IllegalArgumentException(
377: "product name cannot be empty");
378: }
379: if (productName.length() > MAX_PRODUCT_NAME_LEN) {
380: throw new IllegalArgumentException("productName \""
381: + productName + "\" exceeds maximum length "
382: + MAX_PRODUCT_NAME_LEN);
383: }
384: this .productName = productName;
385: }
386:
387: private void setProductVersion(String productVersion) {
388: if (productVersion == null) {
389: throw new NullPointerException(
390: "Parameter productVersion cannot be null");
391: }
392:
393: if (productVersion.length() == 0) {
394: throw new IllegalArgumentException(
395: "product version cannot be empty");
396: }
397: if (productVersion.length() > MAX_PRODUCT_VERSION_LEN) {
398: throw new IllegalArgumentException("productVersion \""
399: + productVersion + "\" exceeds maximum length "
400: + MAX_PRODUCT_VERSION_LEN);
401: }
402: this .productVersion = productVersion;
403: }
404:
405: private void setProductURN(String productURN) {
406: if (productURN == null) {
407: throw new NullPointerException(
408: "Parameter productURN cannot be null");
409: }
410: if (productURN.length() == 0) {
411: throw new IllegalArgumentException(
412: "product URN cannot be empty");
413: }
414: if (productURN.length() > MAX_URN_LEN) {
415: throw new IllegalArgumentException("productURN \""
416: + productURN + "\" exceeds maximum length "
417: + MAX_URN_LEN);
418: }
419: this .productURN = productURN;
420: }
421:
422: private void setProductParentURN(String productParentURN) {
423: if (productParentURN == null) {
424: throw new NullPointerException(
425: "Parameter productParentURN cannot be null");
426: }
427: // optional field - can be empty
428: if (productParentURN.length() > MAX_URN_LEN) {
429: throw new IllegalArgumentException("productParentURN \""
430: + productParentURN + "\" exceeds maximum length "
431: + MAX_URN_LEN);
432: }
433: this .productParentURN = productParentURN;
434: }
435:
436: private void setProductParent(String productParent) {
437: if (productParent == null) {
438: throw new NullPointerException(
439: "Parameter productParent cannot be null");
440: }
441: if (productParent.length() == 0) {
442: throw new IllegalArgumentException(
443: "product parent cannot be empty");
444: }
445: if (productParent.length() > MAX_PRODUCT_PARENT_LEN) {
446: throw new IllegalArgumentException("productParent \""
447: + productParent + "\" exceeds maximum length "
448: + MAX_PRODUCT_PARENT_LEN);
449: }
450: this .productParent = productParent;
451: }
452:
453: void setProductDefinedInstanceID(String productDefinedInstanceID) {
454: if (productDefinedInstanceID == null) {
455: throw new NullPointerException(
456: "Parameter productDefinedInstanceID cannot be null");
457: }
458: if (productDefinedInstanceID.length() > MAX_URN_LEN) {
459: throw new IllegalArgumentException(
460: "productDefinedInstanceID \""
461: + productDefinedInstanceID
462: + "\" exceeds maximum length "
463: + MAX_URN_LEN);
464: }
465: // optional field - can be empty
466: this .productDefinedInstanceID = productDefinedInstanceID;
467: }
468:
469: private void setProductVendor(String productVendor) {
470: if (productVendor == null) {
471: throw new NullPointerException(
472: "Parameter productVendor cannot be null");
473: }
474: if (productVendor.length() == 0) {
475: throw new IllegalArgumentException(
476: "product vendor cannot be empty");
477: }
478: if (productVendor.length() > MAX_PRODUCT_VENDOR_LEN) {
479: throw new IllegalArgumentException("productVendor \""
480: + productVendor + "\" exceeds maximum length "
481: + MAX_PRODUCT_VENDOR_LEN);
482: }
483: this .productVendor = productVendor;
484: }
485:
486: private void setPlatformArch(String platformArch) {
487: if (platformArch == null) {
488: throw new NullPointerException(
489: "Parameter platformArch cannot be null");
490: }
491: if (platformArch.length() == 0) {
492: throw new IllegalArgumentException(
493: "platform architecture cannot be empty");
494: }
495: if (platformArch.length() > MAX_PLATFORM_ARCH_LEN) {
496: throw new IllegalArgumentException("platformArch \""
497: + platformArch + "\" exceeds maximum length "
498: + MAX_PLATFORM_ARCH_LEN);
499: }
500: this .platformArch = platformArch;
501: }
502:
503: private void setTimestamp(Date timestamp) {
504: // can be null
505: this .timestamp = timestamp;
506: }
507:
508: private void setContainer(String container) {
509: if (container == null) {
510: throw new NullPointerException(
511: "Parameter container cannot be null");
512: }
513: if (container.length() == 0) {
514: throw new IllegalArgumentException(
515: "container cannot be empty");
516: }
517: if (container.length() > MAX_CONTAINER_LEN) {
518: throw new IllegalArgumentException("container \""
519: + container + "\" exceeds maximum length "
520: + MAX_CONTAINER_LEN);
521: }
522: this .container = container;
523: }
524:
525: private void setSource(String source) {
526: if (source == null) {
527: throw new NullPointerException(
528: "Parameter source cannot be null");
529: }
530: if (source.length() == 0) {
531: throw new IllegalArgumentException("source cannot be empty");
532: }
533: if (source.length() > MAX_SOURCE_LEN) {
534: throw new IllegalArgumentException("source \"" + source
535: + "\" exceeds maximum length " + MAX_SOURCE_LEN);
536: }
537: this .source = source;
538: }
539:
540: private void setInstallerUID(int installerUID) {
541: this .installerUID = installerUID;
542: }
543:
544: /**
545: * Compares this service tag to the specified object.
546: * The result is {@code true} if and only if the argument is
547: * not {@code null} and is a {@code ServiceTag} object whose
548: * <tt>instance_urn</tt> is the same as the
549: * <tt>instance_urn</tt> of this service tag.
550: *
551: * @return {@code true} if this service tag is the same as
552: * the specified object.
553: */
554: @Override
555: public boolean equals(Object obj) {
556: if (obj == null || !(obj instanceof ServiceTag)) {
557: return false;
558: }
559: ServiceTag st = (ServiceTag) obj;
560: if (st == this ) {
561: return true;
562: }
563: return st.getInstanceURN().equals(getInstanceURN());
564: }
565:
566: /**
567: * Returns the hash code value for this service tag.
568: * @return the hash code value for this service tag.
569: */
570: @Override
571: public int hashCode() {
572: int hash = 7;
573: hash = 19
574: * hash
575: + (this .instanceURN != null ? this .instanceURN
576: .hashCode() : 0);
577: return hash;
578: }
579:
580: /**
581: * Returns the string representation of this service tag.
582: * The format is implementation specific.
583: *
584: * @return the string representation of this service tag.
585: */
586: public String toString() {
587: StringBuilder sb = new StringBuilder();
588: sb.append(ST_NODE_INSTANCE_URN).append("=").append(instanceURN)
589: .append("\n");
590: sb.append(ST_NODE_PRODUCT_NAME).append("=").append(productName)
591: .append("\n");
592: sb.append(ST_NODE_PRODUCT_VERSION).append("=").append(
593: productVersion).append("\n");
594: sb.append(ST_NODE_PRODUCT_URN).append("=").append(productURN)
595: .append("\n");
596: sb.append(ST_NODE_PRODUCT_PARENT_URN).append("=").append(
597: productParentURN).append("\n");
598: sb.append(ST_NODE_PRODUCT_PARENT).append("=").append(
599: productParent).append("\n");
600: sb.append(ST_NODE_PRODUCT_DEFINED_INST_ID).append("=").append(
601: productDefinedInstanceID).append("\n");
602: sb.append(ST_NODE_PRODUCT_VENDOR).append("=").append(
603: productVendor).append("\n");
604: sb.append(ST_NODE_PLATFORM_ARCH).append("=").append(
605: platformArch).append("\n");
606: sb.append(ST_NODE_TIMESTAMP).append("=").append(
607: Util.formatTimestamp(timestamp)).append("\n");
608: sb.append(ST_NODE_CONTAINER).append("=").append(container)
609: .append("\n");
610: sb.append(ST_NODE_SOURCE).append("=").append(source).append(
611: "\n");
612: sb.append(ST_NODE_INSTALLER_UID).append("=").append(
613: String.valueOf(installerUID)).append("\n");
614: return sb.toString();
615: }
616:
617: /**
618: * Returns the {@link ServiceTag} instance for the running Java
619: * platform. The {@link ServiceTag#setSource source} field
620: * of the {@code ServiceTag} will be set to the given {@code source}.
621: * This method will return {@code null} if there is no service tag
622: * for the running Java platform.
623: * <p>
624: * This method is designed for Sun software that bundles the JDK
625: * or the JRE to use. It is recommended that the {@code source}
626: * string contains information about the bundling software
627: * such as the name and the version of the software bundle,
628: * for example,
629: * <blockquote>
630: * <tt>NetBeans IDE 6.0 with JDK 6 Update 5 Bundle</tt>
631: * </blockquote>
632: * in a NetBeans/JDK bundle.
633: * <p>
634: * At the first time to call this method the application
635: * is required to have the write permission to the installed
636: * directory of this running JDK or JRE instance.
637: *
638: * @param source the source that bundles the JDK or the JRE.
639: * @return a {@code ServiceTag} object for the Java platform,
640: * or {@code null} if not supported.
641: * @throws IOException if an error occurs in this operation.
642: */
643: public static ServiceTag getJavaServiceTag(String source)
644: throws IOException {
645: return Installer.getJavaServiceTag(source);
646: }
647:
648: }
|