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 import com.google.common.collect.Maps;
12 import org.apache.commons.lang.StringUtils;
13 import org.apache.maven.artifact.factory.ArtifactFactory;
14 import org.apache.maven.artifact.repository.ArtifactRepository;
15 import org.apache.maven.artifact.resolver.ArtifactResolver;
16 import org.apache.maven.model.Resource;
17 import org.apache.maven.plugin.MojoExecutionException;
18 import org.apache.maven.plugin.MojoFailureException;
19 import org.apache.maven.project.MavenProject;
20 import org.jfrog.maven.annomojo.annotations.MojoComponent;
21 import org.jfrog.maven.annomojo.annotations.MojoParameter;
22
23 import java.io.File;
24 import java.io.IOException;
25 import java.net.HttpURLConnection;
26 import java.net.InetAddress;
27 import java.net.URL;
28 import java.net.UnknownHostException;
29 import java.util.ArrayList;
30 import java.util.HashMap;
31 import java.util.List;
32 import java.util.Map;
33 import java.util.Properties;
34 import java.util.concurrent.ExecutionException;
35 import java.util.concurrent.ExecutorService;
36 import java.util.concurrent.Executors;
37 import java.util.concurrent.Future;
38 import java.util.concurrent.TimeUnit;
39 import java.util.concurrent.TimeoutException;
40
41 import static com.atlassian.maven.plugins.amps.product.ProductHandlerFactory.STUDIO;
42
43
44
45
46 public abstract class AbstractProductHandlerMojo extends AbstractProductHandlerAwareMojo {
47
48
49
50 protected static final String DEFAULT_CONTAINER = "tomcat6x";
51 private static final String DEFAULT_SERVER;
52 private static final String DEFAULT_PRODUCT_DATA_VERSION = "LATEST";
53 private static final String DEFAULT_PDK_VERSION = "0.4";
54 private static final String DEFAULT_WEB_CONSOLE_VERSION = "1.2.8";
55 private static final String DEFAULT_FASTDEV_VERSION = "1.9.1";
56 private static final String DEFAULT_DEV_TOOLBOX_VERSION = "1.1";
57 private static final String DEFAULT_PDE_VERSION = "1.2";
58
59
60
61
62 private static final int DEFAULT_PRODUCT_STARTUP_TIMEOUT = 1000 * 60 * 3;
63
64
65
66
67 private static final int DEFAULT_PRODUCT_SHUTDOWN_TIMEOUT = 1000 * 60 * 3;
68
69 static
70 {
71 String localHostName = null;
72 try
73 {
74 localHostName = InetAddress.getLocalHost().getHostName();
75 }
76 catch (UnknownHostException e)
77 {
78 localHostName = "localhost";
79 }
80 DEFAULT_SERVER = localHostName;
81 }
82
83
84
85
86 @MojoParameter(expression = "${container}", defaultValue = DEFAULT_CONTAINER)
87 protected String containerId;
88
89
90
91
92 @MojoParameter(expression = "${http.port}", defaultValue = "0")
93 private int httpPort;
94
95
96
97
98 @MojoParameter(expression = "${context.path}")
99 protected String contextPath;
100
101
102
103
104 @MojoParameter(expression = "${server}")
105 protected String server;
106
107
108
109
110 @MojoParameter(expression = "${product.version}")
111 private String productVersion;
112
113
114
115
116 @MojoParameter(expression = "${jvmargs}")
117 protected String jvmArgs;
118
119
120
121
122 @MojoParameter(expression = "${product.start.timeout}")
123 private int startupTimeout;
124
125
126
127
128 @MojoParameter(expression = "${product.stop.timeout}")
129 private int shutdownTimeout;
130
131
132
133
134
135
136 @MojoParameter
137 @Deprecated
138 protected Properties systemProperties = new Properties();
139
140
141
142
143
144
145 @MojoParameter
146 protected Map<String, Object> systemPropertyVariables = new HashMap<String, Object>();
147
148
149
150
151
152 @MojoParameter
153 protected File log4jProperties;
154
155
156
157
158
159 @Deprecated
160 @MojoParameter(expression = "${test.resources.version}")
161 private String testResourcesVersion;
162
163
164
165
166 @MojoParameter(expression = "${product.data.version}", defaultValue = DEFAULT_PRODUCT_DATA_VERSION)
167 private String productDataVersion;
168
169
170
171
172 @MojoParameter(expression = "${product.data.path}")
173 private String productDataPath;
174
175
176
177
178 @MojoParameter(expression = "${fastdev.enable}", defaultValue = "true")
179 protected boolean enableFastdev;
180
181
182
183
184 @MojoParameter(expression = "${fastdev.version}", defaultValue = DEFAULT_FASTDEV_VERSION)
185 protected String fastdevVersion;
186
187
188
189
190 @MojoParameter(expression = "${devtoolbox.enable}", defaultValue = "true")
191 protected boolean enableDevToolbox;
192
193
194
195
196 @MojoParameter(expression = "${devtoolbox.version}", defaultValue = DEFAULT_DEV_TOOLBOX_VERSION)
197 protected String devToolboxVersion;
198
199
200
201
202 @MojoParameter(expression = "${pde.enable}", defaultValue = "true")
203 protected boolean enablePde;
204
205
206
207
208 @MojoParameter(expression = "${pde.version}", defaultValue = DEFAULT_PDE_VERSION)
209 protected String pdeVersion;
210
211 @MojoParameter
212 private List<ProductArtifact> pluginArtifacts = new ArrayList<ProductArtifact>();
213
214
215
216 @MojoParameter
217 private List<ProductArtifact> libArtifacts = new ArrayList<ProductArtifact>();
218
219
220
221 @MojoParameter
222 private List<ProductArtifact> bundledArtifacts = new ArrayList<ProductArtifact>();
223
224
225
226
227
228 @Deprecated
229 @MojoParameter
230 private String salVersion;
231
232
233
234
235
236 @Deprecated
237 @MojoParameter(defaultValue = DEFAULT_PDK_VERSION)
238 private String pdkVersion;
239
240
241
242
243
244 @Deprecated
245 @MojoParameter
246 private String restVersion;
247
248
249
250
251
252
253 @Deprecated
254 @MojoParameter(defaultValue = DEFAULT_WEB_CONSOLE_VERSION)
255 private String webConsoleVersion;
256
257
258
259
260
261
262
263 @MojoParameter(expression = "${plugins}")
264 private String pluginArtifactsString;
265
266
267
268
269
270 @MojoParameter(expression = "${lib.plugins}")
271 private String libArtifactsString;
272
273
274
275
276
277 @MojoParameter(expression = "${bundled.plugins}")
278 private String bundledArtifactsString;
279
280
281
282
283 @MojoParameter(expression = "${project.build.directory}", required = true)
284 protected File targetDirectory;
285
286
287
288
289 @MojoParameter(expression = "${project.build.finalName}", required = true)
290 protected String finalName;
291
292
293
294
295 @MojoParameter (expression = "${install.plugin}", defaultValue = "true")
296 protected boolean installPlugin;
297
298
299
300
301
302
303
304 @MojoComponent
305 protected ArtifactResolver artifactResolver;
306
307
308
309
310
311
312 @MojoParameter(expression = "${localRepository}")
313 protected ArtifactRepository localRepository;
314
315
316
317
318
319 @MojoParameter(expression = "${project.remoteArtifactRepositories}")
320 protected List repositories;
321
322
323
324
325
326
327
328 @MojoComponent
329 protected ArtifactFactory artifactFactory;
330
331
332
333
334 @MojoParameter
335 protected List<Product> products = new ArrayList<Product>();
336
337
338
339
340
341 private Map<String, Product> productMap;
342
343
344
345
346 @MojoParameter
347 private String output;
348
349
350
351
352 @MojoParameter (expression = "${parallel}", defaultValue = "false")
353 protected boolean parallel;
354
355
356 protected Product createDefaultProductContext() throws MojoExecutionException
357 {
358 Product ctx = new Product();
359 ctx.setId(getProductId());
360 ctx.setContainerId(containerId);
361 ctx.setServer(server);
362 ctx.setContextPath(contextPath);
363 ctx.setJvmArgs(jvmArgs);
364 ctx.setStartupTimeout(startupTimeout);
365 ctx.setShutdownTimeout(shutdownTimeout);
366
367
368
369 Map<String, Object> properties = new HashMap<String, Object>(systemPropertyVariables);
370 properties.put("atlassian.sdk.version", getPluginInformation().getVersion());
371 setDefaultSystemProperty(properties, "atlassian.dev.mode", "true");
372 setDefaultSystemProperty(properties, "java.awt.headless", "true");
373 setDefaultSystemProperty(properties, "plugin.resource.directories", buildResourcesList());
374 setDefaultSystemProperty(properties, "plugin.root.directories", buildRootProperty());
375
376 ctx.setSystemPropertyVariables(properties);
377 ctx.setBundledArtifacts(bundledArtifacts);
378 ctx.setLibArtifacts(libArtifacts);
379 ctx.setPluginArtifacts(pluginArtifacts);
380 ctx.setLog4jProperties(log4jProperties);
381 ctx.setHttpPort(httpPort);
382
383 ctx.setVersion(productVersion);
384 ctx.setDataVersion(productDataVersion);
385 ctx.setDataPath(productDataPath);
386
387
388 ctx.setRestVersion(restVersion);
389 ctx.setSalVersion(salVersion);
390 ctx.setPdkVersion(pdkVersion);
391 ctx.setWebConsoleVersion(webConsoleVersion);
392
393 ctx.setEnableFastdev(enableFastdev);
394 ctx.setFastdevVersion(fastdevVersion);
395
396 ctx.setEnableDevToolbox(enableDevToolbox);
397 ctx.setDevToolboxVersion(devToolboxVersion);
398
399 ctx.setEnablePde(enablePde);
400 ctx.setPdeVersion(pdeVersion);
401
402 ctx.setHttpPort(httpPort);
403 return ctx;
404 }
405
406
407
408
409
410 private String buildResourcesList()
411 {
412
413
414 StringBuilder resourceProp = new StringBuilder();
415 MavenProject mavenProject = getMavenContext().getProject();
416 @SuppressWarnings("unchecked") List<Resource> resList = mavenProject.getResources();
417 for (int i = 0; i < resList.size(); i++) {
418 resourceProp.append(resList.get(i).getDirectory());
419 if (i + 1 != resList.size()) {
420 resourceProp.append(",");
421 }
422 }
423
424 if (ProjectUtils.shouldDeployTestJar(getMavenContext()))
425 {
426 @SuppressWarnings("unchecked") List<Resource> testResList = mavenProject.getTestResources();
427 for (int i = 0; i < testResList.size(); i++) {
428 if (i == 0 && resourceProp.length() > 0)
429 {
430 resourceProp.append(",");
431 }
432 resourceProp.append(testResList.get(i).getDirectory());
433 if (i + 1 != testResList.size()) {
434 resourceProp.append(",");
435 }
436 }
437 }
438 return resourceProp.toString();
439 }
440
441
442
443
444
445
446 private String buildRootProperty()
447 {
448 MavenProject mavenProject = getMavenContext().getProject();
449 return mavenProject.getBasedir().getPath();
450 }
451
452 private static void setDefaultSystemProperty(final Map<String,Object> props, final String key, final String value)
453 {
454 if (!props.containsKey(key))
455 {
456 props.put(key, System.getProperty(key, value));
457 }
458 }
459
460
461
462
463
464
465 protected void setDefaultValues(Product product, ProductHandler handler)
466 {
467 product.setInstanceId(getProductInstanceId(product));
468
469
470 String dversion = System.getProperty("product.data.version", product.getDataVersion());
471 String pversion = System.getProperty("product.version", product.getVersion());
472 String dpath = System.getProperty("product.data.path", product.getDataPath());
473
474
475 if (!StudioProductHandler.setDefaultValues(getMavenContext(), product))
476 {
477
478
479
480 if (!STUDIO.equals(product.getId()) || STUDIO.equals(System.getProperty("product")))
481 {
482 product.setVersion(pversion);
483 product.setDataVersion(dversion);
484 product.setDataPath(dpath);
485 }
486 }
487
488 product.setArtifactRetriever(new ArtifactRetriever(artifactResolver, artifactFactory, localRepository, repositories));
489
490 if (product.getContainerId() == null)
491 {
492 product.setContainerId(DEFAULT_CONTAINER);
493 }
494
495 if (product.getServer() == null)
496 {
497 product.setServer(DEFAULT_SERVER);
498 }
499
500 if (product.getDataVersion() == null)
501 {
502 product.setDataVersion(DEFAULT_PRODUCT_DATA_VERSION);
503 }
504
505 if (product.getPdkVersion() == null)
506 {
507 product.setPdkVersion(DEFAULT_PDK_VERSION);
508 }
509
510 if (product.getWebConsoleVersion() == null)
511 {
512 product.setWebConsoleVersion(DEFAULT_WEB_CONSOLE_VERSION);
513 }
514
515 if (product.isEnableFastdev() == null)
516 {
517 product.setEnableFastdev(true);
518 }
519
520 if (product.getFastdevVersion() == null)
521 {
522 product.setFastdevVersion(DEFAULT_FASTDEV_VERSION);
523 }
524
525 if (product.isEnableDevToolbox() == null)
526 {
527 product.setEnableDevToolbox(true);
528 }
529
530 if (product.getDevToolboxVersion() == null)
531 {
532 product.setDevToolboxVersion(DEFAULT_DEV_TOOLBOX_VERSION);
533 }
534
535 if (product.getPdeVersion() == null)
536 {
537 product.setPdeVersion(DEFAULT_PDE_VERSION);
538 }
539
540 if (product.getOutput() == null)
541 {
542 product.setOutput(output);
543 }
544
545 if (product.getStartupTimeout() <= 0)
546 {
547 product.setStartupTimeout(DEFAULT_PRODUCT_STARTUP_TIMEOUT);
548 }
549
550 if (product.getShutdownTimeout() <= 0)
551 {
552 product.setShutdownTimeout(DEFAULT_PRODUCT_SHUTDOWN_TIMEOUT);
553 }
554
555 if (product.getHttpPort() == 0)
556 {
557 product.setHttpPort(handler.getDefaultHttpPort());
558 }
559
560 if (product.getVersion() == null)
561 {
562 product.setVersion("RELEASE");
563 }
564
565 if (product.getContextPath() == null)
566 {
567 product.setContextPath("/" + handler.getId());
568 }
569 }
570
571 private List<ProductArtifact> stringToArtifactList(String val, List<ProductArtifact> artifacts)
572 {
573 if (val == null || val.trim().length() == 0)
574 {
575 return artifacts;
576 }
577
578 for (String ptn : val.split(","))
579 {
580 String[] items = ptn.split(":");
581 if (items.length < 2 || items.length > 3)
582 {
583 throw new IllegalArgumentException("Invalid artifact pattern: " + ptn);
584 }
585 String groupId = items[0];
586 String artifactId = items[1];
587 String version = (items.length == 3 ? items[2] : "LATEST");
588 artifacts.add(new ProductArtifact(groupId, artifactId, version));
589 }
590 return artifacts;
591 }
592
593 @Override
594 public final void execute() throws MojoExecutionException, MojoFailureException
595 {
596 stringToArtifactList(pluginArtifactsString, pluginArtifacts);
597 stringToArtifactList(libArtifactsString, libArtifacts);
598 stringToArtifactList(bundledArtifactsString, bundledArtifacts);
599 systemPropertyVariables.putAll((Map) systemProperties);
600
601 detectDeprecatedVersionOverrides();
602
603 doExecute();
604 }
605
606 private void detectDeprecatedVersionOverrides()
607 {
608 Properties props = getMavenContext().getProject().getProperties();
609 for (String deprecatedProperty : new String[] {"sal.version", "rest.version", "web.console.version", "pdk.version"})
610 {
611 if (props.containsKey(deprecatedProperty))
612 {
613 getLog().warn("The property '" + deprecatedProperty + "' is no longer usable to override the related bundled plugin." +
614 " Use <pluginArtifacts> or <libArtifacts> to explicitly override bundled plugins and libraries, respectively.");
615 }
616 }
617 }
618
619
620
621
622
623
624
625
626 Map<String, Product> createProductContexts() throws MojoExecutionException
627 {
628 Map<String, Product> productMap = Maps.newHashMap();
629 MavenContext mavenContext = getMavenContext();
630 MavenGoals goals = getMavenGoals();
631
632
633 makeProductsInheritDefaultConfiguration(products, productMap);
634
635 for (Product ctx : Lists.newArrayList(productMap.values()))
636 {
637 ProductHandler handler = ProductHandlerFactory.create(ctx.getId(), mavenContext, goals);
638 setDefaultValues(ctx, handler);
639
640
641 for (String instanceId : StudioProductHandler.getDependantInstances(ctx))
642 {
643 if (!productMap.containsKey(instanceId))
644 {
645 ProductHandler dependantHandler = createProductHandler(instanceId);
646 productMap.put(instanceId, createProductContext(instanceId, instanceId, dependantHandler));
647 }
648 }
649 }
650
651
652 StudioProductHandler studioProductHandler = (StudioProductHandler) ProductHandlerFactory.create(ProductHandlerFactory.STUDIO, mavenContext, goals);
653 studioProductHandler.configureStudioProducts(productMap);
654
655 return productMap;
656 }
657
658
659
660
661 protected Map<String, Product> getProductContexts() throws MojoExecutionException
662 {
663 if (productMap == null)
664 {
665 productMap = createProductContexts();
666 }
667 return productMap;
668 }
669
670
671
672
673
674
675
676
677 void makeProductsInheritDefaultConfiguration(List<Product> products, Map<String, Product> productMap) throws MojoExecutionException
678 {
679 Product defaultProduct = createDefaultProductContext();
680 productMap.put(getProductId(), defaultProduct);
681 if (!products.isEmpty())
682 {
683 for (Product product : products)
684 {
685 Product processedProduct = product.merge(defaultProduct);
686 if (ProductHandlerFactory.STUDIO_CROWD.equals(processedProduct.getId()))
687 {
688
689 processedProduct.getSystemPropertyVariables().put("atlassian.dev.mode", "false");
690 }
691 String instanceId = getProductInstanceId(processedProduct);
692 productMap.put(instanceId, processedProduct);
693 }
694 }
695 }
696
697 private String getProductInstanceId(Product processedProduct)
698 {
699 return processedProduct.getInstanceId() == null ? processedProduct.getId() : processedProduct.getInstanceId();
700 }
701
702
703 private Product createProductContext(String productNickname, String instanceId, ProductHandler handler) throws MojoExecutionException
704 {
705 getLog().info(String.format("Studio (instanceId=%s): No product with name %s is defined in the pom. Using a default product.", instanceId, productNickname));
706 Product product;
707 product = createDefaultProductContext();
708 product.setId(productNickname);
709 product.setInstanceId(instanceId);
710 setDefaultValues(product, handler);
711 if (ProductHandlerFactory.STUDIO_CROWD.equals(product.getId()))
712 {
713
714 product.getSystemPropertyVariables().put("atlassian.dev.mode", "false");
715 }
716 return product;
717 }
718
719
720
721
722
723 protected void stopProducts(List<ProductExecution> productExecutions) throws MojoExecutionException
724 {
725 ExecutorService executor = Executors.newFixedThreadPool(productExecutions.size());
726 try
727 {
728 long before = System.nanoTime();
729 for (final ProductExecution execution : Iterables.reverse(productExecutions))
730 {
731 final Product product = execution.getProduct();
732 final ProductHandler productHandler = execution.getProductHandler();
733
734 Future<?> task = executor.submit(new Runnable()
735 {
736 @Override
737 public void run()
738 {
739 getLog().info(product.getInstanceId() + ": Shutting down");
740 try
741 {
742 productHandler.stop(product);
743 }
744 catch (MojoExecutionException e)
745 {
746 getLog().error("Exception while trying to stop " + product.getInstanceId(), e);
747 }
748 }
749 });
750
751 try
752 {
753 task.get(product.getShutdownTimeout(), TimeUnit.MILLISECONDS);
754 }
755 catch (TimeoutException e)
756 {
757 getLog().info(product.getInstanceId() + " shutdown: Didn't return in time");
758 task.cancel(true);
759 }
760 }
761 long after = System.nanoTime();
762 getLog().info("amps:stop in " + TimeUnit.NANOSECONDS.toSeconds(after - before) + "s");
763 }
764 catch (InterruptedException e1)
765 {
766 Thread.currentThread().interrupt();
767 }
768 catch (ExecutionException e)
769 {
770 throw new MojoExecutionException("Exception while stopping the products", e);
771 }
772
773
774
775 if (parallel)
776 {
777 waitForProducts(productExecutions, false);
778 }
779 }
780
781
782
783
784
785
786 protected void waitForProducts(List<ProductExecution> productExecutions, boolean startingUp) throws MojoExecutionException
787 {
788 for (ProductExecution productExecution : productExecutions)
789 {
790 pingRepeatedly(productExecution.getProduct(), startingUp);
791 }
792 }
793
794
795
796
797
798
799 private void pingRepeatedly(Product product, boolean startingUp) throws MojoExecutionException
800 {
801 if (product.getHttpPort() != 0)
802 {
803 String url = "http://" + product.getServer() + ":" + product.getHttpPort();
804 if (StringUtils.isNotBlank(product.getContextPath()))
805 {
806 url = url + product.getContextPath();
807 }
808
809 int timeout = startingUp ? product.getStartupTimeout() : product.getShutdownTimeout();
810 final long end = System.nanoTime() + TimeUnit.MILLISECONDS.toNanos(timeout);
811 boolean interrupted = false;
812 boolean success = false;
813 String lastMessage = "";
814
815
816 while (!success && !interrupted && System.nanoTime() < end)
817 {
818 HttpURLConnection connection = null;
819 try
820 {
821 URL urlToPing = new URL(url);
822 connection = (HttpURLConnection) urlToPing.openConnection();
823 int response = connection.getResponseCode();
824
825 lastMessage = "Last response code is " + response;
826 if (startingUp)
827 {
828 success = response < 400;
829 }
830 else
831 {
832 success = response >= 400;
833 }
834 }
835 catch (IOException e)
836 {
837 lastMessage = e.getMessage();
838 success = !startingUp;
839 }
840 finally
841 {
842 if (connection != null)
843 {
844 try
845 {
846 connection.getInputStream().close();
847 }
848 catch (IOException e)
849 {
850
851 }
852 }
853 }
854
855 if (!success)
856 {
857 getLog().info("Waiting for " + url + (startingUp ? "" : " to stop"));
858 try
859 {
860 Thread.sleep(1000);
861 }
862 catch (InterruptedException e)
863 {
864 Thread.currentThread().interrupt();
865 interrupted = true;
866 break;
867 }
868 }
869 }
870
871 if (!success)
872 {
873 throw new MojoExecutionException(String.format("The product %s didn't %s after %ds at %s. %s",
874 product.getInstanceId(), startingUp ? "start" : "stop", TimeUnit.MILLISECONDS.toSeconds(timeout), url, lastMessage));
875 }
876 }
877 }
878
879
880
881
882 private Iterable<ProductExecution> getStudioExecutions(final List<ProductExecution> productExecutions)
883 {
884 return Iterables.filter(productExecutions, new Predicate<ProductExecution>(){
885
886 @Override
887 public boolean apply(ProductExecution input)
888 {
889 return input.getProductHandler() instanceof StudioProductHandler;
890 }});
891 }
892
893
894
895
896
897
898
899
900
901
902
903
904 protected List<ProductExecution> includeStudioDependentProducts(final List<ProductExecution> productExecutions, final MavenGoals goals)
905 throws MojoExecutionException
906 {
907
908 Iterable<ProductExecution> studioExecutions = getStudioExecutions(productExecutions);
909 if (Iterables.isEmpty(studioExecutions))
910 {
911 return productExecutions;
912 }
913
914
915 List<ProductExecution> productExecutionsIncludingStudio = Lists.newArrayList(productExecutions);
916 Map<String, Product> allContexts = getProductContexts();
917 for(ProductExecution execution : studioExecutions)
918 {
919 for (String dependantProduct : StudioProductHandler.getDependantInstances(execution.getProduct()))
920 {
921 Product product = allContexts.get(dependantProduct);
922 productExecutionsIncludingStudio.add(toProductExecution(product));
923 }
924 }
925
926 return productExecutionsIncludingStudio;
927 }
928
929 protected ProductExecution toProductExecution(Product product)
930 {
931 return new ProductExecution(product, createProductHandler(product.getId()));
932 }
933
934 protected abstract void doExecute() throws MojoExecutionException, MojoFailureException;
935
936 protected void setParallelMode(List<ProductExecution> executions)
937 {
938
939 for (ProductExecution execution : executions)
940 {
941 Product product = execution.getProduct();
942 if (parallel)
943 {
944 if (product.getSynchronousStartup() == null)
945 {
946 product.setSynchronousStartup(Boolean.FALSE);
947 }
948 }
949 else
950 {
951 product.setSynchronousStartup(Boolean.TRUE);
952 }
953 }
954 }
955 }