1 package xdoclet.ant;
2
3 import org.apache.commons.logging.LogFactory;
4 import org.apache.tools.ant.*;
5
6 import xdoclet.XDoclet;
7
8 import java.lang.reflect.InvocationTargetException;
9 import java.lang.reflect.Method;
10
11 /***
12 * When XDoclet is invoked via Ant, Ant will only deal with AntProxy objects (except for the {@link XDocletTask}).
13 * Any sub element (plugin, predicates...) AntProxy objects will have a reference to
14 * the *real* object, and all calls initiated by Ant will be forwarded to these objects via
15 * Ant's introspection mechanism.
16 *
17 * <p>This means that any class that should be available from Ant must follow Ant's naming conventions
18 * for <code>setXxx</code> methods. Any class that wish to have child elements should implement a
19 * <code>public Object createElement(String)</code> method (which will be called via reflection
20 * by the AntProxy objects). This way XDoclet can maintain Ant compatibility without having any
21 * compile-time or runtime dependencies to Ant. The only classes that are tied to Ant in XDoclet
22 * are in this package.</p>
23 *
24 * @see XDocletTask
25 *
26 * @author <a href="mailto:aslak.hellesoy at bekk.no">Aslak Hellesøy</a>
27 * @version $Revision: 1.7 $
28 */
29 public class AntProxy implements DynamicConfigurator {
30 private final XDoclet _xdoclet;
31 private final Object _target;
32 private final Project _project;
33 private final String _elementName;
34 private IntrospectionHelper _introspectionHelper;
35
36 /***
37 * Constructs a new AntProxy.
38 *
39 * @param target the object the proxy should act upon.
40 * @param project the project that contains the attributes.
41 * @param elementName name of the element we're representing.
42 */
43 public AntProxy(XDoclet xdoclet, Object target, Project project, String elementName) throws BuildException {
44 if( xdoclet == null ) throw new BuildException( "xdoclet can't be null" );
45 if( target == null ) throw new BuildException( "target can't be null" );
46 if( project == null ) throw new BuildException( "project can't be null" );
47 if( elementName == null ) {
48 LogFactory.getLog(AntProxy.class).warn("Null elementName (?) xdoclet="+xdoclet + " target="+target + " project=" + project);
49 // throw new BuildException( "elementName can't be null" );
50 }
51 _xdoclet = xdoclet;
52 _target = target;
53 _project = project;
54 _elementName = elementName;
55 _introspectionHelper = IntrospectionHelper.getHelper(target.getClass());
56 }
57
58 public final void setDynamicAttribute(String attributeName, String value)
59 throws BuildException {
60 LogFactory.getLog(getClass()).debug("setDynamicAttribute " + attributeName + " " + value + " on " + _target);
61 _introspectionHelper.setAttribute(_project, _target, attributeName, value);
62 }
63
64 public final Object createDynamicElement(String elementName)
65 throws BuildException {
66 Object result = null;
67
68 try {
69 // try the regular createXxx method first
70 result = _introspectionHelper.createElement(_project, _target, elementName);
71 } catch (BuildException be) {
72 // There was no createXxx method. try createElement(String)
73 try {
74 Method createMethod = _target.getClass().getMethod("createElement", new Class[] { String.class });
75
76 result = createMethod.invoke(_target, new Object[] { elementName });
77 } catch (NoSuchMethodException e) {
78 BuildException failure = new BuildException("Can't have <" + elementName + "> under <" + _elementName + ">. No "
79 + _target.getClass().getName() + ".createElement(String) method.", e);
80 _xdoclet.setFailure( failure );
81 throw be;
82 } catch (SecurityException e) {
83 BuildException failure = new BuildException("Can't have <" + elementName + "> under <" + _elementName
84 + ">. SecurityException executing " + _target.getClass().getName() + ".createElement(String) method.", e);
85 _xdoclet.setFailure( failure );
86 throw be;
87 } catch (IllegalAccessException e) {
88 BuildException failure = new BuildException("Can't have <" + elementName + "> under <" + _elementName
89 + ">. IllegalAccessException executing " + _target.getClass().getName()
90 + ".createElement(String) method.", e);
91 _xdoclet.setFailure( failure );
92 throw be;
93 } catch (IllegalArgumentException e) {
94 BuildException failure = new BuildException("Can't have <" + elementName + "> under <" + _elementName
95 + ">. IllegalArgumentException executing " + _target.getClass().getName()
96 + ".createElement(String) method.", e);
97 _xdoclet.setFailure( failure );
98 throw be;
99 } catch (InvocationTargetException e) {
100 Throwable t = (e.getTargetException() != null) ? e.getTargetException() : e;
101
102 BuildException failure = new BuildException("Can't have <" + elementName + "> under <" + _elementName
103 + ">. InvocationTargetException executing " + _target.getClass().getName()
104 + ".createElement(String) method.", t);
105 _xdoclet.setFailure( failure );
106 throw be;
107 }
108 }
109 if( result instanceof ProjectComponent) {
110 ((ProjectComponent)result).setProject(_project);
111 }
112 return new AntProxy(_xdoclet, result, _project, elementName);
113 }
114 }
This page was automatically generated by Maven