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" );
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      public synchronized Enumeration<Object> keys()
96      {
97          return Collections.enumeration( items );
98      }
99  
100     public void copyPropertiesFrom( Properties source )
101     {
102         if ( source != null )
103         {
104             putAll( source );
105         }
106     }
107 
108     public Iterable<Object> getStringKeySet()
109     {
110         //noinspection unchecked
111         return keySet();
112     }
113 
114     public Set<Object> propertiesThatCannotBeSetASystemProperties()
115     {
116         Set<Object> result = new HashSet<Object>();
117         for ( Object key : getStringKeySet() )
118         {
119             if ( KEYS_THAT_CANNOT_BE_USED_AS_SYSTEM_PROPERTIES.contains( key ) )
120             {
121                 result.add( key );
122             }
123         }
124         return result;
125     }
126 
127     public void copyToSystemProperties()
128     {
129 
130         //noinspection unchecked
131         for ( Object o : items )
132         {
133             String key = (String) o;
134             String value = getProperty( key );
135 
136             System.setProperty( key, value );
137         }
138     }
139 
140     static SurefireProperties calculateEffectiveProperties( Properties systemProperties,
141                                                             Map<String, String> systemPropertyVariables,
142                                                             Properties userProperties, SurefireProperties props )
143     {
144         SurefireProperties result = new SurefireProperties();
145         result.copyPropertiesFrom( systemProperties );
146 
147         result.copyPropertiesFrom( props );
148 
149         copyProperties( result, systemPropertyVariables );
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     public void copyTo( Map<Object, Object> target )
174     {
175         target.putAll( this );
176     }
177 
178     public void setProperty( String key, File file )
179     {
180         if ( file != null )
181         {
182             setProperty( key, file.toString() );
183         }
184     }
185 
186     public void setProperty( String key, Boolean aBoolean )
187     {
188         if ( aBoolean != null )
189         {
190             setProperty( key, aBoolean.toString() );
191         }
192     }
193 
194     public void addList( List<?> items, String propertyPrefix )
195     {
196         if ( items != null && !items.isEmpty() )
197         {
198             int i = 0;
199             for ( Object item : items )
200             {
201                 if ( item == null )
202                 {
203                     throw new NullPointerException( propertyPrefix + i + " has null value" );
204                 }
205 
206                 String[] stringArray = StringUtils.split( item.toString(), "," );
207 
208                 for ( String aStringArray : stringArray )
209                 {
210                     setProperty( propertyPrefix + i, aStringArray );
211                     i++;
212                 }
213             }
214         }
215     }
216 
217     public void setClasspath( String prefix, Classpath classpath )
218     {
219         List<String> classpathElements = classpath.getClassPath();
220         for ( int i = 0; i < classpathElements.size(); ++i )
221         {
222             String element = classpathElements.get( i );
223             setProperty( prefix + i, element );
224         }
225     }
226 
227     private static SurefireProperties loadProperties( InputStream inStream )
228         throws IOException
229     {
230         try
231         {
232             Properties p = new Properties();
233             p.load( inStream );
234             return new SurefireProperties( p );
235         }
236         finally
237         {
238             close( inStream );
239         }
240     }
241 
242     public static SurefireProperties loadProperties( File file )
243         throws IOException
244     {
245         return file == null ? new SurefireProperties() : loadProperties( new FileInputStream( file ) );
246     }
247 
248     private static void close( InputStream inputStream )
249     {
250         try
251         {
252             inputStream.close();
253         }
254         catch ( IOException ex )
255         {
256             // ignore
257         }
258     }
259 
260     public void setNullableProperty( String key, String value )
261     {
262         if ( value != null )
263         {
264             super.setProperty( key, value );
265         }
266     }
267 }