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: * The Original Software is NetBeans. The Initial Developer of the Original
026: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
027: * Microsystems, Inc. All Rights Reserved.
028: *
029: * If you wish your version of this file to be governed by only the CDDL
030: * or only the GPL Version 2, indicate your decision by adding
031: * "[Contributor] elects to include this software in this distribution
032: * under the [CDDL or GPL Version 2] license." If you do not indicate a
033: * single choice of license, a recipient has the option to distribute
034: * your version of this file under either the CDDL, the GPL Version 2 or
035: * to extend the choice of license to its licensees as provided above.
036: * However, if you add GPL Version 2 code and therefore, elected the GPL
037: * Version 2 license, then the option applies only if the new code is
038: * made subject to such option by the copyright holder.
039: */
040:
041: package org.netbeans.lib.profiler.global;
042:
043: import java.io.File;
044: import java.io.IOException;
045:
046: /**
047: * Determination of the current platform (OS, hardware) and related services.
048: *
049: * @author Tomas Hurka
050: * @author Misha Dmitriev
051: * @author Ian Formanek
052: */
053: public class Platform implements CommonConstants {
054: //~ Static fields/initializers -----------------------------------------------------------------------------------------------
055:
056: /**
057: * Operating system is Windows NT.
058: */
059: public static final int OS_WINNT = 1;
060:
061: /**
062: * Operating system is Windows 95.
063: */
064: public static final int OS_WIN95 = 2;
065:
066: /**
067: * Operating system is Windows 98.
068: */
069: public static final int OS_WIN98 = 4;
070:
071: /**
072: * Operating system is Solaris.
073: */
074: public static final int OS_SOLARIS = 8;
075:
076: /**
077: * Operating system is Linux.
078: */
079: public static final int OS_LINUX = 16;
080:
081: /**
082: * Operating system is HP-UX.
083: */
084: public static final int OS_HP = 32;
085:
086: /**
087: * Operating system is IBM AIX.
088: */
089: public static final int OS_AIX = 64;
090:
091: /**
092: * Operating system is SGI IRIX.
093: */
094: public static final int OS_IRIX = 128;
095:
096: /**
097: * Operating system is Sun OS.
098: */
099: public static final int OS_SUNOS = 256;
100:
101: /**
102: * Operating system is Compaq TRU64 Unix
103: */
104: public static final int OS_TRU64 = 512;
105:
106: /**
107: * Operating system is OS/2.
108: */
109: public static final int OS_OS2 = 1024;
110:
111: /**
112: * Operating system is Mac.
113: */
114: public static final int OS_MAC = 2048;
115:
116: /**
117: * Operating system is Windows 2000.
118: */
119: public static final int OS_WIN2000 = 4096;
120:
121: /**
122: * Operating system is Compaq OpenVMS
123: */
124: public static final int OS_VMS = 8192;
125:
126: /**
127: * Operating system is one of the Windows variants but we don't know which one it is
128: */
129: public static final int OS_WIN_OTHER = 16384;
130:
131: /**
132: * Operating system is unknown.
133: */
134: public static final int OS_OTHER = 65536;
135:
136: /**
137: * A mask for Windows platforms.
138: */
139: public static final int OS_WINDOWS_MASK = OS_WINNT | OS_WIN95
140: | OS_WIN98 | OS_WIN2000 | OS_WIN_OTHER;
141:
142: /**
143: * A mask for Unix platforms.
144: */
145: public static final int OS_UNIX_MASK = OS_SOLARIS | OS_LINUX
146: | OS_HP | OS_AIX | OS_IRIX | OS_SUNOS | OS_TRU64 | OS_MAC;
147:
148: /**
149: * The operating system on which the tool runs
150: */
151: private static int operatingSystem = -1;
152: private static String jdkDenoteString;
153: private static int jdkVersion;
154: private static int sysArch; // 32/64bit architecture
155:
156: //~ Methods ------------------------------------------------------------------------------------------------------------------
157:
158: /**
159: * Given the name of the directory containing the JFluid native libaries (either just the root JFluid libs dir,
160: * or really the full path, depending on fullPathToLibSpecified parameter), return the full platform-dependent
161: * name for the "profilerinterface" library contained in that directory. If non-null jdkString is specified, it
162: * is used in the resulting path; otherwise the VM is queried for its version and the resulting string is used.
163: *
164: * @param fullAgentPath The path to the library
165: * @param fullPathToLibSpecified whether or not a full path is specified (ending at the platform level)
166: * @param jdkString CommonConstants.JDK_15_STRING
167: * @return A path to the native library to be used for this platform
168: */
169: public static String getAgentNativeLibFullName(
170: String fullAgentPath, boolean fullPathToLibSpecified,
171: String jdkString, int architecture) {
172: boolean is64bitArch;
173:
174: if (jdkString == null) {
175: jdkString = getJDKVersionString();
176: }
177:
178: if (architecture == -1) {
179: architecture = getSystemArchitecture();
180: }
181:
182: is64bitArch = architecture == ARCH_64;
183:
184: if (jdkString.equals(JDK_17_STRING)) {
185: // for now, we use the same libs for 1.6 and 1.7
186: jdkString = JDK_16_STRING;
187: }
188:
189: String libPrefix = ""; // NOI18N
190:
191: if (!isWindows()) { // Mac and UNIXes
192: libPrefix = "lib"; // NOI18N
193: }
194:
195: String libSuffix = ""; // NOI18N
196:
197: if (isWindows()) {
198: libSuffix = ".dll"; // Windows // NOI18N
199: } else if (isMac()) {
200: libSuffix = ".jnilib"; // Mac // NOI18N
201: } else {
202: libSuffix = ".so"; // UNIXes // NOI18N
203: }
204:
205: String libSubPath = "/"; // NOI18N
206:
207: if (!fullPathToLibSpecified) {
208: String libSubDir = isWindows() ? "windows" : (isMac() ? // NOI18N
209: "mac"
210: : (isLinux() ? // NOI18N
211: "linux"
212: : "solaris")); // NOI18N
213: String procArch = null;
214:
215: if (is64bitArch) {
216: if (isLinux() || isWindows() || isSolarisIntel()) {
217: procArch = "amd64"; // NOI18N
218: } else if (isSolarisSparc()) {
219: procArch = "sparcv9"; // NOI18N
220: }
221: } else { // 32bit
222:
223: if (isSolarisIntel()) {
224: procArch = "i386"; // NOI18N
225: } else if (isSolarisSparc()) {
226: procArch = "sparc"; // NOI18N
227: }
228: }
229:
230: if (procArch != null) {
231: libSubDir += ("-" + procArch);
232: }
233:
234: libSubPath = "/deployed/" + jdkString + "/" + libSubDir
235: + "/"; // NOI18N
236: }
237:
238: String fullPath = fullAgentPath;
239:
240: if (fullAgentPath.startsWith("\"")) { // NOI18N
241: fullPath = fullAgentPath.substring(1, fullAgentPath
242: .length() - 1);
243: }
244:
245: fullPath = fullPath.replace('\\', '/'); // NOI18N
246:
247: return fullPath + libSubPath + libPrefix + "profilerinterface"
248: + libSuffix; // NOI18N
249: }
250:
251: /**
252: * Returns JDK minor version
253: */
254: public static int getJDKMinorNumber(String jdkVersionString) {
255: if (jdkVersionString == null) {
256: return 0;
257: }
258:
259: int minorIndex = jdkVersionString.lastIndexOf('_'); // NOI18N
260:
261: if ((minorIndex > 0)
262: && (minorIndex < (jdkVersionString.length() - 1))) {
263: String minorString = jdkVersionString
264: .substring(minorIndex + 1);
265: int subverIndex = minorString.indexOf('-'); // NOI18N
266:
267: if (subverIndex != -1) {
268: minorString = minorString.substring(0, subverIndex);
269: }
270:
271: return Integer.parseInt(minorString);
272: }
273:
274: return 0;
275: }
276:
277: /**
278: * Returns the JFluid-internal JDK version number
279: */
280: public static int getJDKVersionNumber() {
281: if (jdkVersion == 0) {
282: String javaVersion = System.getProperty("java.version"); // NOI18N
283:
284: if (javaVersion.startsWith("1.5")) { // NOI18N
285: jdkVersion = JDK_15;
286: } else if (javaVersion.startsWith("1.6")) { // NOI18N
287: jdkVersion = JDK_16;
288: } else if (javaVersion.startsWith("1.7")) { // NOI18N
289: jdkVersion = JDK_17;
290: } else {
291: jdkVersion = JDK_UNSUPPORTED;
292: }
293: }
294:
295: return jdkVersion;
296: }
297:
298: /**
299: * Returns the string for, essentially, JFluid directory corresponding to a particular JDK version the TA runs on.
300: * Currently it's "jdk15" for JDK 1.5 version and "jdk16" for JDK 1.6 version.
301: */
302: public static String getJDKVersionString(String javaVersionString) {
303: if (javaVersionString == null) {
304: return JDK_UNSUPPORTED_STRING;
305: }
306:
307: if (javaVersionString.startsWith("1.5")) { // NOI18N
308:
309: return JDK_15_STRING;
310: } else if (javaVersionString.startsWith("1.6")) { // NOI18N
311:
312: return JDK_16_STRING;
313: } else if (javaVersionString.startsWith("1.7")) { // NOI18N
314:
315: return JDK_17_STRING;
316: } else {
317: return JDK_UNSUPPORTED_STRING;
318: }
319: }
320:
321: /**
322: * Returns the string for, essentially, JFluid directory corresponding to a particular JDK version the TA runs on.
323: * Currently it's "jdk15" for JDK 1.5 version, "jdk16" for JDK 1.6 version and jdk17 for JDK 1.7 version.
324: */
325: public static String getJDKVersionString() {
326: if (jdkDenoteString == null) {
327: jdkDenoteString = getJDKVersionString(System
328: .getProperty("java.version")); // NOI18N
329: }
330:
331: return jdkDenoteString;
332: }
333:
334: public static String getJFluidNativeLibDirName(
335: String fullJFluidPath, String jdkString, int architecture) {
336: String jFluidNativeLibFullName = getAgentNativeLibFullName(
337: fullJFluidPath, false, jdkString, architecture);
338:
339: return jFluidNativeLibFullName.substring(0,
340: jFluidNativeLibFullName.lastIndexOf('/')); // NOI18N
341: }
342:
343: /**
344: * Test whether we are running on Linux
345: */
346: public static boolean isLinux() {
347: return (getOperatingSystem() == OS_LINUX);
348: }
349:
350: /**
351: * Test whether the supplied OS name is Linux
352: */
353: public static boolean isLinux(String osName) {
354: return (getOperatingSystem(osName) == OS_LINUX);
355: }
356:
357: public static boolean isMac() {
358: return (getOperatingSystem() == OS_MAC);
359: }
360:
361: /**
362: * Get the operating system on which we are is running.
363: * Returns one of the <code>OS_*</code> constants (such as {@link #OS_WINNT})
364: */
365: public static int getOperatingSystem() {
366: if (operatingSystem == -1) {
367: String osName = System.getProperty("os.name"); // NOI18N
368: operatingSystem = getOperatingSystem(osName);
369: }
370:
371: return operatingSystem;
372: }
373:
374: public static int getOperatingSystem(String osName) {
375: if ("Windows NT".equals(osName)) { // NOI18N
376:
377: return OS_WINNT;
378: } else if ("Windows 95".equals(osName)) { // NOI18N
379:
380: return OS_WIN95;
381: } else if ("Windows 98".equals(osName)) { // NOI18N
382:
383: return OS_WIN98;
384: } else if ("Windows 2000".equals(osName)) { // NOI18N
385:
386: return OS_WIN2000;
387: } else if (osName.startsWith("Windows ")) { // NOI18N
388:
389: return OS_WIN_OTHER;
390: } else if ("Solaris".equals(osName)) { // NOI18N
391:
392: return OS_SOLARIS;
393: } else if (osName.startsWith("SunOS")) { // NOI18N
394:
395: return OS_SOLARIS;
396: } else if (osName.endsWith("Linux")) { // NOI18N
397:
398: return OS_LINUX;
399: } else if ("HP-UX".equals(osName)) { // NOI18N
400:
401: return OS_HP;
402: } else if ("AIX".equals(osName)) { // NOI18N
403:
404: return OS_AIX;
405: } else if ("Irix".equals(osName)) { // NOI18N
406:
407: return OS_IRIX;
408: } else if ("SunOS".equals(osName)) { // NOI18N
409:
410: return OS_SOLARIS;
411: } else if ("Digital UNIX".equals(osName)) { // NOI18N
412:
413: return OS_TRU64;
414: } else if ("OS/2".equals(osName)) { // NOI18N
415:
416: return OS_OS2;
417: } else if ("OpenVMS".equals(osName)) { // NOI18N
418:
419: return OS_VMS;
420: } else if (osName.equalsIgnoreCase("mac os x")) { // NOI18N
421:
422: return OS_MAC;
423: } else if (osName.startsWith("Darwin")) { // NOI18N
424:
425: return OS_MAC;
426: } else {
427: return OS_OTHER;
428: }
429: }
430:
431: public static String getProfilerUserDir() throws IOException {
432: String customDir = System.getProperty("nbprofiler.home"); // NOI18N
433:
434: if (customDir != null) {
435: File d = new File(customDir);
436:
437: if (!d.exists()) {
438: if (!d.mkdir()) {
439: throw new IOException("Could not create directory"
440: + customDir); // NOI18N
441: }
442: }
443:
444: return customDir;
445: } else {
446: // use default location
447: String dir = System.getProperty("user.home")
448: + File.separator + ".nbprofiler"; // NOI18N
449: File d = new File(dir);
450:
451: if (!d.exists()) {
452: if (!d.mkdir()) {
453: throw new IOException("Could not create directory"
454: + dir); // NOI18N
455: }
456: }
457:
458: return dir;
459: }
460: }
461:
462: /**
463: * Test whether we are running on Solaris
464: */
465: public static boolean isSolaris() {
466: return (getOperatingSystem() == OS_SOLARIS);
467: }
468:
469: /**
470: * Test whether we are running on Solaris on Intel processor
471: */
472: public static boolean isSolarisIntel() {
473: String procArch = System.getProperty("os.arch"); // NOI18N
474:
475: return isSolaris()
476: && (procArch.endsWith("86") || procArch.equals("amd64")); // NOI18N
477: }
478:
479: /**
480: * Test whether we are running on Solaris on SPARC processor
481: */
482: public static boolean isSolarisSparc() {
483: String procArch = System.getProperty("os.arch"); // NOI18N
484:
485: return isSolaris() && procArch.startsWith("sparc"); // NOI18N
486: }
487:
488: /**
489: * Returns system architecture: 32/64bit
490: */
491: public static int getSystemArchitecture() {
492: if (sysArch == 0) {
493: String architecture = System
494: .getProperty("sun.arch.data.model"); // NOI18N
495:
496: if (architecture == null) {
497: sysArch = ARCH_32;
498: } else if ("32".equals(architecture)) { // NOI18N
499: sysArch = ARCH_32; // defined 32bit environment
500: } else if ("64".equals(architecture)) { // NOI18N
501: sysArch = ARCH_64; // defined 64bit environment
502: } else {
503: sysArch = ARCH_32; // unknown environment, 32bit by default
504: }
505: }
506:
507: return sysArch;
508: }
509:
510: /**
511: * Test whether we are running on some variant of Unix. Linux is included as well as the commercial vendors.
512: */
513: public static boolean isUnix() {
514: return (getOperatingSystem() & OS_UNIX_MASK) != 0;
515: }
516:
517: /**
518: * Test whether we are is running on some variant of Windows
519: */
520: public static boolean isWindows() {
521: return (getOperatingSystem() & OS_WINDOWS_MASK) != 0;
522: }
523:
524: /**
525: * Test whether the supplied OS name is some variant of Windows
526: */
527: public static boolean isWindows(String osName) {
528: return (getOperatingSystem(osName) & OS_WINDOWS_MASK) != 0;
529: }
530:
531: /**
532: * Returns true if current system architecture is 32bit
533: */
534: public static boolean is32bitArchitecture() {
535: return getSystemArchitecture() == ARCH_32;
536: }
537:
538: /**
539: * Returns true if current system architecture is 64bit
540: */
541: public static boolean is64bitArchitecture() {
542: return getSystemArchitecture() == ARCH_64;
543: }
544:
545: /**
546: * Returns true if the given JVM version supports dynaimc attach
547: */
548: public static boolean supportsDynamicAttach(String jdkVersionString) {
549: return CommonConstants.JDK_16_STRING.equals(jdkVersionString)
550: || CommonConstants.JDK_17_STRING
551: .equals(jdkVersionString);
552: }
553:
554: /**
555: * Returns true if the given JVM version passed as String correctly reports "sleeping" state
556: */
557: public static boolean supportsThreadSleepingStateMonitoring(
558: String jdkVersionString) {
559: return ((jdkVersionString != null) && (jdkVersionString
560: .equals(JDK_15_STRING)
561: || jdkVersionString.equals(JDK_16_STRING) || jdkVersionString
562: .equals(JDK_17_STRING)));
563: }
564:
565: /**
566: * Returns true if the current JVM correctly reports "sleeping" state
567: */
568: public static boolean this VMSupportsThreadSleepingStateMonitoring() {
569: return supportsThreadSleepingStateMonitoring(getJDKVersionNumber());
570: }
571:
572: /**
573: * Returns true if the given JVM version number correctly reports "sleeping" state
574: */
575: private static boolean supportsThreadSleepingStateMonitoring(
576: int jdkVersionNumber) {
577: return ((jdkVersionNumber == JDK_15)
578: || (jdkVersionNumber == JDK_16) || (jdkVersionNumber == JDK_17));
579: }
580: }
|