Browse Source

adding componentdef code

git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@564787 13f79535-47bb-0310-9956-ffa450edef68
master
Peter Reilly 18 years ago
parent
commit
31deeb9809
8 changed files with 386 additions and 44 deletions
  1. +21
    -2
      src/main/org/apache/tools/ant/AntTypeDefinition.java
  2. +60
    -1
      src/main/org/apache/tools/ant/ComponentHelper.java
  3. +112
    -17
      src/main/org/apache/tools/ant/IntrospectionHelper.java
  4. +135
    -0
      src/main/org/apache/tools/ant/antlib.xml
  5. +44
    -0
      src/main/org/apache/tools/ant/taskdefs/Componentdef.java
  6. +12
    -0
      src/main/org/apache/tools/ant/taskdefs/Definer.java
  7. +1
    -24
      src/main/org/apache/tools/ant/taskdefs/condition/ConditionBase.java
  8. +1
    -0
      src/main/org/apache/tools/ant/taskdefs/defaults.properties

+ 21
- 2
src/main/org/apache/tools/ant/AntTypeDefinition.java View File

@@ -38,6 +38,23 @@ public class AntTypeDefinition {
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 @@ public class AntTypeDefinition {
* 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 @@ public class AntTypeDefinition {
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 @@ public class AntTypeDefinition {
|| !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


+ 60
- 1
src/main/org/apache/tools/ant/ComponentHelper.java View File

@@ -33,6 +33,8 @@ import java.util.Set;
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 @@ import org.apache.tools.ant.util.FileUtils;
* @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 @@ public class ComponentHelper {
// {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 @@ public class ComponentHelper {
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()));
}
}

/**
@@ -395,6 +416,15 @@ public class ComponentHelper {
return typeClassDefinitions;
}

/**
* 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
@@ -423,7 +453,11 @@ public class ComponentHelper {
* @param def an <code>AntTypeDefinition</code> value.
*/
public void addDataTypeDefinition(AntTypeDefinition def) {
updateDataTypeDefinition(def);
if (!def.isRestrict()) {
updateDataTypeDefinition(def);
} else {
updateRestrictedDefinition(def);
}
}

/**
@@ -607,6 +641,31 @@ public class ComponentHelper {
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);
}
}

/**
* Update the component definition table with a new or
* modified definition.


+ 112
- 17
src/main/org/apache/tools/ant/IntrospectionHelper.java View File

@@ -1383,28 +1383,33 @@ public final class IntrospectionHelper {
}
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 @@ public final class IntrospectionHelper {
* @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 @@ public final class IntrospectionHelper {
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);
}

}

+ 135
- 0
src/main/org/apache/tools/ant/antlib.xml View File

@@ -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>


+ 44
- 0
src/main/org/apache/tools/ant/taskdefs/Componentdef.java View File

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

+ 12
- 0
src/main/org/apache/tools/ant/taskdefs/Definer.java View File

@@ -66,6 +66,7 @@ public abstract class Definer extends DefBase {
private String classname;
private File file;
private String resource;
private boolean restrict = false;

private int format = Format.PROPERTIES;
private boolean definerSet = false;
@@ -144,6 +145,16 @@ public abstract class Definer extends DefBase {
}
}

/**
* 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>
@@ -597,6 +608,7 @@ public abstract class Definer extends DefBase {
def.setClass(cl);
def.setAdapterClass(adapterClass);
def.setAdaptToClass(adaptToClass);
def.setRestrict(restrict);
def.setClassLoader(al);
if (cl != null) {
def.checkClass(getProject());


+ 1
- 24
src/main/org/apache/tools/ant/taskdefs/condition/ConditionBase.java View File

@@ -35,11 +35,7 @@ import org.apache.tools.ant.taskdefs.UpToDate;
*
* @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
@@ -284,23 +280,4 @@ public abstract class ConditionBase extends ProjectComponent
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;
}

}

+ 1
- 0
src/main/org/apache/tools/ant/taskdefs/defaults.properties View File

@@ -12,6 +12,7 @@ bzip2=org.apache.tools.ant.taskdefs.BZip2
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


Loading…
Cancel
Save