in jelly-tags/ant/src/main/java/org/apache/commons/jelly/tags/ant/AntTag.java [110:293]
public void doTag(XMLOutput output) throws JellyTagException {
Project project = getAntProject();
String tagName = getTagName();
Object parentObject = findBeanAncestor();
Object parentTask = findParentTaskObject();
// lets assume that Task instances are not nested inside other Task instances
// for example <manifest> inside a <jar> should be a nested object, where as
// if the parent is not a Task the <manifest> should create a ManifestTask
//
// also its possible to have a root Ant tag which isn't a task, such as when
// defining <fileset id="...">...</fileset>
Object nested = null;
if (parentObject != null && !( parentTask instanceof TaskContainer) ) {
nested = createNestedObject( parentObject, tagName );
}
if (nested == null) {
task = createTask( tagName );
if (task != null) {
if ( log.isDebugEnabled() ) {
log.debug( "Creating an ant Task for name: " + tagName );
}
// the following algorithm follows the lifetime of a tag
// http://jakarta.apache.org/ant/manual/develop.html#writingowntask
// kindly recommended by Stefan Bodewig
// create and set its project reference
if ( task instanceof TaskAdapter ) {
setObject( ((TaskAdapter)task).getProxy() );
}
else {
setObject( task );
}
// set the task ID if one is given
Object id = getAttributes().remove( "id" );
if ( id != null ) {
project.addReference( (String) id, task );
}
// ### we might want to spoof a Target setting here
// now lets initialize
task.init();
// now lets invoke the body to call all the createXXX() or addXXX() methods
String body = getBodyText();
// now lets set any attributes of this tag...
setBeanProperties();
// now lets set the addText() of the body content, if its applicable
Method method = MethodUtils.getAccessibleMethod( task.getClass(),
"addText",
addTaskParamTypes );
if (method != null) {
Object[] args = { body };
try {
method.invoke(this.task, args);
}
catch (IllegalAccessException e) {
throw new JellyTagException(e);
}
catch (InvocationTargetException e) {
throw new JellyTagException(e);
}
}
// now lets set all the attributes of the child elements
// XXXX: to do!
// now we're ready to invoke the task
// XXX: should we call execute() or perform()?
// according to org.apache.tools.ant.Main, redirect stdout and stderr
PrintStream initialOut = System.out;
PrintStream initialErr = System.err;
PrintStream newOut = new PrintStream(new DemuxOutputStream(project, false));
PrintStream newErr = new PrintStream(new DemuxOutputStream(project, true));
try {
System.setOut(newOut);
System.setErr(newErr);
task.perform();
} finally {
System.setOut(initialOut);
System.setErr(initialErr);
}
}
}
if (task == null) {
if (nested == null) {
if ( log.isDebugEnabled() ) {
log.debug( "Trying to create a data type for tag: " + tagName );
}
nested = createDataType( tagName );
}
else {
if ( log.isDebugEnabled() ) {
log.debug( "Created nested property tag: " + tagName );
}
}
if ( nested != null ) {
setObject( nested );
// set the task ID if one is given
Object id = getAttributes().remove( "id" );
if ( id != null ) {
project.addReference( (String) id, nested );
}
// TODO: work out why we always set the name attribute.
// See JELLY-105.
// try{
// PropertyUtils.setProperty( nested, "name", tagName );
// }
// catch (Exception e) {
// log.warn( "Caught exception setting nested name: " + tagName, e );
// }
// now lets invoke the body
String body = getBodyText();
// now lets set any attributes of this tag...
setBeanProperties();
// now lets add it to its parent
if ( parentObject != null ) {
IntrospectionHelper ih = IntrospectionHelper.getHelper( parentObject.getClass() );
try {
if (log.isDebugEnabled()) {
log.debug("About to set the: " + tagName
+ " property on: " + safeToString(parentObject) + " to value: "
+ nested + " with type: " + nested.getClass()
);
}
ih.storeElement( project, parentObject, nested, tagName.toLowerCase() );
}
catch (Exception e) {
log.warn( "Caught exception setting nested: " + tagName, e );
}
// now try to set the property for good measure
// as the storeElement() method does not
// seem to call any setter methods of non-String types
try {
BeanUtils.setProperty( parentObject, tagName, nested );
}
catch (Exception e) {
log.debug("Caught exception trying to set property: " + tagName + " on: " + safeToString(parentObject));
}
}
}
else {
log.warn("Could not convert tag: " + tagName + " into an Ant task, data type or property");
// lets treat this tag as static XML...
StaticTag tag = new StaticTag("", tagName, tagName);
tag.setParent( getParent() );
tag.setBody( getBody() );
tag.setContext(context);
for (Iterator iter = getAttributes().entrySet().iterator(); iter.hasNext();) {
Map.Entry entry = (Map.Entry) iter.next();
String name = (String) entry.getKey();
Object value = entry.getValue();
tag.setAttribute(name, value);
}
tag.doTag(output);
}
}
}