Mercurial > illumos > onarm
comparison usr/src/cmd/krb5/kadmin/gui/visualrt/sunsoft/jws/visual/rt/type/Converter.java @ 0:c9caec207d52 b86
Initial porting based on b86
author | Koji Uno <koji.uno@sun.com> |
---|---|
date | Tue, 02 Jun 2009 18:56:50 +0900 |
parents | |
children | 1a15d5aaf794 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:c9caec207d52 |
---|---|
1 /* | |
2 * CDDL HEADER START | |
3 * | |
4 * The contents of this file are subject to the terms of the | |
5 * Common Development and Distribution License, Version 1.0 only | |
6 * (the "License"). You may not use this file except in compliance | |
7 * with the License. | |
8 * | |
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE | |
10 * or http://www.opensolaris.org/os/licensing. | |
11 * See the License for the specific language governing permissions | |
12 * and limitations under the License. | |
13 * | |
14 * When distributing Covered Code, include this CDDL HEADER in each | |
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. | |
16 * If applicable, add the following below this CDDL HEADER, with the | |
17 * fields enclosed by brackets "[]" replaced with your own identifying | |
18 * information: Portions Copyright [yyyy] [name of copyright owner] | |
19 * | |
20 * CDDL HEADER END | |
21 */ | |
22 /* | |
23 * ident "@(#)Converter.java 1.2 05/06/08 SMI" | |
24 * | |
25 * Copyright (c) 2000 by Sun Microsystems, Inc. | |
26 * All rights reserved. | |
27 */ | |
28 | |
29 /* | |
30 * Copyright (C) 1996 Active Software, Inc. | |
31 * All rights reserved. | |
32 * | |
33 * @(#) Converter.java 1.65 - last change made 08/20/97 | |
34 */ | |
35 | |
36 package sunsoft.jws.visual.rt.type; | |
37 | |
38 import sunsoft.jws.visual.rt.base.Global; | |
39 | |
40 import sunsoft.jws.visual.rt.base.*; | |
41 | |
42 import java.util.*; | |
43 | |
44 /** | |
45 * Base class for all converters. Converts a type of | |
46 * object to a string | |
47 * and back again. | |
48 * | |
49 * @version 1.65, 08/20/97 | |
50 */ | |
51 | |
52 public abstract class Converter { | |
53 /** | |
54 * Table of names for each registered converter. | |
55 */ | |
56 private static Hashtable converterNameTable = new Hashtable(); | |
57 | |
58 /** | |
59 * Table of instances for each converter that has | |
60 * been instantiated. | |
61 */ | |
62 private static Hashtable converterInstanceTable = new Hashtable(); | |
63 | |
64 /** | |
65 * Adds a new type converter to the global table of converters. A | |
66 * converter must be listed for this table in order for the search | |
67 * for a converter for that particular type to be successful. | |
68 * | |
69 * @param typeName the name of the type (what is returned by a | |
70 * call to getClass().getType() for an instance of that type) | |
71 * @param converterClassName the full name of the converter class | |
72 */ | |
73 public static void addConverter(String typeName, | |
74 String converterClassName) { | |
75 converterNameTable.put(typeName, converterClassName); | |
76 } | |
77 | |
78 /** | |
79 * Initialize the type converters for the types we know about. | |
80 */ | |
81 static { | |
82 addConverter(/* NOI18N */"[I", /* NOI18N */ | |
83 "sunsoft.jws.visual.rt.type.IntArrayConverter"); | |
84 addConverter(/* NOI18N */"[D", /* NOI18N */ | |
85 "sunsoft.jws.visual.rt.type.DoubleArrayConverter"); | |
86 addConverter(/* NOI18N */"java.lang.String", | |
87 /* NOI18N */"sunsoft.jws.visual.rt.type.StringConverter"); | |
88 addConverter(/* NOI18N */"[Ljava.lang.String;", | |
89 /* NOI18N */"sunsoft.jws.visual.rt.type.StringArrayConverter"); | |
90 addConverter(/* NOI18N */"java.lang.Boolean", | |
91 /* NOI18N */"sunsoft.jws.visual.rt.type.BooleanConverter"); | |
92 addConverter(/* NOI18N */"java.lang.Character", | |
93 /* NOI18N */"sunsoft.jws.visual.rt.type.CharacterConverter"); | |
94 addConverter(/* NOI18N */"java.lang.Integer", | |
95 /* NOI18N */"sunsoft.jws.visual.rt.type.IntegerConverter"); | |
96 addConverter(/* NOI18N */"java.awt.Color", | |
97 /* NOI18N */"sunsoft.jws.visual.rt.type.ColorConverter"); | |
98 addConverter(/* NOI18N */"java.awt.SystemColor", | |
99 /* NOI18N */"sunsoft.jws.visual.rt.type.ColorConverter"); | |
100 addConverter(/* NOI18N */"java.awt.Font", | |
101 /* NOI18N */"sunsoft.jws.visual.rt.type.FontConverter"); | |
102 addConverter(/* NOI18N */"java.awt.Point", | |
103 /* NOI18N */"sunsoft.jws.visual.rt.type.PointConverter"); | |
104 addConverter(/* NOI18N */"java.awt.Dimension", | |
105 /* NOI18N */"sunsoft.jws.visual.rt.type.DimensionConverter"); | |
106 addConverter(/* NOI18N */"java.awt.Insets", | |
107 /* NOI18N */"sunsoft.jws.visual.rt.type.InsetsConverter"); | |
108 addConverter(/* NOI18N */ | |
109 "sunsoft.jws.visual.rt.awt.GBConstraints", | |
110 /* NOI18N */"sunsoft.jws.visual.rt.type.GBConstraintsConverter"); | |
111 addConverter(/* NOI18N */ | |
112 "sunsoft.jws.visual.rt.base.AttributeManager", | |
113 /* NOI18N */"sunsoft.jws.visual.rt.type.AMConverter"); | |
114 addConverter(/* NOI18N */"sunsoft.jws.visual.rt.type.AMRef", | |
115 /* NOI18N */"sunsoft.jws.visual.rt.type.AMRefConverter"); | |
116 addConverter(/* NOI18N */ | |
117 "sunsoft.jws.visual.rt.base.Attribute", | |
118 /* NOI18N */"sunsoft.jws.visual.rt.type.AttributeConverter"); | |
119 addConverter(/* NOI18N */ | |
120 "sunsoft.jws.visual.rt.base.AttributeList", | |
121 /* NOI18N */"sunsoft.jws.visual.rt.type.AttributeListConverter"); | |
122 addConverter(/* NOI18N */"sunsoft.jws.visual.rt.type.ImageRef", | |
123 /* NOI18N */"sunsoft.jws.visual.rt.type.ImageRefConverter"); | |
124 addConverter(/* NOI18N */ | |
125 "sunsoft.jws.visual.rt.type.AlignmentEnum", | |
126 /* NOI18N */"sunsoft.jws.visual.rt.type.BaseEnumConverter"); | |
127 addConverter(/* NOI18N */ | |
128 "sunsoft.jws.visual.rt.type.AnchorEnum", | |
129 /* NOI18N */"sunsoft.jws.visual.rt.type.BaseEnumConverter"); | |
130 addConverter(/* NOI18N */ | |
131 "sunsoft.jws.visual.rt.type.OrientationEnum", | |
132 /* NOI18N */"sunsoft.jws.visual.rt.type.BaseEnumConverter"); | |
133 addConverter(/* NOI18N */ | |
134 "sunsoft.jws.visual.rt.type.ReliefEnum", | |
135 /* NOI18N */"sunsoft.jws.visual.rt.type.BaseEnumConverter"); | |
136 addConverter(/* NOI18N */"sunsoft.jws.visual.rt.type.ModeEnum", | |
137 /* NOI18N */"sunsoft.jws.visual.rt.type.BaseEnumConverter"); | |
138 addConverter(/* NOI18N */"unknown", /* NOI18N */ | |
139 "sunsoft.jws.visual.rt.type.UnknownTypeConverter"); | |
140 } | |
141 | |
142 /** | |
143 * Returns an existing converter for the given type. Creates a new | |
144 * converter only if necessary (typically the first | |
145 * time one is asked for.) | |
146 */ | |
147 public static Converter getConverter(String typeName) { | |
148 Converter converter; | |
149 | |
150 converter = (Converter)converterInstanceTable.get(typeName); | |
151 if (converter != null) | |
152 return converter; | |
153 | |
154 String converterType = (String) converterNameTable.get | |
155 (typeName); | |
156 if (converterType == null) { | |
157 /* JSTYLED */ | |
158 // Load the class for the type and try again. Some types have | |
159 // static initializers that register their converters. | |
160 loadType(typeName); | |
161 converterType = (String) converterNameTable.get(typeName); | |
162 } | |
163 | |
164 if (converterType == null) { | |
165 converterType = (String) converterNameTable.get | |
166 (/* NOI18N */"unknown"); | |
167 if (converterType == null) | |
168 /* JSTYLED */ | |
169 throw new Error(Global.getMsg("sunsoft.jws.visual.rt.type.Converter.No__converter__defined.20")); | |
170 } | |
171 try { | |
172 Class c = Class.forName(converterType); | |
173 converter = (Converter) c.newInstance(); | |
174 converter.setConverterType(typeName); | |
175 converterInstanceTable.put(typeName, converter); | |
176 return converter; | |
177 } | |
178 catch (Exception e) { | |
179 throw new Error(e.getMessage()); | |
180 } | |
181 } | |
182 | |
183 private static void loadType(String typeName) { | |
184 // For arrays, use the array type | |
185 if (typeName.charAt(0) == /* NOI18N */ '[') { | |
186 int i; | |
187 int len = typeName.length(); | |
188 for (i = 0; i < len; i++) { | |
189 if (typeName.charAt(i) != /* NOI18N */ '[') | |
190 break; | |
191 } | |
192 i++; | |
193 if (i < len) | |
194 typeName = typeName.substring(i, len-1); | |
195 } | |
196 | |
197 try { | |
198 Class.forName(typeName); | |
199 } | |
200 catch (ClassNotFoundException ex) { | |
201 /* JSTYLED */ | |
202 System.out.println(Global.getMsg("sunsoft.jws.visual.rt.type.Converter.Class__not__found__for__.21") + typeName + /* NOI18N */"\"."); | |
203 } | |
204 } | |
205 | |
206 /** | |
207 * Returns true if there is a converter for the given type. | |
208 */ | |
209 public static boolean hasConverter(String typeName) { | |
210 return (converterNameTable.containsKey(typeName)); | |
211 } | |
212 | |
213 /** | |
214 * The type editors (for more complex types.) | |
215 */ | |
216 private static Hashtable typeEditorNameTable = new Hashtable(); | |
217 | |
218 /** | |
219 * Registers a type editor for a type. At run-time (in generated | |
220 * applications) there will typically be no editors, but they are | |
221 * needed for the attribute editor in the designer. The designer | |
222 * will set up all the standard ones. | |
223 * | |
224 * @see TypeEditor | |
225 */ | |
226 public static void addTypeEditor(String typeName, | |
227 String editorClassName) { | |
228 typeEditorNameTable.put(typeName, editorClassName); | |
229 } | |
230 | |
231 /** | |
232 * Returns true if there is an editor for the given type. | |
233 * | |
234 * @see TypeEditor | |
235 */ | |
236 public static boolean hasTypeEditor(String typeName) { | |
237 return (typeEditorNameTable.containsKey(typeName)); | |
238 } | |
239 | |
240 /* BEGIN JSTYLED */ | |
241 /** | |
242 * Returns a new instance of a type editor. | |
243 * The caller (typically the | |
244 * Designer) gets a new one of these every time, one for each | |
245 * attribute being edited, even if they are the same type. Caching | |
246 * instances of these type editors is up to the caller. | |
247 */ | |
248 /* END JSTYLED */ | |
249 | |
250 public static TypeEditor newTypeEditor(String typeName) { | |
251 String editorType = (String) typeEditorNameTable.get(typeName); | |
252 | |
253 if (editorType != null) { | |
254 try { | |
255 // instances of type editors are NOT cached | |
256 Class c = Class.forName(editorType); | |
257 return ((TypeEditor) c.newInstance()); | |
258 } | |
259 catch (Exception ex) { | |
260 /* JSTYLED */ | |
261 throw new VJException(Global.newline() + /* NOI18N */" " + ex.toString()); | |
262 } | |
263 } | |
264 | |
265 return null; | |
266 } | |
267 | |
268 /** | |
269 * Returns whether a converter instance has an | |
270 * associated type editor. | |
271 * | |
272 * @see TypeEditor | |
273 */ | |
274 public boolean hasTypeEditor() { | |
275 return (hasTypeEditor(getConverterType())); | |
276 } | |
277 | |
278 /** | |
279 * Returns a new instance of the type editor associated with this | |
280 * converter. | |
281 */ | |
282 public TypeEditor newTypeEditor() { | |
283 return (newTypeEditor(getConverterType())); | |
284 } | |
285 /* JSTYLED */ | |
286 // ------ Interfaces for Sub-Classers ----------------------------------- | |
287 | |
288 /** | |
289 * The name of the type being edited. | |
290 */ | |
291 protected String converterType; | |
292 | |
293 /** | |
294 * An interface that can be overridden in sub-classes | |
295 * to whom the type | |
296 * converted is important. | |
297 * | |
298 * @see BaseEnumConverter | |
299 */ | |
300 protected void setConverterType(String type) { | |
301 converterType = type; | |
302 } | |
303 | |
304 /** | |
305 * Returns the type of object converted by this converter. | |
306 */ | |
307 public String getConverterType() { | |
308 return (converterType); | |
309 } | |
310 | |
311 /* BEGIN JSTYLED */ | |
312 /** | |
313 * Returns the string representation for an instance of | |
314 * the type this | |
315 * converter converts. Must be declared in subclasses | |
316 * to convert an | |
317 * object of the type specific to that subclass of Converter. | |
318 * <p> | |
319 * One of the two "convertToString" methods must be overridden in | |
320 * the converter sub-class. The overridden "convertToString" | |
321 * method | |
322 * should NOT call "super.convertToString". It is preferrable to | |
323 * override the StringBuffer version (the other one) because this | |
324 * will result in better performance. | |
325 */ | |
326 /* END JSTYLED */ | |
327 public String convertToString(Object obj) { | |
328 enterConvert(TOSTRING, false); | |
329 StringBuffer buf = new StringBuffer(); | |
330 convertToString(obj, buf); | |
331 exitConvert(TOSTRING, false); | |
332 | |
333 return buf.toString(); | |
334 } | |
335 | |
336 /** | |
337 * Places a string representation of an instance of the type this | |
338 * converter converts into a string buffer. | |
339 */ | |
340 public void convertToString(Object obj, StringBuffer buf) { | |
341 enterConvert(TOSTRING, true); | |
342 buf.append(convertToString(obj)); | |
343 exitConvert(TOSTRING, true); | |
344 } | |
345 | |
346 /** | |
347 * Returns a new instance of the type this converter converts, as | |
348 * specified by the string given. Must be declared | |
349 * in subclasses of | |
350 * Converter to convert a string representation into an object of | |
351 * the type converted by the subclass. | |
352 */ | |
353 public abstract Object convertFromString(String s); | |
354 | |
355 /** | |
356 * Converts an instance of the type into a block of code. | |
357 */ | |
358 public void convertToCodeBlock(String amName, | |
359 Attribute a, int indent, StringBuffer buf) { | |
360 | |
361 Converter c = getConverter(a.getType()); | |
362 String attr_name; | |
363 | |
364 indent(buf, indent); | |
365 buf.append(amName); | |
366 buf.append(/* NOI18N */".set(\""); | |
367 attr_name = a.getName(); | |
368 buf.append(attr_name); | |
369 buf.append(/* NOI18N */"\", "); | |
370 buf.append(c.convertToCode(a.getValue())); | |
371 buf.append(/* NOI18N */");"); | |
372 newline(buf); | |
373 } | |
374 | |
375 /** | |
376 * Converts an instance of the type converted into a line of code. | |
377 * This method provides a default way for any type to get a | |
378 * convertToCode method into it. It generates code that will feed | |
379 * the string representation of the object into the | |
380 * appropriate type | |
381 * converter. The performance isn't as good as customized | |
382 * convertToCode functions in subclasses since more classes have to | |
383 * be loaded at runtime. | |
384 */ | |
385 public String convertToCode(Object obj) { | |
386 if (obj != null) | |
387 return (/* NOI18N */"convert(\"" + | |
388 obj.getClass().getName() + /* NOI18N */"\", \"" | |
389 + convertToString(obj) + /* NOI18N */"\")"); | |
390 else | |
391 return (/* NOI18N */"null"); | |
392 } | |
393 | |
394 /** | |
395 * Returns the string that should be displayed in the attribute | |
396 * editor. Subclassers that want something displayed other than | |
397 * what is returned from convertToString should override this | |
398 * method to return that. | |
399 */ | |
400 public String displayString(Object obj) { | |
401 return (convertToString(obj)); | |
402 } | |
403 | |
404 /** | |
405 * Returns true if this type should be displayed in an editor. | |
406 * | |
407 * For the attribute editor, a return value of false means that the | |
408 * the textfield will be hidden. | |
409 * | |
410 * @return true | |
411 */ | |
412 public boolean viewableAsString() { | |
413 return true; | |
414 } | |
415 | |
416 /** | |
417 * Returns true if this type is simple enough to be | |
418 * edited as a string | |
419 * in an editor. | |
420 * | |
421 * Sub-classers that represent type too complex for | |
422 * this should override | |
423 * this function to return false. For the attribute editor, | |
424 * this means | |
425 * that the textfield will be read-only. | |
426 * | |
427 * @see #viewableAsString | |
428 * @return same as viewableAsString | |
429 */ | |
430 public boolean editableAsString() { | |
431 return viewableAsString(); | |
432 } | |
433 | |
434 /** | |
435 * These weird looking enter/exit methods ensure that the converter | |
436 * sub-class is overriding at least one of the "convertToString" | |
437 * methods, and at least one of the "convertToCode" methods. | |
438 * An error will be thrown at runtime if this in not the case. | |
439 * If this check wasn't done here , then the failure to | |
440 * override one | |
441 * of the methods would result in an infinite loop. | |
442 */ | |
443 private static final int TOSTRING = 0; | |
444 private static final int TOCODE = 1; | |
445 | |
446 private boolean converting[] = {false, false}; | |
447 private boolean isBuffered[] = {false, false}; | |
448 private int convertRecurse[] = {0, 0}; | |
449 | |
450 private void enterConvert(int c, boolean isBuffered) { | |
451 if (converting[c] && this.isBuffered[c] != isBuffered) | |
452 throw new Error(Global.getMsg( | |
453 "sunsoft.jws.visual.rt.type.Converter.Sub-classes__of__Conve.22")); | |
454 | |
455 this.isBuffered[c] = isBuffered; | |
456 converting[c] = true; | |
457 convertRecurse[c]++; | |
458 } | |
459 | |
460 private void exitConvert(int c, boolean isBuffered) { | |
461 if (!converting[c]) | |
462 /* BEGIN JSTYLED */ | |
463 throw new Error(Global.getMsg("sunsoft.jws.visual.rt.type.Converter.Convert__exit__without.25")); | |
464 | |
465 if (this.isBuffered[c] != isBuffered) | |
466 throw new Error(Global.getMsg("sunsoft.jws.visual.rt.type.Converter.isBuffered__mismatch__.26")); | |
467 | |
468 /* END JSTYLED */ | |
469 convertRecurse[c]--; | |
470 if (convertRecurse[c] == 0) | |
471 converting[c] = false; | |
472 } | |
473 /* BEGIN JSTYLED */ | |
474 // ------ Utility Functions ---------------------------------------------- | |
475 | |
476 /** | |
477 * Returns a string that can be used as a newline. | |
478 * This string includes | |
479 * a carriage return if we are running on Windows. | |
480 */ | |
481 /* END JSTYLED */ | |
482 public static String newline() { | |
483 return Global.newline(); | |
484 } | |
485 | |
486 /** | |
487 * Appends a newline to buf. This also appends a carriage return | |
488 * if we are running on Windows. | |
489 */ | |
490 public static void newline(StringBuffer buf) { | |
491 Global.newline(buf); | |
492 } | |
493 | |
494 private static final String indentString = /* NOI18N */" "; | |
495 private static int indentLevel = 0; | |
496 | |
497 /** | |
498 * Appends spaces to "buf" based on the current indent level. | |
499 */ | |
500 protected static void indent(StringBuffer buf) { | |
501 for (int i = 0; i < indentLevel; i++) | |
502 buf.append(indentString); | |
503 } | |
504 | |
505 /** | |
506 * Appends spaces to "buf" based on the given indent level. | |
507 */ | |
508 protected static void indent(StringBuffer buf, int indentLevel) { | |
509 for (int i = 0; i < indentLevel; i++) | |
510 buf.append(/* NOI18N */ ' '); | |
511 } | |
512 | |
513 /** | |
514 * Increments the indent level. | |
515 */ | |
516 protected static void incrIndent() { | |
517 indentLevel++; | |
518 } | |
519 | |
520 /** | |
521 * Decrements the indent level. | |
522 */ | |
523 protected static void decrIndent() { | |
524 indentLevel--; | |
525 } | |
526 | |
527 /** | |
528 * Returns the current indent level. | |
529 */ | |
530 protected static int indentLevel() { | |
531 return indentLevel; | |
532 } | |
533 | |
534 /** | |
535 * Returns the last token in a class name. i.e. the name that you | |
536 * can use for a class when you've imported the class already. | |
537 */ | |
538 public static String shortClassName(String className) { | |
539 int index = className.lastIndexOf(/* NOI18N */ '.'); | |
540 if (index == -1) | |
541 return (className); | |
542 else | |
543 return (className.substring(index + 1)); | |
544 } | |
545 | |
546 } |