From 61a377b6697aa5b28716478236a15dc386934a0f Mon Sep 17 00:00:00 2001 From: Costin Manolache Date: Sat, 20 Jul 2002 02:39:11 +0000 Subject: [PATCH] A bit of cleanup, remove duplicated code. Implement the 'projectName.target' instead of super. I'm still trying to find a way to allow Import task to hook in and support whatever policy it wants. git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@273141 13f79535-47bb-0310-9956-ffa450edef68 --- .../sandbox/embed/ProjectHelperImpl2.java | 477 ++++++------------ 1 file changed, 141 insertions(+), 336 deletions(-) diff --git a/proposal/sandbox/embed/ProjectHelperImpl2.java b/proposal/sandbox/embed/ProjectHelperImpl2.java index 149d7793b..68d53b09d 100644 --- a/proposal/sandbox/embed/ProjectHelperImpl2.java +++ b/proposal/sandbox/embed/ProjectHelperImpl2.java @@ -214,8 +214,7 @@ public class ProjectHelperImpl2 extends ProjectHelper { */ public static class AntHandler { /** - * Handles the start of an element. This base implementation just - * throws an exception. + * Handles the start of an element. This base implementation does nothing. * * @param tag The name of the element being started. * Will not be null. @@ -230,12 +229,12 @@ public class ProjectHelperImpl2 extends ProjectHelper { AntXmlContext context) throws SAXParseException { - throw new SAXParseException("Unexpected element \" " + qname + "\"", context.locator); } /** * Handles the start of an element. This base implementation just - * throws an exception. + * throws an exception - you must override this method if you expect + * child elements. * * @param tag The name of the element being started. * Will not be null. @@ -255,14 +254,14 @@ public class ProjectHelperImpl2 extends ProjectHelper { /** * Called when this element and all elements nested into it have been - * handled. + * handled (i.e. at the ). */ public void onEndElement(String uri, String tag, AntXmlContext context) { } /** * Handles text within an element. This base implementation just - * throws an exception. + * throws an exception, you must override it if you expect content. * * @param buf A character array of the text within the element. * Will not be null. @@ -295,6 +294,9 @@ public class ProjectHelperImpl2 extends ProjectHelper { * and setting the project's base directory. */ public File buildFileParent; + + public String currentProjectName; + /** * Locator for the configuration file parser. * Used for giving locations of errors etc. @@ -313,6 +315,8 @@ public class ProjectHelperImpl2 extends ProjectHelper { */ Target implicitTarget = new Target(); + public Target currentTarget=null; + public boolean ignoreProjectTag=false; public static Hashtable importedFiles = new Hashtable(); public static int importlevel = 0; @@ -325,7 +329,7 @@ public class ProjectHelperImpl2 extends ProjectHelper { implicitTarget.setName(""); this.helper=helper; } - + /** * Scans an attribute list for the id attribute and * stores a reference to the target object in the project if an @@ -345,7 +349,6 @@ public class ProjectHelperImpl2 extends ProjectHelper { } - /** * Handler for ant processing. Uses a stack of AntHandlers to * implement each element ( the original parser used a recursive behavior, @@ -353,7 +356,7 @@ public class ProjectHelperImpl2 extends ProjectHelper { */ public static class RootHandler extends DefaultHandler { Stack antHandlers=new Stack(); - AntHandler currentHandler; + AntHandler currentHandler=null; AntXmlContext context; public RootHandler(AntXmlContext context) { @@ -430,7 +433,6 @@ public class ProjectHelperImpl2 extends ProjectHelper { { AntHandler next=currentHandler.onStartChild(uri, tag, qname, attrs, context); antHandlers.push( currentHandler ); - //System.out.println("XXX push " + currentHandler ); currentHandler=next; currentHandler.onStartElement( uri, tag, qname, attrs, context ); } @@ -460,7 +462,6 @@ public class ProjectHelperImpl2 extends ProjectHelper { public void endElement(String uri, String name, String qName) throws SAXException { currentHandler.onEndElement(uri, name, context); AntHandler prev=(AntHandler)antHandlers.pop(); - //System.out.println("XXX pop " + currentHandler + " " + prev); currentHandler=prev; } @@ -473,13 +474,6 @@ public class ProjectHelperImpl2 extends ProjectHelper { public static class MainHandler extends AntHandler { - public void onStartElement(String uri, String tag, String qname, - Attributes attrs, - AntXmlContext context) - throws SAXParseException - { - } - public AntHandler onStartChild(String uri, String name, String qname, Attributes attrs, AntXmlContext context) @@ -519,53 +513,54 @@ public class ProjectHelperImpl2 extends ProjectHelper { AntXmlContext context) throws SAXParseException { - String def = null; - String name = null; String id = null; String baseDir = null; - if (! qname.equals("project")) { - throw new SAXParseException("Config file is not of expected XML type", context.locator); - } - - if( context.ignoreProjectTag ) { - return; - } + Project project=context.project; + for (int i = 0; i < attrs.getLength(); i++) { String key = attrs.getQName(i); String value = attrs.getValue(i); if (key.equals("default")) { - def = value; + if ( value != null && !value.equals("")) { + if( !context.ignoreProjectTag ) + project.setDefaultTarget(value); + } } else if (key.equals("name")) { - name = value; + if (value != null) { + context.currentProjectName=value; + + if( !context.ignoreProjectTag ) { + project.setName(value); + project.addReference(value, project); + } + } } else if (key.equals("id")) { - id = value; + if (value != null) { + // What's the difference between id and name ? + if( !context.ignoreProjectTag ) { + project.addReference(value, project); + } + } } else if (key.equals("basedir")) { - baseDir = value; + if( !context.ignoreProjectTag ) + baseDir = value; } else { + // XXX ignore attributes in a different NS ( maybe store them ? ) throw new SAXParseException("Unexpected attribute \"" + attrs.getQName(i) + "\"", context.locator); } } - Project project=context.project; - - if (def != null && !def.equals("")) { - project.setDefaultTarget(def); - } - - if (name != null) { - project.setName(name); - project.addReference(name, project); - } - - if (id != null) { - project.addReference(id, project); + if( context.ignoreProjectTag ) { + // no further processing + return; } - + // set explicitely before starting ? if (project.getProperty("basedir") != null) { project.setBasedir(project.getProperty("basedir")); } else { + // Default for baseDir is the location of the build file. if (baseDir == null) { project.setBasedir(context.buildFileParent.getAbsolutePath()); } else { @@ -578,7 +573,9 @@ public class ProjectHelperImpl2 extends ProjectHelper { } } } + project.addTarget("", context.implicitTarget); + context.currentTarget=context.implicitTarget; } /** @@ -601,18 +598,11 @@ public class ProjectHelperImpl2 extends ProjectHelper { AntXmlContext context) throws SAXParseException { -// if (qname.equals("import")) { -// return new ImportHandler(); -// } else if (qname.equals("target")) { return new TargetHandler(); - } else if (context.project.getDataTypeDefinitions().get(qname) != null) { - return new DataTypeHandler(context.implicitTarget); - } else if (context.project.getTaskDefinitions().get(qname) != null) { - return new TaskHandler(context.implicitTarget,null,context.implicitTarget); } else { - throw new SAXParseException("Unexpected element \"" + qname + "\" " + name, context.locator); - } + return new ElementHandler(context.implicitTarget,null,context.implicitTarget); + } } } @@ -620,7 +610,6 @@ public class ProjectHelperImpl2 extends ProjectHelper { * Handler for "target" elements. */ public static class TargetHandler extends AntHandler { - private Target target; /** * Initialisation routine called after handler creation @@ -646,10 +635,10 @@ public class ProjectHelperImpl2 extends ProjectHelper { { String name = null; String depends = ""; - String ifCond = null; - String unlessCond = null; - String id = null; - String description = null; + + Project project=context.project; + Target target = new Target(); + context.currentTarget=target; for (int i = 0; i < attrs.getLength(); i++) { String key = attrs.getQName(i); @@ -662,13 +651,15 @@ public class ProjectHelperImpl2 extends ProjectHelper { } else if (key.equals("depends")) { depends = value; } else if (key.equals("if")) { - ifCond = value; + target.setIf(value); } else if (key.equals("unless")) { - unlessCond = value; + target.setUnless(value); } else if (key.equals("id")) { - id = value; + if (value != null && !value.equals("")) { + context.project.addReference(value, target); + } } else if (key.equals("description")) { - description = value; + target.setDescription(value); } else { throw new SAXParseException("Unexpected attribute \"" + key + "\"", context.locator); } @@ -678,60 +669,36 @@ public class ProjectHelperImpl2 extends ProjectHelper { throw new SAXParseException("target element appears without a name attribute", context.locator); } - Project project=context.project; - target = new Target(); - // No need - it'll be handled explicitly - // target.addDependency( "" ); - target.setName(name); - target.setIf(ifCond); - target.setUnless(unlessCond); - target.setDescription(description); - - // START IMPORT CHANGE XXX Move to Import task - int timesRedefined = 0; - Hashtable currentTargets = project.getTargets(); - //currently tracks only one level of super. - if(currentTargets.containsKey(name)){ - project.log("Defined targets: "+ - ProjectHelperImpl2.targetString( currentTargets ) ,Project.MSG_VERBOSE); - - timesRedefined++; - - project.log("Redefining target named: \""+name+"\"" ,Project.MSG_VERBOSE); - - //Adding old target as a new target with super.super[timesRedefined].super.name - Target oldTarget = (Target) currentTargets.get(name); - project.log("Current oldTarget named "+name+" is "+oldTarget.toString() ,Project.MSG_VERBOSE); - - String superTargetName = ""; - for(int i=0; i < timesRedefined; i++){ - superTargetName += "super."; + // If the name has already beend defined ( import for example ) + if(currentTargets.containsKey(name)) { + // Alter the name. + if( context.currentProjectName != null ) { + String newName=context.currentProjectName + "." + name; + project.log("Already defined in main or a previous import, define " + + name + " as " + newName, + Project.MSG_VERBOSE); + name=newName; + } else { + project.log("Already defined in main or a previous import, ignore " + + name, + Project.MSG_VERBOSE); + name=null; } - superTargetName = superTargetName + name; - oldTarget.setName(superTargetName); - - project.addTarget(superTargetName, oldTarget); } - - // if the target is redefined, it redefines it, otherwise just adds it - project.addOrReplaceTarget(name, target); - project.log("Targets are now: "+ - ProjectHelperImpl2.targetString(currentTargets) , - Project.MSG_VERBOSE); + if( name != null ) { + target.setName(name); + project.addOrReplaceTarget(name, target); + } - // END IMPORT CHANGE - // context.project.addTarget(name, target); - if (id != null && !id.equals("")) { - context.project.addReference(id, target); - } + project.log("Targets are now: "+ currentTargets , + Project.MSG_VERBOSE); // take care of dependencies - if (depends.length() > 0) { target.setDepends(depends); } @@ -753,58 +720,44 @@ public class ProjectHelperImpl2 extends ProjectHelper { AntXmlContext context) throws SAXParseException { - if (context.project.getDataTypeDefinitions().get(qname) != null) { - return new DataTypeHandler(target); - } else { - return new TaskHandler(target, null, target); - } + return new ElementHandler(context.currentTarget, null, context.currentTarget); } - } - - private static String targetString(Hashtable currentTargets) { - Enumeration enum=currentTargets.keys(); - StringBuffer sb=new StringBuffer(); - while( enum.hasMoreElements() ) { - String tname=(String)enum.nextElement(); - Target t=(Target)currentTargets.get( tname ); - sb.append( "|" ).append(tname ); - Enumeration enum2=t.getDependencies(); - if( enum2.hasMoreElements() ) sb.append( "=" ); - while(enum2.hasMoreElements() ) { - sb.append(enum2.nextElement()); - if( enum2.hasMoreElements()) sb.append(","); - } + public void onEndElement(String uri, String tag, AntXmlContext context) { + context.currentTarget=context.implicitTarget; } - return sb.toString(); } - + /** - * Handler for all task elements. + * Handler for all project elements ( tasks, data types ) */ - public static class TaskHandler extends AntHandler { + public static class ElementHandler extends AntHandler { /** Containing target, if any. */ - private Target target; + protected Target target; + /** * Container for the task, if any. If target is * non-null, this must be too. */ - private TaskContainer container; + protected TaskContainer container; + /** - * Task created by this handler. + * element created by this handler. */ - private Task task; + protected Object element; + /** * Wrapper for the parent element, if any. The wrapper for this * element will be added to this wrapper as a child. */ - private RuntimeConfigurable2 parentWrapper; + protected RuntimeConfigurable2 parentWrapper; + /** * Wrapper for this element which takes care of actually configuring * the element, if this element is contained within a target. * Otherwise the configuration is performed with the configure method. * @see ProjectHelper#configure(Object,Attributes,Project) */ - private RuntimeConfigurable2 wrapper = null; + protected RuntimeConfigurable2 wrapper = null; /** * Constructor. @@ -822,7 +775,7 @@ public class ProjectHelperImpl2 extends ProjectHelper { * @param target Target this element is part of. * Must not be null. */ - public TaskHandler(TaskContainer container, RuntimeConfigurable2 parentWrapper, Target target) { + public ElementHandler(TaskContainer container, RuntimeConfigurable2 parentWrapper, Target target) { this.container = container; this.parentWrapper = parentWrapper; this.target = target; @@ -849,34 +802,52 @@ public class ProjectHelperImpl2 extends ProjectHelper { AntXmlContext context) throws SAXParseException { - try { - task = context.project.createTask(qname); - } catch (BuildException e) { - // swallow here, will be thrown again in - // UnknownElement.maybeConfigure if the problem persists. - } - - if (task == null) { - task = new UnknownElement(qname); - task.setProject(context.project); - //XXX task.setTaskType(qname); - task.setTaskName(qname); - } + if (context.project.getDataTypeDefinitions().get(qname) != null) { + try { + element = context.project.createDataType(qname); + if (element == null) { + throw new BuildException("Unknown data type "+qname); + } + + wrapper = new RuntimeConfigurable2(element, qname); + wrapper.setAttributes2(attrs); + target.addDataType(wrapper); + } catch (BuildException exc) { + throw new SAXParseException(exc.getMessage(), context.locator, exc); + } + } else { + Task task=null; + try { + task = context.project.createTask(qname); + } catch (BuildException e) { + // swallow here, will be thrown again in + // UnknownElement.maybeConfigure if the problem persists. + } - task.setLocation(new Location(context.locator.getSystemId(), - context.locator.getLineNumber(), - context.locator.getColumnNumber())); - context.configureId(task, attrs); + if (task == null) { + task = new UnknownElement(qname); + task.setProject(context.project); + //XXX task.setTaskType(qname); + task.setTaskName(qname); + } + element=task; + task.setLocation(new Location(context.locator.getSystemId(), + context.locator.getLineNumber(), + context.locator.getColumnNumber())); + context.configureId(task, attrs); + task.setOwningTarget(target); container.addTask(task); task.init(); - //wrapper = task.getRuntimeConfigurableWrapper(); + wrapper=new RuntimeConfigurable2(task, task.getTaskName()); wrapper.setAttributes2(attrs); + if (parentWrapper != null) { parentWrapper.addChild(wrapper); } + } } @@ -917,12 +888,12 @@ public class ProjectHelperImpl2 extends ProjectHelper { AntXmlContext context) throws SAXParseException { - if (task instanceof TaskContainer) { + if (element instanceof TaskContainer) { // task can contain other tasks - no other nested elements possible - return new TaskHandler((TaskContainer)task, wrapper, target); + return new ElementHandler((TaskContainer)element, wrapper, target); } else { - return new NestedElementHandler(task, wrapper, target); + return new NestedElementHandler(element, wrapper, target); } } } @@ -930,25 +901,9 @@ public class ProjectHelperImpl2 extends ProjectHelper { /** * Handler for all nested properties. */ - public static class NestedElementHandler extends AntHandler { + public static class NestedElementHandler extends ElementHandler { /** Parent object (task/data type/etc). */ private Object parent; - /** The nested element itself. */ - private Object child; - /** - * Wrapper for the parent element, if any. The wrapper for this - * element will be added to this wrapper as a child. - */ - private RuntimeConfigurable2 parentWrapper; - /** - * Wrapper for this element which takes care of actually configuring - * the element, if a parent wrapper is provided. - * Otherwise the configuration is performed with the configure method. - * @see ProjectHelper#configure(Object,Attributes,Project) - */ - private RuntimeConfigurable2 childWrapper = null; - /** Target this element is part of, if any. */ - private Target target; /** * Constructor. @@ -969,13 +924,12 @@ public class ProjectHelperImpl2 extends ProjectHelper { public NestedElementHandler(Object parent, RuntimeConfigurable2 parentWrapper, Target target) { + super(null, parentWrapper, target); if (parent instanceof TaskAdapter) { this.parent = ((TaskAdapter) parent).getProxy(); } else { this.parent = parent; } - this.parentWrapper = parentWrapper; - this.target = target; } /** @@ -999,9 +953,6 @@ public class ProjectHelperImpl2 extends ProjectHelper { AntXmlContext context) throws SAXParseException { - Class parentClass = parent.getClass(); - IntrospectionHelper ih = - IntrospectionHelper.getHelper(parentClass); try { String elementName = qname.toLowerCase(Locale.US); @@ -1009,168 +960,22 @@ public class ProjectHelperImpl2 extends ProjectHelper { UnknownElement uc = new UnknownElement(elementName); uc.setProject(context.project); ((UnknownElement) parent).addChild(uc); - child = uc; + element = uc; } else { - child = ih.createElement(context.project, parent, elementName); + Class parentClass = parent.getClass(); + IntrospectionHelper ih = + IntrospectionHelper.getHelper(parentClass); + element = ih.createElement(context.project, parent, elementName); } - context.configureId(child, attrs); - - childWrapper = new RuntimeConfigurable2(child, qname); - childWrapper.setAttributes2(attrs); - parentWrapper.addChild(childWrapper); - } catch (BuildException exc) { - throw new SAXParseException(exc.getMessage(), context.locator, exc); - } - } - - /** - * Adds text to the element, using the wrapper if one is - * available or using addText otherwise. - * - * @param buf A character array of the text within the element. - * Will not be null. - * @param start The start element in the array. - * @param count The number of characters to read from the array. - * - * @exception SAXParseException if the element doesn't support text - * - * @see ProjectHelper#addText(Project,Object,char[],int,int) - */ - public void characters(char[] buf, int start, int count, - AntXmlContext context) - throws SAXParseException - { - childWrapper.addText(buf, start, count); - } - - /** - * Handles the start of an element within this one. Task containers - * will always use a task handler, and all other elements - * will always use another nested element handler. - * - * @param tag The name of the element being started. - * Will not be null. - * @param attrs Attributes of the element being started. - * Will not be null. - * - * @exception SAXParseException if an error occurs when initialising - * the appropriate child handler - */ - public AntHandler onStartChild(String uri, String tag, String qname, - Attributes attrs, - AntXmlContext context) - throws SAXParseException - { - if (child instanceof TaskContainer) { - // taskcontainer nested element can contain other tasks - no other - // nested elements possible - return new TaskHandler((TaskContainer)child, childWrapper, target); - } - else { - return new NestedElementHandler(child, childWrapper, target); - } - } - } - - /** - * Handler for all data types directly subordinate to project or target. - */ - public static class DataTypeHandler extends AntHandler { - /** Parent target, if any. */ - private Target target; - /** The element being configured. */ - private Object element; - /** Wrapper for this element, if it's part of a target. */ - private RuntimeConfigurable2 wrapper = null; - - /** - * Constructor with a target specified. - * - * @param target The parent target of this element. - * May be null. - */ - public DataTypeHandler( Target target) { - this.target = target; - } + context.configureId(element, attrs); - /** - * Initialisation routine called after handler creation - * with the element name and attributes. This configures - * the element with its attributes and sets it up with - * its parent container (if any). Nested elements are then - * added later as the parser encounters them. - * - * @param tag Name of the element which caused this handler - * to be created. Must not be null. - * - * @param attrs Attributes of the element which caused this - * handler to be created. Must not be null. - * - * @exception SAXParseException in case of error, such as a - * BuildException being thrown during configuration. - */ - public void onStartElement(String uri, String propType, String qname, - Attributes attrs, - AntXmlContext context) - throws SAXParseException - { - try { - element = context.project.createDataType(qname); - if (element == null) { - throw new BuildException("Unknown data type "+qname); - } - - wrapper = new RuntimeConfigurable2(element, qname); - wrapper.setAttributes2(attrs); - target.addDataType(wrapper); - } catch (BuildException exc) { - throw new SAXParseException(exc.getMessage(), context.locator, exc); - } - } - - // XXX: (Jon Skeet) Any reason why this doesn't use the wrapper - // if one is available, whereas NestedElementHandler.characters does? - /** - * Adds text to the element. - * - * @param buf A character array of the text within the element. - * Will not be null. - * @param start The start element in the array. - * @param count The number of characters to read from the array. - * - * @exception SAXParseException if the element doesn't support text - * - * @see ProjectHelper#addText(Project,Object,char[],int,int) - */ - public void characters(char[] buf, int start, int count, - AntXmlContext context) - throws SAXParseException - { - try { - ProjectHelper.addText(context.project, element, buf, start, count); + wrapper = new RuntimeConfigurable2(element, qname); + wrapper.setAttributes2(attrs); + parentWrapper.addChild(wrapper); } catch (BuildException exc) { throw new SAXParseException(exc.getMessage(), context.locator, exc); } } - - /** - * Handles the start of an element within this one. - * This will always use a nested element handler. - * - * @param tag The name of the element being started. - * Will not be null. - * @param attrs Attributes of the element being started. - * Will not be null. - * - * @exception SAXParseException if an error occurs when initialising - * the child handler - */ - public AntHandler onStartChild(String uri, String tag, String qname, - Attributes attrs, AntXmlContext context) - throws SAXParseException - { - return new NestedElementHandler(element, wrapper, target); - } } }