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