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