1   package com.atlassian.maven.plugins.amps.util.ant;
2   
3   import java.io.File;
4   import java.util.Collections;
5   import java.util.Map;
6   
7   import org.apache.maven.plugin.logging.Log;
8   import org.apache.tools.ant.taskdefs.Java;
9   
10  public class JavaTaskFactory
11  {
12      private final AntUtils antUtils = new AntUtils();
13      private final Log logger;
14      
15      public JavaTaskFactory(Log logger)
16      {
17          this.logger = logger;
18      }
19      
20      public Java newJavaTask()
21      {
22          return newJavaTask(new Parameters(null, null, Collections.<String, String>emptyMap()));
23      }
24      
25      public Java newJavaTask(Parameters params)
26      {
27          Java java = (Java) antUtils.createAntTask("java");
28          java.setFork(true);
29          
30          // If the user has not specified any output file then the process's output will be logged
31          // to the Ant logging subsystem which will in turn go to the Cargo's logging subsystem as
32          // we're configuring Ant with our own custom build listener (see below).
33          setOutput(params.output, java);
34  
35          // Add a build listener to the Ant project so that we can catch what the Java task logs
36          addBuildListener(java);
37  
38          // Add system properties for the container JVM
39          addSystemProperties(java, params.systemProperties);
40          
41          // Add JVM args if defined
42          addJvmArgs(java, params.jvmArgs);
43          
44          return java;
45      }
46  
47      private void setOutput(String output, Java java)
48      {
49          if (output != null)
50          {
51              File outputFile = new File(output);
52              
53              // Ensure that directories where the output file will go are created
54              outputFile.getAbsoluteFile().getParentFile().mkdirs();
55              
56              java.setOutput(outputFile);
57              java.setAppend(true);
58          }
59      }
60  
61      private void addBuildListener(Java java)
62      {
63          boolean foundBuildListener = false;
64          for (Object listenerObject : java.getProject().getBuildListeners())
65          {
66              if (listenerObject instanceof AntBuildListener)
67              {
68                  foundBuildListener = true;
69                  break;
70              }
71          }
72          if (!foundBuildListener)
73          {
74              java.getProject().addBuildListener(new AntBuildListener(logger));
75          }
76      }
77  
78      /**
79       * Add system properties to the Ant java command used to start the container.
80       * 
81       * @param java the java command that will start the container
82       */
83      private void addSystemProperties(Java java, Map<String, String> systemProperties)
84      {
85          for (Map.Entry<String, String> prop : systemProperties.entrySet())
86          {
87              java.addSysproperty(antUtils.createSysProperty(prop.getKey(), prop.getValue()));
88          }
89      }
90      
91      /**
92       * Add the jvm arguments to the java command.
93       * @param java The java task
94       */
95      private void addJvmArgs(Java java, String jvmArgs)
96      {
97          if (jvmArgs != null)
98          {
99              java.createJvmarg().setLine(jvmArgs);
100         }
101     }
102     
103     public static Parameters output(String output)
104     {
105         return new Parameters(output, null, null);
106     }
107     
108     public static Parameters jvmArgs(String jvmArgs)
109     {
110         return new Parameters(null, jvmArgs, null);
111     }
112     
113     public static Parameters systemProperties(Map<String, String> systemProperties)
114     {
115         return new Parameters(null, null, systemProperties);
116     }
117     
118     public static final class Parameters
119     {
120         private final String jvmArgs;
121         private final Map<String, String> systemProperties;
122         private final String output;
123 
124         private Parameters(String output, String jvmArgs, Map<String, String> systemProperties)
125         {
126             this.output = output;
127             this.jvmArgs = jvmArgs;
128             this.systemProperties = systemProperties;
129         }
130         
131         public Parameters output(String output)
132         {
133             return new Parameters(output, jvmArgs, systemProperties);
134         }
135 
136         public Parameters jvmArgs(String jvmArgs)
137         {
138             return new Parameters(output, jvmArgs, systemProperties);
139         }
140 
141         public Parameters systemProperties(Map<String, String> systemProperties)
142         {
143             return new Parameters(output, jvmArgs, systemProperties);
144         }
145     }
146 }