You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@ant.apache.org by mb...@apache.org on 2010/04/12 20:24:10 UTC

svn commit: r933350 - /ant/core/trunk/src/main/org/apache/tools/ant/RuntimeConfigurable.java

Author: mbenson
Date: Mon Apr 12 18:24:10 2010
New Revision: 933350

URL: http://svn.apache.org/viewvc?rev=933350&view=rev
Log:
Now that we are on Java 1.4, track RuntimeConfigurable attributes using
a LinkedHashMap instead of List/Map combination.  Priority of 'refid' preserved;
bug whereby setting an attribute multiple times would add it multiple times
to the attribute names list is also corrected.

Modified:
    ant/core/trunk/src/main/org/apache/tools/ant/RuntimeConfigurable.java

Modified: ant/core/trunk/src/main/org/apache/tools/ant/RuntimeConfigurable.java
URL: http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/ant/RuntimeConfigurable.java?rev=933350&r1=933349&r2=933350&view=diff
==============================================================================
--- ant/core/trunk/src/main/org/apache/tools/ant/RuntimeConfigurable.java (original)
+++ ant/core/trunk/src/main/org/apache/tools/ant/RuntimeConfigurable.java Mon Apr 12 18:24:10 2010
@@ -22,8 +22,8 @@ import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Enumeration;
-import java.util.HashMap;
 import java.util.Hashtable;
+import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Iterator;
@@ -36,7 +36,6 @@ import org.xml.sax.helpers.AttributeList
  * Wrapper class that holds the attributes of an element, its children, and
  * any text within it. It then takes care of configuring that element at
  * runtime.
- *
  */
 public class RuntimeConfigurable implements Serializable {
 
@@ -65,22 +64,15 @@ public class RuntimeConfigurable impleme
 
     /** Attribute names and values. While the XML spec doesn't require
      *  preserving the order ( AFAIK ), some ant tests do rely on the
-     *  exact order. The following code is copied from AttributeImpl.
-     *  We could also just use SAX2 Attributes and convert to SAX1 ( DOM
-     *  attribute Nodes can also be stored in SAX2 Attributes )
+     *  exact order. 
      * The only exception to this order is the treatment of
      * refid. A number of datatypes check if refid is set
      * when other attributes are set. This check will not
      * work if the build script has the other attribute before
      * the "refid" attribute, so now (ANT 1.7) the refid
      * attribute will be processed first.
-     * (Other than treatment of refid, could just use a LinkedHashMap,
-     * but peterreilly's rev 452635 includes no regression test.)
      */
-    private List/*<String>*/ attributeNames = null;
-
-    /** Map of attribute names to values */
-    private Map/*<String,String>*/ attributeMap = null;
+    private LinkedHashMap/*<String, String>*/ attributeMap = null;
 
     /** Text appearing within the element. */
     private StringBuffer characters = null;
@@ -187,16 +179,17 @@ public class RuntimeConfigurable impleme
         if (name.equalsIgnoreCase(ProjectHelper.ANT_TYPE)) {
             this.polyType = value;
         } else {
-            if (attributeNames == null) {
-                attributeNames = new ArrayList();
-                attributeMap = new HashMap();
+            if (attributeMap == null) {
+                attributeMap = new LinkedHashMap();
             }
-            if (name.equalsIgnoreCase("refid")) {
-                attributeNames.add(0, name);
+            if (name.equalsIgnoreCase("refid") && !attributeMap.isEmpty()) {
+                LinkedHashMap newAttributeMap = new LinkedHashMap();
+                newAttributeMap.put(name, value);
+                newAttributeMap.putAll(attributeMap);
+                attributeMap = newAttributeMap;
             } else {
-                attributeNames.add(name);
+                attributeMap.put(name, value);
             }
-            attributeMap.put(name, value);
             if (name.equals("id")) {
                 this.id = value;
             }
@@ -208,7 +201,6 @@ public class RuntimeConfigurable impleme
      * @param name the name of the attribute to be removed.
      */
     public synchronized void removeAttribute(String name) {
-        attributeNames.remove(name);
         attributeMap.remove(name);
     }
 
@@ -381,10 +373,11 @@ public class RuntimeConfigurable impleme
         IntrospectionHelper ih =
             IntrospectionHelper.getHelper(p, target.getClass());
 
-        if (attributeNames != null) {
-            for (int i = 0; i < attributeNames.size(); i++) {
-                String name = (String) attributeNames.get(i);
-                String value = (String) attributeMap.get(name);
+        if (attributeMap != null) {
+            for (Iterator iter = attributeMap.entrySet().iterator(); iter.hasNext();) {
+                Map.Entry entry = (Map.Entry) iter.next();
+                String name = (String) entry.getKey();
+                String value = (String) entry.getValue();
 
                 // reflect these into the target
                 Object attrValue = PropertyHelper.getPropertyHelper(p).parseProperties(value);
@@ -394,11 +387,11 @@ public class RuntimeConfigurable impleme
                     // id attribute must be set externally
                     if (name.equals("id")) {
                         // Do nothing
-                    } else  if (getElementTag() == null) {
+                    } else if (getElementTag() == null) {
                         throw be;
                     } else {
                         throw new BuildException(
-                            getElementTag() +  " doesn't support the \""
+                            getElementTag() + " doesn't support the \""
                             + be.getAttribute() + "\" attribute", be);
                     }
                 } catch (BuildException be) {
@@ -433,7 +426,6 @@ public class RuntimeConfigurable impleme
         maybeConfigure(p);
     }
 
-
     /**
      * Apply presets, attributes and text are set if not currently set.
      * Nested elements are prepended.