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