View Javadoc
1   package org.apache.maven.surefire.booter;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *     http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.io.File;
23  import java.net.MalformedURLException;
24  import java.net.URL;
25  import java.util.ArrayList;
26  import java.util.Collection;
27  import java.util.Collections;
28  import java.util.Iterator;
29  import java.util.LinkedHashSet;
30  import java.util.List;
31  
32  import static java.io.File.pathSeparatorChar;
33  import static org.apache.maven.surefire.util.internal.UrlUtils.toURL;
34  
35  /**
36   * An ordered list of classpath elements with set behaviour
37   *
38   * A Classpath is immutable and thread safe.
39   *
40   * Immutable and thread safe
41   *
42   * @author Kristian Rosenvold
43   */
44  public class Classpath implements Iterable<String>
45  {
46      private final List<String> unmodifiableElements;
47  
48      public static Classpath join( Classpath firstClasspath, Classpath secondClasspath )
49      {
50          LinkedHashSet<String> accumulated =  new LinkedHashSet<String>(  );
51          if ( firstClasspath != null )
52          {
53              firstClasspath.addTo( accumulated );
54          }
55          if ( secondClasspath != null )
56          {
57              secondClasspath.addTo( accumulated );
58          }
59          return new Classpath( accumulated );
60      }
61  
62  
63      private void addTo( Collection<String> c )
64      {
65          c.addAll( unmodifiableElements );
66      }
67  
68      private Classpath()
69      {
70          this.unmodifiableElements = Collections.emptyList();
71      }
72  
73  
74      public Classpath( Classpath other, String additionalElement )
75      {
76          ArrayList<String> elems = new ArrayList<String>( other.unmodifiableElements );
77          elems.add( additionalElement );
78          unmodifiableElements = Collections.unmodifiableList( elems );
79      }
80  
81      public Classpath( Collection<String> elements )
82      {
83          List<String> newCp = new ArrayList<String>( elements.size() );
84          for ( String element : elements )
85          {
86              element = element.trim();
87              if ( !element.isEmpty() )
88              {
89                  newCp.add( element );
90              }
91          }
92          unmodifiableElements = Collections.unmodifiableList( newCp );
93      }
94  
95      public static Classpath emptyClasspath()
96      {
97          return new Classpath();
98      }
99  
100     public Classpath addClassPathElementUrl( String path )
101     {
102         if ( path == null )
103         {
104             throw new IllegalArgumentException( "Null is not a valid class path element url." );
105         }
106         return !unmodifiableElements.contains( path ) ? new Classpath( this, path ) : this;
107     }
108 
109     public List<String> getClassPath()
110     {
111         return unmodifiableElements;
112     }
113 
114     /**
115      * @deprecated this should be package private method which returns List of Files. It will be
116      * removed in the next major version.
117      *
118      * @return list of {@link URL jar files paths} with {@code file} protocol in URL.
119      * @throws MalformedURLException if {@link URL} could not be created upon given class-path element(s)
120      */
121     @Deprecated
122     public List<URL> getAsUrlList()
123         throws MalformedURLException
124     {
125         List<URL> urls = new ArrayList<URL>();
126         for ( String url : unmodifiableElements )
127         {
128             File f = new File( url );
129             urls.add( toURL( f ) );
130         }
131         return urls;
132     }
133 
134     public void writeToSystemProperty( String propertyName )
135     {
136         StringBuilder sb = new StringBuilder();
137         for ( String element : unmodifiableElements )
138         {
139             sb.append( element )
140               .append( pathSeparatorChar );
141         }
142         System.setProperty( propertyName, sb.toString() );
143     }
144 
145     @Override
146     public boolean equals( Object o )
147     {
148         if ( this == o )
149         {
150             return true;
151         }
152         if ( o == null || getClass() != o.getClass() )
153         {
154             return false;
155         }
156 
157         Classpath classpath = (Classpath) o;
158 
159         return unmodifiableElements.equals( classpath.unmodifiableElements );
160     }
161 
162     public ClassLoader createClassLoader( boolean childDelegation, boolean enableAssertions, String roleName )
163         throws SurefireExecutionException
164     {
165         try
166         {
167             ClassLoader parent = SystemUtils.platformClassLoader();
168             IsolatedClassLoader classLoader = new IsolatedClassLoader( parent, childDelegation, roleName );
169             for ( String classPathElement : unmodifiableElements )
170             {
171                 classLoader.addURL( new File( classPathElement ).toURL() );
172             }
173             if ( parent != null )
174             {
175                 parent.setDefaultAssertionStatus( enableAssertions );
176             }
177             classLoader.setDefaultAssertionStatus( enableAssertions );
178             return classLoader;
179         }
180         catch ( MalformedURLException e )
181         {
182             throw new SurefireExecutionException( "When creating classloader", e );
183         }
184     }
185 
186     @Override
187     public int hashCode()
188     {
189         return unmodifiableElements.hashCode();
190     }
191 
192     public String getLogMessage( String descriptor )
193     {
194         StringBuilder result = new StringBuilder();
195         result.append( descriptor ).append( " classpath:" );
196         for ( String element : unmodifiableElements )
197         {
198             result.append( "  " ).append( element );
199         }
200         return result.toString();
201     }
202 
203     public String getCompactLogMessage( String descriptor )
204     {
205         StringBuilder result = new StringBuilder();
206         result.append( descriptor ).append( " classpath:" );
207         for ( String element : unmodifiableElements )
208         {
209             result.append( "  " );
210             if ( element != null )
211             {
212                 int pos = element.lastIndexOf( File.separatorChar );
213                 if ( pos >= 0 )
214                 {
215                     result.append( element.substring( pos + 1 ) );
216                 }
217                 else
218                 {
219                     result.append( element );
220                 }
221 
222             }
223             else
224             {
225                 result.append( (String) null );
226             }
227         }
228         return result.toString();
229     }
230 
231     @Override
232     public Iterator<String> iterator()
233     {
234         return unmodifiableElements.iterator();
235     }
236 }