1 7 package org.jboss.xb.binding.metadata.unmarshalling.impl; 8 9 import org.jboss.xb.binding.metadata.unmarshalling.DocumentBinding; 10 import org.jboss.xb.binding.metadata.unmarshalling.TopElementBinding; 11 import org.jboss.xb.binding.metadata.unmarshalling.NamespaceBinding; 12 import org.jboss.xb.binding.metadata.unmarshalling.ElementBinding; 13 import org.jboss.xb.binding.metadata.unmarshalling.AttributeBinding; 14 import org.jboss.xb.binding.metadata.unmarshalling.BasicElementBinding; 15 import org.jboss.xb.binding.metadata.unmarshalling.XmlValueBinding; 16 import org.jboss.xb.binding.Util; 17 import org.jboss.xb.binding.JBossXBRuntimeException; 18 19 import javax.xml.namespace.QName ; 20 import java.lang.reflect.Field ; 21 import java.lang.reflect.Method ; 22 import java.lang.reflect.Modifier ; 23 import java.util.Collection ; 24 import java.util.ArrayList ; 25 26 30 public class RuntimeDocumentBinding 31 extends DocumentBindingFactoryImpl.AbstractDocumentBinding 32 { 33 public RuntimeDocumentBinding(DocumentBinding doc) 34 { 35 super(doc); 36 } 37 38 protected NamespaceBinding getNamespaceLocal(String namespaceUri) 39 { 40 return new RuntimeNamespaceBinding(this, namespaceUri); 41 } 42 43 45 private static class RuntimeNamespaceBinding 46 extends DocumentBindingFactoryImpl.AbstractNamespaceBinding 47 { 48 private String pkg; 49 50 public RuntimeNamespaceBinding(DocumentBinding doc, String namespaceUri) 51 { 52 super(doc, namespaceUri); 53 } 54 55 protected String getJavaPackageLocal() 56 { 57 if(pkg == null) 58 { 59 pkg = Util.xmlNamespaceToJavaPackage(namespaceUri); 60 } 61 return pkg; 62 } 63 64 protected TopElementBinding getTopElementLocal(String elementName) 65 { 66 return new RuntimeTopElementBinding(this, elementName); 67 } 68 } 69 70 static class RuntimeTopElementBinding 71 extends DocumentBindingFactoryImpl.AbstractTopElementBinding 72 { 73 private Class javaType; 74 75 public RuntimeTopElementBinding(NamespaceBinding ns, String elementName) 76 { 77 super(ns, elementName); 78 } 79 80 protected Class getJavaTypeLocal() 81 { 82 if(javaType == null) 83 { 84 javaType = loadDefaultClass(this); 85 if(javaType == null) 86 { 87 throw new IllegalStateException ( 88 "Failed to bind top element " + name + ": class not found " + getDefaultClassName(this) 89 ); 90 } 91 } 92 return javaType; 93 } 94 95 protected ElementBinding getElementLocal(QName elementName) 96 { 97 return new RuntimeElementBinding(this, elementName); 98 } 99 100 protected AttributeBinding getAttributeLocal(QName attributeName) 101 { 102 String fieldName = Util.xmlNameToFieldName(attributeName.getLocalPart(), true); 103 return new AttributeBindingImpl(attributeName, null, getJavaType(), fieldName); 104 } 105 106 protected XmlValueBinding getValueLocal() 107 { 108 throw new UnsupportedOperationException ("getValueLocal is not implemented."); 110 } 111 } 112 113 static class RuntimeElementBinding 114 extends DocumentBindingFactoryImpl.AbstractElementBinding 115 { 116 private Field field; 117 private Method getter; 118 private Method setter; 119 private Class fieldType; 120 private Class javaType; 121 122 public RuntimeElementBinding(BasicElementBinding parent, QName elementName) 123 { 124 super(parent, elementName); 125 } 126 127 private void init() 128 { 129 Class parentType = parent.getJavaType(); 130 javaType = loadDefaultClass(this); 131 132 if(Collection .class.isAssignableFrom(parentType)) 133 { 134 if(javaType == null) 135 { 136 javaType = String .class; 137 } 138 } 139 else 140 { 141 String baseMethodName = Util.xmlNameToClassName(name.getLocalPart(), true); 142 try 143 { 144 getter = parentType.getMethod("get" + baseMethodName, null); 145 setter = parentType.getMethod("set" + baseMethodName, new Class []{getter.getReturnType()}); 146 fieldType = getter.getReturnType(); 147 } 148 catch(NoSuchMethodException e) 149 { 150 try 151 { 152 field = parentType.getField(Util.xmlNameToFieldName(name.getLocalPart(), true)); 153 fieldType = field.getType(); 154 } 155 catch(NoSuchFieldException e1) 156 { 157 throw new JBossXBRuntimeException("Failed to bind " + name + " to any field in " + parentType); 158 } 159 } 160 } 161 162 if(javaType == null) 163 { 164 javaType = fieldType; 165 } 166 else if(fieldType != null && fieldType != javaType && fieldType.isAssignableFrom(javaType)) 167 { 168 javaType = fieldType; 169 } 170 171 if(javaType == null) 172 { 173 throw new JBossXBRuntimeException("Failed to bind " + 174 name + 175 " to any Java type: field=" + 176 field + 177 ", getter=" + 178 getter + 179 ", parent=" + 180 parentType 181 ); 182 } 183 else if(Collection .class == javaType || Collection .class.isAssignableFrom(javaType)) 184 { 185 javaType = ArrayList .class; 187 } 188 else if(javaType.isInterface() || Modifier.isAbstract(javaType.getModifiers())) 189 { 190 throw new JBossXBRuntimeException("Failed to bind " + 191 name + 192 " to a non-abstract Java type: field=" + 193 field + 194 ", getter=" + 195 getter + 196 ", parent=" + 197 parentType 198 ); 199 } 200 } 201 202 protected Field getFieldLocal() 203 { 204 if(javaType == null) 205 { 206 init(); 207 } 208 return field; 209 } 210 211 protected Method getGetterLocal() 212 { 213 if(javaType == null) 214 { 215 init(); 216 } 217 return getter; 218 } 219 220 protected Method getSetterLocal() 221 { 222 if(javaType == null) 223 { 224 init(); 225 } 226 return setter; 227 } 228 229 protected Class getFieldTypeLocal() 230 { 231 if(javaType == null) 232 { 233 init(); 234 } 235 return fieldType; 236 } 237 238 protected Class getJavaTypeLocal() 239 { 240 if(javaType == null) 241 { 242 init(); 243 } 244 return javaType; 245 } 246 247 protected ElementBinding getElementLocal(QName elementName) 248 { 249 return new RuntimeElementBinding(this, elementName); 250 } 251 252 protected AttributeBinding getAttributeLocal(QName attributeName) 253 { 254 String fieldName = Util.xmlNameToFieldName(attributeName.getLocalPart(), true); 255 return new AttributeBindingImpl(attributeName, null, getJavaType(), fieldName); 256 } 257 258 protected XmlValueBinding getValueLocal() 259 { 260 throw new UnsupportedOperationException ("getValueLocal is not implemented."); 262 } 263 } 264 265 private static Class loadDefaultClass(BasicElementBinding element) 266 { 267 Class javaType; 268 String clsName = getDefaultClassName(element); 269 try 270 { 271 javaType = Thread.currentThread().getContextClassLoader().loadClass(clsName); 272 } 273 catch(ClassNotFoundException e) 274 { 275 javaType = null; 276 } 277 return javaType; 278 } 279 280 private static String getDefaultClassName(BasicElementBinding element) 281 { 282 QName elementName = element.getName(); 283 NamespaceBinding ns = element.getDocument().getNamespace(elementName.getNamespaceURI()); 284 return ns.getJavaPackage() + "." + Util.xmlNameToClassName(elementName.getLocalPart(), true); 285 } 286 } 287 | Popular Tags |