1 22 package org.jboss.xb.binding; 23 24 import org.xml.sax.Attributes ; 25 26 import java.lang.reflect.Method ; 27 import java.util.Map ; 28 import java.util.HashMap ; 29 30 36 public class DelegatingObjectModelFactory 37 implements GenericObjectModelFactory 38 { 39 private final ObjectModelFactory typedFactory; 40 private final Map addMethodsByParent = new HashMap (); 41 42 public DelegatingObjectModelFactory(ObjectModelFactory typedFactory) 43 { 44 this.typedFactory = typedFactory; 45 46 Method [] methods = typedFactory.getClass().getMethods(); 47 for(int i = 0; i < methods.length; ++i) 48 { 49 Method method = methods[i]; 50 if("addChild".equals(method.getName())) 51 { 52 Class parent = method.getParameterTypes()[0]; 53 AddMethods addMethods = (AddMethods)addMethodsByParent.get(parent); 54 if(addMethods == null) 55 { 56 addMethods = new AddMethods(parent); 57 addMethodsByParent.put(parent, addMethods); 58 } 59 addMethods.addMethod(method); 60 } 61 } 62 } 63 64 public Object newRoot(Object root, 65 UnmarshallingContext navigator, 66 String namespaceURI, 67 String localName, 68 Attributes attrs) 69 { 70 return typedFactory.newRoot(root, navigator, namespaceURI, localName, attrs); 71 } 72 73 public Object newChild(Object parent, UnmarshallingContext navigator, String namespaceURI, String localName, Attributes attrs) 74 { 75 Class objClass = parent.getClass(); 77 Class [] classes = new Class [] { objClass, UnmarshallingContext.class, String .class, String .class, Attributes .class }; 78 Method method = ObjectModelBuilder.getMethodForElement(typedFactory, "newChild", classes); 79 80 while (method == null && objClass.getSuperclass() != Object .class) 82 { 83 objClass = objClass.getSuperclass(); 84 classes = new Class [] { objClass, UnmarshallingContext.class, String .class, String .class, Attributes .class }; 85 method = ObjectModelBuilder.getMethodForElement(typedFactory, "newChild", classes); 86 } 87 88 Object child = null; 90 if (method != null) 91 { 92 Object [] objects = new Object [] { parent, navigator, namespaceURI, localName, attrs }; 93 child = ObjectModelBuilder.invokeFactory(typedFactory, method, objects); 94 } 95 return child; 96 } 97 98 public void addChild(Object parent, 99 Object child, 100 UnmarshallingContext navigator, 101 String namespaceURI, 102 String localName) 103 { 104 115 AddMethods addMethods = (AddMethods)addMethodsByParent.get(parent.getClass()); 116 if(addMethods != null) 117 { 118 Method method = addMethods.getMethodForChild(child.getClass()); 119 if(method != null) 120 { 121 ObjectModelBuilder.invokeFactory(typedFactory, 122 method, 123 new Object []{ 124 parent, 125 child, 126 navigator, 127 namespaceURI, 128 localName 129 } 130 ); 131 } 132 } 133 } 134 135 public void setValue(Object o, UnmarshallingContext navigator, String namespaceURI, String localName, String value) 136 { 137 Class objClass = o.getClass(); 139 Class [] classes = new Class [] { objClass, UnmarshallingContext.class, String .class, String .class, String .class }; 140 Method method = ObjectModelBuilder.getMethodForElement(typedFactory, "setValue", classes); 141 142 while (method == null && objClass.getSuperclass() != Object .class) 144 { 145 objClass = objClass.getSuperclass(); 146 classes = new Class [] { objClass, UnmarshallingContext.class, String .class, String .class, String .class }; 147 method = ObjectModelBuilder.getMethodForElement(typedFactory, "setValue", classes); 148 } 149 150 if (method != null) 152 { 153 Object [] objects = new Object [] { o, navigator, namespaceURI, localName, value }; 154 ObjectModelBuilder.invokeFactory(typedFactory, method, objects); 155 } 156 } 157 158 public Object completeRoot(Object root, UnmarshallingContext navigator, String namespaceURI, String localName) 159 { 160 return root; 161 } 162 163 165 private static class AddMethods 166 { 167 private static final int DEFAULT_METHODS_SIZE = 10; 168 169 public final Class parent; 170 private Method [] methods = new Method [DEFAULT_METHODS_SIZE]; 171 private int totalMethods; 172 173 public AddMethods(Class parent) 174 { 175 this.parent = parent; 176 } 177 178 public void addMethod(Method m) 179 { 180 if(totalMethods == methods.length) 181 { 182 Method [] tmp = methods; 183 methods = new Method [methods.length + DEFAULT_METHODS_SIZE]; 184 System.arraycopy(tmp, 0, methods, 0, tmp.length); 185 } 186 methods[totalMethods++] = m; 187 } 188 189 public Method getMethodForChild(Class child) 190 { 191 Class closestParam = null; 192 Method closestMethod = null; 193 for(int i = 0; i < totalMethods; ++i) 194 { 195 Method method = methods[i]; 196 Class param = method.getParameterTypes()[1]; 197 if(param == child) 198 { 199 return method; 200 } 201 else if(param.isAssignableFrom(child) && (closestParam == null || closestParam.isAssignableFrom(param))) 202 { 203 closestParam = param; 204 closestMethod = method; 205 } 206 } 207 return closestMethod; 208 } 209 210 public boolean equals(Object o) 211 { 212 if(this == o) 213 { 214 return true; 215 } 216 if(!(o instanceof AddMethods)) 217 { 218 return false; 219 } 220 221 final AddMethods addMethods = (AddMethods)o; 222 223 if(!parent.equals(addMethods.parent)) 224 { 225 return false; 226 } 227 228 return true; 229 } 230 231 public int hashCode() 232 { 233 return parent.hashCode(); 234 } 235 } 236 } 237 | Popular Tags |