1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.jetty.maven.plugin;
20
21 import java.io.File;
22 import java.io.FileInputStream;
23 import java.io.InputStream;
24 import java.net.URL;
25 import java.util.ArrayList;
26 import java.util.Enumeration;
27 import java.util.HashSet;
28 import java.util.Iterator;
29 import java.util.List;
30 import java.util.Properties;
31 import java.util.Set;
32 import java.util.TreeMap;
33
34 import org.eclipse.jetty.server.Connector;
35 import org.eclipse.jetty.server.Handler;
36 import org.eclipse.jetty.server.ShutdownMonitor;
37 import org.eclipse.jetty.server.handler.HandlerCollection;
38 import org.eclipse.jetty.util.log.Log;
39 import org.eclipse.jetty.util.log.Logger;
40 import org.eclipse.jetty.util.resource.Resource;
41 import org.eclipse.jetty.util.resource.ResourceCollection;
42 import org.eclipse.jetty.xml.XmlConfiguration;
43
44
45
46
47
48
49
50
51
52 public class Starter
53 {
54 public static final String PORT_SYSPROPERTY = "jetty.port";
55 private static final Logger LOG = Log.getLogger(Starter.class);
56
57 private List<File> jettyXmls;
58 private File contextXml;
59
60 private JettyServer server = new JettyServer();
61 private JettyWebAppContext webApp;
62
63
64 private int stopPort=0;
65 private String stopKey=null;
66 private Properties props;
67 private String token;
68
69
70
71
72
73
74
75
76
77 public class Artifact
78 {
79 public String gid;
80 public String aid;
81 public String path;
82 public Resource resource;
83
84 public Artifact (String csv)
85 {
86 if (csv != null && !"".equals(csv))
87 {
88 String[] atoms = csv.split(",");
89 if (atoms.length >= 3)
90 {
91 gid = atoms[0].trim();
92 aid = atoms[1].trim();
93 path = atoms[2].trim();
94 }
95 }
96 }
97
98 public Artifact (String gid, String aid, String path)
99 {
100 this.gid = gid;
101 this.aid = aid;
102 this.path = path;
103 }
104
105 public boolean equals(Object o)
106 {
107 if (!(o instanceof Artifact))
108 return false;
109
110 Artifact ao = (Artifact)o;
111 return (((gid == null && ao.gid == null) || (gid != null && gid.equals(ao.gid)))
112 && ((aid == null && ao.aid == null) || (aid != null && aid.equals(ao.aid))));
113 }
114 }
115
116
117
118
119
120
121 public void configureJetty () throws Exception
122 {
123 LOG.debug("Starting Jetty Server ...");
124
125
126 applyJettyXml ();
127
128
129
130 Connector[] connectors = this.server.getConnectors();
131 if (connectors == null|| connectors.length == 0)
132 {
133
134 MavenServerConnector httpConnector = new MavenServerConnector();
135 httpConnector.setServer(this.server);
136 String tmp = System.getProperty(PORT_SYSPROPERTY, MavenServerConnector.DEFAULT_PORT_STR);
137 httpConnector.setPort(Integer.parseInt(tmp.trim()));
138 connectors = new Connector[] {httpConnector};
139 this.server.setConnectors(connectors);
140 }
141
142
143 HandlerCollection handlers = (HandlerCollection) server.getChildHandlerByClass(HandlerCollection.class);
144 if (handlers == null)
145 {
146 handlers = new HandlerCollection();
147 server.setHandler(handlers);
148 }
149
150
151 this.server.configureHandlers();
152
153 webApp = new JettyWebAppContext();
154
155
156 configureWebApp();
157
158
159 if (webApp.getTempDirectory() != null)
160 {
161 File qs = new File (webApp.getTempDirectory(), "quickstart-web.xml");
162 if (qs.exists() && qs.isFile())
163 webApp.setQuickStartWebDescriptor(Resource.newResource(qs));
164 }
165
166
167
168
169
170
171
172 if (contextXml != null)
173 {
174 XmlConfiguration xmlConfiguration = new XmlConfiguration(Resource.toURL(contextXml));
175 xmlConfiguration.getIdMap().put("Server",server);
176 xmlConfiguration.configure(webApp);
177 }
178
179 this.server.addWebApplication(webApp);
180
181 if(stopPort>0 && stopKey!=null)
182 {
183 ShutdownMonitor monitor = ShutdownMonitor.getInstance();
184 monitor.setPort(stopPort);
185 monitor.setKey(stopKey);
186 monitor.setExitVm(true);
187 }
188 }
189
190
191
192
193
194 public void configureWebApp ()
195 throws Exception
196 {
197 if (props == null)
198 return;
199
200
201
202 String str = (String)props.get("context.path");
203 if (str != null)
204 webApp.setContextPath(str);
205
206
207
208 str = (String)props.get("web.xml");
209 if (str != null)
210 webApp.setDescriptor(str);
211
212 str = (String)props.get("quickstart.web.xml");
213 if (str != null)
214 webApp.setQuickStartWebDescriptor(Resource.newResource(new File(str)));
215
216
217 str = (String)props.getProperty("tmp.dir");
218 if (str != null)
219 webApp.setTempDirectory(new File(str.trim()));
220
221 str = (String)props.getProperty("tmp.dir.persist");
222 if (str != null)
223 webApp.setPersistTempDirectory(Boolean.valueOf(str));
224
225
226 str = (String)props.getProperty("base.dirs");
227 if (str != null && !"".equals(str.trim()))
228 {
229 ResourceCollection bases = new ResourceCollection(str.split(","));
230 webApp.setWar(bases.getResources()[0].toString());
231 webApp.setBaseResource(bases);
232 }
233
234
235 str = (String)props.getProperty("base.first");
236 if (str != null && !"".equals(str.trim()))
237 webApp.setBaseAppFirst(Boolean.valueOf(str));
238
239
240
241 str = (String)props.getProperty("maven.war.includes");
242 List<String> defaultWarIncludes = fromCSV(str);
243 str = (String)props.getProperty("maven.war.excludes");
244 List<String> defaultWarExcludes = fromCSV(str);
245
246
247 List<Artifact> wars = new ArrayList<Artifact>();
248
249
250 TreeMap<String, OverlayConfig> orderedConfigs = new TreeMap<String, OverlayConfig>();
251 Enumeration<String> pnames = (Enumeration<String>)props.propertyNames();
252 while (pnames.hasMoreElements())
253 {
254 String n = pnames.nextElement();
255 if (n.startsWith("maven.war.artifact"))
256 {
257 Artifact a = new Artifact((String)props.get(n));
258 a.resource = Resource.newResource("jar:"+Resource.toURL(new File(a.path)).toString()+"!/");
259 wars.add(a);
260 }
261 else if (n.startsWith("maven.war.overlay"))
262 {
263 OverlayConfig c = new OverlayConfig ((String)props.get(n), defaultWarIncludes, defaultWarExcludes);
264 orderedConfigs.put(n,c);
265 }
266 }
267
268
269 Set<Artifact> matchedWars = new HashSet<Artifact>();
270
271
272 List<Overlay> overlays = new ArrayList<Overlay>();
273 for (OverlayConfig config:orderedConfigs.values())
274 {
275
276 if (config.isSkip())
277 continue;
278
279
280 if (config.isCurrentProject())
281 {
282 Overlay overlay = new Overlay(config, null);
283 overlays.add(overlay);
284 continue;
285 }
286
287
288 Artifact a = getArtifactForOverlayConfig(config, wars);
289 if (a != null)
290 {
291 matchedWars.add(a);
292 SelectiveJarResource r = new SelectiveJarResource(new URL("jar:"+Resource.toURL(new File(a.path)).toString()+"!/"));
293 r.setIncludes(config.getIncludes());
294 r.setExcludes(config.getExcludes());
295 Overlay overlay = new Overlay(config, r);
296 overlays.add(overlay);
297 }
298 }
299
300
301 for (Artifact a: wars)
302 {
303 if (!matchedWars.contains(a))
304 {
305 Overlay overlay = new Overlay(null, a.resource);
306 overlays.add(overlay);
307 }
308 }
309
310 webApp.setOverlays(overlays);
311
312
313
314 str = (String)props.getProperty("classes.dir");
315 if (str != null && !"".equals(str.trim()))
316 {
317 webApp.setClasses(new File(str));
318 }
319
320 str = (String)props.getProperty("testClasses.dir");
321 if (str != null && !"".equals(str.trim()))
322 {
323 webApp.setTestClasses(new File(str));
324 }
325
326
327
328 str = (String)props.getProperty("lib.jars");
329 if (str != null && !"".equals(str.trim()))
330 {
331 List<File> jars = new ArrayList<File>();
332 String[] names = str.split(",");
333 for (int j=0; names != null && j < names.length; j++)
334 jars.add(new File(names[j].trim()));
335 webApp.setWebInfLib(jars);
336 }
337
338 }
339
340
341
342
343
344 public void getConfiguration (String[] args)
345 throws Exception
346 {
347 for (int i=0; i<args.length; i++)
348 {
349
350 if ("--stop-port".equals(args[i]))
351 stopPort = Integer.parseInt(args[++i]);
352
353
354 if ("--stop-key".equals(args[i]))
355 stopKey = args[++i];
356
357
358 if ("--jetty-xml".equals(args[i]))
359 {
360 jettyXmls = new ArrayList<File>();
361 String[] names = args[++i].split(",");
362 for (int j=0; names!= null && j < names.length; j++)
363 {
364 jettyXmls.add(new File(names[j].trim()));
365 }
366 }
367
368
369 if ("--context-xml".equals(args[i]))
370 {
371 contextXml = new File(args[++i]);
372 }
373
374
375 if ("--props".equals(args[i]))
376 {
377 File f = new File(args[++i].trim());
378 props = new Properties();
379 try (InputStream in = new FileInputStream(f))
380 {
381 props.load(in);
382 }
383 }
384
385
386 if ("--token".equals(args[i]))
387 {
388 token = args[++i].trim();
389 }
390 }
391 }
392
393
394
395
396
397 public void run() throws Exception
398 {
399 LOG.info("Started Jetty Server");
400 server.start();
401 }
402
403
404
405
406
407 public void join () throws Exception
408 {
409 server.join();
410 }
411
412
413
414
415
416 public void communicateStartupResult (Exception e)
417 {
418 if (token != null)
419 {
420 if (e==null)
421 System.out.println(token);
422 else
423 System.out.println(token+"\t"+e.getMessage());
424 }
425 }
426
427
428
429
430
431
432 public void applyJettyXml() throws Exception
433 {
434 if (jettyXmls == null)
435 return;
436 this.server.applyXmlConfigurations(jettyXmls);
437 }
438
439
440
441
442
443
444
445
446 protected void prependHandler (Handler handler, HandlerCollection handlers)
447 {
448 if (handler == null || handlers == null)
449 return;
450
451 Handler[] existing = handlers.getChildHandlers();
452 Handler[] children = new Handler[existing.length + 1];
453 children[0] = handler;
454 System.arraycopy(existing, 0, children, 1, existing.length);
455 handlers.setHandlers(children);
456 }
457
458
459
460
461
462
463
464
465 protected Artifact getArtifactForOverlayConfig (OverlayConfig c, List<Artifact> wars)
466 {
467 if (wars == null || wars.isEmpty() || c == null)
468 return null;
469
470 Artifact war = null;
471 Iterator<Artifact> itor = wars.iterator();
472 while(itor.hasNext() && war == null)
473 {
474 Artifact a = itor.next();
475 if (c.matchesArtifact(a.gid, a.aid, null))
476 war = a;
477 }
478 return war;
479 }
480
481
482
483
484
485
486 private List<String> fromCSV (String csv)
487 {
488 if (csv == null || "".equals(csv.trim()))
489 return null;
490 String[] atoms = csv.split(",");
491 List<String> list = new ArrayList<String>();
492 for (String a:atoms)
493 {
494 list.add(a.trim());
495 }
496 return list;
497 }
498
499
500
501
502
503
504 public static final void main(String[] args)
505 {
506 if (args == null)
507 System.exit(1);
508
509 Starter starter = null;
510 try
511 {
512 starter = new Starter();
513 starter.getConfiguration(args);
514 starter.configureJetty();
515 starter.run();
516 starter.communicateStartupResult(null);
517 starter.join();
518 }
519 catch (Exception e)
520 {
521 starter.communicateStartupResult(e);
522 e.printStackTrace();
523 System.exit(1);
524 }
525
526 }
527 }