--- old/make/tools/src/build/tools/fontchecker/FontChecker.java 2009-10-26 21:00:03.216585936 +0000 +++ /dev/null 2009-10-14 20:51:54.219592243 +0100 @@ -1,452 +0,0 @@ -/* - * Copyright 2002-2004 Sun Microsystems, Inc. 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. Sun designates this - * particular file as subject to the "Classpath" exception as provided - * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - */ - -package build.tools.fontchecker; - -import java.io.*; -import java.util.*; -import java.awt.event.*; -import sun.font.FontManager; - -/** - * FontChecker. - * - *
- * This is a FontChecker program. This class is a "parent" process
- * which invokes a "child" process. The child process will test
- * series of fonts and may crash as it encounters invalid fonts.
- * The "parent" process must then interpret error codes passed to it
- * by the "child" process and restart the "child" process if necessary.
- *
- * usage: java FontChecker [-v] -o outputfile
- *
- *        -o is the name of the file to contains canonical path names of
- *           bad fonts that are identified. This file is not created if
- *           no bad fonts are found.
- *        -v verbose: prints progress messages.
- *
- * 
- * - * @author Ilya Bagrak - */ -public class FontChecker implements ActionListener, FontCheckerConstants { - - /** - * Output stream to subprocess. - * Corresponds to the subprocess's System.in". - */ - private PrintWriter procPipeOut; - - /** - * Input stream from subprocess. - * Corresponds to the subprocess's System.out". - */ - private BufferedInputStream procPipeIn; - - /** - * Child process. - */ - private Process childProc; - - /** - * Name of output file to write file names of bad fonts - */ - private String outputFile; - - /** - * Reference to currently executing thread. - */ - private Thread currThread; - - /** - * Timeout timer for a single font check - */ - private javax.swing.Timer timeOne; - - /** - * Timeout timer for all font checks - */ - private javax.swing.Timer timeAll; - - /** - * max time (in milliseconds) allowed for checking a single font. - */ - private static int timeoutOne = 10000; - - /** - * max time (in milliseconds) allowed for checking all fonts. - */ - private static int timeoutAll = 120000; - - /** - * Boolean flag indicating whether FontChecker is required to - * check non-TrueType fonts. - */ - private boolean checkNonTTF = false; - - /** - * List of bad fonts found in the system. - */ - private Vector badFonts = new Vector(); - - /** - * whether to print warnings messges etc to stdout/err - * default is false - */ - private static boolean verbose = false; - - /* Command to use to exec sub-process. */ - private static String javaCmd = "java"; - - static void printlnMessage(String s) { - if (verbose) { - System.out.println(s); - } - } - - /** - * Event handler for timer event. - *
- * Stops the timer and interrupts the current thread which is - * still waiting on I/O from the child process. - *

- * @param evt timer event - */ - public void actionPerformed(ActionEvent evt) { - if (evt.getSource() == timeOne) { - timeOne.stop(); - printlnMessage("Child timed out: killing"); - childProc.destroy(); - } else { - doExit(); // went on too long (ie timeAll timed out). - } - } - - /** - * Initializes a FontChecker. - *
- * This method is usually called after an unrecoverable error has - * been detected and a child process has either crashed or is in bad - * state. The method creates a new child process from - * scratch and initializes it's input/output streams. - */ - public void initialize() { - try { - if (childProc != null) { - childProc.destroy(); - } - String fileSeparator = System.getProperty("file.separator"); - String javaHome = System.getProperty("java.home"); - String classPath = System.getProperty("java.class.path"); - classPath = "\"" + classPath + "\""; - String opt = "-cp " + classPath + " -Dsun.java2d.fontpath=\"" + - javaHome + fileSeparator + "lib" + fileSeparator + "fonts\""; - - /* command to exec the child process with the same JRE */ - String cmd = - new String(javaHome + fileSeparator + "bin" + - fileSeparator + javaCmd + - " -XXsuppressExitMessage " + opt + - " com.sun.java2d.fontchecker.FontCheckDummy"); - printlnMessage("cmd="+cmd); - childProc = Runtime.getRuntime().exec(cmd); - - } catch (IOException e) { - printlnMessage("can't execute child process"); - System.exit(0); - } catch (SecurityException e) { - printlnMessage("Error: access denied"); - System.exit(0); - } - - /* initialize input/output streams to/from child process */ - procPipeOut = new PrintWriter(childProc.getOutputStream()); - procPipeIn = new BufferedInputStream(childProc.getInputStream()); - - try { - int code = procPipeIn.read(); - if (code != CHILD_STARTED_OK) { - printlnMessage("bad child process start status="+code); - doExit(); - } - } catch (IOException e) { - printlnMessage("can't read child process start status unknown"); - doExit(); - } - } - - private void doExit() { - try { - if (procPipeOut != null) { - /* Tell the child to exit */ - procPipeOut.write(EXITCOMMAND+System.getProperty("line.separator")); - procPipeOut.flush(); - procPipeOut.close(); - } - } catch (Throwable t) { - } - System.exit(0); - } - - /** - * Tries to verify integrity of a font specified by a path. - *
- * This method is used to test whether a font specified by the given - * path is valid and does not crash the system. - *

- * @param fontPath a string representation of font path - * to standard out during while this font is tried - * @return returns true if font is OK, and - * false otherwise. - */ - public boolean tryFont(File fontFile) { - int bytesRead = 0; - String fontPath = fontFile.getAbsolutePath(); - - printlnMessage("Checking font "+fontPath); - - /* store reference to the current thread, so that when the timer - * fires it can be interrupted - */ - currThread = Thread.currentThread(); - timeOne.restart(); - - /* write a string command out to child process - * The command is formed by appending whether to test non-TT fonts - * and font path to be tested - */ - String command = Integer.toString(checkNonTTF ? 1 : 0) + - fontPath + - System.getProperty("line.separator"); - procPipeOut.write(command); - procPipeOut.flush(); - - /* check if underlying stream has encountered an error after - * command has been issued - */ - if (procPipeOut.checkError()){ - printlnMessage("Error: font crashed"); - initialize(); - return false; - } - - /* trying reading error code back from child process */ - try { - bytesRead = procPipeIn.read(); - } catch(InterruptedIOException e) { - /* A timeout timer fired before the operation completed */ - printlnMessage("Error: timeout occured"); - initialize(); - return false; - } catch(IOException e) { - /* there was an error reading from the stream */ - timeOne.stop(); - printlnMessage("Error: font crashed"); - initialize(); - return false; - } catch (Throwable t) { - bytesRead = ERR_FONT_READ_EXCPT; - } finally { - timeOne.stop(); - } - - if (bytesRead == ERR_FONT_OK) { - printlnMessage("Font integrity verified"); - return true; - } else if (bytesRead > 0) { - - switch(bytesRead){ - case ERR_FONT_NOT_FOUND: - printlnMessage("Error: font not found!"); - break; - case ERR_FONT_BAD_FORMAT: - printlnMessage("Error: incorrect font format"); - break; - case ERR_FONT_READ_EXCPT: - printlnMessage("Error: exception reading font"); - break; - case ERR_FONT_DISPLAY: - printlnMessage("Error: can't display characters"); - break; - case ERR_FONT_CRASH: - printlnMessage("Error: font crashed"); - break; - default: - printlnMessage("Error: invalid error code:"+bytesRead); - break; - - } - } else if (bytesRead == ERR_FONT_EOS) { - printlnMessage("Error: end of stream marker encountered"); - } else { - printlnMessage("Error: invalid error code:"+bytesRead); - } - - /* if we still haven't returned from this method, some error - * condition has occured and it is safer to re-initialize - */ - initialize(); - return false; - } - - /** - * Checks the integrity of all system fonts. - *
- * This method goes through every font in system's font path and verifies - * its integrity via the tryFont method. - *

- * @param restart true if checking of fonts should continue - * after the first bad font is found, and false otherwise - * @return returns true if all fonts are valid, - * false otherwise - * @see #tryFont(String, boolean, boolean) - */ - public boolean checkFonts(boolean restart) { - - /* file filter to filter out none-truetype font files */ - FontFileFilter fff = new FontFileFilter(checkNonTTF); - boolean checkOk = true; - - /* get platform-independent font path. Note that this bypasses - * the normal GraphicsEnvironment initialisation. In conjunction with - * the headless setting above, so we want to add - * java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment(); - * to trigger a more normal initialisation. - */ - java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment(); - String fontPath = FontManager.getFontPath(true); - StringTokenizer st = - new StringTokenizer(fontPath, - System.getProperty("path.separator")); - - /* some systems may have multiple font paths separated by - * platform-dependent characters, so fontPath string needs to be - * parsed - */ - timeOne = new javax.swing.Timer(timeoutOne, this); - timeAll = new javax.swing.Timer(timeoutAll, this); - timeAll.restart(); - while (st.hasMoreTokens()) { - File fontRoot = new File(st.nextToken()); - File[] fontFiles = fontRoot.listFiles(fff); - - for (int i = 0; i < fontFiles.length; i++) { - /* for each font file that is not a directory and passes - * through the font filter run the test - */ - if (!fontFiles[i].isDirectory() && - !tryFont(fontFiles[i])) { - - checkOk = false; - badFonts.add(fontFiles[i].getAbsolutePath()); - if (!restart) { - break; - } - } - } - } - - /* Tell the child to exit */ - procPipeOut.write(EXITCOMMAND+System.getProperty("line.separator")); - procPipeOut.flush(); - procPipeOut.close(); - - return checkOk; - } - - public static void main(String args[]){ - try { - /* Background app. */ - System.setProperty("java.awt.headless", "true"); - System.setProperty("sun.java2d.noddraw", "true"); - - boolean restart = true; - boolean errorFlag = false; - - FontChecker fc = new FontChecker(); - int arg = 0; - - while (arg < args.length && errorFlag == false) { - if (args[arg].equals("-v")) { - verbose = true; - } - else if (args[arg].equals("-w") && - System.getProperty("os.name", "unknown"). - startsWith("Windows")) { - javaCmd = "javaw"; - } - else if (args[arg].equals("-o")) { - /* set output file */ - if (++arg < args.length) - fc.outputFile = args[arg]; - else { - /* invalid argument format */ - printlnMessage("Error: invalid argument format"); - errorFlag = true; - } - } - else { - /* invalid command line argument */ - printlnMessage("Error: invalid argument value"); - errorFlag = true; - } - arg++; - } - - if (errorFlag || fc.outputFile == null) { - System.exit(0); - } - - File outfile = new File(fc.outputFile); - if (outfile.exists()) { - outfile.delete(); - } - - fc.initialize(); - - if (!fc.checkFonts(restart)) { - String[] badFonts = (String[])fc.badFonts.toArray(new String[0]); - if (badFonts.length > 0) { - printlnMessage("Bad Fonts:"); - try { - FileOutputStream fos = - new FileOutputStream(fc.outputFile); - PrintStream ps = new PrintStream(fos); - for (int i = 0; i < badFonts.length; i++) { - ps.println(badFonts[i]); - printlnMessage(badFonts[i]); - } - fos.close(); - } catch (IOException e) { - } - } - } else { - printlnMessage("No bad fonts found."); - } - } catch (Throwable t) { - } - System.exit(0); - } -}