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