View Javadoc
1   package org.apache.maven.plugin.invoker;
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.util.ArrayList;
24  import java.util.Arrays;
25  import java.util.Properties;
26  
27  import org.apache.maven.shared.invoker.InvocationRequest;
28  import org.codehaus.plexus.util.StringUtils;
29  
30  /**
31   * Provides a convenient facade around the <code>invoker.properties</code>.
32   * 
33   * @author Benjamin Bentmann
34   * @version $Id: InvokerProperties.java 1637968 2014-11-10 20:02:25Z khmarbaise $
35   */
36  class InvokerProperties
37  {
38  
39      private enum InvocationProperty
40      {
41          PROJECT( "invoker.project" ),
42          GOALS( "invoker.goals" ),
43          PROFILES( "invoker.profiles" ),
44          MAVEN_OPTS( "invoker.mavenOpts" ),
45          FAILURE_BEHAVIOR( "invoker.failureBehavior" ),
46          NON_RECURSIVE( "invoker.nonRecursive" ),
47          OFFLINE( "invoker.offline" ),
48          SYSTEM_PROPERTIES_FILE( "invoker.systemPropertiesFile" ),
49          DEBUG( "invoker.debug" );
50  
51          private final String key;
52  
53          private InvocationProperty( final String s )
54          {
55              this.key = s;
56          }
57  
58          @Override
59          public String toString()
60          {
61              return key;
62          }
63      }
64  
65      /**
66       * The invoker properties being wrapped.
67       */
68      private final Properties properties;
69  
70      /**
71       * Creates a new facade for the specified invoker properties. The properties will not be copied, so any changes to
72       * them will be reflected by the facade.
73       * 
74       * @param properties The invoker properties to wrap, may be <code>null</code> if none.
75       */
76      public InvokerProperties( Properties properties )
77      {
78          this.properties = ( properties != null ) ? properties : new Properties();
79      }
80  
81      /**
82       * Gets the invoker properties being wrapped.
83       * 
84       * @return The invoker properties being wrapped, never <code>null</code>.
85       */
86      public Properties getProperties()
87      {
88          return this.properties;
89      }
90  
91      /**
92       * Gets the name of the corresponding build job.
93       * 
94       * @return The name of the build job or an empty string if not set.
95       */
96      public String getJobName()
97      {
98          return this.properties.getProperty( "invoker.name", "" );
99      }
100 
101     /**
102      * Gets the description of the corresponding build job.
103      * 
104      * @return The description of the build job or an empty string if not set.
105      */
106     public String getJobDescription()
107     {
108         return this.properties.getProperty( "invoker.description", "" );
109     }
110 
111     /**
112      * Gets the specification of JRE versions on which this build job should be run.
113      * 
114      * @return The specification of JRE versions or an empty string if not set.
115      */
116     public String getJreVersion()
117     {
118         return this.properties.getProperty( "invoker.java.version", "" );
119     }
120 
121     /**
122      * Gets the specification of Maven versions on which this build job should be run.
123      *
124      * @return The specification of Maven versions on which this build job should be run.
125      * @since 1.5
126      */
127     public String getMavenVersion()
128     {
129         return this.properties.getProperty( "invoker.maven.version", "" );
130     }
131 
132     /**
133      * Gets the specification of OS families on which this build job should be run.
134      * 
135      * @return The specification of OS families or an empty string if not set.
136      */
137     public String getOsFamily()
138     {
139         return this.properties.getProperty( "invoker.os.family", "" );
140     }
141 
142     /**
143      * Determines whether these invoker properties contain a build definition for the specified invocation index.
144      * 
145      * @param index The one-based index of the invocation to check for, must not be negative.
146      * @return <code>true</code> if the invocation with the specified index is defined, <code>false</code> otherwise.
147      */
148     public boolean isInvocationDefined( int index )
149     {
150         for ( InvocationProperty prop : InvocationProperty.values() )
151         {
152             if ( properties.getProperty( prop.toString() + '.' + index ) != null )
153             {
154                 return true;
155             }
156         }
157         return false;
158     }
159 
160     /**
161      * Configures the specified invocation request from these invoker properties. Settings not present in the invoker
162      * properties will be left unchanged in the invocation request.
163      * 
164      * @param request The invocation request to configure, must not be <code>null</code>.
165      * @param index The one-based index of the invocation to configure, must not be negative.
166      */
167     public void configureInvocation( InvocationRequest request, int index )
168     {
169         String project = get( InvocationProperty.PROJECT, index );
170         if ( project != null )
171         {
172             File file = new File( request.getBaseDirectory(), project );
173             if ( file.isFile() )
174             {
175                 request.setBaseDirectory( file.getParentFile() );
176                 request.setPomFile( file );
177             }
178             else
179             {
180                 request.setBaseDirectory( file );
181                 request.setPomFile( null );
182             }
183         }
184 
185         String goals = get( InvocationProperty.GOALS, index );
186         if ( goals != null )
187         {
188             request.setGoals( new ArrayList<String>( Arrays.asList( StringUtils.split( goals, ", \t\n\r\f" ) ) ) );
189         }
190 
191         String profiles = get( InvocationProperty.PROFILES, index );
192         if ( profiles != null )
193         {
194             // CHECKSTYLE_OFF: LineLength
195             request.setProfiles( new ArrayList<String>( Arrays.asList( StringUtils.split( profiles, ", \t\n\r\f" ) ) ) );
196             // CHECKSTYLE_ON: LineLength
197         }
198 
199         String mvnOpts = get( InvocationProperty.MAVEN_OPTS, index );
200         if ( mvnOpts != null )
201         {
202             request.setMavenOpts( mvnOpts );
203         }
204 
205         String failureBehavior = get( InvocationProperty.FAILURE_BEHAVIOR, index );
206         if ( failureBehavior != null )
207         {
208             request.setFailureBehavior( failureBehavior );
209         }
210 
211         String nonRecursive = get( InvocationProperty.NON_RECURSIVE, index );
212         if ( nonRecursive != null )
213         {
214             request.setRecursive( !Boolean.valueOf( nonRecursive ) );
215         }
216 
217         String offline = get( InvocationProperty.OFFLINE, index );
218         if ( offline != null )
219         {
220             request.setOffline( Boolean.valueOf( offline ) );
221         }
222 
223         String debug = get( InvocationProperty.DEBUG, index );
224         if ( debug != null )
225         {
226             request.setDebug( Boolean.valueOf( debug ) );
227         }
228     }
229 
230     /**
231      * Checks whether the specified exit code matches the one expected for the given invocation.
232      * 
233      * @param exitCode The exit code of the Maven invocation to check.
234      * @param index The index of the invocation for which to check the exit code, must not be negative.
235      * @return <code>true</code> if the exit code is zero and a success was expected or if the exit code is non-zero and
236      *         a failue was expected, <code>false</code> otherwise.
237      */
238     public boolean isExpectedResult( int exitCode, int index )
239     {
240         boolean nonZeroExit = "failure".equalsIgnoreCase( get( "invoker.buildResult", index ) );
241         return ( exitCode != 0 ) == nonZeroExit;
242     }
243 
244     /**
245      * Gets the path to the properties file used to set the system properties for the specified invocation.
246      * 
247      * @param index The index of the invocation for which to check the exit code, must not be negative.
248      * @return The path to the properties file or <code>null</code> if not set.
249      */
250     public String getSystemPropertiesFile( int index )
251     {
252         return get( InvocationProperty.SYSTEM_PROPERTIES_FILE, index );
253     }
254 
255     /**
256      * Gets a value from the invoker properties. The invoker properties are intended to describe the invocation settings
257      * for multiple builds of the same project. For this reason, the properties are indexed. First, a property named
258      * <code>key.index</code> will be queried. If this property does not exist, the value of the property named
259      * <code>key</code> will finally be returned.
260      * 
261      * @param key The (base) key for the invoker property to lookup, must not be <code>null</code>.
262      * @param index The index of the invocation for which to retrieve the value, must not be negative.
263      * @return The value for the requested invoker property or <code>null</code> if not defined.
264      */
265     String get( String key, int index )
266     {
267         if ( index < 0 )
268         {
269             throw new IllegalArgumentException( "invalid invocation index: " + index );
270         }
271 
272         String value = properties.getProperty( key + '.' + index );
273         if ( value == null )
274         {
275             value = properties.getProperty( key );
276         }
277         return value;
278     }
279 
280     private String get( InvocationProperty prop, int index )
281     {
282         return get( prop.toString(), index );
283     }
284 }