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>
<current:if>
<current:isallowed test="${action}"/>
<then>
<do/>
</then>
<current:then>
<current:do/>
</current:then>
</current:if>
</sequential>
</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;
}

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
* 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.
*
* @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
* create and store and instance of a subelement.
* @param elementName Name of the element to create an instance of.
@@ -699,8 +746,9 @@ public final class IntrospectionHelper implements BuildListener {
*/

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

@@ -718,6 +766,26 @@ public final class IntrospectionHelper implements BuildListener {
|| 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
* 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
*/
public static String extractUriFromComponentName(String componentName) {
if (componentName == null) {
return "";
}
int index = componentName.lastIndexOf(':');
if (index == -1) {
return "";
}
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.


+ 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
*/
protected String getTaskType() {
public String getTaskType() {
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.
*/
protected void handleChildren(Object parent,
RuntimeConfigurable parentWrapper)
protected void handleChildren(
Object parent,
RuntimeConfigurable parentWrapper)
throws BuildException {
if (parent instanceof TypeAdapter) {
parent = ((TypeAdapter) parent).getProxy();
}

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

@@ -352,8 +354,8 @@ public class UnknownElement extends Task {
for (int i = 0; it.hasNext(); i++) {
RuntimeConfigurable childWrapper = parentWrapper.getChild(i);
UnknownElement child = (UnknownElement) it.next();
if (!handleChild(ih, parent, child,
childWrapper)) {
if (!handleChild(
parentUri, ih, parent, child, childWrapper)) {
if (!(parent instanceof TaskContainer)) {
ih.throwNotSupported(getProject(), parent,
child.getTag());
@@ -548,14 +550,16 @@ public class UnknownElement extends Task {
*
* @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(
child.getNamespace(), child.getTag());
if (ih.supportsNestedElement(childName)) {
if (ih.supportsNestedElement(parentUri, childName)) {
IntrospectionHelper.Creator creator =
ih.getElementCreator(getProject(), parent, childName);
ih.getElementCreator(getProject(), parentUri, parent, childName);
creator.setPolyType(childWrapper.getPolyType());
Object realChild = creator.create();
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);
task.setProject(context.getProject());
task.setNamespace(uri);
//XXX task.setTaskType(qname);
task.setQName(qname);
task.setTaskType(
ProjectHelper.genComponentName(task.getNamespace(), tag));
task.setTaskName(qname);

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 {
private MacroDef macroDef;
private Map map = new HashMap();
private Map elements = new HashMap();
private Map nsElements = null;
private Map presentElements = new HashMap();
private Hashtable localProperties = new Hashtable();

/**
* Called from MacroDef.MyAntTypeDefinition#create()
@@ -114,17 +116,33 @@ public class MacroInstance extends Task implements DynamicConfigurator {
* has already been seen
*/
public Object createDynamicElement(String name) throws BuildException {
if (macroDef.getElements().get(name) == null) {
if (getNsElements().get(name) == null) {
throw new BuildException("unsupported element " + name);
}
if (elements.get(name) != null) {
if (presentElements.get(name) != null) {
throw new BuildException("Element " + name + " already present");
}
Element ret = new Element();
elements.put(name, ret);
presentElements.put(name, 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
*/
@@ -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) {
StringBuffer ret = new StringBuffer();
StringBuffer macroName = new StringBuffer();
StringBuffer macroName = null;
boolean inMacro = false;
int state = STATE_NORMAL;
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 value = (String) macroMapping.get(name);
if (value == null) {
@@ -167,16 +205,23 @@ public class MacroInstance extends Task implements DynamicConfigurator {
} else {
ret.append(value);
}
macroName = new StringBuffer();
inMacro = false;
macroName = null;
} else {
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();
}
@@ -212,15 +257,15 @@ public class MacroInstance extends Task implements DynamicConfigurator {
while (e.hasMoreElements()) {
RuntimeConfigurable r = (RuntimeConfigurable) e.nextElement();
UnknownElement unknownElement = (UnknownElement) r.getProxy();
String tag = unknownElement.getTag();
String tag = unknownElement.getTaskType();
MacroDef.TemplateElement templateElement =
(MacroDef.TemplateElement) macroDef.getElements().get(tag);
(MacroDef.TemplateElement) getNsElements().get(tag);
if (templateElement == null) {
UnknownElement child = copy(unknownElement);
rc.addChild(child.getWrapper());
ret.addChild(child);
} else {
Element element = (Element) elements.get(tag);
Element element = (Element) presentElements.get(tag);
if (element == null) {
if (!templateElement.isOptional()) {
throw new BuildException(


Loading…
Cancel
Save