001: /*
002: * All content copyright (c) 2003-2007 Terracotta, Inc., except as may otherwise be noted in a separate copyright
003: * notice. All rights reserved.
004: */
005: package com.tc.util;
006:
007: import com.tc.util.runtime.UnknownJvmVersionException;
008: import com.tc.util.runtime.UnknownRuntimeVersionException;
009: import com.tc.util.runtime.VmVersion;
010:
011: import java.util.Properties;
012:
013: public class VendorVmSignature {
014: public static final char SIGNATURE_SEPARATOR = '_';
015:
016: private static final String OS_WINDOWS = "win32";
017: private static final String OS_LINUX = "linux";
018: private static final String OS_SOLARIS_SPARC = "solaris";
019: private static final String OS_MAC_OSX = "osx";
020: private static final String OS_SOLARIS_X86 = "solaris-x86";
021:
022: private static final String VM_VENDOR_SUN = "hotspot";
023: private static final String VM_VENDOR_IBM = "ibm";
024: private static final String VM_VENDOR_BEA = "jrockit";
025:
026: private final String signature;
027:
028: public VendorVmSignature(final Properties props)
029: throws VendorVmSignatureException {
030: signature = generateSignature(props);
031: }
032:
033: public VendorVmSignature() throws VendorVmSignatureException {
034: this (System.getProperties());
035: }
036:
037: private String generateSignature(final Properties source)
038: throws VendorVmSignatureException {
039: String os = getOS(source);
040: String version = getVMVersion(source);
041: String vendor = getVendor(source);
042:
043: validateComponent(os);
044: validateComponent(version);
045: validateComponent(vendor);
046:
047: return vendor + SIGNATURE_SEPARATOR + os + SIGNATURE_SEPARATOR
048: + version;
049: }
050:
051: private String getVendor(final Properties source)
052: throws VendorVmSignatureException {
053: String vendor = source.getProperty("java.vendor");
054:
055: if (vendor == null) {
056: throw new VendorVmSignatureException(
057: "Cannot determine VM vendor: "
058: + "(\"java.vendor\" system property is null)");
059: }
060:
061: if (vendor.toLowerCase().startsWith("bea ")) {
062: return VM_VENDOR_BEA;
063: }
064: if (vendor.toLowerCase().startsWith("apple ")) {
065: return VM_VENDOR_SUN;
066: }
067: if (vendor.toLowerCase().startsWith("ibm ")) {
068: return VM_VENDOR_IBM;
069: }
070: if (vendor.toLowerCase().startsWith("sun ")) {
071: final VmVersion vmVersion;
072: try {
073: vmVersion = new VmVersion(source);
074: } catch (UnknownJvmVersionException ujve) {
075: throw new VendorVmSignatureException(
076: "Unable to extract the JVM version with properties: "
077: + source, ujve);
078: } catch (UnknownRuntimeVersionException urve) {
079: throw new VendorVmSignatureException(
080: "Unable to extract the JVM version with properties: "
081: + source, urve);
082: }
083: if (vmVersion.isJRockit()) {
084: // In at least one case, jrockit 1.4.2_05 on linux, you get "Sun Microsystems Inc." as the vendor...err
085: return VM_VENDOR_BEA;
086: }
087: return VM_VENDOR_SUN;
088: }
089:
090: throw new VendorVmSignatureException(
091: "Unknown or unsupported vendor string: " + vendor);
092: }
093:
094: private static String getVMVersion(final Properties source)
095: throws VendorVmSignatureException {
096: try {
097: final VmVersion vmVersion = new VmVersion(source);
098: return vmVersion.toString().replaceAll("\\.", "");
099: } catch (final UnknownJvmVersionException ujve) {
100: throw new VendorVmSignatureException(
101: "Cannot determine VM version", ujve);
102: } catch (final UnknownRuntimeVersionException urve) {
103: throw new VendorVmSignatureException(
104: "Cannot determine VM version", urve);
105: }
106: }
107:
108: private static String getOS(final Properties source)
109: throws VendorVmSignatureException {
110: final String osProp = source.getProperty("os.name");
111: if (osProp == null) {
112: throw new VendorVmSignatureException(
113: "Cannot determine operating system: "
114: + "(\"os.name\" system property is null)");
115: }
116: final String lowerCaseOS = osProp.toLowerCase();
117:
118: if (lowerCaseOS.startsWith("windows")) {
119: return OS_WINDOWS;
120: }
121: if (lowerCaseOS.startsWith("linux")) {
122: return OS_LINUX;
123: }
124: if (lowerCaseOS.startsWith("mac")) {
125: return OS_MAC_OSX;
126: }
127: if (lowerCaseOS.startsWith("sunos")) {
128: final String arch = source.getProperty("os.arch");
129: if (arch != null) {
130: final String lowerCaseArch = arch.toLowerCase();
131: if (lowerCaseArch.startsWith("sparc")) {
132: return OS_SOLARIS_SPARC;
133: } else if (lowerCaseArch.indexOf("86") > -1) {
134: return OS_SOLARIS_X86;
135: } else {
136: throw new VendorVmSignatureException(
137: "Unknown Solaris architecture: "
138: + "(\"os.arch\" = " + arch + ")");
139: }
140: } else {
141: throw new VendorVmSignatureException(
142: "Cannot determine Solaris architecture: "
143: + "(\"os.arch\" system property is null)");
144: }
145: }
146:
147: throw new VendorVmSignatureException(
148: "Unknown or unsupported OS detected: " + osProp);
149: }
150:
151: private static void validateComponent(final String component) {
152: if (component == null || component.indexOf('.') >= 0) {
153: throw new AssertionError("Invalid component string: "
154: + component);
155: }
156: }
157:
158: public final String getSignature() {
159: return signature;
160: }
161:
162: public String toString() {
163: return getSignature();
164: }
165: }
|