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