Javolution 6.0.0 java
TextContextImpl.java
Go to the documentation of this file.
1 /*
2  * Javolution - Java(TM) Solution for Real-Time and Embedded Systems
3  * Copyright (C) 2012 - Javolution (http://javolution.org/)
4  * All rights reserved.
5  *
6  * Permission to use, copy, modify, and distribute this software is
7  * freely granted, provided that this notice is preserved.
8  */
9 package javolution.text.internal;
10 
11 import java.awt.Color;
12 import java.awt.Font;
13 import java.io.IOException;
14 import java.math.BigDecimal;
15 import java.math.BigInteger;
16 import java.text.DateFormat;
17 import java.text.ParseException;
18 import java.text.SimpleDateFormat;
19 import java.util.Date;
20 import java.util.TimeZone;
21 
23 import javolution.text.CharSet;
24 import javolution.text.Cursor;
29 import javolution.util.FastMap;
30 
37 public final class TextContextImpl extends TextContext {
38 
39  private static final TextFormat<?> OBJECT_FORMAT = new TextFormat<Object>() {
40  ThreadLocal<Object> objToString = new ThreadLocal<Object>();
41 
42  public Appendable format(Object obj, Appendable dest)
43  throws IOException {
44  if (obj == null) return dest.append("null");
45  if (objToString.get() == obj) // Circularity in toString !
46  return TypeFormat.format(System.identityHashCode(obj),
47  dest.append("Object#"));
48  objToString.set(obj);
49  try {
50  String str = obj.toString();
51  return dest.append(str);
52  } finally {
53  objToString.set(null);
54  }
55  }
56 
57  public Object parse(CharSequence csq, Cursor cursor) {
58  throw new UnsupportedOperationException(
59  "Generic object parsing not supported.");
60  }
61 
62  };
63  // Holds class->format local mapping.
65 
66  // Caches class->format from class annotations.
68 
70  public TextContextImpl() {
71  localFormats = new FastMap<Class<?>, TextFormat<?>>(); // Updated only during configuration.
72  defaultFormats = new FastMap<Class<?>, TextFormat<?>>().shared(); // Can be updated concurrently.
74  }
75 
79  .putAll(parent.localFormats);
81  }
82 
83  @Override
84  protected TextContext inner() {
85  return new TextContextImpl(this);
86  }
87 
88  @SuppressWarnings("unchecked")
89  @Override
90  protected <T> TextFormat<T> searchFormat(Class<? extends T> type) {
91  Class<?> cls = type;
92  while (cls != null) {
93  TextFormat<?> format;
94  // Search local format first.
95  if (localFormats.size() > 0) {
96  format = localFormats.get(cls);
97  if (format != null) return (TextFormat<T>) format;
98  }
99  // Then search default format.
100  format = defaultFormats.get(cls);
101  if (format != null) return (TextFormat<T>) format;
102 
103  // Search annotations.
104  DefaultTextFormat annotation = cls
105  .getAnnotation(DefaultTextFormat.class);
106  if (annotation != null) { // Found it.
107  try {
108  format = annotation.value().newInstance();
109  } catch (Throwable error) {
110  LogContext.warning(error);
111  }
112  // Updates the default mapping.
113  Class<?> mappedClass = type;
114  while (true) {
115  defaultFormats.put(mappedClass, format);
116  if (mappedClass.equals(cls)) break;
117  mappedClass = mappedClass.getSuperclass();
118  }
119  return (TextFormat<T>) format;
120  }
121 
122  // Search superclass.
123  cls = cls.getSuperclass();
124  }
125  throw new Error("Object default format not found !");
126  }
127 
128  @Override
129  public <T> void setFormat(Class<? extends T> type, TextFormat<T> format) {
130  localFormats.put(type, format);
131  }
132 
134  // PREDEFINED FORMATS //
136 
137  private void storePrimitiveTypesFormats() {
138  defaultFormats.put(Object.class, OBJECT_FORMAT);
139  defaultFormats.put(Boolean.class, new TextFormat<Boolean>() {
140 
141  public Appendable format(Boolean obj, Appendable dest)
142  throws IOException {
143  return TypeFormat.format(obj.booleanValue(), dest);
144  }
145 
146  public Boolean parse(CharSequence csq, Cursor cursor) {
147  return TypeFormat.parseBoolean(csq, cursor);
148  }
149 
150  });
151  defaultFormats.put(Character.class, new TextFormat<Character>() {
152 
153  public Appendable format(Character obj, Appendable dest)
154  throws IOException {
155  return dest.append(obj.charValue());
156  }
157 
158  public Character parse(CharSequence csq, Cursor cursor) {
159  return Character.valueOf(cursor.nextChar(csq));
160  }
161 
162  });
163  defaultFormats.put(Byte.class, new TextFormat<Byte>() {
164 
165  public Appendable format(Byte obj, Appendable dest)
166  throws IOException {
167  return TypeFormat.format(obj.byteValue(), dest);
168  }
169 
170  public Byte parse(CharSequence csq, Cursor cursor) {
171  return Byte.valueOf(TypeFormat.parseByte(csq, 10, cursor));
172  }
173 
174  });
175  defaultFormats.put(Short.class, new TextFormat<Short>() {
176 
177  public Appendable format(Short obj, Appendable dest)
178  throws IOException {
179  return TypeFormat.format(obj.shortValue(), dest);
180  }
181 
182  public Short parse(CharSequence csq, Cursor cursor) {
183  return Short.valueOf(TypeFormat.parseShort(csq, 10, cursor));
184  }
185 
186  });
187  defaultFormats.put(Integer.class, new TextFormat<Integer>() {
188 
189  public Appendable format(Integer obj, Appendable dest)
190  throws IOException {
191  return TypeFormat.format(obj.intValue(), dest);
192  }
193 
194  public Integer parse(CharSequence csq, Cursor cursor) {
195  return Integer.valueOf(TypeFormat.parseInt(csq, 10, cursor));
196  }
197 
198  });
199  defaultFormats.put(Long.class, new TextFormat<Long>() {
200 
201  public Appendable format(Long obj, Appendable dest)
202  throws IOException {
203  return TypeFormat.format(obj.longValue(), dest);
204  }
205 
206  public Long parse(CharSequence csq, Cursor cursor) {
207  return Long.valueOf(TypeFormat.parseLong(csq, 10, cursor));
208  }
209 
210  });
211  defaultFormats.put(Float.class, new TextFormat<Float>() {
212 
213  public Appendable format(Float obj, Appendable dest)
214  throws IOException {
215  return TypeFormat.format(obj.floatValue(), dest);
216  }
217 
218  public Float parse(CharSequence csq, Cursor cursor) {
219  return new Float(TypeFormat.parseFloat(csq, cursor));
220  }
221 
222  });
223  defaultFormats.put(Double.class, new TextFormat<Double>() {
224 
225  public Appendable format(Double obj, Appendable dest)
226  throws IOException {
227  return TypeFormat.format(obj.doubleValue(), dest);
228  }
229 
230  public Double parse(CharSequence csq, Cursor cursor) {
231  return new Double(TypeFormat.parseDouble(csq, cursor));
232  }
233 
234  });
235  defaultFormats.put(String.class, new TextFormat<String>() {
236 
237  public Appendable format(String obj, Appendable dest)
238  throws IOException {
239  return dest.append(obj);
240  }
241 
242  public String parse(CharSequence csq, Cursor cursor) {
243  CharSequence tmp = csq.subSequence(cursor.getIndex(),
244  csq.length());
245  cursor.setIndex(csq.length());
246  return tmp.toString();
247  }
248 
249  });
250  defaultFormats.put(Class.class, new TextFormat<Class<?>>() {
251 
252  public Appendable format(Class<?> obj, Appendable dest)
253  throws IOException {
254  return dest.append(obj.getName());
255  }
256 
257  public Class<?> parse(CharSequence csq, Cursor cursor) {
258  CharSequence name = cursor.nextToken(csq, CharSet.WHITESPACES);
259  try {
260  return Class.forName(name.toString());
261  } catch (ClassNotFoundException e) {
262  throw new IllegalArgumentException("Class " + name
263  + " Not Found");
264  }
265  }
266 
267  });
268  defaultFormats.put(Date.class, new TextFormat<Date>() {
269  TimeZone tz = TimeZone.getTimeZone("UTC");
270  DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm'Z'");
271  {
272  df.setTimeZone(tz);
273  }
274 
275  public Appendable format(Date obj, Appendable dest)
276  throws IOException {
277  return dest.append(df.format(obj));
278  }
279 
280  public Date parse(CharSequence csq, Cursor cursor) {
281  CharSequence date = cursor.nextToken(csq, CharSet.WHITESPACES);
282  try {
283  return df.parse(date.toString());
284  } catch (ParseException error) {
285  throw new IllegalArgumentException(error);
286  }
287  }
288  });
289  defaultFormats.put(BigInteger.class, new TextFormat<BigInteger>() {
290 
291  public Appendable format(BigInteger obj, Appendable dest)
292  throws IOException {
293  return dest.append(obj.toString());
294  }
295 
296  public BigInteger parse(CharSequence csq, Cursor cursor) {
297  CharSequence value = cursor.nextToken(csq, CharSet.WHITESPACES);
298  return new BigInteger(value.toString());
299  }
300 
301  });
302  defaultFormats.put(BigDecimal.class, new TextFormat<BigDecimal>() {
303 
304  public Appendable format(BigDecimal obj, Appendable dest)
305  throws IOException {
306  return dest.append(obj.toString());
307  }
308 
309  public BigDecimal parse(CharSequence csq, Cursor cursor) {
310  CharSequence value = cursor.nextToken(csq, CharSet.WHITESPACES);
311  return new BigDecimal(value.toString());
312  }
313 
314  });
315  defaultFormats.put(Font.class, new TextFormat<Font>() {
316 
317  public Appendable format(Font obj, Appendable dest)
318  throws IOException {
319  return dest.append(obj.getName());
320  }
321 
322  public Font parse(CharSequence csq, Cursor cursor) {
323  CharSequence name = cursor.nextToken(csq, CharSet.WHITESPACES);
324  return Font.decode(name.toString());
325  }
326 
327  });
328  defaultFormats.put(Color.class, new TextFormat<Color>() {
329 
330  public Appendable format(Color obj, Appendable dest)
331  throws IOException {
332  return dest.append('#').append(
333  Integer.toHexString(obj.getRGB()));
334  }
335 
336  public Color parse(CharSequence csq, Cursor cursor) {
337  CharSequence name = cursor.nextToken(csq, CharSet.WHITESPACES);
338  return Color.decode(name.toString());
339  }
340 
341  });
342 
343  }
344 
345 }
javolution.text.internal.TextContextImpl.TextContextImpl
TextContextImpl(TextContextImpl parent)
Definition: TextContextImpl.java:77
javolution.context.LogContext
Definition: LogContext.java:56
javolution
javolution.util.FastMap
Definition: FastMap.java:98
javolution.text.internal.TextContextImpl.localFormats
final FastMap< Class<?>, TextFormat<?> > localFormats
Definition: TextContextImpl.java:64
javolution.context
Definition: AbstractContext.java:9
javolution.util.FastMap.put
V put(K key, V value)
Definition: FastMap.java:322
javolution.text.internal.TextContextImpl
Definition: TextContextImpl.java:37
javolution.text.internal.TextContextImpl.TextContextImpl
TextContextImpl()
Definition: TextContextImpl.java:70
javolution.text.TypeFormat.parseBoolean
static boolean parseBoolean(CharSequence csq, Cursor cursor)
Definition: TypeFormat.java:65
javolution.text.internal.TextContextImpl.defaultFormats
final FastMap< Class<?>, TextFormat<?> > defaultFormats
Definition: TextContextImpl.java:67
javolution.text.internal.TextContextImpl.setFormat
public< T > void setFormat(Class<? extends T > type, TextFormat< T > format)
Definition: TextContextImpl.java:129
javolution.text.Cursor
Definition: Cursor.java:44
javolution.context.LogContext.warning
static void warning(Object... message)
Definition: LogContext.java:116
javolution.text.internal.TextContextImpl.storePrimitiveTypesFormats
void storePrimitiveTypesFormats()
Definition: TextContextImpl.java:137
javolution.text.internal.TextContextImpl.searchFormat
protected< T > TextFormat< T > searchFormat(Class<? extends T > type)
Definition: TextContextImpl.java:90
javolution.text
Definition: CharArray.java:9
javolution.text.DefaultTextFormat.value
Class<? extends TextFormat<?> > value()
javolution.text.CharSet
Definition: CharSet.java:35
javolution.text.TypeFormat
Definition: TypeFormat.java:43
javolution.text.internal.TextContextImpl.inner
TextContext inner()
Definition: TextContextImpl.java:84
javolution.text.TypeFormat.format
static Appendable format(boolean b, Appendable a)
Definition: TypeFormat.java:597
javolution.text.internal.TextContextImpl.OBJECT_FORMAT
static final TextFormat<?> OBJECT_FORMAT
Definition: TextContextImpl.java:39
javolution.text.DefaultTextFormat
Definition: DefaultTextFormat.java:53
javolution.text.TextFormat
Definition: TextFormat.java:52
javolution.util
Definition: FastBitSet.java:9
javolution.text.TextContext
Definition: TextContext.java:49
javolution.text.Cursor.nextChar
final char nextChar(CharSequence csq)
Definition: Cursor.java:148