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