1 package org.apache.maven.plugin.surefire.booterclient;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.File;
23 import java.io.FileOutputStream;
24 import java.io.IOException;
25 import java.util.HashMap;
26 import java.util.Iterator;
27 import java.util.List;
28 import java.util.Map;
29 import java.util.Properties;
30 import java.util.jar.JarEntry;
31 import java.util.jar.JarOutputStream;
32 import java.util.jar.Manifest;
33 import org.apache.maven.surefire.booter.ClassLoaderConfiguration;
34 import org.apache.maven.surefire.booter.Classpath;
35 import org.apache.maven.surefire.booter.ForkedBooter;
36 import org.apache.maven.surefire.booter.SurefireBooterForkException;
37 import org.apache.maven.surefire.util.Relocator;
38 import org.apache.maven.surefire.util.UrlUtils;
39 import org.codehaus.plexus.util.StringUtils;
40 import org.codehaus.plexus.util.cli.Commandline;
41
42
43
44
45
46
47
48
49 public class ForkConfiguration
50 {
51 public static final String FORK_ONCE = "once";
52
53 public static final String FORK_ALWAYS = "always";
54
55 public static final String FORK_NEVER = "never";
56
57 private final Classpath bootClasspathConfiguration;
58
59 private final String forkMode;
60
61 private Properties systemProperties;
62
63 private String jvmExecutable;
64
65 private String argLine;
66
67 private Map environmentVariables;
68
69 private File workingDirectory;
70
71 private File tempDirectory;
72
73 private boolean debug;
74
75 private String debugLine;
76
77 public ForkConfiguration( Classpath bootClasspathConfiguration, String forkMode, File tmpDir )
78 {
79 this.bootClasspathConfiguration = bootClasspathConfiguration;
80 this.forkMode = getForkMode( forkMode );
81 this.tempDirectory = tmpDir;
82 }
83
84 public Classpath getBootClasspath()
85 {
86 return bootClasspathConfiguration;
87 }
88
89 private static String getForkMode( String forkMode )
90 {
91 if ( "pertest".equalsIgnoreCase( forkMode ) )
92 {
93 return FORK_ALWAYS;
94 }
95 else if ( "none".equalsIgnoreCase( forkMode ) )
96 {
97 return FORK_NEVER;
98 }
99 else if ( forkMode.equals( FORK_NEVER ) || forkMode.equals( FORK_ONCE ) || forkMode.equals( FORK_ALWAYS ) )
100 {
101 return forkMode;
102 }
103 else
104 {
105 throw new IllegalArgumentException( "Fork mode " + forkMode + " is not a legal value" );
106 }
107 }
108
109 public boolean isForking()
110 {
111 return !FORK_NEVER.equals( forkMode );
112 }
113
114 public void setSystemProperties( Properties systemProperties )
115 {
116 this.systemProperties = (Properties) systemProperties.clone();
117 }
118
119 public void setJvmExecutable( String jvmExecutable )
120 {
121 this.jvmExecutable = jvmExecutable;
122 }
123
124 public void setArgLine( String argLine )
125 {
126 this.argLine = argLine;
127 }
128
129 public void setDebugLine( String debugLine )
130 {
131 this.debugLine = debugLine;
132 }
133
134 public void setEnvironmentVariables( Map environmentVariables )
135 {
136 this.environmentVariables = new HashMap( environmentVariables );
137 }
138
139 public void setWorkingDirectory( File workingDirectory )
140 {
141 this.workingDirectory = workingDirectory;
142 }
143
144 public void setTempDirectory( File tempDirectory )
145 {
146 this.tempDirectory = tempDirectory;
147 }
148
149
150 public String getForkMode()
151 {
152 return forkMode;
153 }
154
155 public Properties getSystemProperties()
156 {
157 return systemProperties;
158 }
159
160
161
162
163
164
165
166
167
168 public Commandline createCommandLine( List classPath, ClassLoaderConfiguration classpathConfiguration,
169 boolean shadefire )
170 throws SurefireBooterForkException
171 {
172 return createCommandLine( classPath, classpathConfiguration.isManifestOnlyJarRequestedAndUsable(), shadefire );
173 }
174
175 public Commandline createCommandLine( List classPath, boolean useJar, boolean shadefire )
176 throws SurefireBooterForkException
177 {
178 Commandline cli = new Commandline();
179
180 cli.setExecutable( jvmExecutable );
181
182 if ( argLine != null )
183 {
184 cli.createArg().setLine( stripNewLines( argLine ) );
185 }
186
187 if ( environmentVariables != null )
188 {
189 Iterator iter = environmentVariables.keySet().iterator();
190
191 while ( iter.hasNext() )
192 {
193 String key = (String) iter.next();
194
195 String value = (String) environmentVariables.get( key );
196
197 cli.addEnvironment( key, value );
198 }
199 }
200
201 if ( getDebugLine() != null && !"".equals( getDebugLine() ) )
202 {
203 cli.createArg().setLine( getDebugLine() );
204 }
205
206 if ( useJar )
207 {
208 File jarFile;
209 try
210 {
211 jarFile = createJar( classPath );
212 }
213 catch ( IOException e )
214 {
215 throw new SurefireBooterForkException( "Error creating archive file", e );
216 }
217
218 cli.createArg().setValue( "-jar" );
219
220 cli.createArg().setValue( jarFile.getAbsolutePath() );
221 }
222 else
223 {
224 cli.addEnvironment( "CLASSPATH", StringUtils.join( classPath.iterator(), File.pathSeparator ) );
225
226 final String forkedBooter = ForkedBooter.class.getName();
227
228 cli.createArg().setValue( shadefire ? new Relocator().relocate( forkedBooter ) : forkedBooter );
229 }
230
231 cli.setWorkingDirectory( workingDirectory.getAbsolutePath() );
232
233 return cli;
234 }
235
236
237
238
239
240
241
242
243
244 public File createJar( List classPath )
245 throws IOException
246 {
247 File file = File.createTempFile( "surefirebooter", ".jar", tempDirectory );
248 if ( !debug )
249 {
250 file.deleteOnExit();
251 }
252 FileOutputStream fos = new FileOutputStream( file );
253 JarOutputStream jos = new JarOutputStream( fos );
254 jos.setLevel( JarOutputStream.STORED );
255 JarEntry je = new JarEntry( "META-INF/MANIFEST.MF" );
256 jos.putNextEntry( je );
257
258 Manifest man = new Manifest();
259
260
261
262 String cp = "";
263 for ( Iterator it = classPath.iterator(); it.hasNext(); )
264 {
265 String el = (String) it.next();
266
267 cp += UrlUtils.getURL( new File( el ) ).toExternalForm() + " ";
268 }
269
270 man.getMainAttributes().putValue( "Manifest-Version", "1.0" );
271 man.getMainAttributes().putValue( "Class-Path", cp.trim() );
272 man.getMainAttributes().putValue( "Main-Class", ForkedBooter.class.getName() );
273
274 man.write( jos );
275 jos.close();
276
277 return file;
278 }
279
280 public void setDebug( boolean debug )
281 {
282 this.debug = debug;
283 }
284
285 public boolean isDebug()
286 {
287 return debug;
288 }
289
290 public String stripNewLines( String argline )
291 {
292 return argline.replace( "\n", " " ).replace( "\r", " " );
293 }
294
295 public String getDebugLine()
296 {
297 return debugLine;
298 }
299
300
301 public File getTempDirectory()
302 {
303 return tempDirectory;
304 }
305 }