1 package com.atlassian.maven.plugins.amps;
2
3 import com.atlassian.maven.plugins.amps.product.ProductHandler;
4 import com.atlassian.maven.plugins.amps.product.ProductHandlerFactory;
5 import com.atlassian.maven.plugins.amps.product.studio.StudioProductHandler;
6 import com.atlassian.maven.plugins.amps.util.ArtifactRetriever;
7 import com.atlassian.maven.plugins.amps.util.ProjectUtils;
8 import com.google.common.base.Predicate;
9 import com.google.common.collect.Iterables;
10 import com.google.common.collect.Lists;
11
12 import org.apache.maven.artifact.factory.ArtifactFactory;
13 import org.apache.maven.artifact.repository.ArtifactRepository;
14 import org.apache.maven.artifact.resolver.ArtifactResolver;
15 import org.apache.maven.model.Resource;
16 import org.apache.maven.plugin.MojoExecutionException;
17 import org.apache.maven.plugin.MojoFailureException;
18 import org.apache.maven.project.MavenProject;
19 import org.jfrog.maven.annomojo.annotations.MojoComponent;
20 import org.jfrog.maven.annomojo.annotations.MojoParameter;
21
22 import java.io.File;
23 import java.util.ArrayList;
24 import java.util.HashMap;
25 import java.util.Iterator;
26 import java.util.List;
27 import java.util.Map;
28 import java.util.Properties;
29 import java.util.Set;
30
31
32
33
34 public abstract class AbstractProductHandlerMojo extends AbstractProductHandlerAwareMojo {
35
36
37
38 private static final String DEFAULT_CONTAINER = "tomcat6x";
39 private static final String DEFAULT_SERVER = "localhost";
40 private static final String DEFAULT_PRODUCT_DATA_VERSION = "LATEST";
41 private static final String DEFAULT_PDK_VERSION = "0.4";
42 private static final String DEFAULT_WEB_CONSOLE_VERSION = "1.2.8";
43
44
45
46
47 private static final int DEFAULT_PRODUCT_STARTUP_TIMEOUT = 1000 * 60 * 3;
48
49
50
51
52 private static final int DEFAULT_PRODUCT_SHUTDOWN_TIMEOUT = 1000 * 60 * 3;
53
54
55
56
57 @MojoParameter(expression = "${container}", defaultValue = DEFAULT_CONTAINER)
58 protected String containerId;
59
60
61
62
63 @MojoParameter(expression = "${http.port}", defaultValue = "0")
64 private int httpPort;
65
66
67
68
69 @MojoParameter(expression = "${context.path}")
70 protected String contextPath;
71
72
73
74
75 @MojoParameter(expression = "${server}", defaultValue = DEFAULT_SERVER)
76 protected String server;
77
78
79
80
81 @MojoParameter(expression = "${product.version}")
82 private String productVersion;
83
84
85
86
87 @MojoParameter(expression = "${jvmargs}")
88 protected String jvmArgs;
89
90
91
92
93 @MojoParameter(expression = "${product.start.timeout}")
94 private int startupTimeout;
95
96
97
98
99 @MojoParameter(expression = "${product.stop.timeout}")
100 private int shutdownTimeout;
101
102
103
104
105
106
107 @MojoParameter
108 @Deprecated
109 protected Properties systemProperties = new Properties();
110
111
112
113
114
115
116 @MojoParameter
117 protected Map<String, Object> systemPropertyVariables = new HashMap<String, Object>();
118
119
120
121
122
123 @MojoParameter
124 protected File log4jProperties;
125
126
127
128
129
130 @MojoParameter(expression = "${test.resources.version}")
131 private String testResourcesVersion;
132
133
134
135
136 @MojoParameter(expression = "${product.data.version}", defaultValue = DEFAULT_PRODUCT_DATA_VERSION)
137 private String productDataVersion;
138
139
140
141
142 @MojoParameter(expression = "${product.data.path}")
143 private String productDataPath;
144
145
146
147 @MojoParameter
148 private List<ProductArtifact> pluginArtifacts = new ArrayList<ProductArtifact>();
149
150
151
152 @MojoParameter
153 private List<ProductArtifact> libArtifacts = new ArrayList<ProductArtifact>();
154
155
156
157 @MojoParameter
158 private List<ProductArtifact> bundledArtifacts = new ArrayList<ProductArtifact>();
159
160
161
162
163
164 @MojoParameter
165 private String salVersion;
166
167
168
169
170
171 @MojoParameter(defaultValue = DEFAULT_PDK_VERSION)
172 private String pdkVersion;
173
174
175
176
177
178 @MojoParameter
179 private String restVersion;
180
181
182
183
184
185
186 @MojoParameter(defaultValue = DEFAULT_WEB_CONSOLE_VERSION)
187 private String webConsoleVersion;
188
189
190
191
192
193
194
195 @MojoParameter(expression = "${plugins}")
196 private String pluginArtifactsString;
197
198
199
200
201
202 @MojoParameter(expression = "${lib.plugins}")
203 private String libArtifactsString;
204
205
206
207
208
209 @MojoParameter(expression = "${bundled.plugins}")
210 private String bundledArtifactsString;
211
212
213
214
215 @MojoParameter(expression = "${project.build.directory}", required = true)
216 protected File targetDirectory;
217
218
219
220
221 @MojoParameter(expression = "${project.build.finalName}", required = true)
222 protected String finalName;
223
224
225
226
227 @MojoParameter (expression = "${install.plugin}", defaultValue = "true")
228 protected boolean installPlugin;
229
230
231
232
233
234
235
236 @MojoComponent
237 protected ArtifactResolver artifactResolver;
238
239
240
241
242
243
244 @MojoParameter(expression = "${localRepository}")
245 protected ArtifactRepository localRepository;
246
247
248
249
250
251 @MojoParameter(expression = "${project.remoteArtifactRepositories}")
252 protected List repositories;
253
254
255
256
257
258
259
260 @MojoComponent
261 protected ArtifactFactory artifactFactory;
262
263
264
265
266 @MojoParameter
267 protected List<Product> products = new ArrayList<Product>();
268
269
270
271
272 @MojoParameter
273 private String output;
274
275
276 protected Product createDefaultProductContext() throws MojoExecutionException
277 {
278 Product ctx = new Product();
279 ctx.setId(getProductId());
280 ctx.setContainerId(containerId);
281 ctx.setServer(server);
282 ctx.setContextPath(contextPath);
283 ctx.setJvmArgs(jvmArgs);
284 ctx.setStartupTimeout(startupTimeout);
285 ctx.setShutdownTimeout(shutdownTimeout);
286
287
288
289 setDefaultSystemProperty(systemPropertyVariables, "atlassian.dev.mode", "true");
290 setDefaultSystemProperty(systemPropertyVariables, "java.awt.headless", "true");
291 setDefaultSystemProperty(systemPropertyVariables, "plugin.resource.directories", buildResourcesList());
292 setDefaultSystemProperty(systemPropertyVariables, "plugin.root.directories", buildRootProperty());
293
294 ctx.setSystemPropertyVariables(systemPropertyVariables);
295 ctx.setBundledArtifacts(bundledArtifacts);
296 ctx.setLibArtifacts(libArtifacts);
297 ctx.setPluginArtifacts(pluginArtifacts);
298 ctx.setLog4jProperties(log4jProperties);
299 ctx.setHttpPort(httpPort);
300
301 ctx.setVersion(productVersion);
302 ctx.setDataVersion(productDataVersion);
303 ctx.setDataPath(productDataPath);
304
305
306 ctx.setRestVersion(restVersion);
307 ctx.setSalVersion(salVersion);
308 ctx.setPdkVersion(pdkVersion);
309 ctx.setWebConsoleVersion(webConsoleVersion);
310
311 ctx.setHttpPort(httpPort);
312 return ctx;
313 }
314
315
316
317
318
319 private String buildResourcesList()
320 {
321
322
323 StringBuilder resourceProp = new StringBuilder();
324 MavenProject mavenProject = getMavenContext().getProject();
325 @SuppressWarnings("unchecked") List<Resource> resList = mavenProject.getResources();
326 for (int i = 0; i < resList.size(); i++) {
327 resourceProp.append(resList.get(i).getDirectory());
328 if (i + 1 != resList.size()) {
329 resourceProp.append(",");
330 }
331 }
332
333 if (ProjectUtils.shouldDeployTestJar(getMavenContext()))
334 {
335 @SuppressWarnings("unchecked") List<Resource> testResList = mavenProject.getTestResources();
336 for (int i = 0; i < testResList.size(); i++) {
337 if (i == 0 && resourceProp.length() > 0)
338 {
339 resourceProp.append(",");
340 }
341 resourceProp.append(testResList.get(i).getDirectory());
342 if (i + 1 != testResList.size()) {
343 resourceProp.append(",");
344 }
345 }
346 }
347 return resourceProp.toString();
348 }
349
350
351
352
353
354
355 private String buildRootProperty()
356 {
357 MavenProject mavenProject = getMavenContext().getProject();
358 return mavenProject.getBasedir().getPath();
359 }
360
361 private static void setDefaultSystemProperty(final Map<String,Object> props, final String key, final String value)
362 {
363 if (!props.containsKey(key))
364 {
365 props.put(key, System.getProperty(key, value));
366 }
367 }
368
369
370
371
372
373
374 protected void setDefaultValues(Product product, ProductHandler handler)
375 {
376 product.setInstanceId(getProductInstanceId(product));
377
378
379 StudioProductHandler.setDefaultValues(product);
380
381
382 String dversion = System.getProperty("product.data.version", product.getDataVersion());
383 String pversion = System.getProperty("product.version", product.getVersion());
384 String dpath = System.getProperty("product.data.path", product.getDataPath());
385
386 product.setDataPath(dpath);
387 product.setDataVersion(dversion);
388 product.setVersion(pversion);
389 product.setArtifactRetriever(new ArtifactRetriever(artifactResolver, artifactFactory, localRepository, repositories));
390
391 if (product.getContainerId() == null)
392 {
393 product.setContainerId(DEFAULT_CONTAINER);
394 }
395
396 if (product.getServer() == null)
397 {
398 product.setServer(DEFAULT_SERVER);
399 }
400
401 if (product.getDataVersion() == null)
402 {
403 product.setDataVersion(DEFAULT_PRODUCT_DATA_VERSION);
404 }
405
406 if (product.getPdkVersion() == null)
407 {
408 product.setPdkVersion(DEFAULT_PDK_VERSION);
409 }
410
411 if (product.getWebConsoleVersion() == null)
412 {
413 product.setWebConsoleVersion(DEFAULT_WEB_CONSOLE_VERSION);
414 }
415
416 if (product.getOutput() == null)
417 {
418 product.setOutput(output);
419 }
420
421 if (product.getStartupTimeout() <= 0)
422 {
423 product.setStartupTimeout(DEFAULT_PRODUCT_STARTUP_TIMEOUT);
424 }
425
426 if (product.getShutdownTimeout() <= 0)
427 {
428 product.setShutdownTimeout(DEFAULT_PRODUCT_SHUTDOWN_TIMEOUT);
429 }
430
431 if (product.getHttpPort() == 0)
432 {
433 product.setHttpPort(handler.getDefaultHttpPort());
434 }
435
436 if (product.getVersion() == null)
437 {
438 product.setVersion("RELEASE");
439 }
440
441 if (product.getContextPath() == null)
442 {
443 product.setContextPath("/" + handler.getId());
444 }
445 }
446
447 private List<ProductArtifact> stringToArtifactList(String val, List<ProductArtifact> artifacts)
448 {
449 if (val == null || val.trim().length() == 0)
450 {
451 return artifacts;
452 }
453
454 for (String ptn : val.split(","))
455 {
456 String[] items = ptn.split(":");
457 if (items.length < 2 || items.length > 3)
458 {
459 throw new IllegalArgumentException("Invalid artifact pattern: " + ptn);
460 }
461 String groupId = items[0];
462 String artifactId = items[1];
463 String version = (items.length == 3 ? items[2] : "LATEST");
464 artifacts.add(new ProductArtifact(groupId, artifactId, version));
465 }
466 return artifacts;
467 }
468
469 public final void execute() throws MojoExecutionException, MojoFailureException
470 {
471 stringToArtifactList(pluginArtifactsString, pluginArtifacts);
472 stringToArtifactList(libArtifactsString, libArtifacts);
473 stringToArtifactList(bundledArtifactsString, bundledArtifacts);
474 systemPropertyVariables.putAll((Map) systemProperties);
475
476 detectDeprecatedVersionOverrides();
477
478 doExecute();
479 }
480
481 private void detectDeprecatedVersionOverrides()
482 {
483 Properties props = getMavenContext().getProject().getProperties();
484 for (String deprecatedProperty : new String[] {"sal.version", "rest.version", "web.console.version", "pdk.version"})
485 {
486 if (props.containsKey(deprecatedProperty))
487 {
488 getLog().warn("The property '" + deprecatedProperty + "' is no longer usable to override the related bundled plugin." +
489 " Use <pluginArtifacts> or <libArtifacts> to explicitly override bundled plugins and libraries, respectively.");
490 }
491 }
492 }
493
494
495
496
497
498
499
500
501
502 protected Map<String, Product> getProductContexts(MavenGoals goals) throws MojoExecutionException
503 {
504 Map<String, Product> productMap = new HashMap<String, Product>();
505
506
507 makeProductsInheritDefaultConfiguration(products, productMap);
508
509 for (Product ctx : productMap.values())
510 {
511 ProductHandler handler = ProductHandlerFactory.create(ctx.getId(), getMavenContext(), goals);
512 setDefaultValues(ctx, handler);
513 }
514 return productMap;
515 }
516
517
518
519
520
521
522
523
524 void makeProductsInheritDefaultConfiguration(List<Product> products, Map<String, Product> productMap) throws MojoExecutionException
525 {
526 productMap.put(getProductId(), createDefaultProductContext());
527 if (!products.isEmpty())
528 {
529 Product defaultProduct = createDefaultProductContext();
530 for (Product product : products)
531 {
532 Product processedProduct = product.merge(defaultProduct);
533 String instanceId = getProductInstanceId(processedProduct);
534 productMap.put(instanceId, processedProduct);
535 }
536 }
537 }
538
539 private String getProductInstanceId(Product processedProduct)
540 {
541 return processedProduct.getInstanceId() == null ? processedProduct.getId() : processedProduct.getInstanceId();
542 }
543
544
545 private Product createProductContext(String productNickname, String instanceId, ProductHandler handler) throws MojoExecutionException
546 {
547 getLog().info(String.format("Studio (instanceId=%s): No product with name %s is defined in the pom. Using a default product.", instanceId, productNickname));
548 Product product;
549 product = createDefaultProductContext();
550 product.setId(productNickname);
551 product.setInstanceId(instanceId);
552 setDefaultValues(product, handler);
553 return product;
554 }
555
556
557 private Iterator<ProductExecution> getStudioExecutions(final List<ProductExecution> productExecutions)
558 {
559 return Iterables.filter(productExecutions, new Predicate<ProductExecution>(){
560
561 @Override
562 public boolean apply(ProductExecution input)
563 {
564 return input.getProductHandler() instanceof StudioProductHandler;
565 }}).iterator();
566 }
567
568
569
570
571
572
573
574
575
576
577
578
579 protected List<ProductExecution> includeStudioDependentProducts(final List<ProductExecution> productExecutions, final MavenGoals goals)
580 throws MojoExecutionException
581 {
582
583 Iterator<ProductExecution> studioExecutions = getStudioExecutions(productExecutions);
584 if (!studioExecutions.hasNext())
585 {
586 return productExecutions;
587 }
588
589
590 List<ProductExecution> productExecutionsIncludingStudio = Lists.newArrayList(productExecutions);
591 while (studioExecutions.hasNext())
592 {
593 ProductExecution studioExecution = studioExecutions.next();
594 Product studioProduct = studioExecution.getProduct();
595 StudioProductHandler studioProductHandler = (StudioProductHandler) studioExecution.getProductHandler();
596
597
598 final List<String> dependantProductIds = studioProductHandler.getDependantInstances(studioProduct);
599
600
601 List<ProductExecution> dependantProducts = Lists.newArrayList();
602 Map<String, Product> allContexts = getProductContexts(goals);
603 for (String instanceId : dependantProductIds)
604 {
605 Product product = allContexts.get(instanceId);
606 ProductHandler handler;
607 if (product == null)
608 {
609 handler = createProductHandler(instanceId);
610 product = createProductContext(instanceId, instanceId, handler);
611 }
612 else
613 {
614 handler = createProductHandler(product.getId());
615 }
616
617 dependantProducts.add(new ProductExecution(product, handler));
618 }
619
620
621 studioProductHandler.configure(studioProduct, dependantProducts);
622
623
624
625 Set<String> exclusions = studioProductHandler.getExcludedInstances(studioProduct);
626 if (exclusions != null)
627 {
628 Iterator<ProductExecution> iterator = dependantProducts.iterator();
629 while (iterator.hasNext())
630 {
631 String executedInstance = iterator.next().getProduct().getInstanceId();
632 if (exclusions.contains(executedInstance))
633 {
634 iterator.remove();
635 }
636 }
637 }
638
639
640
641 productExecutionsIncludingStudio.addAll(dependantProducts);
642 }
643
644 return productExecutionsIncludingStudio;
645 }
646
647 protected abstract void doExecute() throws MojoExecutionException, MojoFailureException;
648 }