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