Author: gscokart
Date: Sat Jan 24 15:23:02 2009
New Revision: 737379

URL: http://svn.apache.org/viewvc?rev=737379&view=rev
Log:
isolate project references to prepare extraction of AntUnitScriptRunner

Modified:
    ant/antlibs/antunit/trunk/src/main/org/apache/ant/antunit/AntUnit.java

Modified: ant/antlibs/antunit/trunk/src/main/org/apache/ant/antunit/AntUnit.java
URL: 
http://svn.apache.org/viewvc/ant/antlibs/antunit/trunk/src/main/org/apache/ant/antunit/AntUnit.java?rev=737379&r1=737378&r2=737379&view=diff
==============================================================================
--- ant/antlibs/antunit/trunk/src/main/org/apache/ant/antunit/AntUnit.java 
(original)
+++ ant/antlibs/antunit/trunk/src/main/org/apache/ant/antunit/AntUnit.java Sat 
Jan 24 15:23:02 2009
@@ -78,7 +78,7 @@
     /**
      * project instance for the build file currently under test.
      */
-    private Project newProject;
+    private ProjectHandler currentProject = new ProjectHandler();
 
     /**
      * listeners.
@@ -198,6 +198,69 @@
         }
     }
 
+    /** Manage the project reference in order to minimize the number of 
project creation
+     * while allowing every test to run in isolation.  
+     */ 
+    private class ProjectHandler {
+        
+        /** ant script currently under testing */
+        private File scriptFile;
+        
+        /** The project currently used. */
+        private Project project = null;
+        
+        /** Indicates if a target has already be executed using this project. 
+         * Value is undefined when project is null.
+         */
+        private boolean projectIsDirty;
+        
+        /** Set the ant script to use. */
+        public void activate(File f) {
+            scriptFile = f;
+            project = null;
+        }
+
+        /** Declare that the current ant script doesn't need to be used 
anymore. */
+        public void deactivate() {
+            scriptFile = null;
+            project = null;
+        }
+
+        /** Indicates if there is a project currently under test. */
+        public boolean isActif() {
+            return scriptFile!=null;
+        }
+
+        /**
+         * Get the project currently in use.  The caller is not allowed to 
invoke a target or
+         * do anything that would break the isolation of the test targets.
+         * @pre isActif()
+         */
+        public Project get() {
+            if (!isActif()) throw new AssertionError("scriptFile==null");
+            if (project==null) {
+                project = createProjectForFile(scriptFile);
+                projectIsDirty = false;
+            }
+            return project;
+        }
+        
+        /**
+         * Get a project that has not yet been used in order to execute a 
target on it.
+         * @pre isActif()
+         */
+        public Project getRenewed() {
+            if (!isActif()) throw new AssertionError("scriptFile==null");
+            if (project==null || projectIsDirty) {
+                project = createProjectForFile(scriptFile);
+            }
+            //we already set isDirty to true in order to make sure we didn't 
reuse
+            //this project next time getRenewed is called.  
+            projectIsDirty = true;
+            return project;
+        }
+    }
+
     private class AntUnitScriptRunner {
         /**
          * name of the magic setUp target.
@@ -229,12 +292,9 @@
         private boolean suiteSetUp;
         private boolean suiteTearDown;
         
-        public List scanFile(File f) {
-            // setup project instance
-            newProject = createProjectForFile(f);
-
-            // find targets
-            Map targets = newProject.getTargets();
+        public List scanFile() {
+            Project newProject = currentProject.get();
+            Map targets = newProject.getTargets();            
             setUp = targets.containsKey(SETUP);
             tearDown = targets.containsKey(TEARDOWN);
             suiteSetUp = targets.containsKey(SUITESETUP);
@@ -251,9 +311,10 @@
         }
 
         public boolean startSuite() {
-            newProject.fireBuildStarted();
+            currentProject.get().fireBuildStarted();
             if (suiteSetUp) {
                 try {
+                    Project newProject = currentProject.getRenewed();
                     newProject.executeTarget(SUITESETUP);
                 } catch (AssertionFailedException e) {
                     fireStartTest(SUITESETUP);
@@ -269,6 +330,7 @@
         }
 
         public void runTarget(String name) {
+            Project newProject = currentProject.getRenewed();
             Vector v = new Vector();
             if (setUp) {
                 v.add(SETUP);
@@ -306,6 +368,7 @@
         public void endSuite(Throwable caught) {
             if (suiteTearDown) {
                 try {
+                    Project newProject = currentProject.getRenewed();
                     newProject.executeTarget(SUITETEARDOWN);
                 } catch (AssertionFailedException e) {
                     fireStartTest(SUITETEARDOWN);
@@ -315,7 +378,7 @@
                     fireFailOrError(SUITETEARDOWN, e);
                 }
             }
-            newProject.fireBuildFinished(caught);
+            currentProject.get().fireBuildFinished(caught);
         }
         
         /** Report a failure or an exception for the test target name */
@@ -346,8 +409,9 @@
      */
     private void doFile(File f) {
         log("Running tests in build file " + f, Project.MSG_DEBUG);
+        currentProject.activate(f);
         AntUnitScriptRunner scriptRunner = new AntUnitScriptRunner();
-        List testTargets = scriptRunner.scanFile(f);
+        List testTargets = scriptRunner.scanFile();
 
         // start test
         Throwable caught = null;
@@ -359,15 +423,12 @@
             while (iter.hasNext()) {
                 String name = (String) iter.next();
                 scriptRunner.runTarget(name);
-                if (iter.hasNext()) {
-                    newProject = createProjectForFile(f);
-                }
             }
         } catch (Throwable e) {
             caught = e;
         } finally {
             scriptRunner.endSuite(caught);            
-            newProject = null;
+            currentProject.deactivate();
         }
     }
 
@@ -377,8 +438,8 @@
      * @param outputToHandle the output to handle.
      */
     public void handleOutput(String outputToHandle) {
-        if (newProject != null) {
-            newProject.demuxOutput(outputToHandle, false);
+        if (currentProject.isActif()) {
+            currentProject.get().demuxOutput(outputToHandle, false);
         } else {
             super.handleOutput(outputToHandle);
         }
@@ -392,8 +453,8 @@
      */
     public int handleInput(byte[] buffer, int offset, int length)
         throws IOException {
-        if (newProject != null) {
-            return newProject.demuxInput(buffer, offset, length);
+        if (currentProject.isActif()) {
+            return currentProject.get().demuxInput(buffer, offset, length);
         }
         return super.handleInput(buffer, offset, length);
     }
@@ -403,8 +464,8 @@
      * @param toFlush the output String to flush.
      */
     public void handleFlush(String toFlush) {
-        if (newProject != null) {
-            newProject.demuxFlush(toFlush, false);
+        if (currentProject.isActif()) {
+            currentProject.get().demuxFlush(toFlush, false);
         } else {
             super.handleFlush(toFlush);
         }
@@ -415,8 +476,8 @@
      * @param errorOutputToHandle the error output to handle.
      */
     public void handleErrorOutput(String errorOutputToHandle) {
-        if (newProject != null) {
-            newProject.demuxOutput(errorOutputToHandle, true);
+        if (currentProject.isActif()) {
+            currentProject.get().demuxOutput(errorOutputToHandle, true);
         } else {
             super.handleErrorOutput(errorOutputToHandle);
         }
@@ -427,8 +488,8 @@
      * @param errorOutputToFlush the error output to flush.
      */
     public void handleErrorFlush(String errorOutputToFlush) {
-        if (newProject != null) {
-            newProject.demuxFlush(errorOutputToFlush, true);
+        if (currentProject.isActif()) {
+            currentProject.get().demuxFlush(errorOutputToFlush, true);
         } else {
             super.handleErrorFlush(errorOutputToFlush);
         }


Reply via email to