1 7 package org.jboss.xml.binding; 8 9 import org.jboss.logging.Logger; 10 import org.jboss.util.Classes; 11 12 import java.lang.reflect.Method ; 13 import java.lang.reflect.Field ; 14 import java.util.Map ; 15 import java.util.HashMap ; 16 17 21 public class MappingObjectModelProvider 22 implements GenericObjectModelProvider 23 { 24 private static final Logger log = Logger.getLogger(MappingObjectModelProvider.class); 25 26 private final Map classMappings = new HashMap (); 27 private final Map fieldMappings = new HashMap (); 28 29 public void mapClassToElement(Class cls, String namespaceURI, String localName, ObjectModelProvider provider) 30 { 31 ClassToElementMapping mapping = new ClassToElementMapping(cls, namespaceURI, localName, 32 provider instanceof GenericObjectModelProvider ? 33 (GenericObjectModelProvider)provider : new DelegatingObjectModelProvider(provider) 34 ); 35 classMappings.put(mapping.cls, mapping); 36 } 37 38 public void mapFieldToElement(Class cls, 39 String field, 40 String namespaceURI, 41 String localName, 42 TypeConverter converter) 43 { 44 FieldToElementMapping mapping = new FieldToElementMapping(cls, field, namespaceURI, localName, converter); 45 fieldMappings.put(mapping.localName, mapping); 46 } 47 48 50 public Object getChildren(Object o, String namespaceURI, String localName) 51 { 52 Object children = null; 53 if(!writeAsValue(o.getClass())) 54 { 55 children = getJavaValue(localName, o, true); 56 } 57 return children; 58 } 59 60 public Object getElementValue(Object o, String namespaceURI, String localName) 61 { 62 Object value = null; 63 if(writeAsValue(o.getClass())) 64 { 65 value = o; 66 } 67 else 68 { 69 value = getJavaValue(localName, o, false); 70 } 71 return value; 72 } 73 74 public Object getAttributeValue(Object o, String namespaceURI, String localName) 75 { 76 Object value = null; 77 if(writeAsValue(o.getClass())) 78 { 79 value = o; 80 } 81 else 82 { 83 value = getJavaValue(localName, o, false); 84 } 85 return value; 86 } 87 88 public Object getRoot(Object o, String namespaceURI, String localName) 89 { 90 String correspCls = Util.xmlNameToClassName(localName, true); 91 String shortName = Classes.stripPackageName(o.getClass()); 92 return correspCls.equals(shortName) ? o : null; 93 } 94 95 97 private Object getJavaValue(String localName, Object o, boolean forComplexType) 98 { 99 Method getter = null; 100 Field field = null; 101 102 final FieldToElementMapping mapping = (FieldToElementMapping)fieldMappings.get(localName); 103 if(mapping != null) 104 { 105 getter = mapping.getter; 106 } 107 else 108 { 109 String getterStr = Util.xmlNameToGetMethodName(localName, true); 110 try 111 { 112 getter = o.getClass().getMethod(getterStr, null); 113 } 114 catch(NoSuchMethodException e) 115 { 116 String attr = Util.xmlNameToClassName(localName, true); 117 attr = Character.toLowerCase(attr.charAt(0)) + attr.substring(1); 118 try 119 { 120 field = o.getClass().getField(attr); 121 } 122 catch(NoSuchFieldException e1) 123 { 124 if(log.isDebugEnabled()) 125 { 126 log.debug("getChildren: found neither getter nor field for " + localName + " in " + o.getClass()); 127 } 128 } 129 } 130 } 131 132 Object value = null; 133 try 134 { 135 if(getter != null && (!forComplexType || forComplexType && !writeAsValue(getter.getReturnType()))) 136 { 137 value = getter.invoke(o, null); 138 } 139 else if(field != null && (!forComplexType || forComplexType && !writeAsValue(field.getType()))) 140 { 141 value = field.get(o); 142 } 143 } 144 catch(Exception e) 145 { 146 log.error("Failed to provide value for " + localName + " from " + o, e); 147 } 148 149 if(value != null && mapping != null) 150 { 151 value = mapping.converter.marshal(value); 152 } 153 154 return value; 155 } 156 157 private boolean writeAsValue(final Class type) 158 { 159 return Classes.isPrimitive(type) || 160 type == String .class || 161 type == java.util.Date .class; 162 } 163 164 166 private class ClassToElementMapping 167 { 168 public final Class cls; 169 public final String namespaceURI; 170 public final String localName; 171 public final GenericObjectModelProvider provider; 172 173 public ClassToElementMapping(Class cls, 174 String namespaceURI, 175 String localName, 176 GenericObjectModelProvider provider) 177 { 178 this.cls = cls; 179 this.namespaceURI = namespaceURI; 180 this.localName = localName; 181 this.provider = provider; 182 } 183 184 public boolean equals(Object o) 185 { 186 if(this == o) 187 { 188 return true; 189 } 190 if(!(o instanceof ClassToElementMapping)) 191 { 192 return false; 193 } 194 195 final ClassToElementMapping classToElementMapping = (ClassToElementMapping)o; 196 197 if(cls != null ? !cls.equals(classToElementMapping.cls) : classToElementMapping.cls != null) 198 { 199 return false; 200 } 201 if(localName != null ? 202 !localName.equals(classToElementMapping.localName) : 203 classToElementMapping.localName != null) 204 { 205 return false; 206 } 207 if(namespaceURI != null ? 208 !namespaceURI.equals(classToElementMapping.namespaceURI) : 209 classToElementMapping.namespaceURI != null) 210 { 211 return false; 212 } 213 214 return true; 215 } 216 217 public int hashCode() 218 { 219 int result; 220 result = (cls != null ? cls.hashCode() : 0); 221 result = 29 * result + (namespaceURI != null ? namespaceURI.hashCode() : 0); 222 result = 29 * result + (localName != null ? localName.hashCode() : 0); 223 return result; 224 } 225 } 226 227 private class FieldToElementMapping 228 { 229 public final Class cls; 230 public final String field; 231 public final String namespaceURI; 232 public final String localName; 233 public final TypeConverter converter; 234 public final Method getter; 235 public final Method setter; 236 237 public FieldToElementMapping(Class cls, 238 String field, 239 String namespaceURI, 240 String localName, 241 TypeConverter converter) 242 { 243 this.cls = cls; 244 this.field = field; 245 this.namespaceURI = namespaceURI; 246 this.localName = localName; 247 this.converter = converter; 248 249 try 250 { 251 getter = Classes.getAttributeGetter(cls, field); 252 } 253 catch(NoSuchMethodException e) 254 { 255 throw new IllegalStateException ("Getter not found for " + field + " in class " + cls.getName()); 256 } 257 258 try 259 { 260 setter = Classes.getAttributeSetter(cls, field, getter.getReturnType()); 261 } 262 catch(NoSuchMethodException e) 263 { 264 throw new IllegalStateException ("Setter not found for " + field + " in class " + cls.getName()); 265 } 266 } 267 268 public boolean equals(Object o) 269 { 270 if(this == o) 271 { 272 return true; 273 } 274 if(!(o instanceof FieldToElementMapping)) 275 { 276 return false; 277 } 278 279 final FieldToElementMapping fieldToElementMapping = (FieldToElementMapping)o; 280 281 if(cls != null ? !cls.equals(fieldToElementMapping.cls) : fieldToElementMapping.cls != null) 282 { 283 return false; 284 } 285 if(field != null ? !field.equals(fieldToElementMapping.field) : fieldToElementMapping.field != null) 286 { 287 return false; 288 } 289 if(localName != null ? 290 !localName.equals(fieldToElementMapping.localName) : 291 fieldToElementMapping.localName != null) 292 { 293 return false; 294 } 295 if(namespaceURI != null ? 296 !namespaceURI.equals(fieldToElementMapping.namespaceURI) : 297 fieldToElementMapping.namespaceURI != null) 298 { 299 return false; 300 } 301 302 return true; 303 } 304 305 public int hashCode() 306 { 307 int result; 308 result = (cls != null ? cls.hashCode() : 0); 309 result = 29 * result + (field != null ? field.hashCode() : 0); 310 result = 29 * result + (namespaceURI != null ? namespaceURI.hashCode() : 0); 311 result = 29 * result + (localName != null ? localName.hashCode() : 0); 312 return result; 313 } 314 } 315 } 316 | Popular Tags |