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