Browse Source

Implement namespace uri scoping

nested elements of types/tasks use the same NS uri as the task/type.
also cleanup macrodef attribute handling


git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@275639 13f79535-47bb-0310-9956-ffa450edef68
master
Peter Reilly 21 years ago
parent
commit
9931a12c72
7 changed files with 171 additions and 36 deletions
  1. +3
    -3
      docs/manual/CoreTypes/antlib.html
  2. +70
    -2
      src/main/org/apache/tools/ant/IntrospectionHelper.java
  3. +17
    -0
      src/main/org/apache/tools/ant/ProjectHelper.java
  4. +1
    -1
      src/main/org/apache/tools/ant/Task.java
  5. +13
    -9
      src/main/org/apache/tools/ant/UnknownElement.java
  6. +2
    -1
      src/main/org/apache/tools/ant/helper/ProjectHelper2.java
  7. +65
    -20
      src/main/org/apache/tools/ant/taskdefs/MacroInstance.java

+ 3
- 3
docs/manual/CoreTypes/antlib.html View File

@@ -133,9 +133,9 @@
<sequential> <sequential>
<current:if> <current:if>
<current:isallowed test="${action}"/> <current:isallowed test="${action}"/>
<then>
<do/>
</then>
<current:then>
<current:do/>
</current:then>
</current:if> </current:if>
</sequential> </sequential>
</macrodef> </macrodef>


+ 70
- 2
src/main/org/apache/tools/ant/IntrospectionHelper.java View File

@@ -642,6 +642,52 @@ public final class IntrospectionHelper implements BuildListener {
return nc; return nc;
} }


private NestedCreator getNestedCreator(
Project project, String parentUri, Object parent,
String elementName) throws BuildException {

String uri = ProjectHelper.extractUriFromComponentName(elementName);
String name = ProjectHelper.extractNameFromComponentName(elementName);

NestedCreator nc = null;
if (uri.equals(parentUri)) { // || uri.equals("")) {
nc = (NestedCreator) nestedCreators.get(
name.toLowerCase(Locale.US));
}
if (nc == null) {
nc = createAddTypeCreator(project, parent, elementName);
}
if (nc == null && parent instanceof DynamicConfigurator) {
DynamicConfigurator dc = (DynamicConfigurator) parent;
final Object nestedElement = dc.createDynamicElement(elementName);
if (nestedElement != null) {
nc = new NestedCreator() {
public boolean isPolyMorphic() {
return false;
}
public Class getElementClass() {
return null;
}

public Object getRealObject() {
return null;
}

public Object create(
Project project, Object parent, Object ignore) {
return nestedElement;
}
public void store(Object parent, Object child) {
}
};
}
}
if (nc == null) {
throwNotSupported(project, parent, elementName);
}
return nc;
}

/** /**
* Creates a named nested element. Depending on the results of the * Creates a named nested element. Depending on the results of the
* initial introspection, either a method in the given parent instance * initial introspection, either a method in the given parent instance
@@ -692,6 +738,7 @@ public final class IntrospectionHelper implements BuildListener {
* for an element of a parent. * for an element of a parent.
* *
* @param project Project to which the parent object belongs. * @param project Project to which the parent object belongs.
* @param parentUri The namespace uri of the parent object.
* @param parent Parent object used to create the creator object to * @param parent Parent object used to create the creator object to
* create and store and instance of a subelement. * create and store and instance of a subelement.
* @param elementName Name of the element to create an instance of. * @param elementName Name of the element to create an instance of.
@@ -699,8 +746,9 @@ public final class IntrospectionHelper implements BuildListener {
*/ */


public Creator getElementCreator( public Creator getElementCreator(
Project project, Object parent, String elementName) {
NestedCreator nc = getNestedCreator(project, parent, elementName);
Project project, String parentUri, Object parent, String elementName) {
NestedCreator nc = getNestedCreator(
project, parentUri, parent, elementName);
return new Creator(project, parent, nc); return new Creator(project, parent, nc);
} }


@@ -718,6 +766,26 @@ public final class IntrospectionHelper implements BuildListener {
|| addTypeMethods.size() != 0; || addTypeMethods.size() != 0;
} }


/**
* Indicate if this element supports a nested element of the
* given name.
*
* @param parentUri the uri of the parent
* @param elementName the name of the nested element being checked
*
* @return true if the given nested element is supported
*/
public boolean supportsNestedElement(String parentUri, String elementName) {
String uri = ProjectHelper.extractUriFromComponentName(elementName);
String name = ProjectHelper.extractNameFromComponentName(elementName);

return (
nestedCreators.containsKey(name.toLowerCase(Locale.US))
&& (uri.equals(parentUri))) // || uri.equals("")))
|| DynamicConfigurator.class.isAssignableFrom(bean)
|| addTypeMethods.size() != 0;
}

/** /**
* Stores a named nested element using a storage method determined * Stores a named nested element using a storage method determined
* by the initial introspection. If no appropriate storage method * by the initial introspection. If no appropriate storage method


+ 17
- 0
src/main/org/apache/tools/ant/ProjectHelper.java View File

@@ -525,12 +525,29 @@ public class ProjectHelper {
* @return The uri or "" if not present * @return The uri or "" if not present
*/ */
public static String extractUriFromComponentName(String componentName) { public static String extractUriFromComponentName(String componentName) {
if (componentName == null) {
return "";
}
int index = componentName.lastIndexOf(':'); int index = componentName.lastIndexOf(':');
if (index == -1) { if (index == -1) {
return ""; return "";
} }
return componentName.substring(0, index); return componentName.substring(0, index);
} }
/**
* extract the element name from a component name
*
* @param componentName The stringified form for {uri, name}
* @return The element name of the component
*/
public static String extractNameFromComponentName(String componentName) {
int index = componentName.lastIndexOf(':');
if (index == -1) {
return componentName;
}
return componentName.substring(index+1);
}


/** /**
* Add location to build exception. * Add location to build exception.


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

@@ -493,7 +493,7 @@ public abstract class Task extends ProjectComponent {
* *
* @return the type of task * @return the type of task
*/ */
protected String getTaskType() {
public String getTaskType() {
return taskType; return taskType;
} }




+ 13
- 9
src/main/org/apache/tools/ant/UnknownElement.java View File

@@ -336,13 +336,15 @@ public class UnknownElement extends Task {
* *
* @exception BuildException if the children cannot be configured. * @exception BuildException if the children cannot be configured.
*/ */
protected void handleChildren(Object parent,
RuntimeConfigurable parentWrapper)
protected void handleChildren(
Object parent,
RuntimeConfigurable parentWrapper)
throws BuildException { throws BuildException {
if (parent instanceof TypeAdapter) { if (parent instanceof TypeAdapter) {
parent = ((TypeAdapter) parent).getProxy(); parent = ((TypeAdapter) parent).getProxy();
} }


String parentUri = getNamespace();
Class parentClass = parent.getClass(); Class parentClass = parent.getClass();
IntrospectionHelper ih = IntrospectionHelper.getHelper(parentClass); IntrospectionHelper ih = IntrospectionHelper.getHelper(parentClass);


@@ -352,8 +354,8 @@ public class UnknownElement extends Task {
for (int i = 0; it.hasNext(); i++) { for (int i = 0; it.hasNext(); i++) {
RuntimeConfigurable childWrapper = parentWrapper.getChild(i); RuntimeConfigurable childWrapper = parentWrapper.getChild(i);
UnknownElement child = (UnknownElement) it.next(); UnknownElement child = (UnknownElement) it.next();
if (!handleChild(ih, parent, child,
childWrapper)) {
if (!handleChild(
parentUri, ih, parent, child, childWrapper)) {
if (!(parent instanceof TaskContainer)) { if (!(parent instanceof TaskContainer)) {
ih.throwNotSupported(getProject(), parent, ih.throwNotSupported(getProject(), parent,
child.getTag()); child.getTag());
@@ -548,14 +550,16 @@ public class UnknownElement extends Task {
* *
* @return whether the creation has been successful * @return whether the creation has been successful
*/ */
private boolean handleChild(IntrospectionHelper ih,
Object parent, UnknownElement child,
RuntimeConfigurable childWrapper) {
private boolean handleChild(
String parentUri,
IntrospectionHelper ih,
Object parent, UnknownElement child,
RuntimeConfigurable childWrapper) {
String childName = ProjectHelper.genComponentName( String childName = ProjectHelper.genComponentName(
child.getNamespace(), child.getTag()); child.getNamespace(), child.getTag());
if (ih.supportsNestedElement(childName)) {
if (ih.supportsNestedElement(parentUri, childName)) {
IntrospectionHelper.Creator creator = IntrospectionHelper.Creator creator =
ih.getElementCreator(getProject(), parent, childName);
ih.getElementCreator(getProject(), parentUri, parent, childName);
creator.setPolyType(childWrapper.getPolyType()); creator.setPolyType(childWrapper.getPolyType());
Object realChild = creator.create(); Object realChild = creator.create();
if (realChild instanceof PreSetDef.PreSetDefinition) { if (realChild instanceof PreSetDef.PreSetDefinition) {


+ 2
- 1
src/main/org/apache/tools/ant/helper/ProjectHelper2.java View File

@@ -939,8 +939,9 @@ public class ProjectHelper2 extends ProjectHelper {
UnknownElement task = new UnknownElement(tag); UnknownElement task = new UnknownElement(tag);
task.setProject(context.getProject()); task.setProject(context.getProject());
task.setNamespace(uri); task.setNamespace(uri);
//XXX task.setTaskType(qname);
task.setQName(qname); task.setQName(qname);
task.setTaskType(
ProjectHelper.genComponentName(task.getNamespace(), tag));
task.setTaskName(qname); task.setTaskName(qname);


Location location = new Location(context.getLocator().getSystemId(), Location location = new Location(context.getLocator().getSystemId(),


+ 65
- 20
src/main/org/apache/tools/ant/taskdefs/MacroInstance.java View File

@@ -84,8 +84,10 @@ import org.apache.tools.ant.UnknownElement;
public class MacroInstance extends Task implements DynamicConfigurator { public class MacroInstance extends Task implements DynamicConfigurator {
private MacroDef macroDef; private MacroDef macroDef;
private Map map = new HashMap(); private Map map = new HashMap();
private Map elements = new HashMap();
private Map nsElements = null;
private Map presentElements = new HashMap();
private Hashtable localProperties = new Hashtable(); private Hashtable localProperties = new Hashtable();


/** /**
* Called from MacroDef.MyAntTypeDefinition#create() * Called from MacroDef.MyAntTypeDefinition#create()
@@ -114,17 +116,33 @@ public class MacroInstance extends Task implements DynamicConfigurator {
* has already been seen * has already been seen
*/ */
public Object createDynamicElement(String name) throws BuildException { public Object createDynamicElement(String name) throws BuildException {
if (macroDef.getElements().get(name) == null) {
if (getNsElements().get(name) == null) {
throw new BuildException("unsupported element " + name); throw new BuildException("unsupported element " + name);
} }
if (elements.get(name) != null) {
if (presentElements.get(name) != null) {
throw new BuildException("Element " + name + " already present"); throw new BuildException("Element " + name + " already present");
} }
Element ret = new Element(); Element ret = new Element();
elements.put(name, ret);
presentElements.put(name, ret);
return ret; return ret;
} }


private Map getNsElements() {
if (nsElements == null) {
nsElements = new HashMap();
String myUri = ProjectHelper.extractUriFromComponentName(
getTaskType());
for (Iterator i = macroDef.getElements().entrySet().iterator();
i.hasNext();) {
Map.Entry entry = (Map.Entry) i.next();
nsElements.put(ProjectHelper.genComponentName(
myUri, (String) entry.getKey()),
entry.getValue());
}
}
return nsElements;
}
/** /**
* Embedded element in macro instance * Embedded element in macro instance
*/ */
@@ -148,18 +166,38 @@ public class MacroInstance extends Task implements DynamicConfigurator {
} }
} }


private static final int STATE_NORMAL = 0;
private static final int STATE_EXPECT_BRACKET = 1;
private static final int STATE_EXPECT_NAME = 2;
private String macroSubs(String s, Map macroMapping) { private String macroSubs(String s, Map macroMapping) {
StringBuffer ret = new StringBuffer(); StringBuffer ret = new StringBuffer();
StringBuffer macroName = new StringBuffer();
StringBuffer macroName = null;
boolean inMacro = false; boolean inMacro = false;
int state = STATE_NORMAL;
for (int i = 0; i < s.length(); ++i) { for (int i = 0; i < s.length(); ++i) {
if (s.charAt(i) == '$') {
inMacro = true;
} else {
if (inMacro) {
if (s.charAt(i) == '{') {
continue;
} else if (s.charAt(i) == '}') {
char ch = s.charAt(i);
switch (state) {
case STATE_NORMAL:
if (ch == '$') {
state = 1;
} else {
ret.append(ch);
}
break;
case STATE_EXPECT_BRACKET:
if (ch == '{') {
state = 2;
macroName = new StringBuffer();
} else {
state = 0;
ret.append('$');
ret.append(ch);
}
break;
case STATE_EXPECT_NAME:
if (ch == '}') {
state = 0;
String name = macroName.toString(); String name = macroName.toString();
String value = (String) macroMapping.get(name); String value = (String) macroMapping.get(name);
if (value == null) { if (value == null) {
@@ -167,16 +205,23 @@ public class MacroInstance extends Task implements DynamicConfigurator {
} else { } else {
ret.append(value); ret.append(value);
} }
macroName = new StringBuffer();
inMacro = false;
macroName = null;
} else { } else {
macroName.append(s.charAt(i)); macroName.append(s.charAt(i));
} }
} else {
ret.append(s.charAt(i));
}
} }
} }
switch (state) {
case STATE_NORMAL:
break;
case STATE_EXPECT_BRACKET:
ret.append('$');
break;
case STATE_EXPECT_NAME:
ret.append("${");
ret.append(macroName.toString());
break;
}


return ret.toString(); return ret.toString();
} }
@@ -212,15 +257,15 @@ public class MacroInstance extends Task implements DynamicConfigurator {
while (e.hasMoreElements()) { while (e.hasMoreElements()) {
RuntimeConfigurable r = (RuntimeConfigurable) e.nextElement(); RuntimeConfigurable r = (RuntimeConfigurable) e.nextElement();
UnknownElement unknownElement = (UnknownElement) r.getProxy(); UnknownElement unknownElement = (UnknownElement) r.getProxy();
String tag = unknownElement.getTag();
String tag = unknownElement.getTaskType();
MacroDef.TemplateElement templateElement = MacroDef.TemplateElement templateElement =
(MacroDef.TemplateElement) macroDef.getElements().get(tag);
(MacroDef.TemplateElement) getNsElements().get(tag);
if (templateElement == null) { if (templateElement == null) {
UnknownElement child = copy(unknownElement); UnknownElement child = copy(unknownElement);
rc.addChild(child.getWrapper()); rc.addChild(child.getWrapper());
ret.addChild(child); ret.addChild(child);
} else { } else {
Element element = (Element) elements.get(tag);
Element element = (Element) presentElements.get(tag);
if (element == null) { if (element == null) {
if (!templateElement.isOptional()) { if (!templateElement.isOptional()) {
throw new BuildException( throw new BuildException(


Loading…
Cancel
Save