1 /* -------------------------------------------------------------------
2 * Java source file for the class DataConverterManager
3 *
4 * Copyright (c), 2002, Masahiro Takatsuka.
5 * All Rights Researved.
6 *
7 * Original Author: Masahiro Takatsuka (masa@jbeans.net)
8 * $Author: takatsukam $
9 *
10 * $Date: 2003/07/25 04:51:45 $
11 *
12 * $Id: DataConverterManager.java,v 1.1.1.1 2003/07/25 04:51:45 takatsukam Exp $
13 *
14 * Reference: Document no:
15 * ___ ___
16 *
17 * To Do:
18 * ___
19 *
20 ------------------------------------------------------------------- */
21
22 /* --------------------------- Package ---------------------------- */
23 package net.jbeans.data.converter;
24
25 /* ------------------ Import classes (packages) ------------------- *//package-summary/html">color="#329900"> ------------------ Import classes (packages) ------------------- *//package-summary.html">color="#329900">/* ------------------ Import classes (packages) ------------------- *//package-summary.html">color="#329900"> ------------------ Import classes (packages) ------------------- */
26 import java.awt.*;
27 import java.util.*;
28 import javax.swing.*;
29
30 import net.jbeans.lang.*;
31 import net.jbeans.util.*;
32 import net.jbeans.util.debug.*;
33
34 /*====================================================================
35 Implementation of class DataConverterManager
36 ====================================================================*/
37 /***
38 * generally describe DataConverterManager in here
39 *
40 * @version $Revision: 1.1.1.1 $
41 * @author Masahiro Takatsuka (masa@jbeans.net)
42 */
43
44 public class DataConverterManager {
45 private static final boolean DEBUG = Debug.getDebugFlag(DataConverterManager.class);
46 /*
47 * private method to retrieve String form resource.
48 */
49 private static String resources = "net.jbeans.data.converter.DataConverter";
50 private static String getResourceValue(String key) {
51 return ResourceBundleUtil.getResourceValue(DataConverterManager.class.getClassLoader(), resources, key);
52 }
53 // private static final String NO_CONVERTER = getResourceValue("data.converter.no.converter.string");
54 private static final String NO_CONVERTER = "No converter was found.";
55
56 private static String NO_CHANGE_KEY = "NoChange";
57 private static DataConverter NO_CHANGE_CONVERTER = new NoChangeConverter();
58 private static String[] SEARCH_PATH = { "net.jbeans.data.converter" };
59 private static Hashtable REGISTRY = null;
60 private static String DATA_CONV_NAME = "net.jbeans.data.converter.DataConverter";
61 private static Class[] DEFAULT_CONVERTER = {
62 BasicTypeConverter.class,
63 PrimitiveToStringConverter.class,
64 PrimitiveToWrapperConverter.class,
65 StringToPrimitiveBooleanConverter.class,
66 StringToPrimitiveByteConverter.class,
67 StringToPrimitiveDoubleConverter.class,
68 StringToPrimitiveFloatConverter.class,
69 StringToPrimitiveIntConverter.class,
70 StringToPrimitiveLongConverter.class,
71 StringToPrimitiveShortConverter.class,
72 WrapperToPrimitiveBooleanConverter.class,
73 WrapperToPrimitiveByteConverter.class,
74 WrapperToPrimitiveDoubleConverter.class,
75 WrapperToPrimitiveFloatConverter.class,
76 WrapperToPrimitiveIntConverter.class,
77 WrapperToPrimitiveLongConverter.class,
78 WrapperToPrimitiveShortConverter.class
79 };
80
81 private static String getFullConversionKey(Class sourceType, Class targetType) {
82 String key = sourceType.getName() + "_" + targetType.getName();
83 if (ClassUtil.isSubclass(sourceType, targetType)) {
84 key = NO_CHANGE_KEY;
85 }
86
87 return key;
88 }
89
90 private static String getShortConversionKey(Class sourceType, Class targetType) {
91 int index = 0;
92 String sourceName = sourceType.getName();
93 index = sourceName.lastIndexOf('.');
94 sourceName = sourceName.substring(index + 1);
95 String targetName = targetType.getName();
96 index = targetName.lastIndexOf('.');
97 targetName = targetName.substring(index + 1);
98
99 return sourceName + "_" + targetName;
100 }
101
102 // register default converters.
103 private static synchronized void initialize() {
104 if (REGISTRY != null) {
105 return;
106 }
107 REGISTRY = new Hashtable();
108 try {
109 String className = null;
110 for (int i = 0; i < DEFAULT_CONVERTER.length; i++) {
111 Class convClass = DEFAULT_CONVERTER[i];
112 DataConverter dc = (DataConverter) convClass.newInstance();
113 Class[] sourceTypes = dc.getSourceDataTypes();
114 Class[] targetTypes = dc.getTargetDataTypes();
115
116 for (int j = 0; j < sourceTypes.length; j++) {
117 for (int k = 0; k < targetTypes.length; k++) {
118 if (sourceTypes[j] == targetTypes[k]) {
119 continue;
120 }
121 String key = getFullConversionKey(sourceTypes[j], targetTypes[k]);
122 load(key, dc.getClass().getName());
123 }
124 }
125 }
126 } catch (InstantiationException ex) {
127 ex.printStackTrace();
128 } catch (IllegalAccessException ex) {
129 ex.printStackTrace();
130 }
131 }
132
133 /***
134 * Register a data converter class to be used to convert a given
135 * source class to a given target class.
136 *
137 * <p>First, if there is a security manager, its
138 * <code>checkPropertiesAccess</code> method is called.
139 * This could result in a SecurityException.
140 *
141 * @param converterClass the Class object of the data converter class. If
142 * this is null, then any existing definition will be removed.
143 * @exception SecurityException if a security manager exists and its
144 * <code>checkPropertiesAccess</code> method doesn't allow
145 * setting of system properties.
146 * @see SecurityManager#checkPropertiesAccess
147 */
148 public final static void registerConverter(Class converterClass) {
149 SecurityManager sm = System.getSecurityManager();
150 if (sm != null) {
151 sm.checkPropertiesAccess();
152 }
153 initialize();
154
155 if (converterClass == null) {
156 return;
157 }
158 try {
159 DataConverter dc = (DataConverter) converterClass.newInstance();
160 Class[] sourceTypes = dc.getSourceDataTypes();
161 Class[] targetTypes = dc.getTargetDataTypes();
162
163 for (int i = 0; i < sourceTypes.length; i++) {
164 for (int j = 0; j < targetTypes.length; j++) {
165 if (sourceTypes[i] == targetTypes[j]) {
166 continue;
167 }
168 String key = getFullConversionKey(sourceTypes[i], targetTypes[j]);
169 REGISTRY.put(key, converterClass);
170 }
171 }
172 } catch (IllegalAccessException ex) {
173 ex.printStackTrace();
174 } catch (InstantiationException ex) {
175 ex.printStackTrace();
176 }
177
178 }
179
180 /***
181 * instantiates a named class. This method first tries the classloader of
182 * "sibling", then try the system classloader.
183 */
184 private static Object instantiate(Class sibling, String className) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
185 // First check with sibling's classloader (if any).
186 ClassLoader cl = sibling.getClassLoader();
187 if (cl != null) {
188 try {
189 Class cls = cl.loadClass(className);
190 return cls.newInstance();
191 } catch (Exception ex) {
192 // drop through for the system classloader.
193 }
194 }
195 //try the system classloader.
196 try {
197 cl = ClassLoader.getSystemClassLoader();
198 if (cl != null) {
199 Class cls = cl.loadClass(className);
200 return cls.newInstance();
201 }
202 } catch (Exception ex) {
203 // Drop through.
204 }
205
206 // Now try the bootstrap classloader.
207 Class cls = Class.forName(className);
208 return cls.newInstance();
209 }
210
211 public final static synchronized boolean isThereConverFor(Class sourceType, Class targetType) {
212 System.out.println("sourceType = " + sourceType);
213 System.out.println("targetType = " + targetType);
214 if ((findConverter(sourceType, targetType) != null) ||
215 ClassUtil.isSubclass(sourceType, targetType) ||
216 targetType == java.lang.String.class) {
217 return true;
218 }
219 JOptionPane.showMessageDialog(new Frame(),
220 NO_CONVERTER,
221 "Data Converter Manager",
222 JOptionPane.ERROR_MESSAGE);
223
224 return false;
225 }
226
227 /***
228 * Locate a data converter for a given source and target types.
229 *
230 * @param sourceType The Class object for the type to be converted.
231 * @param targetType The Class object for the type to be converted into.
232 * @return A data converter object for the given source and target classes.
233 * The result is null if no suitable converter can be found.
234 */
235 public final static synchronized DataConverter findConverter(Class sourceType, Class targetType) {
236 initialize();
237 String key = getFullConversionKey(sourceType, targetType);
238 if (DEBUG) {
239 System.out.println("key = "+ key);
240 }
241 if (key.equals(NO_CHANGE_KEY)) {
242 return NO_CHANGE_CONVERTER;
243 }
244 Class converterClass = (Class) REGISTRY.get(key);
245 if (converterClass != null) {
246 try {
247 Object o = converterClass.newInstance();
248 return (DataConverter) o;
249 } catch (Exception ex) {
250 System.err.println("Couldn't instantiate type editor \"" +
251 converterClass.getName() + "\" : " + ex);
252 }
253 }
254
255 // Now try adding "Converter" to the fully-qualified class names.
256 String converterName = key + "Converter";
257 try {
258 return (DataConverter) instantiate(sourceType, converterName);
259 } catch (Exception ex) {
260 // ignore errors.
261 }
262
263 // Now try looking for <searchPath>.Foo1Foo2Converter
264 converterName = getShortConversionKey(sourceType, targetType);
265 for (int i = 0; i < SEARCH_PATH.length; i++) {
266 String name = SEARCH_PATH[i] + "." + converterName + "Converter";
267 try {
268 return (DataConverter) instantiate(sourceType, name);
269 } catch (Exception ex) {
270 // ignore any errors.
271 }
272 }
273
274 // We couldn't find a suitable Editor.
275 return null;
276 }
277
278 /***
279 * Gets the package names that will be searched for data converters.
280 *
281 * @return The array of package names that will be searched in
282 * order to find data converters.
283 * <p> This is initially set to {"net.jbeans.data.converter"}.
284 */
285 public final static synchronized String[] getConverterSearchPath() {
286 // Return a copy of the searchPath.
287 String result[] = new String[SEARCH_PATH.length];
288 for (int i = 0; i < SEARCH_PATH.length; i++) {
289 result[i] = SEARCH_PATH[i];
290 }
291 return result;
292 }
293
294 /***
295 * Change the list of package names that will be used for finding data
296 * converters
297 *
298 * <p>First, if there is a security manager,
299 * its <code>checkPropertiesAccess</code> method is called.
300 * This could result in a SecurityException.
301 *
302 * @param path Array of package names.
303 * @exception SecurityException if a security manager exists and its
304 * <code>checkPropertiesAccess</code> method doesn't allow
305 * setting of system properties.
306 * @see SecurityManager#checkPropertiesAccess
307 */
308 public final static synchronized void setConverterSearchPath(String path[]) {
309 SecurityManager sm = System.getSecurityManager();
310 if (sm != null) {
311 sm.checkPropertiesAccess();
312 }
313 if (path == null) {
314 path = new String[0];
315 }
316 SEARCH_PATH = path;
317 }
318
319 private static synchronized void load(String key, String converterName) {
320 try {
321 Class cls = Class.forName(converterName);
322 REGISTRY.put(key, cls);
323 return;
324 } catch (Exception ex) {
325
326 }
327 // This shouldn't happen.
328 System.err.println("load of " + converterName + " failed");
329 }
330
331 public static Object convert(Object source, Class targetType) {
332 if (source == null) {
333 return null;
334 }
335
336 Class sourceType = source.getClass();
337 boolean found = true;
338 DataConverter conv = null;
339
340 if (sourceType.isPrimitive()) {
341 sourceType = ClassUtil.getWrapperClass(sourceType);
342 }
343 if (ClassUtil.isSubclass(sourceType, targetType)) {
344 conv = null; // no converter needed.
345 } else {
346 conv = findConverter(sourceType, targetType);
347 if (conv == null) {
348 found = false;
349 }
350 }
351 if (!found) {
352 JOptionPane.showMessageDialog(new Frame(),
353 NO_CONVERTER,
354 "Data Converter Manager",
355 JOptionPane.ERROR_MESSAGE);
356 return null;
357 }
358 if (conv != null) {
359 try {
360 source = conv.convert(source, targetType.getName());
361 } catch (Exception e) {
362 e.printStackTrace();
363 source = null;
364 }
365 }
366 return source;
367 }
368
369 /* ----------------------------- test ----------------------------- */
370 public final static void main(String[] args) {
371 Frame f = new Frame();
372 f.setBounds(100, 100, 300, 300);
373 Button b = new Button("myButton");
374
375 f.add(b);
376 f.setVisible(true);
377 }
378 }
This page was automatically generated by Maven