ant-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Bruce Atherton <br...@callenish.com>
Subject [PATCH] Fix custom selectors within container
Date Fri, 24 May 2002 22:22:12 GMT
Ok, I've figured out what is going on with Erik's problem. Turns out it has 
nothing to do with addConfigured(). A patch is included below.

I'll go into details here so no one else runs into the same sort of 
problem. I'll submit a patch for the selector programming page soon as 
well, to document it.

When a selector requires more than one attribute or element to be set 
before it can perform some initialization (such as <custom> needing both a 
classname and a classpath before creating the object) the initialization is 
deferred to execute() time. For a selector, the only guaranteed method run 
at execute() time is isSelected(), so that seems like a good place to do 
interdependent initialization.

All the core Ant selectors validate themselves before performing their 
selections. In the case of a selector container, that means it runs the 
validation on each of the contained core selectors before it runs 
isSelected() on them. This is a good idea because selector containers can 
short circuit, so there is no guarantee that the isSelected() method will 
be called on all the contained selectors. If a validation pass didn't 
happen first, you might find a build file that worked fine for months 
suddenly declare itself invalid.

The problem turned out to be the interaction of these two designs. By 
calling the validate() method which checks for the existence of the object 
before calling isSelected() where the object is created, custom selectors 
within containers throw an "Internal Error" build exception.

Anyway, here is a patch that fixes that problem by moving the object 
creation into the validation codepath. Not ideal, but it works. The patch 
also fixes custom classpaths, and changes the default settings of <date> 
and <size> to "equal", as discussed previously.



Index: docs/manual/CoreTypes/selectors.html
===================================================================
RCS file: 
/home/cvspublic/jakarta-ant/docs/manual/CoreTypes/Attic/selectors.html,v
retrieving revision 1.1.2.1
diff -u -r1.1.2.1 selectors.html
--- docs/manual/CoreTypes/selectors.html	10 May 2002 15:40:31 -0000	1.1.2.1
+++ docs/manual/CoreTypes/selectors.html	23 May 2002 15:31:36 -0000
@@ -140,7 +140,7 @@
              <li>after - select files whose last modified date is after 
the indicated date
              <li>equal - select files  whose last modified date is this 
exact date
            </ul>
-          The default is before.
+          The default is equal.
          <td valign="top" align="center">No</td>
        </tr>
      </table>
@@ -401,7 +401,7 @@
              <li>more - select files greater than the indicated size
              <li>equal - select files this exact size
            </ul>
-          The default is less.
+          The default is equal.
          <td valign="top" align="center">No</td>
        </tr>
      </table>
@@ -607,7 +607,7 @@
  &lt;/fileset&gt;
  </pre></blockquote>

-    <p>Selects all the files in the top directory along with all the
+    <p>Selects all the files in the top directory along with all the
      image files below it.
      </p>

@@ -645,7 +645,7 @@
              &lt;/fileset&gt;
          &lt;/zip&gt;
      &lt;/target&gt;
-
+
  &lt;/project&gt;
  </pre></blockquote>

@@ -658,13 +658,13 @@
      <a name="customselect"></a>
      <h3>Custom Selectors</h3>

-    <p>You can write your own selectors and use them within the selector
+    <p>You can write your own selectors and use them within the selector
      containers by specifying them within the &lt;custom&gt; tag.</p>

      <p>First, you have to write your selector class in Java. The only
      requirement it must meet in order to be a selector is that it implements
      the <code>org.apache.tools.ant.types.selectors.FileSelector</code>
-    interface, which contains a single method. See
+    interface, which contains a single method. See
      <a href="selectors-program.html">Programming Selectors in Ant</a> for
      more information.</p>

Index: src/main/org/apache/tools/ant/types/selectors/BaseExtendSelector.java
===================================================================
RCS file: 
/home/cvspublic/jakarta-ant/src/main/org/apache/tools/ant/types/selectors/BaseExtendSelector.java,v
retrieving revision 1.1.2.1
diff -u -r1.1.2.1 BaseExtendSelector.java
--- src/main/org/apache/tools/ant/types/selectors/BaseExtendSelector.java 
20 May 2002 20:28:36 -0000	1.1.2.1
+++ src/main/org/apache/tools/ant/types/selectors/BaseExtendSelector.java 
23 May 2002 15:32:17 -0000
@@ -83,7 +83,7 @@
      }

      /**
-     * Set all the Parameters for this dynamic selector, collected by
+     * Set all the Parameters for this custom selector, collected by
       * the ExtendSelector class.
       *
       * @param parameters the complete set of parameters for this selector
Index: src/main/org/apache/tools/ant/types/selectors/BaseSelector.java
===================================================================
RCS file: 
/home/cvspublic/jakarta-ant/src/main/org/apache/tools/ant/types/selectors/BaseSelector.java,v
retrieving revision 1.1
diff -u -r1.1 BaseSelector.java
--- src/main/org/apache/tools/ant/types/selectors/BaseSelector.java	30 Apr 
2002 22:38:35 -0000	1.1
+++ src/main/org/apache/tools/ant/types/selectors/BaseSelector.java	23 May 
2002 15:32:17 -0000
@@ -118,7 +118,9 @@
       * in isSelected() in the case of an error condition.
       */
      public void validate() {
-        verifySettings();
+        if (getError() == null) {
+            verifySettings();
+        }
          if (getError() != null) {
              throw new BuildException(errmsg);
          }
Index: src/main/org/apache/tools/ant/types/selectors/ContainsSelector.java
===================================================================
RCS file: 
/home/cvspublic/jakarta-ant/src/main/org/apache/tools/ant/types/selectors/ContainsSelector.java,v
retrieving revision 1.1.2.1
diff -u -r1.1.2.1 ContainsSelector.java
--- src/main/org/apache/tools/ant/types/selectors/ContainsSelector.java	10 
May 2002 15:40:32 -0000	1.1.2.1
+++ src/main/org/apache/tools/ant/types/selectors/ContainsSelector.java	23 
May 2002 15:32:17 -0000
@@ -114,7 +114,7 @@
      }

      /**
-     * When using this as a dynamic selector, this method will be called.
+     * When using this as a custom selector, this method will be called.
       * It translates each parameter into the appropriate setXXX() call.
       *
       * @param parameters the complete set of parameters for this selector
Index: src/main/org/apache/tools/ant/types/selectors/DateSelector.java
===================================================================
RCS file: 
/home/cvspublic/jakarta-ant/src/main/org/apache/tools/ant/types/selectors/DateSelector.java,v
retrieving revision 1.1
diff -u -r1.1 DateSelector.java
--- src/main/org/apache/tools/ant/types/selectors/DateSelector.java	30 Apr 
2002 22:38:35 -0000	1.1
+++ src/main/org/apache/tools/ant/types/selectors/DateSelector.java	23 May 
2002 15:32:18 -0000
@@ -74,7 +74,7 @@
      private long millis = -1;
      private String dateTime = null;
      private boolean includeDirs = false;
-    private int cmp = 0;
+    private int cmp = 2;
      public final static String MILLIS_KEY = "millis";
      public final static String DATETIME_KEY = "datetime";
      public final static String CHECKDIRS_KEY = "checkdirs";
@@ -157,7 +157,7 @@
      }

      /**
-     * When using this as a dynamic selector, this method will be called.
+     * When using this as a custom selector, this method will be called.
       * It translates each parameter into the appropriate setXXX() call.
       *
       * @param parameters the complete set of parameters for this selector
Index: src/main/org/apache/tools/ant/types/selectors/DepthSelector.java
===================================================================
RCS file: 
/home/cvspublic/jakarta-ant/src/main/org/apache/tools/ant/types/selectors/DepthSelector.java,v
retrieving revision 1.1
diff -u -r1.1 DepthSelector.java
--- src/main/org/apache/tools/ant/types/selectors/DepthSelector.java	30 Apr 
2002 22:38:35 -0000	1.1
+++ src/main/org/apache/tools/ant/types/selectors/DepthSelector.java	23 May 
2002 15:32:18 -0000
@@ -106,7 +106,7 @@
      }

      /**
-     * When using this as a dynamic selector, this method will be called.
+     * When using this as a custom selector, this method will be called.
       * It translates each parameter into the appropriate setXXX() call.
       *
       * @param parameters the complete set of parameters for this selector
Index: src/main/org/apache/tools/ant/types/selectors/ExtendFileSelector.java
===================================================================
RCS file: 
/home/cvspublic/jakarta-ant/src/main/org/apache/tools/ant/types/selectors/ExtendFileSelector.java,v
retrieving revision 1.1.2.1
diff -u -r1.1.2.1 ExtendFileSelector.java
--- src/main/org/apache/tools/ant/types/selectors/ExtendFileSelector.java 
20 May 2002 20:28:36 -0000	1.1.2.1
+++ src/main/org/apache/tools/ant/types/selectors/ExtendFileSelector.java 
23 May 2002 15:32:18 -0000
@@ -59,12 +59,12 @@
  import org.apache.tools.ant.types.Parameterizable;

  /**
- * This is the interface to be used by all dynamic selectors, those that are
+ * This is the interface to be used by all custom selectors, those that are
   * called through the &lt;custom&gt; tag. It is the amalgamation of two
   * interfaces, the FileSelector and the Paramterizable interface. Note that
   * you will almost certainly want the default behaviour for handling
   * Parameters, so you probably want to use the BaseExtendSelector class
- * as the base class for your dynamic selector rather than implementing
+ * as the base class for your custom selector rather than implementing
   * this interface from scratch.
   *
   * @author <a href="mailto:bruce@callenish.com">Bruce Atherton</a>
Index: src/main/org/apache/tools/ant/types/selectors/ExtendSelector.java
===================================================================
RCS file: 
/home/cvspublic/jakarta-ant/src/main/org/apache/tools/ant/types/selectors/ExtendSelector.java,v
retrieving revision 1.1
diff -u -r1.1 ExtendSelector.java
--- src/main/org/apache/tools/ant/types/selectors/ExtendSelector.java	30 
Apr 2002 22:38:35 -0000	1.1
+++ src/main/org/apache/tools/ant/types/selectors/ExtendSelector.java	23 
May 2002 15:32:18 -0000
@@ -58,6 +58,7 @@
  import java.util.Vector;

  import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.AntClassLoader;
  import org.apache.tools.ant.types.DataType;
  import org.apache.tools.ant.types.Path;
  import org.apache.tools.ant.types.Parameter;
@@ -72,7 +73,7 @@
  public class ExtendSelector extends BaseSelector {

      private String classname = null;
-    private ExtendFileSelector dynselector = null;
+    private FileSelector dynselector = null;
      private Vector paramVec = new Vector();
      private Path classpath = null;

@@ -83,7 +84,7 @@
      }

      /**
-     * Sets the classname of the dynamic selector.
+     * Sets the classname of the custom selector.
       *
       * @param classname is the class which implements this selector
       */
@@ -92,13 +93,21 @@
      }

      /**
-     * Instantiates the identified dynamic selector class.
+     * Instantiates the identified custom selector class.
       */
      public void selectorCreate() {
          if (classname != null && classname.length() > 0) {
              try {
-                dynselector = (ExtendFileSelector)
-                        Class.forName(classname).newInstance();
+                Class c = null;
+                if (classpath == null) {
+                    c = Class.forName(classname);
+                } else {
+                    AntClassLoader al = new AntClassLoader(getProject(),
+                                                           classpath);
+                    c = al.loadClass(classname);
+                    AntClassLoader.initializeClass(c);
+                }
+                dynselector = (FileSelector) c.newInstance();
              }
              catch (ClassNotFoundException cnfexcept) {
                  setError("Selector " + classname +
@@ -118,7 +127,7 @@
      }

      /**
-     * Create new parameters to pass to dynamic selector.
+     * Create new parameters to pass to custom selector.
       *
       * @param p The new Parameter object
       */
@@ -162,7 +171,7 @@
      }

      /**
-     * Set the classpath to use for loading a dynamic selector by using
+     * Set the classpath to use for loading a custom selector by using
       * a reference.
       */
      public void setClasspathref(Reference r) {
@@ -174,37 +183,45 @@

      /**
       * These are errors specific to ExtendSelector only. If there are
-     * errors in the dynamic selector, it should throw a BuildException
+     * errors in the custom selector, it should throw a BuildException
       * when isSelected() is called.
       */
      public void verifySettings() {
+        // Creation is done here rather than in isSelected() because some
+        // containers may do a validation pass before running isSelected(),
+        // but we need to check for the existence of the created class.
+        if (dynselector == null) {
+            selectorCreate();
+        }
          if (classname == null || classname.length() < 1) {
              setError("The classname attribute is required");
          }
          else if (dynselector == null) {
-            setError("Internal Error: The dynamic selector is not set");
+            setError("Internal Error: The custom selector was not created");
+        }
+        else if (!(dynselector instanceof ExtendFileSelector) &&
+                (paramVec.size() > 0)) {
+            setError("Cannot set parameters on custom selector that does not "
+                    + "implement ExtendFileSelector");
          }
      }


      /**
-     * Allows the dynamic selector to choose whether to select a file. This
-     * is also where the Parameters are passed to the dynamic selector,
+     * Allows the custom selector to choose whether to select a file. This
+     * is also where the Parameters are passed to the custom selector,
       * since we know we must have them all by now. And since we must know
       * both classpath and classname, creating the class is deferred to here
       * as well.
       */
      public boolean isSelected(File basedir, String filename, File file)
              throws BuildException {
-        if (dynselector == null) {
-            selectorCreate();
-        }
          validate();
-        if (paramVec.size() > 0) {
+        if (paramVec.size() > 0 && dynselector instanceof 
ExtendFileSelector) {
              Parameter[] paramArray = new Parameter[paramVec.size()];
              paramVec.copyInto(paramArray);
              // We know that dynselector must be non-null if no error message
-            dynselector.setParameters(paramArray);
+            ((ExtendFileSelector)dynselector).setParameters(paramArray);
          }
          return dynselector.isSelected(basedir,filename,file);
      }
Index: src/main/org/apache/tools/ant/types/selectors/FilenameSelector.java
===================================================================
RCS file: 
/home/cvspublic/jakarta-ant/src/main/org/apache/tools/ant/types/selectors/FilenameSelector.java,v
retrieving revision 1.1.2.1
diff -u -r1.1.2.1 FilenameSelector.java
--- src/main/org/apache/tools/ant/types/selectors/FilenameSelector.java	20 
May 2002 20:28:36 -0000	1.1.2.1
+++ src/main/org/apache/tools/ant/types/selectors/FilenameSelector.java	23 
May 2002 15:32:18 -0000
@@ -134,7 +134,7 @@
      }

      /**
-     * When using this as a dynamic selector, this method will be called.
+     * When using this as a custom selector, this method will be called.
       * It translates each parameter into the appropriate setXXX() call.
       *
       * @param parameters the complete set of parameters for this selector
Index: src/main/org/apache/tools/ant/types/selectors/SizeSelector.java
===================================================================
RCS file: 
/home/cvspublic/jakarta-ant/src/main/org/apache/tools/ant/types/selectors/SizeSelector.java,v
retrieving revision 1.1.2.1
diff -u -r1.1.2.1 SizeSelector.java
--- src/main/org/apache/tools/ant/types/selectors/SizeSelector.java	10 May 
2002 15:40:32 -0000	1.1.2.1
+++ src/main/org/apache/tools/ant/types/selectors/SizeSelector.java	23 May 
2002 15:32:21 -0000
@@ -71,7 +71,7 @@
      private long size = -1;
      private long multiplier = 1;
      private long sizelimit = -1;
-    private int cmp = 0;
+    private int cmp = 2;
      public final static String SIZE_KEY = "value";
      public final static String UNITS_KEY = "units";
      public final static String WHEN_KEY = "when";
@@ -179,7 +179,7 @@
      }

      /**
-     * When using this as a dynamic selector, this method will be called.
+     * When using this as a custom selector, this method will be called.
       * It translates each parameter into the appropriate setXXX() call.
       *
       * @param parameters the complete set of parameters for this selector


--
To unsubscribe, e-mail:   <mailto:ant-dev-unsubscribe@jakarta.apache.org>
For additional commands, e-mail: <mailto:ant-dev-help@jakarta.apache.org>


Mime
View raw message