// Copyright 2000-2005, FreeHEP. package hep.graphics.heprep.ref; import java.awt.*; import java.io.*; import java.util.*; import org.freehep.util.ScientificFormat; import org.freehep.swing.ColorConverter; import hep.graphics.heprep.*; import hep.graphics.heprep.xml.*; import hep.graphics.heprep.util.*; /** * * @author M.Donszelmann * * @version $Id: DefaultHepRepAttValue.java 8584 2006-08-10 23:06:37Z duns $ */ public class DefaultHepRepAttValue implements HepRepAttValue, Serializable { private static final ScientificFormat scientific = new ScientificFormat(); private String name; private String lowerCaseName; // values implemented as separate items, so that they do not take up unnecessary space for an Object // only ONE of these is filled private String lowerCaseString; private Object objectValue; private long longValue; private double doubleValue; private boolean booleanValue; private int type; private int showLabel; private DefaultHepRepAttValue() { // Un-initialized, for clone } void replace(DefaultHepRepAttValue attValue) { name = attValue.name; lowerCaseName = attValue.lowerCaseName; lowerCaseString = attValue.lowerCaseString; objectValue = attValue.objectValue; longValue = attValue.longValue; doubleValue = attValue.doubleValue; booleanValue = attValue.booleanValue; type = attValue.type; showLabel = attValue.showLabel; } /** * Create an String Attribute Value * @param name name of the value * @param value value * @param showLabel code what to show as a label */ public DefaultHepRepAttValue(String name, String value, int showLabel) { init(name, TYPE_STRING, showLabel); objectValue = (value == null) ? null : value.intern(); lowerCaseString = (value == null) ? null : value.toLowerCase().intern(); } /** * Create an Color Attribute Value * @param name name of the value * @param value value * @param showLabel code what to show as a label */ public DefaultHepRepAttValue(String name, Color value, int showLabel) { init(name, TYPE_COLOR, showLabel); objectValue = value; } /** * Create an long Attribute Value * @param name name of the value * @param value value * @param showLabel code what to show as a label */ public DefaultHepRepAttValue(String name, long value, int showLabel) { init(name, TYPE_LONG, showLabel); longValue = value; } /** * Create an int Attribute Value * @param name name of the value * @param value value * @param showLabel code what to show as a label */ public DefaultHepRepAttValue(String name, int value, int showLabel) { init(name, TYPE_INT, showLabel); longValue = value; } /** * Create an double Attribute Value * @param name name of the value * @param value value * @param showLabel code what to show as a label */ public DefaultHepRepAttValue(String name, double value, int showLabel) { init(name, TYPE_DOUBLE, showLabel); doubleValue = value; } /** * Create an boolean Attribute Value * @param name name of the value * @param value value * @param showLabel code what to show as a label */ public DefaultHepRepAttValue(String name, boolean value, int showLabel) { init(name, TYPE_BOOLEAN, showLabel); booleanValue = value; } /** * Create a typed Attribute Value * @param name name of the value * @param value value * @param type tyoe of the value * @param showLabel code what to show as a label */ public DefaultHepRepAttValue(String name, String value, String type, int showLabel) { int t = toType(type); init(name, t, showLabel); switch (t) { case TYPE_STRING: objectValue = value.intern(); lowerCaseString = value.toLowerCase().intern(); break; case TYPE_COLOR: objectValue = HepRepColor.get(value); break; case TYPE_LONG: longValue = Long.decode(value).longValue(); break; case TYPE_INT: longValue = Integer.decode(value).intValue(); break; case TYPE_DOUBLE: doubleValue = HepRepUtil.decodeNumber(value); break; case TYPE_BOOLEAN: booleanValue = Boolean.valueOf(value).booleanValue(); break; default: System.err.println("Unknown type in DefaultHepRepAttValue: '"+type+"'"); objectValue = value; break; } } private void init(String name, int type, int showLabel) { this.name = name.intern(); this.lowerCaseName = name.toLowerCase().intern(); this.type = type; this.showLabel = showLabel; } public HepRepAttValue copy() throws CloneNotSupportedException { DefaultHepRepAttValue copy = new DefaultHepRepAttValue(); copy.init(name, type, showLabel); copy.lowerCaseString = lowerCaseString; copy.objectValue = objectValue; copy.longValue = longValue; copy.doubleValue = doubleValue; copy.booleanValue = booleanValue; return copy; } public String getName() { return name; } public String getLowerCaseName() { return lowerCaseName; } public int getType() { return type; } // Use the toString method of object, so that this is well defined // for all data types. public String getTypeName() { return toString(type); } private static String labelStrings[] = {"NAME", "DESC", "VALUE", "EXTRA"}; private static Map labelTable; static { labelTable = new HashMap(5); // FIXME: JHEPREP-4 labelTable.put("NONE", new Integer(HepRepAttValue.SHOW_NONE)); labelTable.put("NAME", new Integer(HepRepAttValue.SHOW_NAME)); labelTable.put("DESC", new Integer(HepRepAttValue.SHOW_DESC)); labelTable.put("VALUE", new Integer(HepRepAttValue.SHOW_VALUE)); labelTable.put("EXTRA", new Integer(HepRepAttValue.SHOW_EXTRA)); } /** * Convert showLabel string to a int code * @param labelString showLabel string * @return showLabel code */ public static int toShowLabel(String labelString) { int showLabel = SHOW_NONE; if (labelString != null) { StringTokenizer st = new StringTokenizer(labelString, ", "); while (st.hasMoreTokens()) { String label = st.nextToken(); Integer number = (Integer)labelTable.get(label); if (number != null) { showLabel += number.intValue(); } else { showLabel += Integer.decode(label).intValue(); } } } return showLabel; } /** * Converts a showLabel code to a string * @param showLabel code * @return showLabel string */ public static String toShowLabel(int showLabel) { String label = null; if (showLabel == HepRepAttValue.SHOW_NONE) { label = "NONE"; } else { for (int i=0; i<16; i++) { if (((showLabel >> i) & 0x0001) == 0x0001) { if (label == null) { label = ""; } else { label += ", "; } if (i < labelStrings.length) { label += labelStrings[i]; } else { label += "0x"+Integer.toHexString(0x0001 << i); } } } } return label; } /** * Converts a type code to a string * @param type code * @return type string */ public static String toString(int type) { switch(type) { case TYPE_STRING: return("String"); case TYPE_COLOR: return("Color"); case TYPE_LONG: return("long"); case TYPE_INT: return("int"); case TYPE_DOUBLE: return("double"); case TYPE_BOOLEAN: return("boolean"); default: throw new RuntimeException("Unknown type stored in HepRepAttDef: '"+type+"'"); } } private static final Map stringToType; static { stringToType = new HashMap(6); stringToType.put("String", new Integer(TYPE_STRING)); stringToType.put("Color", new Integer(TYPE_COLOR)); stringToType.put("long", new Integer(TYPE_LONG)); stringToType.put("int", new Integer(TYPE_INT)); stringToType.put("double", new Integer(TYPE_DOUBLE)); stringToType.put("boolean", new Integer(TYPE_BOOLEAN)); } /** * Converts type string to type code * @param type type string * @return code for type or -1 if unknown */ public static int toType(String type) { Integer code = (type != null) ? (Integer)stringToType.get(type) : null; return (code == null) ? TYPE_UNKNOWN : code.intValue(); } private static final Map types; static { try { XMLHepRepReader.readDefaults(); } catch (IOException ioe) { System.err.println("Problem reading HepRep Defaults "+ioe); } // add all defaults to types. Set attValues = HepRepDefaults.getAttValues(); types = new HashMap(attValues.size()); for (Iterator i=attValues.iterator(); i.hasNext(); ) { HepRepAttValue attValue = (HepRepAttValue)i.next(); types.put(attValue.getLowerCaseName(), attValue.getTypeName()); } } /** * Add a new type for guessing * @param name name of the type * @param type suggested type */ public static void addGuessedType(String name, String type) { types.put(name.toLowerCase(), type); } /** * Returns type, unless type is null, in which case it guesses the type from the name, * and if not found from the value. If found from the value a message is printed * and the new association is added to the name table. If not found, the type defaults * to String and is also added to the table, but no message is printed. * @param name name from which to guess the type * @param value value from which to guess the type * @param type suggested type, or null * @return guessed type */ public static String guessType(String name, String value, String type) { if (type != null) return type; type = guessTypeFromName(name); if (type == null) { type = guessTypeFromValue(value); if (!type.equals("String")) { System.out.println("Guessed type for '"+name+"' to be '"+type+"'."); } types.put(name.toLowerCase(), type); } return type; } /** * Returns type from a guess by name, or null if it cannot be guessed. * @param name name to guess from * @return guessed type */ public static String guessTypeFromName(String name) { return (String)types.get(name.toLowerCase()); } /** * Returns type, guessed from the value. Defaults to String. * @param value value to guess from * @return guessed type */ public static String guessTypeFromValue(String value) { if (value == null) return "String"; try { // guess long and ints to be double to allow for flexibility... Double.valueOf(value); return "double"; } catch (NumberFormatException e) { } if (value.equalsIgnoreCase("false") || value.equalsIgnoreCase("true")) { return "boolean"; } try { ColorConverter cc = new ColorConverter(); cc.stringToColor(value); return "Color"; } catch (ColorConverter.ColorConversionException e) { } return "String"; } public int showLabel() { return showLabel; } public String getString() throws HepRepTypeException { try { return (String)objectValue; } catch (ClassCastException cce) { throw new HepRepTypeException("Attribute Value for '"+getName()+ "' with value '"+getAsString()+ "' of type '"+getTypeName()+ "' cannot be converted to type 'String'"); } } public String getLowerCaseString() throws HepRepTypeException { try { return lowerCaseString; } catch (ClassCastException cce) { throw new HepRepTypeException("Attribute Value for '"+getName()+ "' with value '"+getAsString()+ "' of type '"+getTypeName()+ "' cannot be converted to type 'String'"); } } public Color getColor() throws HepRepTypeException { try { return (Color)objectValue; } catch (ClassCastException cce) { throw new HepRepTypeException("Attribute Value for '"+getName()+ "' with value '"+getAsString()+ "' of type '"+getTypeName()+ "' cannot be converted to type 'Color'"); } } public long getLong() throws HepRepTypeException { if ((type != TYPE_LONG) && (type != TYPE_INT)) { throw new HepRepTypeException("Attribute Value for '"+getName()+ "' with value '"+getAsString()+ "' of type '"+getTypeName()+ "' cannot be converted to type 'long'"); } return longValue; } public int getInteger() throws HepRepTypeException { if (type != TYPE_INT) { throw new HepRepTypeException("Attribute Value for '"+getName()+ "' with value '"+getAsString()+ "' of type '"+getTypeName()+ "' cannot be converted to type 'int'"); } return (int)longValue; } public double getDouble() throws HepRepTypeException { if ((type != TYPE_DOUBLE) && (type != TYPE_LONG) && (type != TYPE_INT)) { throw new HepRepTypeException("Attribute Value for '"+getName()+ "' with value '"+getAsString()+ "' of type '"+getTypeName()+ "' cannot be converted to type 'double'"); } return (type == TYPE_DOUBLE) ? doubleValue : longValue; } public boolean getBoolean() throws HepRepTypeException { if ((type != TYPE_BOOLEAN) && (type != TYPE_LONG) && (type != TYPE_INT)) { throw new HepRepTypeException("Attribute Value for '"+getName()+"'and value+'"+objectValue+"' of type'"+getTypeName()+"' cannot be converted to type 'boolean'"); } return (type == TYPE_BOOLEAN) ? booleanValue : longValue != 0; } public String getAsString() { return getAsString(this); } /** * Return the Attribute Value as string * @param attValue attribute value * @return attribute string */ public static String getAsString(HepRepAttValue attValue) { switch(attValue.getType()) { case TYPE_STRING: return attValue.getString(); case TYPE_COLOR: return getAsString(attValue.getColor()); case TYPE_LONG: return getAsString(attValue.getLong()); case TYPE_INT: return getAsString(attValue.getInteger()); case TYPE_DOUBLE: return getAsString(attValue.getDouble()); case TYPE_BOOLEAN: return getAsString(attValue.getBoolean()); default: return "Unknown typecode: "+attValue.getType(); } } /** * Return Color Attribute Value as String * @param value value * @return attribute string */ public static String getAsString(Color value) { return HepRepColor.get(value); } /** * Return long Attribute Value as String * @param value value * @return attribute string */ public static String getAsString(long value) { return Long.toString(value); } /** * Return int Attribute Value as String * @param value value * @return attribute string */ public static String getAsString(int value) { return Integer.toString(value); } /** * Return double Attribute Value as String * @param value value * @return attribute string */ public static String getAsString(double value) { return scientific.format(value); } /** * Return boolean Attribute Value as String * @param value value * @return attribute string */ public static String getAsString(boolean value) { return value ? "true" : "false"; } public String toString() { return getClass()+"["+ "name(lcase)="+getLowerCaseName()+", "+ "value="+getAsString()+", "+ "showLabel="+toShowLabel(showLabel())+"]"; } /* Disabled for FREEHEP-386 public boolean equals(Object o) { if (o == this) return true; if (o instanceof HepRepAttValue) { HepRepAttValue attValue = (HepRepAttValue)o; boolean r = (attValue.getLowerCaseName().equals(getLowerCaseName()) && (attValue.getType() == getType()) && (attValue.showLabel() == showLabel())); if (r) { switch(attValue.getType()) { case TYPE_STRING: r = r && (attValue.getString().equals(getString())); break; case TYPE_COLOR: r = r && (attValue.getColor().equals(getColor())); break; case TYPE_LONG: r = r && (attValue.getLong() == getLong()); break; case TYPE_INT: r = r && (attValue.getInteger() == getInteger()); break; case TYPE_DOUBLE: // FREEHEP-386 // r = r && (attValue.getDouble() == getDouble()); break; case TYPE_BOOLEAN: r = r && (attValue.getBoolean() == getBoolean()); break; default: r = false; break; } } if (HepRepUtil.debug() && !r) { System.out.println(this+" != "+attValue); } return r; } return false; } public int hashCode() { long hash = getLowerCaseName().hashCode(); hash |= getType(); hash |= showLabel(); switch(getType()) { default: case TYPE_STRING: hash |= getString().hashCode(); break; case TYPE_COLOR: hash |= getColor().hashCode(); break; case TYPE_LONG: hash |= getLong(); break; case TYPE_INT: hash |= getInteger(); break; case TYPE_DOUBLE: hash |= Double.doubleToLongBits(getDouble()); break; case TYPE_BOOLEAN: hash |= getBoolean() ? 1 : 2; break; } return (int)hash; } */ }