Author: peterreilly Date: Fri Aug 10 15:26:22 2007 New Revision: 564787 URL: http://svn.apache.org/viewvc?view=rev&rev=564787 Log: adding componentdef code
Added: ant/core/trunk/src/main/org/apache/tools/ant/antlib.xml ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/Componentdef.java Modified: ant/core/trunk/src/main/org/apache/tools/ant/AntTypeDefinition.java ant/core/trunk/src/main/org/apache/tools/ant/ComponentHelper.java ant/core/trunk/src/main/org/apache/tools/ant/IntrospectionHelper.java ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/Definer.java ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/condition/ConditionBase.java ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/defaults.properties Modified: ant/core/trunk/src/main/org/apache/tools/ant/AntTypeDefinition.java URL: http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/ant/AntTypeDefinition.java?view=diff&rev=564787&r1=564786&r2=564787 ============================================================================== --- ant/core/trunk/src/main/org/apache/tools/ant/AntTypeDefinition.java (original) +++ ant/core/trunk/src/main/org/apache/tools/ant/AntTypeDefinition.java Fri Aug 10 15:26:22 2007 @@ -38,6 +38,23 @@ private Class adaptToClass; private String className; private ClassLoader classLoader; + private boolean restrict = false; + + /** + * Set the restrict attribute. + * @param restrict the value to set. + */ + public void setRestrict(boolean restrict) { + this.restrict = restrict; + } + + /** + * Get the restrict attribute. + * @return the restrict attribute. + */ + public boolean isRestrict() { + return restrict; + } /** * Set the definition's name. @@ -129,7 +146,7 @@ * class and the definition class is not * assignable from the assignable class. * @param project the current project. - * @return the exposed class. + * @return the exposed class - may return null if upable to load the class */ public Class getExposedClass(Project project) { if (adaptToClass != null) { @@ -327,6 +344,7 @@ return (other != null && other.getClass() == getClass() && other.getTypeClass(project).equals(getTypeClass(project)) && other.getExposedClass(project).equals(getExposedClass(project)) + && other.restrict == restrict && other.adapterClass == adapterClass && other.adaptToClass == adaptToClass); } @@ -349,7 +367,8 @@ || !extractClassname(adapterClass).equals( extractClassname(other.adapterClass)) || !extractClassname(adaptToClass).equals( - extractClassname(other.adaptToClass))) { + extractClassname(other.adaptToClass)) + || restrict != other.restrict) { return false; } // all the names are the same: check if the class path of the loader Modified: ant/core/trunk/src/main/org/apache/tools/ant/ComponentHelper.java URL: http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/ant/ComponentHelper.java?view=diff&rev=564787&r1=564786&r2=564787 ============================================================================== --- ant/core/trunk/src/main/org/apache/tools/ant/ComponentHelper.java (original) +++ ant/core/trunk/src/main/org/apache/tools/ant/ComponentHelper.java Fri Aug 10 15:26:22 2007 @@ -33,6 +33,8 @@ import java.util.Stack; import java.util.List; import java.util.ArrayList; +import java.util.Map; +import java.util.HashMap; import org.apache.tools.ant.taskdefs.Typedef; import org.apache.tools.ant.taskdefs.Definer; @@ -56,6 +58,9 @@ * @since Ant1.6 */ public class ComponentHelper { + /** Map of component name to lists of restricted definitions */ + private Map restrictedDefinitions = new HashMap(); + /** Map from component name to anttypedefinition */ private AntTypeTable antTypeTable; @@ -123,6 +128,14 @@ // {tasks, types} private static Properties[] defaultDefinitions = new Properties[2]; + /** + * Get the project. + * @return the project owner of this helper. + */ + public Project getProject() { + return project; + } + /** * Find a project component for a specific project, creating * it if it does not exist. @@ -196,6 +209,14 @@ for (Iterator i = helper.checkedNamespaces.iterator(); i.hasNext();) { checkedNamespaces.add(i.next()); } + + // Add the restricted definitions + for (Iterator i = helper.restrictedDefinitions.entrySet().iterator(); + i.hasNext();) { + Map.Entry entry = (Map.Entry) i.next(); + restrictedDefinitions.put( + entry.getKey(), new ArrayList((List) entry.getValue())); + } } /** @@ -396,6 +417,15 @@ } /** + * This returns a list of restricted definitions for a name. + * @param componentName the name to use. + * @return the list of restricted definitions for a particular name. + */ + public List getRestrictedDefinitions(String componentName) { + return (List) restrictedDefinitions.get(componentName); + } + + /** * Adds a new datatype definition. * Attempting to override an existing definition with an * equivalent one (i.e. with the same classname) results in @@ -423,7 +453,11 @@ * @param def an <code>AntTypeDefinition</code> value. */ public void addDataTypeDefinition(AntTypeDefinition def) { - updateDataTypeDefinition(def); + if (!def.isRestrict()) { + updateDataTypeDefinition(def); + } else { + updateRestrictedDefinition(def); + } } /** @@ -605,6 +639,31 @@ boolean sameValidity = (defValid == validDefinition(old)); //must have same validity; then if they are valid they must also be the same: return sameValidity && (!defValid || def.sameDefinition(old, project)); + } + + /** + * update the restricted definition table with a new or + * modified definition. + */ + private void updateRestrictedDefinition(AntTypeDefinition def) { + String name = def.getName(); + synchronized (restrictedDefinitions) { + List list = (List) restrictedDefinitions.get(name); + if (list == null) { + list = new ArrayList(); + restrictedDefinitions.put(name, list); + } + // Check if the classname is already present and remove it + // if it is + for (Iterator i = list.iterator(); i.hasNext();) { + AntTypeDefinition current = (AntTypeDefinition) i.next(); + if (current.getClassName().equals(def.getClassName())) { + i.remove(); + break; + } + } + list.add(def); + } } /** Modified: ant/core/trunk/src/main/org/apache/tools/ant/IntrospectionHelper.java URL: http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/ant/IntrospectionHelper.java?view=diff&rev=564787&r1=564786&r2=564787 ============================================================================== --- ant/core/trunk/src/main/org/apache/tools/ant/IntrospectionHelper.java (original) +++ ant/core/trunk/src/main/org/apache/tools/ant/IntrospectionHelper.java Fri Aug 10 15:26:22 2007 @@ -1383,28 +1383,33 @@ } ComponentHelper helper = ComponentHelper.getComponentHelper(project); - Object addedObject = null; - Method addMethod = null; - Class clazz = helper.getComponentClass(elementName); - if (clazz == null) { - return null; - } - addMethod = findMatchingMethod(clazz, addTypeMethods); - if (addMethod == null) { + MethodAndObject restricted = createRestricted( + helper, elementName, addTypeMethods); + MethodAndObject topLevel = createTopLevel( + helper, elementName, addTypeMethods); + + if (restricted == null && topLevel == null) { return null; } - addedObject = helper.createComponent(elementName); - if (addedObject == null) { - return null; + + if (restricted != null && topLevel != null) { + throw new BuildException( + "ambiguous: type and component definitions for " + + elementName); } - Object rObject = addedObject; - if (addedObject instanceof PreSetDef.PreSetDefinition) { - rObject = ((PreSetDef.PreSetDefinition) addedObject).createObject(project); + + MethodAndObject methodAndObject + = restricted != null ? restricted : topLevel; + + Object rObject = methodAndObject.object; + if (methodAndObject.object instanceof PreSetDef.PreSetDefinition) { + rObject = ((PreSetDef.PreSetDefinition) methodAndObject.object) + .createObject(project); } - final Object nestedObject = addedObject; + final Object nestedObject = methodAndObject.object; final Object realObject = rObject; - - return new NestedCreator(addMethod) { + + return new NestedCreator(methodAndObject.method) { Object create(Project project, Object parent, Object ignore) throws InvocationTargetException, IllegalAccessException { if (!getMethod().getName().endsWith("Configured")) { @@ -1460,6 +1465,9 @@ * @return a matching <code>Method</code>; null if none found. */ private Method findMatchingMethod(Class paramClass, List methods) { + if (paramClass == null) { + return null; + } Class matchedClass = null; Method matchedMethod = null; @@ -1486,4 +1494,91 @@ int ends = (MAX_REPORT_NESTED_TEXT - ELLIPSIS.length()) / 2; return new StringBuffer(text).replace(ends, text.length() - ends, ELLIPSIS).toString(); } + + + private class MethodAndObject { + private Method method; + private Object object; + public MethodAndObject(Method method, Object object) { + this.method = method; + this.object = object; + } + } + + /** + * + */ + private AntTypeDefinition findRestrictedDefinition( + ComponentHelper helper, String componentName, List methods) { + AntTypeDefinition definition = null; + Class matchedDefinitionClass = null; + + List definitions = helper.getRestrictedDefinitions(componentName); + if (definitions == null) { + return null; + } + for (int i = 0; i < definitions.size(); ++i) { + AntTypeDefinition d = (AntTypeDefinition) definitions.get(i); + Class exposedClass = d.getExposedClass(helper.getProject()); + if (exposedClass == null) { + continue; + } + Method method = findMatchingMethod(exposedClass, methods); + if (method == null) { + continue; + } + if (matchedDefinitionClass != null) { + throw new BuildException( + "ambiguous: restricted definitions for " + + componentName + " " + + matchedDefinitionClass + " and " + exposedClass); + } + matchedDefinitionClass = exposedClass; + definition = d; + } + return definition; + } + + private MethodAndObject createRestricted( + ComponentHelper helper, String elementName, List addTypeMethods) { + + Project project = helper.getProject(); + + AntTypeDefinition restrictedDefinition = + findRestrictedDefinition(helper, elementName, addTypeMethods); + + if (restrictedDefinition == null) { + return null; + } + + Method addMethod = findMatchingMethod( + restrictedDefinition.getExposedClass(project), addTypeMethods); + if (addMethod == null) { + throw new BuildException( + "Ant Internal Error - contract mismatch for " + + elementName); + } + Object addedObject = restrictedDefinition.create(project); + if (addedObject == null) { + throw new BuildException( + "Failed to create object " + elementName + + " of type " + restrictedDefinition.getTypeClass(project)); + } + return new MethodAndObject(addMethod, addedObject); + } + + private MethodAndObject createTopLevel( + ComponentHelper helper, String elementName, List methods) { + Class clazz = helper.getComponentClass(elementName); + if (clazz == null) { + return null; + } + Method addMethod = findMatchingMethod(clazz, addTypeMethods); + if (addMethod == null) { + return null; + } + Object addedObject = helper.createComponent(elementName); + return new MethodAndObject(addMethod, addedObject); + } + } Added: ant/core/trunk/src/main/org/apache/tools/ant/antlib.xml URL: http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/ant/antlib.xml?view=auto&rev=564787 ============================================================================== --- ant/core/trunk/src/main/org/apache/tools/ant/antlib.xml (added) +++ ant/core/trunk/src/main/org/apache/tools/ant/antlib.xml Fri Aug 10 15:26:22 2007 @@ -0,0 +1,135 @@ +<?xml version="1.0"?> + <!-- +/* + * 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. + * + */ +--> +<antlib> + <!-- + This is the ant lib definition for ant. + Currently it only contains componentdefinitions (restricted + types that are not allowed at the top level) + - conditions, selectors and comparators + (those that are not top-level types (taskdefs or typedefs). + defined in defaults.properties of taskdefs and types + packages). + + This is currently experimental and it is most + likely that these definitions will be placed + in a Java Ant definition class. + --> + <!-- conditions --> + <componentdef name="and" onerror="ignore" + classname="org.apache.tools.ant.taskdefs.condition.And"/> + <componentdef name="contains" onerror="ignore" + classname="org.apache.tools.ant.taskdefs.condition.Contains"/> + <componentdef name="equals" onerror="ignore" + classname="org.apache.tools.ant.taskdefs.condition.Equals"/> + <componentdef name="filesmatch" onerror="ignore" + classname="org.apache.tools.ant.taskdefs.condition.FilesMatch"/> + <componentdef name="hasfreespace" onerror="ignore" + classname="org.apache.tools.ant.taskdefs.condition.HasFreeSpace"/> + <componentdef name="hasmethod" onerror="ignore" + classname="org.apache.tools.ant.taskdefs.condition.HasMethod"/> + <componentdef name="http" onerror="ignore" + classname="org.apache.tools.ant.taskdefs.condition.Http"/> + <componentdef name="isfailure" onerror="ignore" + classname="org.apache.tools.ant.taskdefs.condition.IsFailure"/> + <componentdef name="isfalse" onerror="ignore" + classname="org.apache.tools.ant.taskdefs.condition.IsFalse"/> + <componentdef name="isreachable" onerror="ignore" + classname="org.apache.tools.ant.taskdefs.condition.IsReachable"/> + <componentdef name="isreference" onerror="ignore" + classname="org.apache.tools.ant.taskdefs.condition.IsReference"/> + <componentdef name="isset" onerror="ignore" + classname="org.apache.tools.ant.taskdefs.condition.IsSet"/> + <componentdef name="issigned" onerror="ignore" + classname="org.apache.tools.ant.taskdefs.condition.IsSigned"/> + <componentdef name="istrue" onerror="ignore" + classname="org.apache.tools.ant.taskdefs.condition.IsTrue"/> + <componentdef name="matches" onerror="ignore" + classname="org.apache.tools.ant.taskdefs.condition.Matches"/> + <componentdef name="not" onerror="ignore" + classname="org.apache.tools.ant.types.resources.selectors.Not"/> + <componentdef name="or" onerror="ignore" + classname="org.apache.tools.ant.taskdefs.condition.Or"/> + <componentdef name="os" onerror="ignore" + classname="org.apache.tools.ant.taskdefs.condition.Os"/> + <componentdef name="parsersupports" onerror="ignore" + classname="org.apache.tools.ant.taskdefs.condition.ParserSupports"/> + <componentdef name="resourcecontains" onerror="ignore" + classname="org.apache.tools.ant.taskdefs.condition.ResourceContains"/> + <componentdef name="resourcesmatch" onerror="ignore" + classname="org.apache.tools.ant.taskdefs.condition.ResourcesMatch"/> + <componentdef name="socket" onerror="ignore" + classname="org.apache.tools.ant.taskdefs.condition.Socket"/> + <componentdef name="typefound" onerror="ignore" + classname="org.apache.tools.ant.taskdefs.condition.TypeFound"/> + <componentdef name="xor" onerror="ignore" + classname="org.apache.tools.ant.taskdefs.condition.Xor"/> + + <!-- selectors --> + <componentdef name="and" onerror="ignore" + classname="org.apache.tools.ant.types.resources.selectors.And" /> + <componentdef name="compare" onerror="ignore" + classname="org.apache.tools.ant.types.resources.selectors.Compare" /> + <componentdef name="contains" onerror="ignore" + classname="org.apache.tools.ant.types.selectors.ContainsSelector" /> + <componentdef name="containsregexp" onerror="ignore" + classname="org.apache.tools.ant.types.selectors.ContainsRegexpSelector" /> + <componentdef name="date" onerror="ignore" + classname="org.apache.tools.ant.types.resources.selectors.Date" /> + <componentdef name="exists" onerror="ignore" + classname="org.apache.tools.ant.types.resources.selectors.Exists" /> + <componentdef name="instanceof" onerror="ignore" + classname="org.apache.tools.ant.types.resources.selectors.InstanceOf" /> + <componentdef name="majority" onerror="ignore" + classname="org.apache.tools.ant.types.resources.selectors.Majority" /> + <componentdef name="modified" onerror="ignore" + classname="org.apache.tools.ant.types.selectors.modifiedselector.ModifiedSelector" /> + <componentdef name="name" onerror="ignore" + classname="org.apache.tools.ant.types.resources.selectors.Name" /> + <componentdef name="none" onerror="ignore" + classname="org.apache.tools.ant.types.resources.selectors.None" /> + <componentdef name="not" onerror="ignore" + classname="org.apache.tools.ant.types.resources.selectors.Not" /> + <componentdef name="or" onerror="ignore" + classname="org.apache.tools.ant.types.resources.selectors.Or" /> + <componentdef name="size" onerror="ignore" + classname="org.apache.tools.ant.types.resources.selectors.Size" /> + <componentdef name="type" onerror="ignore" + classname="org.apache.tools.ant.types.resources.selectors.Type" /> + + + <!-- comparators --> + <componentdef name="name" onerror="ignore" + classname="org.apache.tools.ant.types.resources.comparators.Name" /> + <componentdef name="size" onerror="ignore" + classname="org.apache.tools.ant.types.resources.comparators.Size" /> + <componentdef name="date" onerror="ignore" + classname="org.apache.tools.ant.types.resources.comparators.Date" /> + <componentdef name="exists" onerror="ignore" + classname="org.apache.tools.ant.types.resources.comparators.Exists" /> + <componentdef name="type" onerror="ignore" + classname="org.apache.tools.ant.types.resources.comparators.Type" /> + <componentdef name="content" onerror="ignore" + classname="org.apache.tools.ant.types.resources.comparators.Content" /> + <componentdef name="reverse" onerror="ignore" + classname="org.apache.tools.ant.types.resources.comparators.Reverse" /> + +</antlib> + Added: ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/Componentdef.java URL: http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/Componentdef.java?view=auto&rev=564787 ============================================================================== --- ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/Componentdef.java (added) +++ ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/Componentdef.java Fri Aug 10 15:26:22 2007 @@ -0,0 +1,44 @@ +/* + * 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.taskdefs; + +import org.apache.tools.ant.Task; +import org.apache.tools.ant.TaskAdapter; + +/** + * Adds a compenent definition to the current project. + * used in the current project. Two attributes are needed, the name that identifies + * this compenent uniquely, and the full name of the class ( + * including the packages) that + * implements this component.</p> + * @since Ant 1.8 + * @ant.task category="internal" + */ +public class Componentdef extends Definer { + + /** + * Default constructor. + * Creates a new ComponentDef instance. + * Sets the restrict attribute to true. + */ + + public Componentdef() { + setRestrict(true); + } +} Modified: ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/Definer.java URL: http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/Definer.java?view=diff&rev=564787&r1=564786&r2=564787 ============================================================================== --- ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/Definer.java (original) +++ ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/Definer.java Fri Aug 10 15:26:22 2007 @@ -66,6 +66,7 @@ private String classname; private File file; private String resource; + private boolean restrict = false; private int format = Format.PROPERTIES; private boolean definerSet = false; @@ -145,6 +146,16 @@ } /** + * The restrict attribute. + * If this is true, only use this definition in add(X). + * @param restrict the value to set. + */ + protected void setRestrict(boolean restrict) { + this.restrict = restrict; + } + + + /** * What to do if there is an error in loading the class. * <dl> * <li>error - throw build exception</li> @@ -597,6 +608,7 @@ def.setClass(cl); def.setAdapterClass(adapterClass); def.setAdaptToClass(adaptToClass); + def.setRestrict(restrict); def.setClassLoader(al); if (cl != null) { def.checkClass(getProject()); Modified: ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/condition/ConditionBase.java URL: http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/condition/ConditionBase.java?view=diff&rev=564787&r1=564786&r2=564787 ============================================================================== --- ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/condition/ConditionBase.java (original) +++ ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/condition/ConditionBase.java Fri Aug 10 15:26:22 2007 @@ -35,11 +35,7 @@ * * @since Ant 1.4 */ -public abstract class ConditionBase extends ProjectComponent - implements DynamicElement { - - private static final String CONDITION_ANTLIB - = "antlib:org.apache.tools.ant.types.conditions:"; +public abstract class ConditionBase extends ProjectComponent { /** * name of the component @@ -282,25 +278,6 @@ */ public void add(Condition c) { conditions.addElement(c); - } - - /** - * Create a dynamically discovered condition. Built-in conditions can - * be discovered from the org.apache.tools.ant.taskdefs.condition - * antlib. - * @param name the condition to create. - * @return the dynamic condition if found, null otherwise. - */ - public Object createDynamicElement(String name) { - Object cond = ComponentHelper.getComponentHelper(getProject()) - .createComponent(CONDITION_ANTLIB + name); - if (!(cond instanceof Condition)) { - return null; - } - log("Dynamically discovered '" + name + "' " + cond, - Project.MSG_DEBUG); - add((Condition) cond); - return cond; } } Modified: ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/defaults.properties URL: http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/defaults.properties?view=diff&rev=564787&r1=564786&r2=564787 ============================================================================== --- ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/defaults.properties (original) +++ ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/defaults.properties Fri Aug 10 15:26:22 2007 @@ -12,6 +12,7 @@ checksum=org.apache.tools.ant.taskdefs.Checksum chmod=org.apache.tools.ant.taskdefs.Chmod classloader=org.apache.tools.ant.taskdefs.Classloader +componentdef=org.apache.tools.ant.taskdefs.Componentdef concat=org.apache.tools.ant.taskdefs.Concat condition=org.apache.tools.ant.taskdefs.ConditionTask copy=org.apache.tools.ant.taskdefs.Copy --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]