1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.geronimo.mavenplugins.selenium;
21
22 import java.io.File;
23 import java.io.PrintWriter;
24 import java.io.BufferedWriter;
25 import java.io.FileWriter;
26
27 import java.net.URL;
28 import java.net.MalformedURLException;
29 import java.util.Map;
30
31 import org.apache.maven.project.MavenProject;
32 import org.apache.maven.artifact.Artifact;
33 import org.apache.maven.plugin.MojoFailureException;
34 import org.apache.maven.plugin.MojoExecutionException;
35
36 import org.apache.geronimo.genesis.AntMojoSupport;
37 import org.apache.geronimo.genesis.ObjectHolder;
38
39 import org.apache.commons.io.IOUtils;
40
41 import org.apache.tools.ant.taskdefs.Java;
42 import org.apache.tools.ant.types.Environment;
43 import org.apache.tools.ant.types.Path;
44
45 import org.codehaus.plexus.util.FileUtils;
46
47 /**
48 * Start the Selenium server.
49 *
50 * @goal start-server
51 *
52 * @version $Rev: 451403 $ $Date: 2006-09-29 12:48:14 -0700 (Fri, 29 Sep 2006) $
53 */
54 public class StartServerMojo
55 extends AntMojoSupport
56 {
57 /**
58 * The port number the server will use.
59 *
60 * @parameter expression="${port}" default-value="4444"
61 */
62 private int port = -1;
63
64 /**
65 * Timeout for the server in seconds.
66 *
67 * @parameter expression="${timeout}" default-value="-1"
68 */
69 private int timeout = -1;
70
71 /**
72 * Enable the server's debug mode..
73 *
74 * @parameter expression="${debug}" default-value="false"
75 */
76 private boolean debug = false;
77
78 /**
79 * The file or resource to use for default user-extentions.js.
80 *
81 * @parameter default-value="org/apache/geronimo/mavenplugins/selenium/default-user-extentions.js"
82 */
83 private String defaultUserExtensions = null;
84
85 /**
86 * Enable or disable default user-extentions.js
87 *
88 * @parameter default-value="true"
89 */
90 private boolean defaultUserExtensionsEnabled = true;
91
92 /**
93 * Location of the user-extentions.js to load into the server.
94 * If defaultUserExtensionsEnabled is true, then this file will be appended to the defaults.
95 *
96 * @parameter
97 */
98 private String userExtensions = null;
99
100 /**
101 * Map of of plugin artifacts.
102 *
103 * @parameter expression="${plugin.artifactMap}"
104 * @required
105 * @readonly
106 */
107 private Map pluginArtifactMap = null;
108
109 /**
110 * Working directory where Selenium server will be started from.
111 *
112 * @parameter expression="${project.build.directory}/selenium"
113 * @required
114 */
115 private File workingDirectory = null;
116
117 /**
118 * Enable logging mode.
119 *
120 * @parameter expression="${logOutput}" default-value="false"
121 */
122 protected boolean logOutput = false;
123
124 /**
125 * The file that Selenium server logs will be written to.
126 *
127 * @parameter expression="${logFile}" default-value="${project.build.directory}/selenium/server.log"
128 * @required
129 */
130 private File logFile = null;
131
132 /**
133 * Flag to control if we background the server or block Maven execution.
134 *
135 * @parameter default-value="false"
136 * @required
137 */
138 private boolean background = false;
139
140
141
142
143
144 /**
145 * The maven project.
146 *
147 * @parameter expression="${project}"
148 * @required
149 * @readonly
150 */
151 private MavenProject project = null;
152
153 protected MavenProject getProject() {
154 return project;
155 }
156
157
158
159
160
161 private File getPluginArchive() {
162 String path = getClass().getProtectionDomain().getCodeSource().getLocation().getFile();
163 return new File(path);
164 }
165
166 private Artifact getPluginArtifact(final String name) throws MojoExecutionException {
167 Artifact artifact = (Artifact)pluginArtifactMap.get(name);
168 if (artifact == null) {
169 throw new MojoExecutionException("Unable to locate '" + name + "' in the list of plugin artifacts");
170 }
171
172 return artifact;
173 }
174
175 protected void doExecute() throws Exception {
176 log.info("Starting Selenium server...");
177
178 final Java java = (Java)createTask("java");
179
180 FileUtils.forceMkdir(workingDirectory);
181
182 java.setFork(true);
183 java.setDir(workingDirectory);
184 java.setFailonerror(true);
185
186 if (logOutput) {
187 FileUtils.forceMkdir(logFile.getParentFile());
188
189 log.info("Redirecting output to: " + logFile);
190
191 java.setLogError(true);
192 java.setOutput(logFile);
193 }
194
195 java.setClassname("org.openqa.selenium.server.SeleniumServer");
196
197 Path classpath = java.createClasspath();
198 classpath.createPathElement().setLocation(getPluginArchive());
199 classpath.createPathElement().setLocation(getPluginArtifact("log4j:log4j").getFile());
200 classpath.createPathElement().setLocation(getPluginArtifact("org.openqa.selenium.server:selenium-server").getFile());
201
202 Environment.Variable var;
203
204 var = new Environment.Variable();
205 var.setKey("selenium.log");
206 var.setFile(logFile);
207 java.addSysproperty(var);
208
209 var = new Environment.Variable();
210 var.setKey("selenium.loglevel");
211 var.setValue(debug == true ? "DEBUG" : "INFO");
212 java.addSysproperty(var);
213
214 var = new Environment.Variable();
215 var.setKey("log4j.configuration");
216 var.setValue("org/apache/geronimo/mavenplugins/selenium/log4j.properties");
217 java.addSysproperty(var);
218
219
220
221 java.createArg().setValue("-port");
222 java.createArg().setValue(String.valueOf(port));
223
224 if (debug) {
225 java.createArg().setValue("-debug");
226 }
227
228 if (timeout > 0) {
229 log.info("Timeout after: " + timeout + " seconds");
230
231 java.createArg().setValue("-timeout");
232 java.createArg().setValue(String.valueOf(timeout));
233 }
234
235 File userExtentionsFile = getUserExtentionsFile();
236 if (userExtentionsFile != null) {
237 log.info("User extensions: " + userExtentionsFile);
238
239 java.createArg().setValue("-userExtensions");
240 java.createArg().setFile(userExtentionsFile);
241 }
242
243
244 final ObjectHolder errorHolder = new ObjectHolder();
245
246
247 Thread t = new Thread("Selenium Server Runner") {
248 public void run() {
249 try {
250 java.execute();
251 }
252 catch (Exception e) {
253 errorHolder.set(e);
254
255
256
257
258
259 }
260 }
261 };
262 t.start();
263
264 log.debug("Waiting for Selenium server...");
265
266
267 URL url = new URL("http://localhost:" + port + "/selenium-server");
268 boolean started = false;
269 while (!started) {
270 if (errorHolder.isSet()) {
271 throw new MojoExecutionException("Failed to start Selenium server", (Throwable)errorHolder.get());
272 }
273
274 log.debug("Trying connection to: " + url);
275
276 try {
277 Object input = url.openConnection().getContent();
278 started = true;
279 }
280 catch (Exception e) {
281
282 }
283
284 Thread.sleep(1000);
285 }
286
287 log.info("Selenium server started");
288
289 if (!background) {
290 log.info("Waiting for Selenium to shutdown...");
291
292 t.join();
293 }
294 }
295
296 /**
297 * Resolve a resource to a file, URL or resource.
298 */
299 private URL resolveResource(final String name) throws MalformedURLException, MojoFailureException {
300 assert name != null;
301
302 URL url;
303
304 File file = new File(name);
305 if (file.exists()) {
306 url = file.toURL();
307 }
308 else {
309 try {
310 url = new URL(name);
311 }
312 catch (MalformedURLException e) {
313 url = Thread.currentThread().getContextClassLoader().getResource(name);
314 }
315 }
316
317 if (url == null) {
318 throw new MojoFailureException("Could not resolve resource: " + name);
319 }
320
321 log.debug("Resolved resource '" + name + "' as: " + url);
322
323 return url;
324 }
325
326 /**
327 * Retutn the user-extentions.js file to use, or null if it should not be installed.
328 */
329 private File getUserExtentionsFile() throws Exception {
330 if (!defaultUserExtensionsEnabled && userExtensions == null) {
331 return null;
332 }
333
334
335 File file = new File(workingDirectory, "user-extensions.js");
336 if (file.exists()) {
337 log.debug("Reusing previously generated file: " + file);
338
339 return file;
340 }
341
342 PrintWriter writer = new PrintWriter(new BufferedWriter(new FileWriter(file)));
343
344 if (defaultUserExtensionsEnabled) {
345 URL url = resolveResource(defaultUserExtensions);
346 log.debug("Using defaults: " + url);
347
348 writer.println("//");
349 writer.println("// Default user extentions; from: " + url);
350 writer.println("//");
351
352 IOUtils.copy(url.openStream(), writer);
353 }
354
355 if (userExtensions != null) {
356 URL url = resolveResource(userExtensions);
357 log.debug("Using user extentions: " + url);
358
359 writer.println("//");
360 writer.println("// User extentions; from: " + url);
361 writer.println("//");
362
363 IOUtils.copy(url.openStream(), writer);
364 }
365
366 writer.flush();
367 writer.close();
368
369 return file;
370 }
371 }