PageRenderTime 58ms CodeModel.GetById 30ms RepoModel.GetById 0ms app.codeStats 0ms

/src/main/java/com/atlassian/jira/plugins/bitbucket/spi/DvcsRepositoryManager.java

https://bitbucket.org/dusanhornik/demo-repository
Java | 297 lines | 245 code | 48 blank | 4 comment | 7 complexity | c714a4a5ff89499fe688a8fc7fa1e385 MD5 | raw file
  1. package com.atlassian.jira.plugins.bitbucket.spi;
  2. import com.atlassian.jira.issue.IssueManager;
  3. import com.atlassian.jira.plugins.bitbucket.IssueLinker;
  4. import com.atlassian.jira.plugins.bitbucket.activeobjects.v2.IssueMapping;
  5. import com.atlassian.jira.plugins.bitbucket.activeobjects.v2.ProjectMapping;
  6. import com.atlassian.jira.plugins.bitbucket.api.*;
  7. import com.atlassian.jira.plugins.bitbucket.api.impl.DefaultSourceControlRepository;
  8. import com.atlassian.jira.plugins.bitbucket.streams.GlobalFilter;
  9. import com.atlassian.jira.plugins.bitbucket.velocity.VelocityUtils;
  10. import com.atlassian.sal.api.ApplicationProperties;
  11. import com.atlassian.templaterenderer.TemplateRenderer;
  12. import com.google.common.base.Function;
  13. import com.google.common.collect.Lists;
  14. import com.google.common.collect.Sets;
  15. import org.slf4j.Logger;
  16. import org.slf4j.LoggerFactory;
  17. import java.io.IOException;
  18. import java.io.StringWriter;
  19. import java.util.*;
  20. import java.util.regex.Matcher;
  21. import java.util.regex.Pattern;
  22. public abstract class DvcsRepositoryManager implements RepositoryManager, RepositoryUriFactory
  23. {
  24. private static final Logger log = LoggerFactory.getLogger(DvcsRepositoryManager.class);
  25. public static final int MAX_VISIBLE_FILES = 5;
  26. protected final RepositoryPersister repositoryPersister;
  27. private final Communicator communicator;
  28. private final Encryptor encryptor;
  29. private final ApplicationProperties applicationProperties;
  30. private final IssueLinker issueLinker;
  31. private final TemplateRenderer templateRenderer;
  32. private final Function<IssueMapping, Changeset> toChangesetTransformer;
  33. private final IssueManager issueManager;
  34. /* Maps ProjectMapping to SourceControlRepository */
  35. private final Function<ProjectMapping, SourceControlRepository> TO_SOURCE_CONTROL_REPOSITORY = new Function<ProjectMapping, SourceControlRepository>()
  36. {
  37. @Override
  38. public SourceControlRepository apply(ProjectMapping pm)
  39. {
  40. String decryptedAdminPassword = encryptor.decrypt(pm.getAdminPassword(), pm.getProjectKey(),
  41. pm.getRepositoryUrl());
  42. return new DefaultSourceControlRepository(pm.getID(), pm.getRepositoryName(), pm.getRepositoryType(), getRepositoryUri(pm.getRepositoryUrl()),
  43. pm.getProjectKey(), pm.getAdminUsername(), decryptedAdminPassword, pm.getAccessToken());
  44. }
  45. };
  46. public DvcsRepositoryManager(Communicator communicator, RepositoryPersister repositoryPersister, Encryptor encryptor,
  47. ApplicationProperties applicationProperties, IssueLinker issueLinker, TemplateRenderer templateRenderer,
  48. IssueManager issueManager)
  49. {
  50. this.communicator = communicator;
  51. this.repositoryPersister = repositoryPersister;
  52. this.encryptor = encryptor;
  53. this.applicationProperties = applicationProperties;
  54. this.issueLinker = issueLinker;
  55. this.templateRenderer = templateRenderer;
  56. this.issueManager = issueManager;
  57. toChangesetTransformer = new ToChangesetTransformer(this);
  58. }
  59. public String getRepositoryName(String repositoryType, String projectKey, String repositoryUrl,
  60. String adminUsername, String adminPassword, String accessToken) throws SourceControlException
  61. {
  62. RepositoryUri repositoryUri = getRepositoryUri(repositoryUrl);
  63. return getCommunicator().getRepositoryName(repositoryType, projectKey, repositoryUri, adminUsername, adminPassword, accessToken);
  64. }
  65. @Override
  66. public SourceControlRepository addRepository(String repositoryType, String projectKey, String repositoryUrl, String adminUsername, String adminPassword, String accessToken)
  67. {
  68. // Remove trailing slashes from URL
  69. if (repositoryUrl.endsWith("/"))
  70. {
  71. repositoryUrl = repositoryUrl.substring(0, repositoryUrl.length() - 1);
  72. }
  73. // Set all URLs to HTTPS
  74. if (repositoryUrl.startsWith("http:"))
  75. {
  76. repositoryUrl = repositoryUrl.replaceFirst("http:", "https:");
  77. }
  78. String repositoryName = getRepositoryName(repositoryType, projectKey, repositoryUrl, adminUsername, adminPassword, accessToken);
  79. String encryptedAdminPassword = encryptor.encrypt(adminPassword, projectKey, repositoryUrl);
  80. ProjectMapping pm = repositoryPersister.addRepository(repositoryName, repositoryType, projectKey, repositoryUrl,
  81. adminUsername, encryptedAdminPassword, accessToken);
  82. return TO_SOURCE_CONTROL_REPOSITORY.apply(pm);
  83. }
  84. @Override
  85. public SourceControlRepository getRepository(int repositoryId)
  86. {
  87. ProjectMapping repository = repositoryPersister.getRepository(repositoryId);
  88. return TO_SOURCE_CONTROL_REPOSITORY.apply(repository);
  89. }
  90. @Override
  91. public List<SourceControlRepository> getRepositories(String projectKey)
  92. {
  93. List<ProjectMapping> repositories = repositoryPersister.getRepositories(projectKey, getRepositoryType());
  94. return Lists.transform(repositories, TO_SOURCE_CONTROL_REPOSITORY);
  95. }
  96. @Override
  97. public List<Changeset> getChangesets(String issueKey)
  98. {
  99. List<IssueMapping> issueMappings = repositoryPersister.getIssueMappings(issueKey, getRepositoryType());
  100. return Lists.transform(issueMappings, toChangesetTransformer);
  101. }
  102. @Override
  103. public Changeset getChangeset(SourceControlRepository repository, String node)
  104. {
  105. return getCommunicator().getChangeset(repository, node);
  106. }
  107. @Override
  108. public Changeset getChangeset(SourceControlRepository repository, Changeset changeset)
  109. {
  110. return getCommunicator().getChangeset(repository, changeset);
  111. }
  112. @Override
  113. public void removeRepository(int id)
  114. {
  115. repositoryPersister.removeRepository(id);
  116. }
  117. @Override
  118. public void addChangeset(SourceControlRepository repository, String issueId, Changeset changeset)
  119. {
  120. repositoryPersister.addChangeset(issueId, changeset);
  121. }
  122. @Override
  123. public SourceControlUser getUser(SourceControlRepository repository, String username)
  124. {
  125. return getCommunicator().getUser(repository, username);
  126. }
  127. @Override
  128. public String getHtmlForChangeset(SourceControlRepository repository, Changeset changeset)
  129. {
  130. Map<String, Object> templateMap = new HashMap<String, Object>();
  131. templateMap.put("velocity_utils", new VelocityUtils());
  132. templateMap.put("issue_linker", issueLinker);
  133. templateMap.put("changeset", changeset);
  134. templateMap.put("repository", repository);
  135. String documentJpgUrl = getApplicationProperties().getBaseUrl() + "/download/resources/com.atlassian.jira.plugins.jira-bitbucket-connector-plugin/images/document.jpg";
  136. templateMap.put("document_jpg_url", documentJpgUrl);
  137. String authorName = changeset.getRawAuthor();
  138. String login = changeset.getAuthor();
  139. String commitURL = changeset.getCommitURL(repository);
  140. SourceControlUser user = getUser(repository, changeset.getAuthor());
  141. String gravatarUrl = user.getAvatar().replace("s=32", "s=60");
  142. String commitMessage = changeset.getMessage();
  143. templateMap.put("gravatar_url", gravatarUrl);
  144. templateMap.put("user_url", repository.getRepositoryUri().getUserUrl(CustomStringUtils.encodeUriPath(login)));
  145. templateMap.put("login", login);
  146. templateMap.put("user_name", authorName);
  147. templateMap.put("commit_message", commitMessage);
  148. templateMap.put("commit_url", commitURL);
  149. templateMap.put("commit_hash", changeset.getNode());
  150. StringWriter sw = new StringWriter();
  151. try
  152. {
  153. templateRenderer.render("/templates/com/atlassian/jira/plugins/bitbucket/issuetabpanels/commits-view.vm", templateMap, sw);
  154. } catch (IOException e)
  155. {
  156. log.warn(e.getMessage(), e);
  157. }
  158. return sw.toString();
  159. }
  160. @Override
  161. public SynchronisationOperation getSynchronisationOperation(SynchronizationKey key, ProgressWriter progressProvider)
  162. {
  163. return new DefaultSynchronisationOperation(key, this, getCommunicator(), progressProvider, issueManager);
  164. }
  165. protected boolean hasValidFormat(String url)
  166. {
  167. // Valid URL
  168. Pattern p = Pattern.compile("^(https|http)://[a-zA-Z0-9][-a-zA-Z0-9]*(.[a-zA-Z0-9]+)+/[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|]");
  169. Matcher m = p.matcher(url);
  170. return m.matches();
  171. }
  172. @Override
  173. public abstract String getRepositoryType();
  174. public ApplicationProperties getApplicationProperties()
  175. {
  176. return applicationProperties;
  177. }
  178. public Communicator getCommunicator()
  179. {
  180. return communicator;
  181. }
  182. @Override
  183. public UrlInfo getUrlInfo(String repositoryUrl, String projectKey)
  184. {
  185. if (!hasValidFormat(repositoryUrl)) return null;
  186. UrlInfo urlInfo = getCommunicator().getUrlInfo(getRepositoryUri(repositoryUrl), projectKey);
  187. if (urlInfo==null) return null;
  188. return validateUrlInfo(urlInfo);
  189. }
  190. public UrlInfo validateUrlInfo(UrlInfo urlInfo)
  191. {
  192. ProjectMapping[] repos = repositoryPersister.findRepositories(urlInfo.getProjectKey(), urlInfo.getRepositoryUrl());
  193. if (repos.length>0)
  194. {
  195. urlInfo.addValidationError("Repository " + urlInfo.getRepositoryUrl() + " is already linked to project "
  196. + urlInfo.getProjectKey());
  197. }
  198. return urlInfo;
  199. }
  200. @Override
  201. public Changeset reloadChangeset(IssueMapping issueMapping)
  202. {
  203. ProjectMapping pm = repositoryPersister.getRepository(issueMapping.getRepositoryId());
  204. SourceControlRepository repository = TO_SOURCE_CONTROL_REPOSITORY.apply(pm);
  205. Changeset changeset = getCommunicator().getChangeset(repository, issueMapping.getNode());
  206. repositoryPersister.addChangeset(issueMapping.getIssueId(), changeset);
  207. return changeset;
  208. }
  209. @Override
  210. public void setupPostcommitHook(SourceControlRepository repo)
  211. {
  212. getCommunicator().setupPostcommitHook(repo, getPostCommitUrl(repo));
  213. }
  214. private String getPostCommitUrl(SourceControlRepository repo)
  215. {
  216. return getApplicationProperties().getBaseUrl() + "/rest/bitbucket/1.0/repository/" + repo.getId() + "/sync";
  217. }
  218. @Override
  219. public void removePostcommitHook(SourceControlRepository repo)
  220. {
  221. getCommunicator().removePostcommitHook(repo, getPostCommitUrl(repo));
  222. }
  223. @Override
  224. public Set<Changeset> getLatestChangesets(int count, GlobalFilter gf)
  225. {
  226. List<IssueMapping> latestIssueMappings = repositoryPersister.getLatestIssueMappings(count, gf, getRepositoryType());
  227. List<Changeset> changesets = Lists.transform(latestIssueMappings, toChangesetTransformer);
  228. return Sets.newHashSet(changesets);
  229. }
  230. @Override
  231. public Date getLastCommitDate(SourceControlRepository repo)
  232. {
  233. ProjectMapping projectMapping = repositoryPersister.getRepository(repo.getId());
  234. return projectMapping.getLastCommitDate();
  235. }
  236. @Override
  237. public void setLastCommitDate(SourceControlRepository repo, Date date)
  238. {
  239. ProjectMapping projectMapping = repositoryPersister.getRepository(repo.getId());
  240. if (projectMapping == null)
  241. throw new SourceControlException("Repository " + repo.getRepositoryUri().getRepositoryUrl() + " ("+ repo.getId() + ") does not exists!" );
  242. projectMapping.setLastCommitDate(date);
  243. projectMapping.save();
  244. }
  245. @Override
  246. public void removeAllChangesets(int repositoryId) {
  247. repositoryPersister.removeAllIssueMappings(repositoryId);
  248. }
  249. }