package org.codehaus.mojo.mant; import java.io.StringReader; import java.util.Iterator; import java.util.List; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.Element; import org.dom4j.io.SAXReader; /** * Wraps a task and applies the given mappings to the task attributes. * */ public class AntTask { private Element task; public AntTask( String task, String[] mappings ) throws DocumentException { this.task = createTask( task, mappings ); } public Element getTask() { return task; } /** * Apply mappings to the given node. * Attributes are only created if the parent already exists. * @param task TODO * @param mappings TODO * @param mappings TODO * @return * @throws DocumentException */ private Element createTask( String task, String[] mappings ) throws DocumentException { Element node = createElement( task ); for ( int i = 0; i < mappings.length; i += 2 ) { String mavenProperty = mappings[i + 1]; String[] components = getComponents( mappings[i] ); String parentPath = components[0]; String attributeName = components[1]; List list = node.selectNodes( parentPath ); Iterator allMatches = list.iterator(); while ( allMatches.hasNext() ) { Element match = (Element) allMatches.next(); match.addAttribute( attributeName, mavenProperty ); } } return node; } /** * Creates a node object from the given string representation. * @param task * @return * @throws DocumentException */ private Element createElement( String task ) throws DocumentException { SAXReader reader = new SAXReader(); Document document = reader.read( new StringReader( task ) ); return (Element) document.getRootElement().clone(); } /** * Ensures the xpath expression is of the correct format. * It should refer to an attribute and also a ./ is prepended * if the first character is an @ so that the parent isn't an * empty string when split. * @param xpath * @return */ private String[] getComponents( String xpath ) { String standardXpath = xpath.startsWith( "@" ) ? "./" + xpath : xpath; String[] components = standardXpath.split( "/@" ); if ( components.length != 2 ) { throw new RuntimeException( "xpath expression must refer to an attribute: " + xpath ); } return components; } }