1 19 20 package de.gulden.util.xml.serializer.smart; 21 22 import de.gulden.util.Toolbox; 23 import de.gulden.util.xml.*; 24 import de.gulden.util.xml.serializer.*; 25 import java.lang.reflect.*; 26 import java.lang.reflect.Field ; 27 import java.lang.reflect.InvocationTargetException ; 28 import java.util.*; 29 import org.w3c.dom.Document ; 30 import org.w3c.dom.Element ; 31 32 38 public class SmartReflectionXMLSerializer implements XMLSerializer { 39 40 44 47 public static final Class DEFAULT_COLLECTION_CLASS = ArrayList.class; 48 49 50 54 57 public static Class DEFAULT_MAP_CLASS = de.gulden.util.OrderedHashMap.class; 58 59 60 64 68 protected SmartReflectionXMLSerializerFactory factory; 69 70 71 75 78 SmartReflectionXMLSerializer(SmartReflectionXMLSerializerFactory factory) { 79 super(); 80 setFactory(factory); 81 } 82 83 84 88 91 public SmartReflectionXMLSerializerFactory getFactory() { 92 return factory; 93 } 94 95 98 public void setFactory(SmartReflectionXMLSerializerFactory smartReflectionXMLSerializerFactory) { 99 this.factory = smartReflectionXMLSerializerFactory; 100 } 101 102 public Element xmlSerialize(Object object, Document document) throws XMLException { 103 throw new Error ("NOT IMPLEMENTED YET"); 105 } 106 107 public Object xmlDeserialize(Element element) throws XMLException { 108 Class clazz=getFactory().mapToClass(element.getTagName(), element.getAttribute("class")); 109 Object o; 110 try { 111 o=clazz.newInstance(); 112 } catch (InstantiationException ie) { 113 throw new XMLException(ie); 114 } catch (IllegalAccessException iae) { 115 throw new XMLException(iae); 116 } 117 xmlDeserialize(o,element); 118 return o; 119 } 120 121 public void xmlDeserialize(Object object, Element element) throws XMLException { 122 xmlDeserialize(object,element,true); 123 } 124 125 public void xmlDeserialize(Object object, Element element, boolean enableSerializableActive) throws XMLException { 126 if ((enableSerializableActive)&&(object instanceof XMLSerializableActive)) { 128 ((XMLSerializableActive)object).xmlDeserialize(element,this); 129 } else if (object instanceof XMLSerializable) { 131 Class clazz=object.getClass(); 132 try { 133 java.lang.reflect.Field [] fields=clazz.getFields(); 135 for (int i=0;i<fields.length;i++) { 136 int fieldModifiers=fields[i].getModifiers(); 137 if (!( 138 java.lang.reflect.Modifier.isTransient(fieldModifiers) 139 ||java.lang.reflect.Modifier.isStatic(fieldModifiers) 140 ||java.lang.reflect.Modifier.isFinal(fieldModifiers) 141 ||java.lang.reflect.Modifier.isVolatile(fieldModifiers) 142 )) { 143 String fieldName=fields[i].getName(); 144 Class fieldType=fields[i].getType(); 145 Object fieldObject=fields[i].get(object); 146 String xmlName=XMLToolbox.translateJavaNameToXMLName(fieldName); 147 148 if (fieldType.isPrimitive()||(fieldType==String .class)) { 150 String attr=element.getAttribute(xmlName); 151 String valueStr=null; 152 if ((attr!=null)&&(!attr.equals(""))) { 154 valueStr=attr; 155 } else { 157 Element e=XMLToolbox.getChild(element,xmlName); 158 if (e!=null) { 160 if (fieldType==String .class) { 161 valueStr=XMLToolbox.getLangstring(e); } 164 if (valueStr==null) { 165 valueStr=XMLToolbox.getText(e); 166 } 167 } else if ((fieldType==String .class)&&(fieldName.equals("text"))) { 169 valueStr=XMLToolbox.getLangstring(element); if (valueStr==null) { 171 valueStr=XMLToolbox.getText(element); 172 } 173 } else { 175 valueStr=null; } 177 } 178 if (valueStr!=null) { 179 fieldType=convertPrimitiveClassToWrapperClass(fieldType); 181 Object fieldValue; 182 if (fieldType==String .class) { 183 fieldValue=valueStr; 184 } else if (Boolean .class.isAssignableFrom(fieldType)) { 185 fieldValue=Boolean.valueOf(de.gulden.util.Toolbox.parseBoolean(valueStr)); 186 } else if (Number .class.isAssignableFrom(fieldType)) { 187 Class [] valueOfParamType={String .class}; 188 java.lang.reflect.Method valueOfMethod=fieldType.getMethod("valueOf",valueOfParamType); 189 Object [] valueOfParamValue={valueStr}; 190 fieldValue=valueOfMethod.invoke(null,valueOfParamValue); 191 } else { 192 throw new XMLException("can't deserialize attribute of type "+fieldType.getName()); 193 } 194 setFieldValue(fields[i],object,fieldValue); 195 } 196 } else if (Collection.class.isAssignableFrom(fieldType)) { 198 Collection c = (Collection)fieldObject; 199 if (c == null) { 200 Class t; 202 if (fieldType.isInterface()||java.lang.reflect.Modifier.isAbstract(fieldModifiers)) { 203 t=DEFAULT_COLLECTION_CLASS; } else { 206 t=fieldType; 207 } 208 c = (Collection)t.newInstance(); } 210 String [] childrenTagNames=getChildrenTagNames(clazz,fieldName,xmlName); 211 org.w3c.dom.NodeList nl=XMLToolbox.getChildren(element,childrenTagNames); 212 for (int j=0;j<nl.getLength();j++) { 213 Element childTag=(Element )nl.item(j); 214 Object child=xmlDeserialize(childTag); c.add(child); 217 } 218 if (fieldObject==null) { 219 setFieldValue(fields[i],object,c); 220 } 221 } else if (Map.class.isAssignableFrom(fieldType)) { 223 Map m = (Map)fieldObject; 224 if (m == null) { 225 Class t; 227 if (fieldType.isInterface()||java.lang.reflect.Modifier.isAbstract(fieldModifiers)) { 228 t=DEFAULT_MAP_CLASS; } else { 231 t=fieldType; 232 } 233 m=(Map)t.newInstance(); } 235 String [] childrenTagNames=getChildrenTagNames(clazz,fieldName,xmlName); 236 org.w3c.dom.NodeList nl=XMLToolbox.getChildren(element,childrenTagNames); 237 for (int j=0;j<nl.getLength();j++) { 238 Element childTag=(Element )nl.item(j); 239 Object child=xmlDeserialize(childTag); Class [] getIdParamType={}; 244 java.lang.reflect.Method getIdMethod; 245 try { 246 getIdMethod=child.getClass().getMethod("getId",getIdParamType); 247 } catch (NoSuchMethodException nsme0) { 248 throw new XMLException("mapped objects must contain a getId():String method to be return a key ("+child.getClass().getName()+")"); 249 } 250 Object [] getIdParamValue={}; 251 String key=(String )getIdMethod.invoke(child,getIdParamValue); 252 m.put(key,child); 253 } 254 if (fieldObject==null) { 255 setFieldValue(fields[i],object,m); 256 } 257 } else if (fieldType.isArray()) { 259 throw new XMLException("NOT IMPLEMENTED YET: array types cannot be XML-deserialized"); 260 } else { 262 Element e=XMLToolbox.getChild(element,xmlName); 263 if (e==null) { 264 } else { 266 Object o; 268 if (fieldObject==null) { 269 o = xmlDeserialize(e); } else { 271 o = fieldObject; xmlDeserialize(o, e, true); 273 } 274 setFieldValue(fields[i],object,o); 275 } 276 } 277 } 278 } 279 } catch (NoSuchMethodException nsme) { 280 throw new XMLException(nsme); 281 } catch (IllegalAccessException iae) { 282 throw new XMLException(iae); 283 } catch (InstantiationException ie) { 284 throw new XMLException(ie); 285 } catch (java.lang.reflect.InvocationTargetException ite) { 286 throw new XMLException(ite.getTargetException()); 287 } 288 } else { 289 throw new XMLException("object of type '"+object.getClass().getName()+"' cannot be deserialized from XML - it does not implement XMLSerializable"); 290 } 291 } 292 293 294 298 301 protected static void setFieldValue(Field field, Object object, Object value) throws InvocationTargetException , IllegalAccessException { 302 String fieldName=field.getName(); 303 String setterName="set"+Toolbox.capitalize(fieldName); 304 Class [] setterParams={field.getType()}; 305 try { 306 java.lang.reflect.Method m=object.getClass().getMethod(setterName,setterParams); 307 Object [] setterValues={value}; 309 m.invoke(object,setterValues); 310 } catch (NoSuchMethodException nsme) { 311 field.set(object,value); 313 } 314 } 315 316 319 protected static String [] getChildrenTagNames(Class clazz, String fieldName, String xmlName) { 320 String [] result=null; 322 try { 323 Field xmlMapAssignField=clazz.getField("XML_COLLECTION_ELEMENTS"); 324 Object [][] xmlMapAssign=(Object [][])xmlMapAssignField.get(null); 325 if (xmlMapAssign!=null) { 326 for (int i=0;(result==null)&&(i<xmlMapAssign.length);i++) { 327 String key=(String )xmlMapAssign[i][0]; 328 if (key.equals(fieldName)) { String [] assignedFields=(String [])xmlMapAssign[i][1]; 330 return assignedFields; 331 } 332 } 333 } 334 } catch (NoSuchFieldException nsfe) { 335 } catch (IllegalAccessException iae) { 337 } 339 if (result==null) { if (xmlName.endsWith("ies")) { 342 xmlName=xmlName.substring(0,xmlName.length()-3)+"y"; 343 } else if (xmlName.endsWith("s")) { 344 xmlName=xmlName.substring(0,xmlName.length()-1); 345 } 346 result=new String [1]; 347 result[0]=xmlName; 348 } 349 return result; 350 } 351 352 protected static Class convertPrimitiveClassToWrapperClass(Class c) { 353 if (c.isPrimitive()) { 355 try { 356 return Class.forName("java.lang."+Toolbox.capitalize(c.getName())); 357 } catch (ClassNotFoundException cnfe) { return null; 359 } 360 } else { 361 return c; 362 } 363 } 364 365 } | Popular Tags |