Mercurial > hg > jslab
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 |