PageRenderTime 47ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/ap3-bundles/ap3-api/src/main/java/com/atlassian/ap3/spi/command/AbstractProjectCreatorCommand.java

https://bitbucket.org/atlassian/ap3-sdk
Java | 282 lines | 227 code | 54 blank | 1 comment | 22 complexity | cc86e9bd5993d58bc28f799638e47e6e MD5 | raw file
  1. package com.atlassian.ap3.spi.command;
  2. import java.io.IOException;
  3. import java.nio.file.Files;
  4. import java.nio.file.Path;
  5. import java.nio.file.Paths;
  6. import java.security.NoSuchAlgorithmException;
  7. import java.util.Iterator;
  8. import java.util.Map;
  9. import javax.inject.Inject;
  10. import com.atlassian.ap3.api.Ap3Exception;
  11. import com.atlassian.ap3.api.ContainerResolver;
  12. import com.atlassian.ap3.api.annotation.RequiresKit;
  13. import com.atlassian.ap3.api.kit.KitDescriptorLocator;
  14. import com.atlassian.ap3.api.oauth.OAuthKeyUtil;
  15. import com.atlassian.ap3.api.oauth.OAuthKeyPair;
  16. import com.atlassian.ap3.api.prompt.Prompter;
  17. import com.atlassian.ap3.api.prompt.PrompterException;
  18. import com.atlassian.ap3.api.template.*;
  19. import com.atlassian.ap3.home.HomeLocator;
  20. import com.atlassian.ap3.spi.kit.KitDescriptor;
  21. import com.google.common.base.Predicate;
  22. import com.google.common.collect.Iterables;
  23. import org.apache.commons.lang3.StringUtils;
  24. import io.airlift.command.Group;
  25. import io.airlift.command.Option;
  26. @Group(name = "new", description = "Creates a new Atlassian Plugin", defaultCommand = NewDefaultCommand.class)
  27. public abstract class AbstractProjectCreatorCommand extends BaseAp3Command
  28. {
  29. @Option(name = {"-tn", "--template-name"}, title = "Template Name", description = "The name of the template to use")
  30. private String templateName;
  31. @Option(name = {"-tf", "--template-folder"}, title = "Template Folder", description = "The path of a local template to use")
  32. private String templatePath;
  33. @Option(name = {"-n", "--name"}, title = "Plugin Name", description = "The name of your new plugin")
  34. private String pluginName;
  35. @Option(name = {"-d", "--description"}, title = "Description", description = "The description for your new plugin")
  36. private String pluginDescription;
  37. @Inject
  38. protected HomeLocator homeLocator;
  39. @Inject
  40. protected AP3TemplateManager templateManager;
  41. @Inject
  42. protected Prompter prompter;
  43. @Inject
  44. protected ProjectGenerator projectGenerator;
  45. @Inject
  46. protected KitDescriptorLocator kitLocator;
  47. @Inject
  48. private OAuthKeyUtil keyGenerator;
  49. @Inject
  50. private ContainerResolver containerResolver;
  51. public TemplateInfo getTemplateInfo() throws Ap3Exception
  52. {
  53. if(StringUtils.isNotBlank(templatePath))
  54. {
  55. Path templateFolder = Paths.get(templatePath);
  56. if(Files.exists(templateFolder) && Files.isReadable(templateFolder))
  57. {
  58. return getTemplateFromPath(templateFolder);
  59. }
  60. }
  61. return getTemplateByName();
  62. }
  63. @Override
  64. public void run() throws Ap3Exception
  65. {
  66. TemplateInfo templateInfo = getTemplateInfo();
  67. if(null == templateInfo)
  68. {
  69. System.out.println("Template not found!");
  70. return;
  71. }
  72. PluginIdentifier pluginId = getPluginIdentifier();
  73. Map<String,Object> context = createContext(templateInfo,pluginId);
  74. try
  75. {
  76. mergeTemplateVariables(templateInfo,pluginId,context);
  77. }
  78. catch (IOException e)
  79. {
  80. throw new Ap3Exception("Unable to merge template variables", e);
  81. }
  82. Path projectRoot = createProject(templateInfo,pluginId,context);
  83. prompter.showInfo("Project successfully created in: " + projectRoot.toAbsolutePath().toString());
  84. }
  85. protected abstract Map<String,Object> createContext(TemplateInfo templateInfo, PluginIdentifier pluginId) throws Ap3Exception;
  86. protected Path createProject(TemplateInfo templateInfo, PluginIdentifier pluginId, Map<String,Object> context) throws Ap3Exception
  87. {
  88. try
  89. {
  90. if (!this.getClass().isAnnotationPresent(RequiresKit.class))
  91. {
  92. throw new Ap3Exception("RequiresKit annotation missing from command '" + this.getClass().getSimpleName() + "'");
  93. }
  94. Class<? extends KitDescriptor> kitClass = this.getClass().getAnnotation(RequiresKit.class).value();
  95. OAuthKeyPair keyPair = new OAuthKeyPair("","");
  96. if(templateInfo.getRequiresOauth())
  97. {
  98. keyPair = keyGenerator.generateKeys();
  99. context.put("oauthBlock",keyGenerator.getOAuthXmlBlock(keyPair));
  100. }
  101. return projectGenerator.generateProject(templateInfo,context,pluginId,kitLocator.getKitDescriptor(kitClass),keyPair);
  102. }
  103. catch (IOException | NoSuchAlgorithmException e)
  104. {
  105. throw new Ap3Exception("Error generating project", e);
  106. }
  107. }
  108. private TemplateInfo getTemplateFromPath(Path templateFolder) throws Ap3Exception
  109. {
  110. return templateManager.loadTemplateFromPath(templateFolder);
  111. }
  112. private TemplateInfo getTemplateByName() throws Ap3Exception
  113. {
  114. if (!this.getClass().isAnnotationPresent(RequiresKit.class))
  115. {
  116. throw new Ap3Exception("KitProvider annotation missing from command '" + this.getClass().getSimpleName() + "'");
  117. }
  118. Class<? extends KitDescriptor> kitClass = this.getClass().getAnnotation(RequiresKit.class).value();
  119. KitDescriptor kit = kitLocator.getKitDescriptor(kitClass);
  120. String repoUrl = kit.getTemplatesRepoUrl();
  121. Iterable<TemplateInfo> templates = templateManager.listKitTemplates(repoUrl, globalOptions.isOffline());
  122. if(null == templates || !templates.iterator().hasNext())
  123. {
  124. return null;
  125. }
  126. if (StringUtils.isBlank(templateName))
  127. {
  128. if (!templates.iterator().hasNext())
  129. {
  130. //TODO: not sure what to do here yet
  131. return null;
  132. }
  133. return promptForTemplate(templates);
  134. }
  135. else
  136. {
  137. Iterator<TemplateInfo> it = Iterables.filter(templates, new Predicate<TemplateInfo>()
  138. {
  139. @Override
  140. public boolean apply(TemplateInfo input)
  141. {
  142. return templateName.equals(input.getKey());
  143. }
  144. }).iterator();
  145. if(it.hasNext())
  146. {
  147. return it.next();
  148. }
  149. else
  150. {
  151. System.out.println("Invalid template name");
  152. return promptForTemplate(templates);
  153. }
  154. }
  155. }
  156. public PluginIdentifier getPluginIdentifier() throws Ap3Exception
  157. {
  158. if(StringUtils.isBlank(pluginName))
  159. {
  160. try
  161. {
  162. this.pluginName = prompter.promptNotBlank("Enter your new plugin name");
  163. }
  164. catch (PrompterException e)
  165. {
  166. throw new Ap3Exception("Error prompting for plugin name", e);
  167. }
  168. }
  169. return new PluginIdentifier(pluginName);
  170. }
  171. protected void mergeTemplateVariables(TemplateInfo templateInfo, PluginIdentifier pluginId, Map<String, Object> context) throws Ap3Exception, IOException
  172. {
  173. if(StringUtils.isBlank(pluginDescription))
  174. {
  175. pluginDescription = "The " + pluginId.getName() + " plugin";
  176. }
  177. String containerVersion = containerResolver.getLatestContainerVersion(true);
  178. context.put("latestP3Version",containerVersion);
  179. context.put("pluginName",pluginId.getName());
  180. context.put("pluginDescription",pluginDescription);
  181. context.put("pluginFolder",pluginId.getDashedName());
  182. if(templateInfo.getVariables().isEmpty())
  183. {
  184. return;
  185. }
  186. for(TemplateVariable variable : templateInfo.getVariables())
  187. {
  188. if(context.containsKey(variable.getName()))
  189. {
  190. continue;
  191. }
  192. String value = null;
  193. try
  194. {
  195. if(StringUtils.isNotBlank(variable.getStaticValue()))
  196. {
  197. value = variable.getStaticValue();
  198. }
  199. else if(!variable.getChoices().isEmpty())
  200. {
  201. value = prompter.promptForChoice(variable.getPrompt(),variable.getChoices());
  202. }
  203. else
  204. {
  205. value = prompter.promptNotBlank(variable.getPrompt(),variable.getDefaultValue());
  206. }
  207. context.put(variable.getName(),value);
  208. }
  209. catch (PrompterException e)
  210. {
  211. throw new Ap3Exception("Error prompting for template variable", e);
  212. }
  213. }
  214. }
  215. private TemplateInfo promptForTemplate(Iterable<TemplateInfo> templates) throws Ap3Exception
  216. {
  217. TemplateInfo template = null;
  218. try
  219. {
  220. template = prompter.promptForChoice("Choose a template", templates);
  221. }
  222. catch (PrompterException e)
  223. {
  224. throw new Ap3Exception("Error prompting for template", e);
  225. }
  226. return template;
  227. }
  228. }