001 /*
002 * @(#)Platform.java 1.0 06/08/25
003 */ // ************************************************************************
004 // * Copyright (c) 2006 by the Association for Computing Machinery *
005 // * *
006 // * The Java Task Force seeks to impose few restrictions on the use of *
007 // * these packages so that users have as much freedom as possible to *
008 // * use this software in constructive ways and can make the benefits of *
009 // * that work available to others. In view of the legal complexities *
010 // * of software development, however, it is essential for the ACM to *
011 // * maintain its copyright to guard against attempts by others to *
012 // * claim ownership rights. The full text of the JTF Software License *
013 // * is available at the following URL: *
014 // * *
015 // * http://www.acm.org/jtf/jtf-software-license.pdf *
016 // * *
017 // ************************************************************************
018 /**
019 * Class extracted from ACM JTF acm.util package (http://jtf.acm.org/).
020 * Modified slightly to support FANG
021 */
022 package fang;
023
024 import java.awt.*;
025 import java.io.*;
026 import java.lang.reflect.*;
027 import java.util.*;
028
029 /* Class: Platform */
030 /**
031 * This class contains methods to support platform-specific code.
032 */
033 public class Platform
034 {
035
036 /* Constant: UNKNOWN */
037 /** Indicates that the type of system cannot be determined. */
038 public static final int UNKNOWN = 0;
039
040 /* Constant: MAC */
041 /** Indicates that the system is some variety of Apple Macintosh. */
042 public static final int MAC = 1;
043
044 /* Constant: UNIX */
045 /** Indicates that the system is some variety of Unix or Linux. */
046 public static final int UNIX = 2;
047
048 /* Constant: WINDOWS */
049 /** Indicates that the system is some variety of Microsoft Windows. */
050 public static final int WINDOWS = 3;
051
052 /* Static method: getPlatform() */
053 /**
054 * Returns an enumeration constant specifying the type of platform
055 * on which this applet is running, which is one of the supported
056 * types defined at the beginning of this class.
057 *
058 * @usage int platform = Platform.getPlatform();
059 * @return A constant specifying the platform type
060 */
061 public static int getPlatform()
062 {
063 if (platform != -1)
064 {
065 return platform;
066 }
067 String name = System.getProperty("os.name", "").toLowerCase();
068 if (name.startsWith("mac"))
069 {
070 return platform = MAC;
071 }
072 if (name.startsWith("windows"))
073 {
074 return platform = WINDOWS;
075 }
076 if (name.startsWith("microsoft"))
077 {
078 return platform = WINDOWS;
079 }
080 if (name.startsWith("ms"))
081 {
082 return platform = WINDOWS;
083 }
084 if (name.startsWith("unix"))
085 {
086 return platform = UNIX;
087 }
088 if (name.startsWith("linux"))
089 {
090 return platform = UNIX;
091 }
092 return platform = UNKNOWN;
093 }
094
095 /* Static method: isMac */
096 /**
097 * Checks whether the platform is a Macintosh.
098 *
099 * @usage if (Platform.isMac()) . . .
100 * @return <code>true</code> if the platform is a Macintosh, <code>false</code> otherwise
101 */
102 public static boolean isMac()
103 {
104 return getPlatform() == MAC;
105 }
106
107 /* Static method: isWindows() */
108 /**
109 * Checks whether the platform is a Windows machine.
110 *
111 * @usage if (Platform.isWindows()) . . .
112 * @return <code>true</code> if the platform is a Windows machine, <code>false</code> otherwise
113 */
114 public static boolean isWindows()
115 {
116 return getPlatform() == WINDOWS;
117 }
118
119 /* Static method: isUnix() */
120 /**
121 * Checks whether the platform is Unix.
122 *
123 * @usage if (Platform.isUnix()) . . .
124 * @return <code>true</code> if the platform is Unix, <code>false</code> otherwise
125 */
126 public static boolean isUnix()
127 {
128 return getPlatform() == UNIX;
129 }
130
131 /* Static method: setFileTypeAndCreator(filename, type, creator) */
132 /**
133 * Sets the Macintosh file type and creator. This method is ignored on non-Mac
134 * platforms.
135 *
136 * @usage setFileTypeAndCreator(filename, type, creator);
137 * @param filename The name of the file
138 * @param type A four-character string indicating the file type
139 * @param creator A four-character string indicating the file type
140 */
141 public static void setFileTypeAndCreator(String filename, String type, String creator)
142 {
143 if (!isMac())
144 {
145 return ;
146 }
147 try
148 {
149 setFileTypeAndCreator(new File(filename), type, creator);
150 }
151 catch (Exception ex)
152 {
153 /* Empty */
154 }
155 }
156
157 /* Static method: setFileTypeAndCreator(file, type, creator) */
158 /**
159 * Sets the Macintosh file type and creator. This method is ignored on non-Mac
160 * platforms.
161 *
162 * @usage setFileTypeAndCreator(file, type, creator);
163 * @param file The <code>File</code> object corresponding to the file
164 * @param type A four-character string indicating the file type
165 * @param creator A four-character string indicating the file type
166 */
167 @SuppressWarnings("unchecked")
168 public static void setFileTypeAndCreator(File file, String type, String creator)
169 {
170 if (!isMac())
171 {
172 return ;
173 }
174 try
175 {
176 Class mrjOSTypeClass = Class.forName("com.apple.mrj.MRJOSType");
177 Class mrjFileUtilsClass = Class.forName("com.apple.mrj.MRJFileUtils");
178 Class[] sig1 = {Class.forName("java.lang.String")};
179 Constructor constructor = mrjOSTypeClass.getConstructor(sig1);
180 Class[] sig2 = {Class.forName("java.io.File"), mrjOSTypeClass, mrjOSTypeClass};
181 Method fn = mrjFileUtilsClass.getMethod("setFileTypeAndCreator", sig2);
182 Object[] args1 = {(type + " ").substring(0, 4)};
183 Object osType = constructor.newInstance(args1);
184 Object[] args2 = {(creator + " ").substring(0, 4)};
185 Object creatorType = constructor.newInstance(args2);
186 Object[] args3 = {file, osType, creatorType};
187 fn.invoke(null, args3);
188 }
189 catch (Exception ex)
190 {
191 /* Empty */
192 }
193 finally
194 {}
195 }
196
197 /* Static method: compareVersion(version) */
198 /**
199 * This method compares the Java version given in the system properties
200 * with the specified version and returns -1, 0, or +1 depending on whether
201 * the system version is earlier than, equal to, or later than the specified
202 * one. Thus, to test whether the current version of the JDK was at least
203 * 1.2.1, for example, you could write
204 *
205 * <p><table cellspacing=0 cellpadding=0><tr><td width=36> </td>
206 * <td><table cellspacing=0 cellpadding=0><tr><td><pre><font face=courier size=-1><b>
207 * if (Platform.compareVersion("1.2.1") >= 0) . . .
208 * </b></font></pre></td></tr></table></td></tr></table>
209 *
210 * @usage int cmp = Platform.compareVersion(version);
211 * @param version A string consisting of integers separated by periods
212 * @return -1, 0, or +1 depending on whether the system version is earlier than,
213 * equal to, or later than the specified one
214 */
215 public static int compareVersion(String version)
216 {
217 return compareVersion(System.getProperty("java.version"), version);
218 }
219
220 /* Static method: compareVersion(v1, v2) */
221 /**
222 * This method compares the version strings <code>v1</code> and <code>v2</code>
223 * and returns -1, 0, or +1 depending on whether <code>v1</code> is earlier
224 * than, equal to, or later than <code>v2</code>.
225 *
226 * @usage int cmp = Platform.compareVersion(v1, v2);
227 * @param v1 A string consisting of integers separated by periods
228 * @param v2 A second version string in the same format
229 * @return -1, 0, or +1 depending on whether <code>v1</code> is earlier than,
230 * equal to, or later than <code>v2</code>
231 */
232 public static int compareVersion(String v1, String v2)
233 {
234 StringTokenizer t1 = new StringTokenizer(v1, ".");
235 StringTokenizer t2 = new StringTokenizer(v2, ".");
236 while (t1.hasMoreTokens() && t2.hasMoreTokens())
237 {
238 int n1 = Integer.parseInt(t1.nextToken());
239 int n2 = Integer.parseInt(t2.nextToken());
240 if (n1 != n2)
241 {
242 return (n1 < n2) ? -1 : + 1;
243 }
244 }
245 if (t1.hasMoreTokens())
246 {
247 return + 1;
248 }
249 if (t2.hasMoreTokens())
250 {
251 return -1;
252 }
253 return 0;
254 }
255
256 /* Static method: isSwingAvailable() */
257 /**
258 * Checks whether Swing is available. Unfortunately, some browsers seem to lie
259 * about the JDK version and return a 1.2 number without actually having Swing.
260 * This implementation tests the version first, but then confirms the result
261 * by looking for the <code>JComponent</code> class. Checking the version first
262 * means that no <nobr><code>SecurityException</code>s</nobr> will be logged in
263 * Windows machines, which always log <nobr><code>SecurityException</code>s</nobr>,
264 * even if the exception is caught.
265 *
266 * @usage if (Platform.isSwingAvailable()) . . .
267 * @return <code>true</code> if Swing is available, <code>false</code> otherwise
268 */
269 public static boolean isSwingAvailable()
270 {
271 if (!swingChecked)
272 {
273 swingChecked = true;
274 isSwingAvailable = false;
275 if (compareVersion("1.2") >= 0)
276 {
277 try
278 {
279 isSwingAvailable = Class.forName("javax.swing.JComponent") != null;
280 }
281 catch (Exception ex)
282 {
283 /* Empty */
284 }
285 }
286 }
287 return isSwingAvailable;
288 }
289
290 /* Static method: isSunAudioAvailable() */
291 /**
292 * Checks whether the <code>sun.audio</code> package is available.
293 *
294 * @usage if (Platform.isSunAudioAvailable()) . . .
295 * @return <code>true</code> if the <code>sun.audio</code> package is available,
296 * <code>false</code> otherwise
297 */
298 public static boolean isSunAudioAvailable()
299 {
300 if (!sunAudioChecked)
301 {
302 sunAudioChecked = true;
303 try
304 {
305 isSunAudioAvailable = Class.forName("sun.audio.AudioPlayer") != null;
306 }
307 catch (Exception ex)
308 {
309 isSunAudioAvailable = false;
310 }
311 }
312 return isSunAudioAvailable;
313 }
314
315 /* Static method: isJMFAvailable() */
316 /**
317 * Checks whether the Java Media Framework is available.
318 *
319 * @usage if (Platform.isJMFAvailable()) . . .
320 * @return <code>true</code> if the JMF package is available, <code>false</code> otherwise
321 */
322 public static boolean isJMFAvailable()
323 {
324 if (!jmfChecked)
325 {
326 jmfChecked = true;
327 try
328 {
329 isJMFAvailable = Class.forName("javax.media.Player") != null;
330 }
331 catch (Exception ex)
332 {
333 isJMFAvailable = false;
334 }
335 }
336 return isJMFAvailable;
337 }
338
339 /* Static method: areCollectionsAvailable() */
340 /**
341 * Checks whether the JDK 1.2 collection classes are available. Some browsers
342 * return a version of the JDK that does not actually match what is supported.
343 * This method actually checks whether the collection classes are there by
344 * looking for the <code>ArrayList</code> class.
345 *
346 * @usage if (Platform.areCollectionsAvailable()) . . .
347 * @return <code>true</code> if collections are available, <code>false</code> otherwise
348 */
349 public static boolean areCollectionsAvailable()
350 {
351 if (!collectionsChecked)
352 {
353 collectionsChecked = true;
354 try
355 {
356 areCollectionsAvailable = Class.forName("java.util.ArrayList") != null;
357 }
358 catch (Exception ex)
359 {
360 areCollectionsAvailable = false;
361 }
362 }
363 return areCollectionsAvailable;
364 }
365
366 /* Static method: areStandardFontFamiliesAvailable() */
367 /**
368 * Checks whether the JDK 1.2 standard font families (<code>Serif</code>,
369 * <code>SansSerif</code>, and <code>Monospaced</code>) are available.
370 *
371 * @usage if (Platform.areStandardFontFamiliesAvailable()) . . .
372 * @return <code>true</code> if the standard fonts are available, <code>false</code> otherwise
373 */
374 public static boolean areStandardFontFamiliesAvailable()
375 {
376 if (!fontsChecked)
377 {
378 fontsChecked = true;
379 try
380 {
381 Class < ? > toolkitClass = Class.forName("java.awt.Toolkit");
382 Method getFontList = toolkitClass.getMethod("getFontList", new Class[0]);
383 String[] fonts = (String[]) getFontList.invoke(Toolkit.getDefaultToolkit(), new Object[0]);
384 int standardFontCount = 0;
385 for (int i = 0; i < fonts.length; i++)
386 {
387 if (fonts[i].equals("Serif") || fonts[i].equals("SansSerif") || fonts[i].equals("Monospaced"))
388 {
389 standardFontCount++;
390 }
391 }
392 areStandardFontFamiliesAvailable = (standardFontCount == 3);
393 }
394 catch (Exception ex)
395 {
396 areStandardFontFamiliesAvailable = false;
397 }
398 }
399 return areStandardFontFamiliesAvailable;
400 }
401
402 /* Private static variables */
403 private static int platform = -1;
404 private static boolean areStandardFontFamiliesAvailable;
405 private static boolean fontsChecked;
406 private static boolean isSwingAvailable;
407 private static boolean swingChecked;
408 private static boolean areCollectionsAvailable;
409 private static boolean collectionsChecked;
410 private static boolean isSunAudioAvailable;
411 private static boolean sunAudioChecked;
412 private static boolean isJMFAvailable;
413 private static boolean jmfChecked;
414 }