public void doTag()

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);
            }
        }
    }