View Javadoc
1   package org.apache.maven.plugin.surefire;
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.io.FileInputStream;
24  import java.io.IOException;
25  import java.io.InputStream;
26  import java.util.Collection;
27  import java.util.Collections;
28  import java.util.Enumeration;
29  import java.util.HashSet;
30  import java.util.LinkedHashSet;
31  import java.util.List;
32  import java.util.Map;
33  import java.util.Properties;
34  import java.util.Set;
35  
36  import org.apache.maven.surefire.booter.Classpath;
37  import org.apache.maven.surefire.booter.KeyValueSource;
38  import org.apache.maven.surefire.util.internal.StringUtils;
39  
40  import static java.util.Arrays.asList;
41  
42  /**
43   * A properties implementation that preserves insertion order.
44   */
45  public class SurefireProperties
46      extends Properties
47      implements KeyValueSource
48  {
49      private static final Collection<String> KEYS_THAT_CANNOT_BE_USED_AS_SYSTEM_PROPERTIES =
50              asList( "java.library.path", "file.encoding", "jdk.map.althashing.threshold", "line.separator" );
51  
52      private final LinkedHashSet<Object> items = new LinkedHashSet<Object>();
53  
54      public SurefireProperties()
55      {
56      }
57  
58      public SurefireProperties( Properties source )
59      {
60          if ( source != null )
61          {
62              this.putAll( source );
63          }
64      }
65  
66      public SurefireProperties( KeyValueSource source )
67      {
68          if ( source != null )
69          {
70              source.copyTo( this );
71          }
72      }
73  
74      @Override
75      public synchronized Object put( Object key, Object value )
76      {
77          items.add( key );
78          return super.put( key, value );
79      }
80  
81      @Override
82      public synchronized Object remove( Object key )
83      {
84          items.remove( key );
85          return super.remove( key );
86      }
87  
88      @Override
89      public synchronized void clear()
90      {
91          items.clear();
92          super.clear();
93      }
94  
95      @Override
96      public synchronized Enumeration<Object> keys()
97      {
98          return Collections.enumeration( items );
99      }
100 
101     public void copyPropertiesFrom( Properties source )
102     {
103         if ( source != null )
104         {
105             putAll( source );
106         }
107     }
108 
109     public Iterable<Object> getStringKeySet()
110     {
111         //noinspection unchecked
112         return keySet();
113     }
114 
115     public Set<Object> propertiesThatCannotBeSetASystemProperties()
116     {
117         Set<Object> result = new HashSet<Object>();
118         for ( Object key : getStringKeySet() )
119         {
120             if ( KEYS_THAT_CANNOT_BE_USED_AS_SYSTEM_PROPERTIES.contains( key ) )
121             {
122                 result.add( key );
123             }
124         }
125         return result;
126     }
127 
128     public void copyToSystemProperties()
129     {
130 
131         //noinspection unchecked
132         for ( Object o : items )
133         {
134             String key = (String) o;
135             String value = getProperty( key );
136 
137             System.setProperty( key, value );
138         }
139     }
140 
141     static SurefireProperties calculateEffectiveProperties( Properties systemProperties,
142                                                             Map<String, String> systemPropertyVariables,
143                                                             Properties userProperties, SurefireProperties props )
144     {
145         SurefireProperties result = new SurefireProperties();
146         result.copyPropertiesFrom( systemProperties );
147 
148         result.copyPropertiesFrom( props );
149 
150         copyProperties( result, systemPropertyVariables );
151 
152         // We used to take all of our system properties and dump them in with the
153         // user specified properties for SUREFIRE-121, causing SUREFIRE-491.
154         // Not gonna do THAT any more... instead, we only propagate those system properties
155         // that have been explicitly specified by the user via -Dkey=value on the CLI
156 
157         result.copyPropertiesFrom( userProperties );
158         return result;
159     }
160 
161     public static void copyProperties( Properties target, Map<String, String> source )
162     {
163         if ( source != null )
164         {
165             for ( String key : source.keySet() )
166             {
167                 String value = source.get( key );
168                 target.setProperty( key, value == null ? "" : value );
169             }
170         }
171     }
172 
173     @Override
174     public void copyTo( Map<Object, Object> target )
175     {
176         target.putAll( this );
177     }
178 
179     public void setProperty( String key, File file )
180     {
181         if ( file != null )
182         {
183             setProperty( key, file.toString() );
184         }
185     }
186 
187     public void setProperty( String key, Boolean aBoolean )
188     {
189         if ( aBoolean != null )
190         {
191             setProperty( key, aBoolean.toString() );
192         }
193     }
194 
195     public void setProperty( String key, Long value )
196     {
197         if ( value != null )
198         {
199             setProperty( key, value.toString() );
200         }
201     }
202 
203     public void addList( List<?> items, String propertyPrefix )
204     {
205         if ( items != null && !items.isEmpty() )
206         {
207             int i = 0;
208             for ( Object item : items )
209             {
210                 if ( item == null )
211                 {
212                     throw new NullPointerException( propertyPrefix + i + " has null value" );
213                 }
214 
215                 String[] stringArray = StringUtils.split( item.toString(), "," );
216 
217                 for ( String aStringArray : stringArray )
218                 {
219                     setProperty( propertyPrefix + i, aStringArray );
220                     i++;
221                 }
222             }
223         }
224     }
225 
226     public void setClasspath( String prefix, Classpath classpath )
227     {
228         List<String> classpathElements = classpath.getClassPath();
229         for ( int i = 0; i < classpathElements.size(); ++i )
230         {
231             String element = classpathElements.get( i );
232             setProperty( prefix + i, element );
233         }
234     }
235 
236     private static SurefireProperties loadProperties( InputStream inStream )
237         throws IOException
238     {
239         try
240         {
241             Properties p = new Properties();
242             p.load( inStream );
243             return new SurefireProperties( p );
244         }
245         finally
246         {
247             close( inStream );
248         }
249     }
250 
251     public static SurefireProperties loadProperties( File file )
252         throws IOException
253     {
254         return file == null ? new SurefireProperties() : loadProperties( new FileInputStream( file ) );
255     }
256 
257     private static void close( InputStream inputStream )
258     {
259         try
260         {
261             inputStream.close();
262         }
263         catch ( IOException ex )
264         {
265             // ignore
266         }
267     }
268 
269     public void setNullableProperty( String key, String value )
270     {
271         if ( value != null )
272         {
273             super.setProperty( key, value );
274         }
275     }
276 }