1   package com.atlassian.maven.plugins.amps;
2   
3   import java.io.File;
4   import java.util.List;
5   
6   import com.atlassian.maven.plugins.amps.codegen.ConditionFactory;
7   import com.atlassian.maven.plugins.amps.codegen.ContextProviderFactory;
8   import com.atlassian.maven.plugins.amps.codegen.PluginModuleSelectionQueryer;
9   import com.atlassian.maven.plugins.amps.codegen.jira.ActionTypeFactory;
10  import com.atlassian.maven.plugins.amps.codegen.jira.CustomFieldSearcherFactory;
11  import com.atlassian.maven.plugins.amps.codegen.jira.CustomFieldTypeFactory;
12  import com.atlassian.maven.plugins.amps.codegen.prompter.PluginModulePrompter;
13  import com.atlassian.maven.plugins.amps.codegen.prompter.PluginModulePrompterFactory;
14  import com.atlassian.maven.plugins.amps.product.ProductHandlerFactory;
15  import com.atlassian.maven.plugins.amps.util.GoogleAmpsTracker;
16  import com.atlassian.plugins.codegen.MavenProjectRewriter;
17  import com.atlassian.plugins.codegen.PluginProjectChangeset;
18  import com.atlassian.plugins.codegen.PluginXmlRewriter;
19  import com.atlassian.plugins.codegen.ProjectFilesRewriter;
20  import com.atlassian.plugins.codegen.modules.PluginModuleCreator;
21  import com.atlassian.plugins.codegen.modules.PluginModuleCreatorFactory;
22  import com.atlassian.plugins.codegen.modules.PluginModuleLocation;
23  import com.atlassian.plugins.codegen.modules.PluginModuleProperties;
24  
25  import org.apache.commons.lang.StringUtils;
26  import org.apache.maven.artifact.DependencyResolutionRequiredException;
27  import org.apache.maven.model.Resource;
28  import org.apache.maven.plugin.MojoExecutionException;
29  import org.apache.maven.plugin.MojoFailureException;
30  import org.apache.maven.project.MavenProject;
31  import org.jfrog.maven.annomojo.annotations.MojoComponent;
32  import org.jfrog.maven.annomojo.annotations.MojoGoal;
33  import org.jfrog.maven.annomojo.annotations.MojoRequiresDependencyResolution;
34  
35  /**
36   * @since 3.6
37   */
38  @MojoRequiresDependencyResolution("compile")
39  @MojoGoal("create-plugin-module")
40  public class PluginModuleGenerationMojo extends AbstractProductAwareMojo
41  {
42  
43      @MojoComponent
44      private PluginModuleSelectionQueryer pluginModuleSelectionQueryer;
45  
46      @MojoComponent
47      private PluginModulePrompterFactory pluginModulePrompterFactory;
48  
49      @MojoComponent
50      private PluginModuleCreatorFactory pluginModuleCreatorFactory;
51  
52      @Override
53      public void execute() throws MojoExecutionException, MojoFailureException
54      {
55          //can't figure out how to get plexus to fire a method after injection, so doing it here
56          pluginModulePrompterFactory.setLog(getLog());
57          try
58          {
59              pluginModulePrompterFactory.scanForPrompters();
60          } catch (Exception e)
61          {
62              String message = "Error initializing Plugin Module Prompters";
63              getLog().error(message);
64              throw new MojoExecutionException(message);
65          }
66  
67          String productId = getProductId();
68  
69          MavenProject project = getMavenContext().getProject();
70          File javaDir = getJavaSourceRoot(project);
71          File testDir = getJavaTestRoot(project);
72          File resourcesDir = getResourcesRoot(project);
73  
74          initHelperFactories(productId, project);
75  
76          PluginModuleLocation moduleLocation = new PluginModuleLocation.Builder(javaDir)
77                  .resourcesDirectory(resourcesDir)
78                  .testDirectory(testDir)
79                  .templateDirectory(new File(resourcesDir, "templates"))
80                  .groupAndArtifactId(project.getGroupId(), project.getArtifactId())
81                  .build();
82  
83          if (!moduleLocation.getPluginXml()
84                  .exists())
85          {
86              String message = "Couldn't find the atlassian-plugin.xml, please run this goal in an atlassian plugin project root.";
87              getLog().error(message);
88              throw new MojoExecutionException(message);
89          }
90  
91          runGeneration(productId, project, moduleLocation);
92  
93  
94      }
95  
96      private void runGeneration(String productId, MavenProject project, PluginModuleLocation moduleLocation) throws MojoExecutionException
97      {
98          PluginModuleCreator creator = null;
99          try
100         {
101             creator = pluginModuleSelectionQueryer.selectModule(pluginModuleCreatorFactory.getModuleCreatorsForProduct(productId));
102 
103             String trackingLabel = getPluginInformation().getId() + ":" + creator.getModuleName();
104             getGoogleTracker().track(GoogleAmpsTracker.CREATE_PLUGIN_MODULE,trackingLabel);
105 
106             PluginModulePrompter modulePrompter = pluginModulePrompterFactory.getPrompterForCreatorClass(creator.getClass());
107             if (modulePrompter == null)
108             {
109                 String message = "Couldn't find an input prompter for: " + creator.getClass()
110                         .getName();
111                 getLog().error(message);
112                 throw new MojoExecutionException(message);
113             }
114 
115             modulePrompter.setDefaultBasePackage(project.getGroupId());
116             modulePrompter.setPluginKey(project.getGroupId() + "." + project.getArtifactId());
117             
118             PluginModuleProperties moduleProps = modulePrompter.getModulePropertiesFromInput(moduleLocation);
119             moduleProps.setProductId(getGadgetCompatibleProductId(productId));
120 
121             PluginProjectChangeset changeset = creator.createModule(moduleProps);
122             
123             getLog().info("Adding the following items to the project:");
124             for (String desc : changeset.getChangeDescriptionsOrSummaries())
125             {
126                 getLog().info("  " + desc);
127             }
128             
129             // edit pom if needed
130             try
131             {
132                 new MavenProjectRewriter(project.getFile()).applyChanges(changeset);
133             }
134             catch (Exception e)
135             {
136                 getLog().error("Unable to apply changes to POM: " + e);
137             }
138             
139             // apply changes to project files
140             new ProjectFilesRewriter(moduleLocation).applyChanges(changeset);
141             new PluginXmlRewriter(moduleLocation).applyChanges(changeset);
142             
143             if (pluginModuleSelectionQueryer.addAnotherModule())
144             {
145                 runGeneration(productId, project, moduleLocation);
146             }
147 
148         } catch (Exception e)
149         {
150             e.printStackTrace();
151             throw new MojoExecutionException("Error creating plugin module", e);
152         }
153 
154     }
155 
156     private String getGadgetCompatibleProductId(String pid)
157     {
158         String productId = pid;
159         if (ProductHandlerFactory.JIRA
160                 .equals(pid))
161         {
162             productId = "JIRA";
163         } else if (ProductHandlerFactory.CONFLUENCE
164                 .equals(pid))
165         {
166             productId = "Confluence";
167         } else if (ProductHandlerFactory.BAMBOO
168                 .equals(pid))
169         {
170             productId = "Bamboo";
171         } else if (ProductHandlerFactory.CROWD
172                 .equals(pid))
173         {
174             productId = "Crowd";
175         } else if (ProductHandlerFactory.FECRU
176                 .equals(pid))
177         {
178             productId = "FishEye";
179         } else
180         {
181             productId = "Other";
182         }
183 
184         return productId;
185 
186     }
187 
188     private File getJavaSourceRoot(MavenProject project)
189     {
190         return new File(project.getModel()
191                 .getBuild()
192                 .getSourceDirectory());
193     }
194 
195     private File getJavaTestRoot(MavenProject project)
196     {
197         return new File(project.getModel()
198                 .getBuild()
199                 .getTestSourceDirectory());
200     }
201 
202     private File getResourcesRoot(MavenProject project)
203     {
204         File resourcesRoot = null;
205         for (Resource resource : (List<Resource>) project.getModel()
206                 .getBuild()
207                 .getResources())
208         {
209             String pathToCheck = "src" + File.separator + "main" + File.separator + "resources";
210             if (StringUtils.endsWith(resource.getDirectory(), pathToCheck))
211             {
212                 resourcesRoot = new File(resource.getDirectory());
213             }
214         }
215         return resourcesRoot;
216     }
217 
218     private void initHelperFactories(String productId, MavenProject project) throws MojoExecutionException
219     {
220         List<String> pluginClasspath;
221         try
222         {
223             pluginClasspath = project.getCompileClasspathElements();
224         } catch (DependencyResolutionRequiredException e)
225         {
226             throw new MojoExecutionException("Dependencies MUST be resolved", e);
227         }
228 
229         try
230         {
231             ConditionFactory.locateAvailableConditions(productId, pluginClasspath);
232         } catch (Exception e)
233         {
234             String message = "Error initializing Plugin Module Conditions";
235             getLog().error(message);
236             //keep going, doesn't matter
237         }
238 
239         try
240         {
241             ContextProviderFactory.locateAvailableContextProviders(productId, pluginClasspath);
242         } catch (Exception e)
243         {
244             String message = "Error initializing Plugin Module Context Providers";
245             getLog().error(message);
246             //keep going, doesn't matter
247         }
248 
249         if (ProductHandlerFactory.JIRA
250                 .equals(productId))
251         {
252             try
253             {
254                 ActionTypeFactory.locateAvailableActionTypes(pluginClasspath);
255             } catch (Exception e)
256             {
257                 String message = "Error initializing JIRA Action Types";
258                 getLog().error(message);
259                 //keep going, doesn't matter
260             }
261 
262             try
263             {
264                 CustomFieldTypeFactory.locateAvailableCustomFieldTypes(pluginClasspath);
265             } catch (Exception e)
266             {
267                 String message = "Error initializing JIRA Custom Field Types";
268                 getLog().error(message);
269                 //keep going, doesn't matter
270             }
271 
272             try
273             {
274                 CustomFieldSearcherFactory.locateAvailableCustomFieldSearchers(pluginClasspath);
275             } catch (Exception e)
276             {
277                 String message = "Error initializing JIRA Custom Field Searchers";
278                 getLog().error(message);
279                 //keep going, doesn't matter
280             }
281         }
282     }
283 }