1 37 package net.sourceforge.cruisecontrol; 38 39 import org.apache.log4j.Logger; 40 import org.jdom.Attribute; 41 import org.jdom.Element; 42 43 import java.lang.reflect.Method ; 44 import java.util.HashMap ; 45 import java.util.HashSet ; 46 import java.util.Iterator ; 47 import java.util.Map ; 48 import java.util.Set ; 49 50 57 public class PluginXMLHelper { 58 private static final Logger LOG = Logger.getLogger(PluginXMLHelper.class); 59 private ProjectHelper projectHelper; 60 61 public PluginXMLHelper(ProjectHelper plugins) { 62 projectHelper = plugins; 63 } 64 65 83 public Object configure(Element objectElement, Class pluginClass, 84 boolean skipChildElements) 85 throws CruiseControlException { 86 87 Object pluginInstance = instantiatePlugin(pluginClass); 88 return configure(objectElement, pluginInstance, skipChildElements); 89 90 } 91 92 98 private Object instantiatePlugin(Class pluginClass) throws CruiseControlException { 99 Object pluginInstance; 100 try { 101 pluginInstance = pluginClass.getConstructor(null).newInstance(null); 102 } catch (Exception e) { 103 LOG.fatal("Could not instantiate class", e); 104 throw new CruiseControlException("Could not instantiate class: " 105 + pluginClass.getName()); 106 } 107 return pluginInstance; 108 } 109 110 115 public Object configure(Element objectElement, Object pluginInstance, 116 boolean skipChildElements) throws CruiseControlException { 117 118 LOG.debug("configure " + objectElement.getName() + " instance " + pluginInstance.getClass() 119 + " self configuring: " + (pluginInstance instanceof SelfConfiguringPlugin) 120 + " skip:" + skipChildElements); 121 if (pluginInstance instanceof SelfConfiguringPlugin) { 122 ((SelfConfiguringPlugin) pluginInstance).configure(objectElement); 123 } else { 124 configureObject(objectElement, pluginInstance, skipChildElements); 125 } 126 return pluginInstance; 127 } 128 129 145 protected void configureObject(Element objectElement, Object object, boolean skipChildElements) 146 throws CruiseControlException { 147 148 LOG.debug("configuring object " + objectElement.getName() 149 + " object " + object.getClass() + " skip " + skipChildElements); 150 151 Map setters = new HashMap (); 152 Map creators = new HashMap (); 153 Set adders = new HashSet (); 154 155 Method [] methods = object.getClass().getMethods(); 156 for (int i = 0; i < methods.length; i++) { 157 final Method method = methods[i]; 158 final String name = method.getName(); 159 if (name.startsWith("set")) { 160 setters.put(name.substring("set".length()).toLowerCase(), method); 161 } else if (name.startsWith("create")) { 162 creators.put(name.substring("create".length()).toLowerCase(), method); 163 } else if (name.equals("add") && method.getParameterTypes().length == 1) { 164 adders.add(method); 165 } 166 } 167 168 setFromAttributes(objectElement, setters, object); 169 170 if (!skipChildElements) { 171 Iterator childElementIterator = objectElement.getChildren().iterator(); 172 while (childElementIterator.hasNext()) { 173 Element childElement = (Element) childElementIterator.next(); 174 if (creators.containsKey(childElement.getName().toLowerCase())) { 175 LOG.debug("treating child with creator " + childElement.getName()); 176 try { 177 Method method = (Method ) creators.get(childElement.getName().toLowerCase()); 178 Object childObject = method.invoke(object, null); 179 configureObject(childElement, childObject, false); 180 } catch (Exception e) { 181 throw new CruiseControlException(e.getMessage()); 182 } 183 } else { 184 Object childObject = projectHelper.configurePlugin(childElement, false); 186 187 Method adder = null; 188 for (Iterator iterator = adders.iterator(); iterator.hasNext();) { 190 Method method = (Method ) iterator.next(); 191 Class type = method.getParameterTypes()[0]; 192 if (type.isAssignableFrom(childObject.getClass())) { 193 adder = method; 194 break; 195 } 196 } 197 198 if (adder != null) { 199 try { 200 LOG.debug("treating child with adder " + childElement.getName() + " adding " + childObject); 201 adder.invoke(object, new Object []{childObject}); 202 } catch (Exception e) { 203 LOG.fatal("Error configuring plugin.", e); 204 } 205 } else { 206 throw new CruiseControlException("Nested element: '" + childElement.getName() 207 + "' is not supported for the <" + objectElement.getName() + "> tag."); 208 } 209 } 210 } 211 } 212 } 213 214 private void setFromAttributes(Element objectElement, Map setters, Object object) throws CruiseControlException { 215 for (Iterator iter = objectElement.getAttributes().iterator(); iter.hasNext(); ) { 216 Attribute attribute = (Attribute) iter.next(); 217 callSetter(attribute.getName(), attribute.getValue(), setters, object); 218 } 219 } 220 221 private void callSetter(String propName, String propValue, Map setters, Object object) 222 throws CruiseControlException { 223 224 if (setters.containsKey(propName.toLowerCase())) { 225 LOG.debug("Setting " + propName.toLowerCase() + " to " + propValue); 226 try { 227 Method method = (Method ) setters.get(propName.toLowerCase()); 228 Class [] parameters = method.getParameterTypes(); 229 if (String .class.isAssignableFrom(parameters[0])) { 230 method.invoke(object, new Object []{propValue}); 231 } else if (int.class.isAssignableFrom(parameters[0])) { 232 method.invoke(object, new Object []{Integer.valueOf(propValue)}); 233 } else if (long.class.isAssignableFrom(parameters[0])) { 234 method.invoke(object, new Object []{Long.valueOf(propValue)}); 235 } else if (boolean.class.isAssignableFrom(parameters[0])) { 236 method.invoke(object, 237 new Object []{Boolean.valueOf(propValue)}); 238 } else { 239 LOG.error("rCouldn't invoke setter " + propName.toLowerCase()); 240 } 241 } catch (Exception e) { 242 LOG.fatal("Error configuring plugin.", e); 243 } 244 } else { 245 throw new CruiseControlException("Attribute: '" + propName 246 + "' is not supported for class: '" + object.getClass().getName() + "'."); 247 } 248 } 249 250 } 251 | Popular Tags |