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