comparison src/samer/core_/X.java @ 0:bf79fb79ee13

Initial Mercurial check in.
author samer
date Tue, 17 Jan 2012 17:50:20 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:bf79fb79ee13
1 /*
2 * X.java
3 *
4 * Copyright (c) 2001, Samer Abdallah, King's College London.
5 * All rights reserved.
6 *
7 * This software is provided AS IS and WITHOUT ANY WARRANTY;
8 * without even the implied warranty of MERCHANTABILITY or
9 * FITNESS FOR A PARTICULAR PURPOSE.
10 */
11
12 package samer.core;
13 import java.io.StringWriter;
14 import java.util.StringTokenizer;
15 import java.awt.Font;
16 import java.awt.Rectangle;
17 import java.awt.Color;
18 import java.awt.SystemColor;
19
20 import samer.core.Environment.Datum;
21 import samer.core.Environment.Codec;
22 import samer.core.Environment.Autocoder;
23
24 /**
25 Static methods for converting objects and extracting correctly typed
26 values from Environments. Short name
27 because of expected frequent use! Also, contains
28 several Codec classes.
29 @see samer.core.Environment
30 @see samer.core.Environment.Datum
31 @see samer.core.Environment.Autocoder
32 */
33
34 public class X
35 {
36 /** Tries to extract an Object from the given Datum, throws Exception in failure */
37 public static Object object(Datum b) throws Exception {
38 Object ret=b.get(ObjectCodec,null);
39 if (ret==null) throw new Exception("no data");
40 return ret;
41 }
42
43 /** Tries to extract a String given Datum */
44 public static String string(Datum b) throws Exception {
45 String ret=(String)b.get(StringCodec,null);
46 if (ret==null) throw new Exception("datum has no value");
47 return ret;
48 }
49
50 /** Tries to extract a Font given Datum. If this fails, tries
51 to decode def using FontCodec. def can be a Font or a String. */
52 public static Font font(Datum b, Object def) {
53 return (Font)b.get(FontCodec,def);
54 }
55
56 /** Tries to extract a Rectangle from given Datum. If this fails, tries
57 to decode def as a rectangle. */
58 public static Rectangle rect(Datum b, Rectangle def) {
59 return (Rectangle)b.get(RectangleCodec,def);
60 }
61
62 /** Get String from Datum, returning def if this fails */
63 public static String string(Datum b,String def) {
64 return (String)b.get(StringCodec,def);
65 }
66
67 /** Get Color from Datum, decoding def if this fails. def can
68 be a Color or a String. See ColorCodec. */
69 public static Color color(Datum b, Object def) {
70 return (Color)b.get(ColorCodec,def);
71 }
72
73 /** Extract int from Datum */
74 public static int _int(Datum b,int def) {
75 return ((Integer)b.get(IntegerCodec,new Integer(def))).intValue();
76 }
77 /** Extract double from Datum */
78 public static double _double(Datum b,double def) {
79 return ((Double)b.get(DoubleCodec,new Double(def))).doubleValue();
80 }
81 /** Extract boolean from Datum */
82 public static boolean _bool(Datum b,boolean def) {
83 return ((Boolean)b.get(BooleanCodec,new Boolean(def))).booleanValue();
84 }
85
86 /** store given object to current environment */
87 public static void store(String name, Object value) {
88 Shell.env().store(name,value,codec(value));
89 }
90
91 /** Extracts an integer array from a string. Valid strings are, eg
92 "(1,2,3)", "(4 5 6)", "7 8 9", "10, 11, 12" */
93 public static int[] parseIntArray(String s, int n)
94 {
95 StringTokenizer token = new StringTokenizer(s,"(), ");
96 int[] a=new int[n];
97
98 for (int i=0; i<n; i++) {
99 a[i]=Integer.parseInt(token.nextToken());
100 }
101 return a;
102 }
103
104 /** @see samer.core.X.parseIntArray */
105 public static double[] doubleArray(String s, int n)
106 {
107 StringTokenizer token = new StringTokenizer(s,"(), ");
108 double[] a=new double[n];
109
110 for (int i=0; i<n; i++) {
111 a[i]=parseDouble(token.nextToken());
112 }
113 return a;
114 }
115
116 /** Sets each integer in the int array to the numeric value of the corresponding
117 Objects in the Object array (they have to be subclasses of Numbe).
118 */
119 public static void setIntArray(int[] a, Object[] b) {
120 for (int i=0; i<a.length; i++)
121 a[i]=((Number)b[i]).intValue();
122 }
123
124 /** Base class for objects that can convert some type to and from String or
125 Object. @see samer.core.Environment.Codec */
126 public static class BaseCodec implements Codec
127 {
128 public Class targetClass() { return Object.class; }
129
130 /** convert to string using object's toString() method (a reasonable default) */
131 public String string(Object o) { return o.toString(); }
132
133 /** Convert to object by returning original object. This might be OK for
134 * immutable objects, but should be overriden for mutable ones, perhaps
135 * returning a clone of the original or an object of a different class altogether.
136 */
137 public Object object(Object o) { return o; }
138
139 /** Decode given object to by return it the given object itself. */
140 public Object decode(Object o) { return o; }
141 };
142
143 public static Codec ObjectCodec = new BaseCodec();
144
145 /** Can decode numbers in Integer, Number, or String form */
146 public static Codec IntegerCodec = new BaseCodec()
147 {
148 public Class targetClass() { return Integer.class; }
149
150 /** If given object is any subclass of java.lang.Number, then its
151 numerical value is returned as an Integer. If it is a string,
152 the string is parsed to extract an integer value. Any other
153 class will probably cause this function to barf.
154 */
155
156 public Object decode(Object o) {
157 // if (o==null) return null;
158 if (o instanceof Integer) return o;
159 if (o instanceof String) return Integer.decode(o.toString());
160 return new Integer(((Number)o).intValue());
161 }
162 };
163
164 private static DoubleFormat fmt=new DoubleFormat(3);
165
166 /** Convert double to string using the (private) current DoubleFormat object */
167 public static String string(double v) { return fmt._format(v); }
168
169 /** Convert string to double */
170 public static double parseDouble(String s) {
171 return Double.valueOf(s).doubleValue();
172 }
173
174 /** Can decode numbers in Double, Number, or String form */
175 public static Codec DoubleCodec = new BaseCodec()
176 {
177 public Class targetClass() { return Double.class; }
178
179 public String string(Object o) { return fmt._format(((Number)o).doubleValue()); }
180
181 /** Can decode String or any subclass of Number */
182 public Object decode(Object o) {
183 // if (o==null) return null;
184 if (o instanceof Double) return o;
185 if (o instanceof String) return Double.valueOf(o.toString());
186 return new Double(((Number)o).doubleValue());
187 }
188
189 };
190
191 /** Can decode Boolean or String ("true" or "false") form */
192 public static Codec BooleanCodec = new BaseCodec()
193 {
194 public Class targetClass() { return Boolean.class; }
195 public Object decode(Object o) {
196 // if (o==null) return null;
197 if (o instanceof Boolean) return o;
198 return Boolean.valueOf(o.toString());
199 }
200 };
201
202 public static Codec StringCodec = new BaseCodec()
203 {
204 public Class targetClass() { return String.class; }
205 public Object decode(Object o) {
206 // if (o==null) return null;
207 if (o instanceof String) return o;
208 else return o.toString();
209 }
210 };
211
212
213 /** Can decode Color or String form
214 String can be "#rrggbb" where rrggbb are hex,
215 or "(r,g,b)" or "(r g b)" where r, g, b are integers,
216 or "$bg", which evaluates to SystemColor.control, the
217 default background color for components,
218 or "$fg", which evaluates to SystemColor.controlText,
219 the default foreground color.
220 */
221
222 public static Codec ColorCodec = new Codec()
223 {
224 public Class targetClass() { return Color.class; }
225 public Object object(Object o) { return o; }
226 public String string(Object o) {
227 StringBuffer buf=new StringBuffer("#");
228 buf.append(Integer.toHexString(((Color)o).getRGB() & 0xffffff));
229 return buf.toString();
230 }
231 public Object decode(Object o) {
232 // if (o==null) return null;
233 if (o instanceof Color) return o;
234
235 String s=o.toString();
236 if (s.startsWith("(")) {
237 int[] a=parseIntArray(s,3);
238 return new Color(a[0],a[1],a[2]);
239 }
240 if (s.equals("$bg")) return SystemColor.control;
241 if (s.equals("$fg")) return SystemColor.controlText;
242 return Color.decode(s);
243 }
244 };
245
246 /** Can decode Font or String, using Font.decode(),
247 eg "Helvetica-PLAIN-12" */
248 public static Codec FontCodec = new Codec()
249 {
250 public Class targetClass() { return Font.class; }
251 public Object object(Object o) { return o; }
252 public String string(Object o) { return o.toString(); }
253 public Object decode(Object o) {
254 // if (o==null) return null;
255 if (o instanceof Font) return o;
256 return Font.decode(o.toString());
257 }
258 };
259
260 public static Codec RectangleCodec = new Codec()
261 {
262 public Class targetClass() { return Font.class; }
263 public Object object(Object o) { return o; }
264 public String string(Object o) {
265 Rectangle r=(Rectangle)o;
266 StringBuffer buf=new StringBuffer();
267
268 buf.append('(');
269 buf.append(String.valueOf(r.x)); buf.append(',');
270 buf.append(String.valueOf(r.y)); buf.append(',');
271 buf.append(String.valueOf(r.width)); buf.append(',');
272 buf.append(String.valueOf(r.height));
273 buf.append(')');
274 return buf.toString();
275 }
276
277 public Object decode(Object o) {
278 // if (o==null) return null;
279 if (o instanceof Rectangle) return o;
280
281 int[] a=parseIntArray(o.toString(),4);
282 return new Rectangle(a[0],a[1],a[2],a[3]);
283 }
284 };
285
286 public static Codec codec(Object o) { return codec(o.getClass()); }
287 public static Codec codec(Class c)
288 {
289 for (int i=classes.length-1; i>0; i--) {
290 if (classes[i].isAssignableFrom(c)) return codecs[i];
291 }
292 return codecs[0];
293 }
294
295 private static Class[] classes = {
296 Object.class,
297 Font.class,
298 Rectangle.class,
299 Color.class,
300 String.class,
301 Boolean.class,
302 Integer.class,
303 Double.class
304 };
305
306 private static Codec[] codecs = {
307 ObjectCodec,
308 FontCodec,
309 RectangleCodec,
310 ColorCodec,
311 StringCodec,
312 BooleanCodec,
313 IntegerCodec,
314 DoubleCodec
315 };
316 }
317