View Javadoc
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