📄 skinromizationtool.java
字号:
/* * * * Copyright 1990-2007 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER * * This program 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. * * This program 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 at /legal/license.txt). * * 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 or visit www.sun.com if you need additional * information or have any questions. * *//** * This tool takes XML file describing skin as input and produces Java * and C files with romized skin's properties values. Those files are * intended to be compiled with the rest of Chameleon source files. * */package com.sun.midp.skinromization;import java.io.*;import java.util.*;import javax.xml.parsers.*;import org.w3c.dom.*;import java.awt.image.*;import java.awt.*;import com.sun.midp.imageutil.*;import java.lang.reflect.*;import com.sun.midp.romization.*;import com.sun.midp.chameleon.skins.resources.*;/** * Represents romization job */class RomizationJob { /** XML file name to get skin properties from */ public String skinXMLFileName = ""; /** Skin images directory name */ public String skinImagesDirName = ""; /** Output file name for RomizedSkin class */ public String outBinFileName = ""; /** Output file name for romized images data */ public String outCFileName = ""; /** For QA purposes: overrides images romization settings from XML */ public String imageRomOverride = ""; /** * Forces images romization overriding the settings from XML * and romization of skin.bin. */ public boolean romizeAll = false;}/** * Main tool class */public class SkinRomizationTool { /** Romizer that does actual romization */ private static SkinRomizer romizer = null; /** Romization job to perform */ private static RomizationJob romizationJob = null; /** Print debug output while running */ private static boolean debug = false; /** Print usage info and exit */ private static boolean printHelp = false; /** * Main method * * @param args Command line arguments */ public static void main(String[] args) { try { parseArgs(args); if (printHelp) { printHelp(); return; } if (!validateParsedArgs()) { System.exit(1); } romizer = new SkinRomizer(debug); romizer.romize(romizationJob); } catch (Exception e) { e.printStackTrace(); System.exit(1); } } /** * Parses command line arguments * * @param args command line arguments */ private static void parseArgs(String[] args) { romizationJob = new RomizationJob(); for (int i = 0; i < args.length; ++i) { String arg = args[i]; if (arg.equals("-help")) { printHelp = true; break; } else if (arg.equals("-xml")) { romizationJob.skinXMLFileName = args[++i]; } else if (arg.equals("-outbin")) { romizationJob.outBinFileName = args[++i]; } else if (arg.equals("-imagedir")) { romizationJob.skinImagesDirName = args[++i]; } else if (arg.equals("-outc")) { romizationJob.outCFileName = args[++i]; } else if (arg.equals("-romizeall")) { romizationJob.romizeAll = true; } else if (arg.equals("-debug")) { debug = true; // this option is for QA purposes only and therefore // hidden, undocumented and unsupported } else if (arg.equals("-qaimagerom")) { romizationJob.imageRomOverride = args[++i]; } else { throw new IllegalArgumentException("invalid option \"" + args[i] + "\""); } } } /** * Validates parsed arguments, printing error message * if some arg is invalid. * * @return true, if all arguments are valid */ private static boolean validateParsedArgs() { File f = new File(romizationJob.skinXMLFileName); if (!f.isFile()) { System.err.println( "SkinRomizationTool: Couldn't find input XML file: " + '"' + romizationJob.skinXMLFileName + '"'); return false; } f = new File(romizationJob.skinImagesDirName); if (!f.isDirectory()) { System.err.println("SkinRomizationTool: " + '"' + romizationJob.skinImagesDirName + '"' + " isn't a directory"); return false; } return true; } /** * Prints usage information */ private static void printHelp() { /** * Following options are recognized: * -xml: XML file describing skin. * -outbin: Output binary file. Has no effect * if -romizeall option is given. * -outc: Output C file. If empty, output will be to stdout. * -romizeall: Forces romization of all Chameleon resources. * -help: Print usage information. * -debug: Be verbose: print some debug info while running. * */ System.err.println("Usage: java -jar " + "com.sun.midp.SkinRomizationTool " + "-xml <localXMLFile> " + "-imagedir <skinImagesDirName> " + "-outbin <localOutputBinFile> " + "-outc <localOutputCFile> " + "[-romizeall] " + "[-debug] " + "[-help]"); }}/** * Base class for all skin properties */abstract class SkinPropertyBase { /** Print some debug info */ static boolean debug = false; /** Name of property ID */ String idName; /** Integer number used as property ID */ int id; /** Offset of the property value(s) in romized values array */ int valueOffset; /** * Constructor * * @param idName name of the property's ID * @param id property's ID * @exception IllegalArgumentException if some of parameters * are invalid */ SkinPropertyBase(String idName, String id) { this.idName = idName; try { this.id = Integer.parseInt(id); } catch (NumberFormatException e) { throw new IllegalArgumentException( "Skin property " + '"' + idName + '"' + " has illegal ID value: " + '"' + id + '"'); } // offset will be set later this.valueOffset = -1; } /** * Tests if two properties have the same value * * @param prop property to compare value with * @return true if properties have the same value */ abstract boolean isEqualValue(SkinPropertyBase prop); /** * How many entries in values array is required for * storing this property value * * @return number of array entries required for storing * the value of this property */ abstract int getValueOffsetDelta(); /** * Prints values array entries for this property's value * * @param out where to print entries */ abstract void outputValue(BinaryOutputStreamExt out) throws java.io.IOException; /** * Factory method: constructs SkinProperty from DOM node that * corresponds to the property description in XML file.` * * @param n DOM node that corresponds to the property * description in XML file * @return SkinPropertyBase object constructed from DOM node * @exception IllegalArgumentException if DOM node is invalid */ static SkinPropertyBase valueOf(Node n) throws IllegalArgumentException { if (debug) { System.err.println("Property node: " + n.getNodeName()); } SkinPropertyBase p = null; String idName = getAttributeValue(n, "Key"); String id = getAttributeValue(n, "KeyValue"); String value = getAttributeValue(n, "Value"); if (debug) { System.err.println("\tID name: " + idName); System.err.println("\tID: " + id); System.err.println("\tValue: " + value); System.err.println(""); } String nodeName = n.getNodeName(); if (nodeName.equals("integer")) { p = new IntSkinProperty(idName, id, value); } else if (nodeName.equals("integer_seq")) { p = new IntSeqSkinProperty(idName, id, value); } else if (nodeName.equals("string")) { p = new StringSkinProperty(idName, id, value); } else if (nodeName.equals("font")) { p = new FontSkinProperty(idName, id, value); } else if (nodeName.equals("image")) { String isRomized = getAttributeValue(n, "Romized"); p = new ImageSkinProperty(idName, id, value, isRomized); } else if (nodeName.equals("composite_image")) { String totalPieces = getAttributeValue(n, "Pieces"); String isRomized = getAttributeValue(n, "Romized"); p = new CompositeImageSkinProperty(idName, id, value, totalPieces, isRomized); } else { throw new IllegalArgumentException( "Illegal skin property node: " + '"' + nodeName + '"'); } return p; } /** * Helper method: gets attribute value from node with some * errors checking. * * @param n DOM node to get attribute value from * @param attrName attribute name * @return requested attribute value */ private static String getAttributeValue(Node n, String attrName) { Element e = (Element)n; String attrValue = e.getAttribute(attrName); return attrValue.trim(); } /** * Helper method for renaming symbolic property value coming * from XML file (constant name) into another constant name. * Needed for backward compatibility. * * @param value original value * @return renamed value */ protected static String renameSymbolicValue(String value) { /** * Value can be in form of "Graphics.VALUE" where "VALUE" is * the name of one of the constants defined in Graphics class. * Convert such value into "SkinResourcesConstants.VALUE". * The reason why "SkinResourcesConstants.VALUE" is not used * directly in XML file is backward compatibility. */ if (value.startsWith("Graphics.")) { int dotIdx = value.indexOf("."); value = "SkinResourcesConstants" + value.substring(dotIdx); } /** * Value can be in form of "ScrollIndSkin.VALUE" where "VALUE" is * the name of one of the constants defined in * ScrollIndResourcesConstants class. * Convert such value into "ScrollIndResourcesConstants.VALUE". * The reason why "ScrollIndResourcesConstants.VALUE" is not * used directly in XML file is backward compatibility. */ if (value.startsWith("ScrollIndSkin.")) { int dotIdx = value.indexOf("."); value = "ScrollIndResourcesConstants" + value.substring(dotIdx); } /** * Value can be in form of "FontResources.VALUE" where "VALUE" is * the name of one of the constants defined in * FontResourcesConstants class. * Convert such value into "FontResourcesConstants.VALUE". * The reason why "FontResourcesConstants.VALUE" is not * used directly in XML file is backward compatibility. */ if (value.startsWith("FontResources.")) { int dotIdx = value.indexOf("."); value = "FontResourcesConstants" + value.substring(dotIdx); } return value; } /** * Helper method for convertic symbolic property value into int value. * Basically, it converts integer constant name into constant value. * * @param value symbolic value * @return integer value */ protected static int symbolicValueToInt(String value) { int dotIdx = value.indexOf("."); if (dotIdx == -1 || dotIdx == value.length() - 1) { throw new IllegalArgumentException(); } String className = value.substring(0, dotIdx); if (className.length() == 0) { throw new IllegalArgumentException(); } className = "com.sun.midp.chameleon.skins.resources." + className; Class c = null; try { c = Class.forName(className); } catch (Throwable t) { throw new IllegalArgumentException(); } String fieldName = value.substring(dotIdx + 1); if (fieldName.length() == 0) { throw new IllegalArgumentException(); } Field f = null; try { f = c.getField(fieldName); } catch (Throwable t) { throw new IllegalArgumentException(); } int val = 0; try { val = f.getInt(null); } catch (Throwable t) { throw new IllegalArgumentException(); } return val; } /** * Property value can be primitive arithmetic expression. * This helper method evaluates such expression. Operators * precedence is simple, left to right. * * @param exp expression to evaluate * @return integer expression value */ protected static int evalValueExpression(String exp) { int result = 0; char op = '='; StringTokenizer st = new StringTokenizer(exp); while (true) { String v = renameSymbolicValue(st.nextToken()); int intVal = 0; try { int radix = 10; if (v.startsWith("0x")) { v = v.substring(2); radix = 16; } intVal = Integer.parseInt(v, radix); } catch (NumberFormatException e) { intVal = symbolicValueToInt(v); } switch (op) { case '=': result = intVal; break; case '|': result |= intVal; break; default: throw new IllegalArgumentException(); } if (!st.hasMoreTokens()) { break; } String opStr = st.nextToken(); if (opStr.length() > 1) { throw new IllegalArgumentException(); } op = (opStr.toCharArray())[0]; } return result;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -