Updated Branches:
  refs/heads/master 626e59333 -> 36f458b63

o Made the classpath object truly immutable and threadsafe


Project: http://git-wip-us.apache.org/repos/asf/maven-surefire/repo
Commit: http://git-wip-us.apache.org/repos/asf/maven-surefire/commit/36f458b6
Tree: http://git-wip-us.apache.org/repos/asf/maven-surefire/tree/36f458b6
Diff: http://git-wip-us.apache.org/repos/asf/maven-surefire/diff/36f458b6

Branch: refs/heads/master
Commit: 36f458b633553c7b4ff755e0aeb3a637e0375493
Parents: 626e593
Author: Kristian Rosenvold <krosenv...@apache.org>
Authored: Wed May 29 20:05:31 2013 +0200
Committer: Kristian Rosenvold <krosenv...@apache.org>
Committed: Wed May 29 20:05:31 2013 +0200

----------------------------------------------------------------------
 .../plugin/surefire/AbstractSurefireMojo.java      |    3 +-
 ...BooterDeserializerStartupConfigurationTest.java |    2 +-
 .../booterclient/ForkConfigurationTest.java        |    2 +-
 .../apache/maven/surefire/booter/Classpath.java    |  108 +++++++++------
 .../surefire/booter/ClasspathConfiguration.java    |    5 +-
 .../maven/surefire/booter/PropertiesWrapper.java   |    2 +
 .../maven/surefire/booter/ClasspathTest.java       |   35 ++---
 .../surefire/booter/PropertiesWrapperTest.java     |    5 +-
 8 files changed, 88 insertions(+), 74 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/36f458b6/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/AbstractSurefireMojo.java
----------------------------------------------------------------------
diff --git 
a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/AbstractSurefireMojo.java
 
b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/AbstractSurefireMojo.java
index 28ae11c..d254d55 100644
--- 
a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/AbstractSurefireMojo.java
+++ 
b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/AbstractSurefireMojo.java
@@ -1177,9 +1177,8 @@ public abstract class AbstractSurefireMojo
                 ClasspathCache.setCachedClasspath( providerName, 
providerClasspath );
 
             }
-            Classpath inprocClassPath = new Classpath( providerClasspath );
             Artifact surefireArtifact = getCommonArtifact();
-            inprocClassPath.addClassPathElementUrl( 
surefireArtifact.getFile().getAbsolutePath() );
+            Classpath inprocClassPath = 
providerClasspath.addClassPathElementUrl( 
surefireArtifact.getFile().getAbsolutePath() );
 
             final Classpath testClasspath = generateTestClasspath();
 

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/36f458b6/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/BooterDeserializerStartupConfigurationTest.java
----------------------------------------------------------------------
diff --git 
a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/BooterDeserializerStartupConfigurationTest.java
 
b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/BooterDeserializerStartupConfigurationTest.java
index 5446bd6..bbcf5e1 100644
--- 
a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/BooterDeserializerStartupConfigurationTest.java
+++ 
b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/BooterDeserializerStartupConfigurationTest.java
@@ -101,7 +101,7 @@ public class BooterDeserializerStartupConfigurationTest
     {
         Classpath testClassPath = new Classpath( Arrays.asList( new String[]{ 
"CP1", "CP2" } ) );
         Classpath providerClasspath = new Classpath( Arrays.asList( new 
String[]{ "SP1", "SP2" } ) );
-        return new ClasspathConfiguration( testClassPath, providerClasspath, 
new Classpath(), true, true );
+        return new ClasspathConfiguration( testClassPath, providerClasspath, 
Classpath.emptyClasspath(), true, true );
     }
 
     public static ClassLoaderConfiguration getSystemClassLoaderConfiguration()

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/36f458b6/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/ForkConfigurationTest.java
----------------------------------------------------------------------
diff --git 
a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/ForkConfigurationTest.java
 
b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/ForkConfigurationTest.java
index c37b9f2..9a310b2 100644
--- 
a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/ForkConfigurationTest.java
+++ 
b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/ForkConfigurationTest.java
@@ -71,7 +71,7 @@ public class ForkConfigurationTest
     public static ForkConfiguration getForkConfiguration( String argLine, 
String jvm )
         throws IOException
     {
-        return new ForkConfiguration( new Classpath(), null, null, jvm, new 
File( "." ).getCanonicalFile(), argLine,
+        return new ForkConfiguration( Classpath.emptyClasspath(), null, null, 
jvm, new File( "." ).getCanonicalFile(), argLine,
                                       null, false, 1, false );
     }
 

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/36f458b6/surefire-booter/src/main/java/org/apache/maven/surefire/booter/Classpath.java
----------------------------------------------------------------------
diff --git 
a/surefire-booter/src/main/java/org/apache/maven/surefire/booter/Classpath.java 
b/surefire-booter/src/main/java/org/apache/maven/surefire/booter/Classpath.java
index a667a9c..2fdb4eb 100644
--- 
a/surefire-booter/src/main/java/org/apache/maven/surefire/booter/Classpath.java
+++ 
b/surefire-booter/src/main/java/org/apache/maven/surefire/booter/Classpath.java
@@ -21,86 +21,93 @@ package org.apache.maven.surefire.booter;
 
 import org.apache.maven.surefire.util.UrlUtils;
 
+import javax.annotation.concurrent.Immutable;
+import javax.annotation.concurrent.ThreadSafe;
 import java.io.File;
 import java.net.MalformedURLException;
 import java.net.URL;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
 import java.util.List;
 
 /**
  * An ordered list of classpath elements with set behaviour
  *
+ * A Classpath is immutable and thread safe.
+ *
+ *
  * @author Kristian Rosenvold
  */
-public class Classpath
+@ThreadSafe
+@Immutable
+public class Classpath implements Iterable<String>
 {
 
+    private final List<String> unmodifiableElements;
+
     public static Classpath join( Classpath firstClasspath, Classpath 
secondClasspath )
     {
-        Classpath joinedClasspath = new Classpath();
-        joinedClasspath.addElementsOfClasspath( firstClasspath );
-        joinedClasspath.addElementsOfClasspath( secondClasspath );
-        return joinedClasspath;
+        LinkedHashSet<String> accumulated =  new LinkedHashSet<String>(  );
+        if (firstClasspath != null) firstClasspath.addTo( accumulated );
+        if (secondClasspath != null) secondClasspath.addTo( accumulated );
+        return new Classpath( accumulated );
     }
 
-    private final List<String> elements;
 
-    public Classpath()
-    {
-        this.elements = new ArrayList<String>();
+    private void addTo(Collection<String> c){
+        c.addAll( unmodifiableElements );
     }
 
-    public Classpath( Classpath other )
+    private Classpath()
     {
-        this.elements = new ArrayList<String>( other.elements );
+        this.unmodifiableElements = Collections.emptyList();
     }
 
-    public Classpath( List<String> elements )
+
+    public Classpath( Classpath other, String additionalElement )
     {
-        this();
-        addElements( elements );
+        ArrayList<String> elems = new ArrayList<String>( 
other.unmodifiableElements );
+        elems.add( additionalElement );
+        this.unmodifiableElements = Collections.unmodifiableList( elems );
     }
 
-    public void addClassPathElementUrl( String path )
+    public Classpath( Iterable<String> elements )
     {
-        if ( path == null )
-        {
-            throw new IllegalArgumentException( "Null is not a valid class 
path element url." );
-        }
-        else if ( !elements.contains( path ) )
+        List<String> newCp = new ArrayList<String>(  );
+        for ( String element : elements )
         {
-            elements.add( path );
+            newCp.add( element );
         }
+        this.unmodifiableElements = Collections.unmodifiableList( newCp );
     }
 
-    private void addElements( List<String> additionalElements )
+    public static Classpath emptyClasspath()
     {
-        for ( Object additionalElement : additionalElements )
-        {
-            String element = (String) additionalElement;
-            addClassPathElementUrl( element );
-        }
+        return new Classpath();
     }
 
-    private void addElementsOfClasspath( Classpath otherClasspath )
+    public Classpath addClassPathElementUrl( String path )
     {
-        if ( otherClasspath != null )
+        if ( path == null )
         {
-            addElements( otherClasspath.elements );
+            throw new IllegalArgumentException( "Null is not a valid class 
path element url." );
         }
+        return !unmodifiableElements.contains( path ) ? new Classpath( this, 
path ) : this;
     }
 
     public List<String> getClassPath()
     {
-        return Collections.unmodifiableList( elements );
+        return unmodifiableElements;
     }
 
     public List<URL> getAsUrlList()
         throws MalformedURLException
     {
         List<URL> urls = new ArrayList<URL>();
-        for ( String url : elements )
+        for ( String url : unmodifiableElements )
         {
             File f = new File( url );
             urls.add( UrlUtils.getURL( f ) );
@@ -111,7 +118,7 @@ public class Classpath
     public void writeToSystemProperty( String propertyName )
     {
         StringBuilder sb = new StringBuilder();
-        for ( String element : elements )
+        for ( String element : unmodifiableElements )
         {
             sb.append( element ).append( File.pathSeparatorChar );
         }
@@ -131,7 +138,8 @@ public class Classpath
 
         Classpath classpath = (Classpath) o;
 
-        return !( elements != null ? !elements.equals( classpath.elements ) : 
classpath.elements != null );
+        return !( unmodifiableElements
+            != null ? !unmodifiableElements.equals( 
classpath.unmodifiableElements ) : classpath.unmodifiableElements != null );
 
     }
 
@@ -164,36 +172,50 @@ public class Classpath
 
     public int hashCode()
     {
-        return elements != null ? elements.hashCode() : 0;
+        return unmodifiableElements != null ? unmodifiableElements.hashCode() 
: 0;
     }
 
     public String getLogMessage( String descriptor )
     {
         StringBuilder result = new StringBuilder();
         result.append( descriptor ).append( " classpath:" );
-        for ( String element : elements )
+        for ( String element : unmodifiableElements )
         {
             result.append( "  " ).append( element );
         }
         return result.toString();
     }
+
     public String getCompactLogMessage( String descriptor )
     {
         StringBuilder result = new StringBuilder();
         result.append( descriptor ).append( " classpath:" );
-        for ( String element : elements )
+        for ( String element : unmodifiableElements )
         {
             result.append( "  " );
-            if (element != null){
+            if ( element != null )
+            {
                 int pos = element.lastIndexOf( File.separatorChar );
-                if (pos >= 0){
-                result.append(  element.substring(  pos + 1) );
-                } else
-                    result.append( element);
+                if ( pos >= 0 )
+                {
+                    result.append( element.substring( pos + 1 ) );
+                }
+                else
+                {
+                    result.append( element );
+                }
 
-            } else result.append(element);
+            }
+            else
+            {
+                result.append( element );
+            }
         }
         return result.toString();
     }
 
+    public Iterator<String> iterator()
+    {
+        return unmodifiableElements.iterator();
+    }
 }

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/36f458b6/surefire-booter/src/main/java/org/apache/maven/surefire/booter/ClasspathConfiguration.java
----------------------------------------------------------------------
diff --git 
a/surefire-booter/src/main/java/org/apache/maven/surefire/booter/ClasspathConfiguration.java
 
b/surefire-booter/src/main/java/org/apache/maven/surefire/booter/ClasspathConfiguration.java
index 2df6e46..9b3f9c3 100644
--- 
a/surefire-booter/src/main/java/org/apache/maven/surefire/booter/ClasspathConfiguration.java
+++ 
b/surefire-booter/src/main/java/org/apache/maven/surefire/booter/ClasspathConfiguration.java
@@ -57,12 +57,13 @@ public class ClasspathConfiguration
 
     public ClasspathConfiguration( boolean enableAssertions, boolean 
childDelegation )
     {
-        this( new Classpath(), new Classpath(), new Classpath(), 
enableAssertions, childDelegation );
+        this( Classpath.emptyClasspath(), Classpath.emptyClasspath(), 
Classpath.emptyClasspath(), enableAssertions, childDelegation );
     }
 
     ClasspathConfiguration( PropertiesWrapper properties )
     {
-        this( properties.getClasspath( CLASSPATH ), properties.getClasspath( 
SUREFIRE_CLASSPATH ), new Classpath(),
+        this( properties.getClasspath( CLASSPATH ), properties.getClasspath( 
SUREFIRE_CLASSPATH ),
+              Classpath.emptyClasspath(),
               properties.getBooleanProperty( ENABLE_ASSERTIONS ), 
properties.getBooleanProperty( CHILD_DELEGATION ) );
     }
 

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/36f458b6/surefire-booter/src/main/java/org/apache/maven/surefire/booter/PropertiesWrapper.java
----------------------------------------------------------------------
diff --git 
a/surefire-booter/src/main/java/org/apache/maven/surefire/booter/PropertiesWrapper.java
 
b/surefire-booter/src/main/java/org/apache/maven/surefire/booter/PropertiesWrapper.java
index 28fb1d3..e5e3d8e 100644
--- 
a/surefire-booter/src/main/java/org/apache/maven/surefire/booter/PropertiesWrapper.java
+++ 
b/surefire-booter/src/main/java/org/apache/maven/surefire/booter/PropertiesWrapper.java
@@ -28,6 +28,8 @@ import java.util.Properties;
 import org.apache.maven.surefire.util.internal.StringUtils;
 
 /**
+ * Makes java.util.Properties behave like it's 2013
+ *
  * @author Kristian Rosenvold
  */
 public class PropertiesWrapper

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/36f458b6/surefire-booter/src/test/java/org/apache/maven/surefire/booter/ClasspathTest.java
----------------------------------------------------------------------
diff --git 
a/surefire-booter/src/test/java/org/apache/maven/surefire/booter/ClasspathTest.java
 
b/surefire-booter/src/test/java/org/apache/maven/surefire/booter/ClasspathTest.java
index 700a3a5..78a180b 100644
--- 
a/surefire-booter/src/test/java/org/apache/maven/surefire/booter/ClasspathTest.java
+++ 
b/surefire-booter/src/test/java/org/apache/maven/surefire/booter/ClasspathTest.java
@@ -24,6 +24,8 @@ import java.util.List;
 
 import junit.framework.TestCase;
 
+import static org.apache.maven.surefire.booter.Classpath.emptyClasspath;
+
 /**
  * @author Kristian Rosenvold
  */
@@ -39,7 +41,7 @@ public class ClasspathTest
     public void testShouldWriteEmptyPropertyForEmptyClasspath()
         throws Exception
     {
-        Classpath classpath = new Classpath();
+        Classpath classpath = Classpath.emptyClasspath();
         classpath.writeToSystemProperty( DUMMY_PROPERTY_NAME );
         assertEquals( "", System.getProperty( DUMMY_PROPERTY_NAME ) );
     }
@@ -47,9 +49,7 @@ public class ClasspathTest
     public void testShouldWriteSeparatedElementsAsSystemProperty()
         throws Exception
     {
-        Classpath classpath = new Classpath();
-        classpath.addClassPathElementUrl( DUMMY_URL_1 );
-        classpath.addClassPathElementUrl( DUMMY_URL_2 );
+        Classpath classpath = 
Classpath.emptyClasspath().addClassPathElementUrl( DUMMY_URL_1 
).addClassPathElementUrl( DUMMY_URL_2 );
         classpath.writeToSystemProperty( DUMMY_PROPERTY_NAME );
         assertEquals( DUMMY_URL_1 + File.pathSeparatorChar + DUMMY_URL_2 + 
File.pathSeparatorChar,
                       System.getProperty( DUMMY_PROPERTY_NAME ) );
@@ -57,9 +57,8 @@ public class ClasspathTest
 
     public void testShouldAddNoDuplicateElements()
     {
-        Classpath classpath = new Classpath();
-        classpath.addClassPathElementUrl( DUMMY_URL_1 );
-        classpath.addClassPathElementUrl( DUMMY_URL_1 );
+        Classpath classpath =
+            emptyClasspath().addClassPathElementUrl( DUMMY_URL_1 
).addClassPathElementUrl( DUMMY_URL_1 );
         assertClasspathConsistsOfElements( classpath, new String[]{ 
DUMMY_URL_1 } );
     }
 
@@ -81,10 +80,8 @@ public class ClasspathTest
     public void testShouldHaveAllElementsAfterJoiningTwoDifferentClasspaths()
         throws Exception
     {
-        Classpath firstClasspath = new Classpath();
-        firstClasspath.addClassPathElementUrl( DUMMY_URL_1 );
-        Classpath secondClasspath = new Classpath();
-        secondClasspath.addClassPathElementUrl( DUMMY_URL_2 );
+        Classpath firstClasspath = Classpath.emptyClasspath();
+        Classpath secondClasspath = firstClasspath.addClassPathElementUrl( 
DUMMY_URL_1 ).addClassPathElementUrl( DUMMY_URL_2 );
         Classpath joinedClasspath = Classpath.join( firstClasspath, 
secondClasspath );
         assertClasspathConsistsOfElements( joinedClasspath, new String[]{ 
DUMMY_URL_1, DUMMY_URL_2 } );
     }
@@ -92,10 +89,8 @@ public class ClasspathTest
     public void 
testShouldNotHaveDuplicatesAfterJoiningTowClasspathsWithEqualElements()
         throws Exception
     {
-        Classpath firstClasspath = new Classpath();
-        firstClasspath.addClassPathElementUrl( DUMMY_URL_1 );
-        Classpath secondClasspath = new Classpath();
-        secondClasspath.addClassPathElementUrl( DUMMY_URL_1 );
+        Classpath firstClasspath = 
Classpath.emptyClasspath().addClassPathElementUrl( DUMMY_URL_1 );
+        Classpath secondClasspath = 
Classpath.emptyClasspath().addClassPathElementUrl( DUMMY_URL_1 );
         Classpath joinedClasspath = Classpath.join( firstClasspath, 
secondClasspath );
         assertClasspathConsistsOfElements( joinedClasspath, new String[]{ 
DUMMY_URL_1 } );
     }
@@ -132,16 +127,14 @@ public class ClasspathTest
 
     private Classpath createClasspathWithTwoElements()
     {
-        Classpath classpath = new Classpath();
-        classpath.addClassPathElementUrl( DUMMY_URL_1 );
-        classpath.addClassPathElementUrl( DUMMY_URL_2 );
-        return classpath;
+        Classpath classpath = Classpath.emptyClasspath();
+        return classpath.addClassPathElementUrl( DUMMY_URL_1 
).addClassPathElementUrl( DUMMY_URL_2 );
     }
 
     public void 
testShouldThrowIllegalArgumentExceptionWhenNullIsAddedAsClassPathElementUrl()
         throws Exception
     {
-        Classpath classpath = new Classpath();
+        Classpath classpath = Classpath.emptyClasspath();
         try
         {
             classpath.addClassPathElementUrl( null );
@@ -155,7 +148,7 @@ public class ClasspathTest
     public void testShouldNotAddNullAsClassPathElementUrl()
         throws Exception
     {
-        Classpath classpath = new Classpath();
+        Classpath classpath = Classpath.emptyClasspath();
         try
         {
             classpath.addClassPathElementUrl( null );

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/36f458b6/surefire-booter/src/test/java/org/apache/maven/surefire/booter/PropertiesWrapperTest.java
----------------------------------------------------------------------
diff --git 
a/surefire-booter/src/test/java/org/apache/maven/surefire/booter/PropertiesWrapperTest.java
 
b/surefire-booter/src/test/java/org/apache/maven/surefire/booter/PropertiesWrapperTest.java
index 560b00b..bda705b 100644
--- 
a/surefire-booter/src/test/java/org/apache/maven/surefire/booter/PropertiesWrapperTest.java
+++ 
b/surefire-booter/src/test/java/org/apache/maven/surefire/booter/PropertiesWrapperTest.java
@@ -99,10 +99,7 @@ public class PropertiesWrapperTest
 
     private Classpath createClasspathWithTwoElements()
     {
-        Classpath classpath = new Classpath();
-        classpath.addClassPathElementUrl( FIRST_ELEMENT );
-        classpath.addClassPathElementUrl( SECOND_ELEMENT );
-        return classpath;
+        return Classpath.emptyClasspath().addClassPathElementUrl( 
FIRST_ELEMENT ).addClassPathElementUrl( SECOND_ELEMENT );
     }
 
     private Classpath readClasspathFromProperties()

Reply via email to