Mercurial > hg > jslab
view src/samer/core_/X.java @ 0:bf79fb79ee13
Initial Mercurial check in.
author | samer |
---|---|
date | Tue, 17 Jan 2012 17:50:20 +0000 |
parents | |
children |
line wrap: on
line source
/* * X.java * * Copyright (c) 2001, Samer Abdallah, King's College London. * All rights reserved. * * This software is provided AS IS and WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. */ package samer.core; import java.io.StringWriter; import java.util.StringTokenizer; import java.awt.Font; import java.awt.Rectangle; import java.awt.Color; import java.awt.SystemColor; import samer.core.Environment.Datum; import samer.core.Environment.Codec; import samer.core.Environment.Autocoder; /** Static methods for converting objects and extracting correctly typed values from Environments. Short name because of expected frequent use! Also, contains several Codec classes. @see samer.core.Environment @see samer.core.Environment.Datum @see samer.core.Environment.Autocoder */ public class X { /** Tries to extract an Object from the given Datum, throws Exception in failure */ public static Object object(Datum b) throws Exception { Object ret=b.get(ObjectCodec,null); if (ret==null) throw new Exception("no data"); return ret; } /** Tries to extract a String given Datum */ public static String string(Datum b) throws Exception { String ret=(String)b.get(StringCodec,null); if (ret==null) throw new Exception("datum has no value"); return ret; } /** Tries to extract a Font given Datum. If this fails, tries to decode def using FontCodec. def can be a Font or a String. */ public static Font font(Datum b, Object def) { return (Font)b.get(FontCodec,def); } /** Tries to extract a Rectangle from given Datum. If this fails, tries to decode def as a rectangle. */ public static Rectangle rect(Datum b, Rectangle def) { return (Rectangle)b.get(RectangleCodec,def); } /** Get String from Datum, returning def if this fails */ public static String string(Datum b,String def) { return (String)b.get(StringCodec,def); } /** Get Color from Datum, decoding def if this fails. def can be a Color or a String. See ColorCodec. */ public static Color color(Datum b, Object def) { return (Color)b.get(ColorCodec,def); } /** Extract int from Datum */ public static int _int(Datum b,int def) { return ((Integer)b.get(IntegerCodec,new Integer(def))).intValue(); } /** Extract double from Datum */ public static double _double(Datum b,double def) { return ((Double)b.get(DoubleCodec,new Double(def))).doubleValue(); } /** Extract boolean from Datum */ public static boolean _bool(Datum b,boolean def) { return ((Boolean)b.get(BooleanCodec,new Boolean(def))).booleanValue(); } /** store given object to current environment */ public static void store(String name, Object value) { Shell.env().store(name,value,codec(value)); } /** Extracts an integer array from a string. Valid strings are, eg "(1,2,3)", "(4 5 6)", "7 8 9", "10, 11, 12" */ public static int[] parseIntArray(String s, int n) { StringTokenizer token = new StringTokenizer(s,"(), "); int[] a=new int[n]; for (int i=0; i<n; i++) { a[i]=Integer.parseInt(token.nextToken()); } return a; } /** @see samer.core.X.parseIntArray */ public static double[] doubleArray(String s, int n) { StringTokenizer token = new StringTokenizer(s,"(), "); double[] a=new double[n]; for (int i=0; i<n; i++) { a[i]=parseDouble(token.nextToken()); } return a; } /** Sets each integer in the int array to the numeric value of the corresponding Objects in the Object array (they have to be subclasses of Numbe). */ public static void setIntArray(int[] a, Object[] b) { for (int i=0; i<a.length; i++) a[i]=((Number)b[i]).intValue(); } /** Base class for objects that can convert some type to and from String or Object. @see samer.core.Environment.Codec */ public static class BaseCodec implements Codec { public Class targetClass() { return Object.class; } /** convert to string using object's toString() method (a reasonable default) */ public String string(Object o) { return o.toString(); } /** Convert to object by returning original object. This might be OK for * immutable objects, but should be overriden for mutable ones, perhaps * returning a clone of the original or an object of a different class altogether. */ public Object object(Object o) { return o; } /** Decode given object to by return it the given object itself. */ public Object decode(Object o) { return o; } }; public static Codec ObjectCodec = new BaseCodec(); /** Can decode numbers in Integer, Number, or String form */ public static Codec IntegerCodec = new BaseCodec() { public Class targetClass() { return Integer.class; } /** If given object is any subclass of java.lang.Number, then its numerical value is returned as an Integer. If it is a string, the string is parsed to extract an integer value. Any other class will probably cause this function to barf. */ public Object decode(Object o) { // if (o==null) return null; if (o instanceof Integer) return o; if (o instanceof String) return Integer.decode(o.toString()); return new Integer(((Number)o).intValue()); } }; private static DoubleFormat fmt=new DoubleFormat(3); /** Convert double to string using the (private) current DoubleFormat object */ public static String string(double v) { return fmt._format(v); } /** Convert string to double */ public static double parseDouble(String s) { return Double.valueOf(s).doubleValue(); } /** Can decode numbers in Double, Number, or String form */ public static Codec DoubleCodec = new BaseCodec() { public Class targetClass() { return Double.class; } public String string(Object o) { return fmt._format(((Number)o).doubleValue()); } /** Can decode String or any subclass of Number */ public Object decode(Object o) { // if (o==null) return null; if (o instanceof Double) return o; if (o instanceof String) return Double.valueOf(o.toString()); return new Double(((Number)o).doubleValue()); } }; /** Can decode Boolean or String ("true" or "false") form */ public static Codec BooleanCodec = new BaseCodec() { public Class targetClass() { return Boolean.class; } public Object decode(Object o) { // if (o==null) return null; if (o instanceof Boolean) return o; return Boolean.valueOf(o.toString()); } }; public static Codec StringCodec = new BaseCodec() { public Class targetClass() { return String.class; } public Object decode(Object o) { // if (o==null) return null; if (o instanceof String) return o; else return o.toString(); } }; /** Can decode Color or String form String can be "#rrggbb" where rrggbb are hex, or "(r,g,b)" or "(r g b)" where r, g, b are integers, or "$bg", which evaluates to SystemColor.control, the default background color for components, or "$fg", which evaluates to SystemColor.controlText, the default foreground color. */ public static Codec ColorCodec = new Codec() { public Class targetClass() { return Color.class; } public Object object(Object o) { return o; } public String string(Object o) { StringBuffer buf=new StringBuffer("#"); buf.append(Integer.toHexString(((Color)o).getRGB() & 0xffffff)); return buf.toString(); } public Object decode(Object o) { // if (o==null) return null; if (o instanceof Color) return o; String s=o.toString(); if (s.startsWith("(")) { int[] a=parseIntArray(s,3); return new Color(a[0],a[1],a[2]); } if (s.equals("$bg")) return SystemColor.control; if (s.equals("$fg")) return SystemColor.controlText; return Color.decode(s); } }; /** Can decode Font or String, using Font.decode(), eg "Helvetica-PLAIN-12" */ public static Codec FontCodec = new Codec() { public Class targetClass() { return Font.class; } public Object object(Object o) { return o; } public String string(Object o) { return o.toString(); } public Object decode(Object o) { // if (o==null) return null; if (o instanceof Font) return o; return Font.decode(o.toString()); } }; public static Codec RectangleCodec = new Codec() { public Class targetClass() { return Font.class; } public Object object(Object o) { return o; } public String string(Object o) { Rectangle r=(Rectangle)o; StringBuffer buf=new StringBuffer(); buf.append('('); buf.append(String.valueOf(r.x)); buf.append(','); buf.append(String.valueOf(r.y)); buf.append(','); buf.append(String.valueOf(r.width)); buf.append(','); buf.append(String.valueOf(r.height)); buf.append(')'); return buf.toString(); } public Object decode(Object o) { // if (o==null) return null; if (o instanceof Rectangle) return o; int[] a=parseIntArray(o.toString(),4); return new Rectangle(a[0],a[1],a[2],a[3]); } }; public static Codec codec(Object o) { return codec(o.getClass()); } public static Codec codec(Class c) { for (int i=classes.length-1; i>0; i--) { if (classes[i].isAssignableFrom(c)) return codecs[i]; } return codecs[0]; } private static Class[] classes = { Object.class, Font.class, Rectangle.class, Color.class, String.class, Boolean.class, Integer.class, Double.class }; private static Codec[] codecs = { ObjectCodec, FontCodec, RectangleCodec, ColorCodec, StringCodec, BooleanCodec, IntegerCodec, DoubleCodec }; }