diff options
Diffstat (limited to 'framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/TaskAdapter.java')
-rw-r--r-- | framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/TaskAdapter.java | 182 |
1 files changed, 182 insertions, 0 deletions
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/TaskAdapter.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/TaskAdapter.java new file mode 100644 index 00000000..3a3001f6 --- /dev/null +++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/TaskAdapter.java @@ -0,0 +1,182 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.tools.ant; + +import java.lang.reflect.Method; + +import org.apache.tools.ant.dispatch.DispatchUtils; +import org.apache.tools.ant.dispatch.Dispatchable; + +/** + * Uses introspection to "adapt" an arbitrary Bean which doesn't + * itself extend Task, but still contains an execute method and optionally + * a setProject method. + * + */ +public class TaskAdapter extends Task implements TypeAdapter { + + /** Object to act as a proxy for. */ + private Object proxy; + + /** + * No-arg constructor for reflection. + */ + public TaskAdapter() { + } + + /** + * Constructor for given proxy. + * So you could write easier code + * <pre> + * myTaskContainer.addTask( new TaskAdapter(myProxy) ); + * </pre> + * + * @param proxy The object which Ant should use as task. + */ + public TaskAdapter(Object proxy) { + this(); + setProxy(proxy); + } + + /** + * Checks whether or not a class is suitable to be adapted by TaskAdapter. + * If the class is of type Dispatchable, the check is not performed because + * the method that will be executed will be determined only at runtime of + * the actual task and not during parse time. + * + * This only checks conditions which are additionally required for + * tasks adapted by TaskAdapter. Thus, this method should be called by + * Project.checkTaskClass. + * + * Throws a BuildException and logs as Project.MSG_ERR for + * conditions that will cause the task execution to fail. + * Logs other suspicious conditions with Project.MSG_WARN. + * + * @param taskClass Class to test for suitability. + * Must not be <code>null</code>. + * @param project Project to log warnings/errors to. + * Must not be <code>null</code>. + * + * @see Project#checkTaskClass(Class) + */ + public static void checkTaskClass(final Class<?> taskClass, + final Project project) { + if (!Dispatchable.class.isAssignableFrom(taskClass)) { + // don't have to check for interface, since then + // taskClass would be abstract too. + try { + final Method executeM = taskClass.getMethod("execute", (Class[]) null); + // don't have to check for public, since + // getMethod finds public method only. + // don't have to check for abstract, since then + // taskClass would be abstract too. + if (!Void.TYPE.equals(executeM.getReturnType())) { + final String message = "return type of execute() should be " + + "void but was \"" + executeM.getReturnType() + "\" in " + + taskClass; + project.log(message, Project.MSG_WARN); + } + } catch (NoSuchMethodException e) { + final String message = "No public execute() in " + taskClass; + project.log(message, Project.MSG_ERR); + throw new BuildException(message); + } catch (LinkageError e) { + String message = "Could not load " + taskClass + ": " + e; + project.log(message, Project.MSG_ERR); + throw new BuildException(message, e); + } + } + } + + /** + * Check if the proxy class is a valid class to use + * with this adapter. + * The class must have a public no-arg "execute()" method. + * @param proxyClass the class to check. + */ + public void checkProxyClass(Class<?> proxyClass) { + checkTaskClass(proxyClass, getProject()); + } + + /** + * Executes the proxied task. + * + * @exception BuildException if the project could not be set + * or the method could not be executed. + */ + public void execute() throws BuildException { + try { + Method setLocationM = proxy.getClass().getMethod( + "setLocation", new Class[] {Location.class}); + if (setLocationM != null) { + setLocationM.invoke(proxy, new Object[] {getLocation()}); + } + } catch (NoSuchMethodException e) { + // ignore this if the class being used as a task does not have + // a set location method. + } catch (Exception ex) { + log("Error setting location in " + proxy.getClass(), + Project.MSG_ERR); + throw new BuildException(ex); + } + + try { + Method setProjectM = proxy.getClass().getMethod( + "setProject", new Class[] {Project.class}); + if (setProjectM != null) { + setProjectM.invoke(proxy, new Object[] {getProject()}); + } + } catch (NoSuchMethodException e) { + // ignore this if the class being used as a task does not have + // a set project method. + } catch (Exception ex) { + log("Error setting project in " + proxy.getClass(), + Project.MSG_ERR); + throw new BuildException(ex); + } + + try { + DispatchUtils.execute(proxy); + } catch (BuildException be) { + throw be; + } catch (Exception ex) { + log("Error in " + proxy.getClass(), Project.MSG_VERBOSE); + throw new BuildException(ex); + } + } + + /** + * Sets the target object to proxy for. + * + * @param o The target object. Must not be <code>null</code>. + */ + public void setProxy(Object o) { + this.proxy = o; + } + + /** + * Returns the target object being proxied. + * + * @return the target proxy object. + */ + public Object getProxy() { + return proxy; + } + +} |