1 18 package org.apache.batik.test.xml; 19 20 import java.lang.reflect.Constructor ; 21 import java.lang.reflect.Method ; 22 import java.util.Vector ; 23 24 import org.w3c.dom.Element ; 25 import org.w3c.dom.Node ; 26 import org.w3c.dom.NodeList ; 27 28 35 public class XMLReflect implements XMLReflectConstants{ 36 42 public static final String NO_MATCHING_CONSTRUCTOR 43 = "xml.XMLReflect.error.no.matching.constructor"; 44 45 48 public static Object buildObject(Element element) throws Exception { 49 50 Element classDefiningElement = 51 getClassDefiningElement(element); 52 53 String className 54 = classDefiningElement.getAttribute(XR_CLASS_ATTRIBUTE); 55 56 Class cl = Class.forName(className); 57 Object [] argsArray = null; 58 Class [] argsClasses = null; 59 60 NodeList children = element.getChildNodes(); 61 if(children != null && children.getLength() > 0){ 62 int n = children.getLength(); 63 Vector args = new Vector (); 64 for(int i=0; i<n; i++){ 65 Node child = children.item(i); 66 if(child.getNodeType() == Node.ELEMENT_NODE){ 67 Element childElement = (Element )child; 68 String tagName = childElement.getTagName().intern(); 69 if(tagName == XR_ARG_TAG){ 70 Object arg = buildArgument(childElement); 71 args.addElement(arg); 72 } 73 } 74 } 75 76 if(args.size() > 0){ 77 argsArray = new Object [args.size()]; 78 args.copyInto(argsArray); 79 80 argsClasses = new Class [args.size()]; 81 82 for(int i=0; i<args.size(); i++){ 83 argsClasses[i] = argsArray[i].getClass(); 84 } 85 } 86 } 87 88 Constructor constructor 89 = getDeclaredConstructor(cl, argsClasses); 90 91 if (constructor == null) { 92 String argsClassesStr = "null"; 93 if (argsClasses != null) { 94 argsClassesStr = ""; 95 for (int i=0; i<argsClasses.length; i++) { 96 argsClassesStr += argsClasses[i].getName() + " / "; 97 } 98 } 99 throw new Exception (Messages.formatMessage(NO_MATCHING_CONSTRUCTOR, 100 new Object [] { className, 101 argsClassesStr })); 102 } 103 return configureObject(constructor.newInstance(argsArray), 104 element, classDefiningElement); 105 } 106 107 110 public static Object configureObject(Object obj, 111 Element element, 112 Element classDefiningElement) throws Exception { 113 Vector v = new Vector (); 118 v.addElement(element); 119 while (element != classDefiningElement) { 120 element = (Element ) element.getParentNode(); 121 v.addElement(element); 122 } 123 124 int ne = v.size(); 125 for (int j=ne-1; j>=0; j--) { 126 element = (Element )v.elementAt(j); 127 NodeList children = element.getChildNodes(); 128 if(children != null && children.getLength() > 0){ 129 int n = children.getLength(); 130 for(int i=0; i<n; i++){ 131 Node child = children.item(i); 132 if(child.getNodeType() == Node.ELEMENT_NODE){ 133 Element childElement = (Element )child; 134 String tagName = childElement.getTagName().intern(); 135 if(tagName == XR_PROPERTY_TAG){ 136 Object arg = buildArgument(childElement); 137 String propertyName 138 = childElement.getAttribute(XR_NAME_ATTRIBUTE); 139 setObjectProperty(obj, propertyName, arg); 140 } 141 } 142 } 143 144 } 145 } 146 147 return obj; 148 } 149 150 153 public static void setObjectProperty(Object obj, 154 String propertyName, 155 Object propertyValue) 156 throws Exception { 157 Class cl = obj.getClass(); 158 Method m = null; 159 try { 160 m = cl.getMethod("set" + propertyName, 161 new Class []{propertyValue.getClass()}); 162 163 } catch (NoSuchMethodException e) { 164 Class propertyClass = propertyValue.getClass(); 169 try { 170 if (propertyClass == java.lang.Double .class) { 171 m = cl.getMethod("set" + propertyName, 172 new Class [] {java.lang.Double.TYPE}); 173 } else if (propertyClass == java.lang.Float .class) { 174 m = cl.getMethod("set" + propertyName, 175 new Class [] {java.lang.Float.TYPE}); 176 } else if (propertyClass == java.lang.Integer .class) { 177 m = cl.getMethod("set" + propertyName, 178 new Class [] {java.lang.Integer.TYPE}); 179 } else if (propertyClass == java.lang.Boolean .class) { 180 m = cl.getMethod("set" + propertyName, 181 new Class [] {java.lang.Boolean.TYPE}); 182 } else { 183 System.err.println("Could not find a set method for property : " + propertyName 184 + " with value " + propertyValue + " and class " + propertyValue.getClass().getName()); 185 throw e; 186 } 187 } catch (NoSuchMethodException nsme) { 188 throw nsme; 189 } 190 } 191 if(m != null){ 192 m.invoke(obj, new Object []{propertyValue}); 193 } 194 } 195 196 197 201 public static Constructor getDeclaredConstructor(Class cl, 202 Class [] argClasses){ 203 Constructor [] cs = cl.getDeclaredConstructors(); 204 for(int i=0; i<cs.length; i++){ 205 Class [] reqArgClasses = cs[i].getParameterTypes(); 206 if(reqArgClasses != null && reqArgClasses.length > 0){ 207 if(reqArgClasses.length == argClasses.length){ 208 int j=0; 209 for(; j<argClasses.length; j++){ 210 if(!reqArgClasses[j].isAssignableFrom(argClasses[j])){ 211 break; 212 } 213 } 214 if(j == argClasses.length){ 215 return cs[i]; 216 } 217 } 218 } 219 else{ 220 if(argClasses == null || argClasses.length == 0){ 221 return cs[i]; 222 } 223 } 224 } 225 226 return null; 227 } 228 229 234 public static Object buildArgument(Element element) throws Exception { 235 if(!element.hasChildNodes()){ 236 Element classDefiningElement = 237 getClassDefiningElement(element); 238 239 String classAttr = classDefiningElement.getAttribute(XR_CLASS_ATTRIBUTE); 240 241 Class cl = Class.forName(classAttr); 243 244 if(element.hasAttribute(XR_VALUE_ATTRIBUTE)){ 245 String value = element.getAttribute(XR_VALUE_ATTRIBUTE); 246 247 248 Constructor constructor 249 = cl.getDeclaredConstructor(new Class [] { String .class }); 250 251 return constructor.newInstance(new Object [] {value}); 252 } 253 else{ 254 return cl.newInstance(); 256 } 257 } 258 else{ 259 return buildObject(element); 260 } 261 } 262 263 266 public static Element getClassDefiningElement(Element element) { 267 if(element != null){ 268 String classAttr = element.getAttribute(XR_CLASS_ATTRIBUTE); 269 270 if(classAttr == null || "".equals(classAttr)){ 271 Node parent = element.getParentNode(); 272 if(parent != null && parent.getNodeType() == Node.ELEMENT_NODE){ 273 return getClassDefiningElement((Element )parent); 274 } 275 else{ 276 return null; 277 } 278 } 279 280 return element; 281 282 } 283 284 return null; 285 } 286 } 287 | Popular Tags |