PageRenderTime 104ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/src/org/bitbucket/connectors/jetbrains/tasks/BitbucketIssueRepository.java

https://bitbucket.org/atlassian/jetbrains-bitbucket-connector/
Java | 300 lines | 234 code | 61 blank | 5 comment | 19 complexity | d62ca4a33fdb09d8bccc8766daa80c49 MD5 | raw file
  1. package org.bitbucket.connectors.jetbrains.tasks;
  2. import com.intellij.openapi.diagnostic.Logger;
  3. import com.intellij.openapi.util.Ref;
  4. import com.intellij.tasks.*;
  5. import com.intellij.tasks.impl.BaseRepository;
  6. import com.intellij.tasks.impl.BaseRepositoryImpl;
  7. import com.intellij.tasks.impl.LocalTaskImpl;
  8. import com.intellij.tasks.impl.TaskUtil;
  9. import com.intellij.tasks.pivotal.PivotalTrackerRepository;
  10. import com.intellij.util.NullableFunction;
  11. import com.intellij.util.containers.ContainerUtil;
  12. import com.intellij.util.xmlb.annotations.Attribute;
  13. import com.intellij.util.xmlb.annotations.Tag;
  14. import org.bitbucket.connectors.jetbrains.BitbucketSettings;
  15. import org.bitbucket.connectors.jetbrains.BitbucketUtil;
  16. import org.jdom.Element;
  17. import org.jetbrains.annotations.NotNull;
  18. import org.jetbrains.annotations.Nullable;
  19. import javax.swing.*;
  20. import java.lang.reflect.Method;
  21. import java.text.MessageFormat;
  22. import java.text.ParseException;
  23. import java.util.Arrays;
  24. import java.util.Date;
  25. import java.util.List;
  26. @Tag("Bitbucket")
  27. public class BitbucketIssueRepository extends BaseRepositoryImpl {
  28. private static final Logger log =
  29. Logger.getInstance("#org.bitbucket.connectors.jetbrains.tasks.BitbucketIssueRepository");
  30. @SuppressWarnings({"UnusedDeclaration"})
  31. public BitbucketIssueRepository() {}
  32. protected BitbucketIssueRepository(BitbucketIssueRepositoryType type) {
  33. super(type);
  34. }
  35. public BitbucketIssueRepository(BitbucketIssueRepository other) {
  36. super(other);
  37. setRepositoryName(other.getRepositoryName());
  38. setRepositoryOwner(other.getRepositoryOwner());
  39. }
  40. protected String myRepoName = null;
  41. @Attribute("repo")
  42. public String getRepositoryName() {
  43. return myRepoName;
  44. }
  45. public void setRepositoryName(String s) {
  46. myRepoName = s;
  47. }
  48. protected String myRepoOwner = null;
  49. @Attribute("owner")
  50. public String getRepositoryOwner() {
  51. return myRepoOwner;
  52. }
  53. public void setRepositoryOwner(String s) {
  54. myRepoOwner = s;
  55. }
  56. @Override
  57. public Task[] getIssues(@Nullable String query, int max, long since) throws Exception {
  58. log.debug("getIssues: " + query);
  59. @SuppressWarnings({"unchecked"}) List<Object> children = getIssues(query);
  60. if (children == null) return Task.EMPTY_ARRAY;
  61. List<Task> taskList = ContainerUtil.mapNotNull(children, new NullableFunction<Object, Task>() {
  62. public Task fun(Object o) {
  63. final Task issue = createIssue((Element) o);
  64. log.debug("Loaded Issue: " + issue);
  65. return issue;
  66. }
  67. });
  68. return taskList.toArray(new Task[taskList.size()]);
  69. }
  70. // https://api.bitbucket.org/1.0/repositories/sylvanaar2/lua-for-idea/issues/?format=xml&status=new&status=open
  71. // sylvanaar2/lua-for-idea/issues?status=new&status=open status=new&status=open
  72. private List getIssues(String query) throws Exception {
  73. log.debug(query);
  74. final BitbucketSettings settings = BitbucketSettings.getInstance();
  75. String url = "/repositories/" + getRepositoryOwner() + "/" + getRepositoryName() + "/issues";
  76. log.debug("getIssues for : " + url);
  77. String queryParameters = "status=new&status=open";
  78. Element element =
  79. BitbucketUtil.request(settings.getLogin(), settings.getPassword(), url, false, null, queryParameters);
  80. return element.getChild("issues").getChildren("resource");
  81. }
  82. TaskState mapState(String state) {
  83. if (state.equals("new")) return TaskState.SUBMITTED;
  84. if (state.equals("open")) return TaskState.OPEN;
  85. return TaskState.RESOLVED;
  86. }
  87. @Nullable
  88. private Task createIssue(final Element element) {
  89. if (element != null) log.debug(element.getText());
  90. else {
  91. log.debug("NULL element");
  92. return null;
  93. }
  94. final String id = element.getChildText("local_id");
  95. if (id == null) {
  96. return null;
  97. }
  98. final String summary = element.getChildText("title");
  99. if (summary == null) {
  100. return null;
  101. }
  102. final String description = element.getChildText("content");
  103. final Ref<Date> created = new Ref<Date>();
  104. try {
  105. created.set(parseDate(element, "created_on"));
  106. } catch (ParseException e) {
  107. log.warn(e);
  108. }
  109. final String kind = element.getChild("metadata").getChildText("kind");
  110. final TaskType taskType =
  111. kind.equals("bug") ? TaskType.BUG : (kind.equals("enhancement") ? TaskType.FEATURE : TaskType.OTHER);
  112. final String state = element.getChildText("status");
  113. final TaskState taskState = mapState(state);
  114. final boolean isClosed = taskState.equals(TaskState.RESOLVED);
  115. // /1.0/repositories/sylvanaar2/lua-for-idea/issues/79
  116. final String issueUrl = element.getChildText("resource_uri").replace("/1.0/repositories", "").replace("/issues/", "/issue/");
  117. return new LocalTaskImpl(new Task() {
  118. public String getCustomIcon() {
  119. return null;
  120. }
  121. @Override
  122. public boolean isIssue() {
  123. return true;
  124. }
  125. //https://bitbucket.org/sylvanaar2/lua-for-idea/issue/80
  126. @Override
  127. public String getIssueUrl() {
  128. return "https://" + BitbucketUtil.BITBUCKET_DN + issueUrl;
  129. }
  130. @NotNull
  131. @Override
  132. public String getId() {
  133. return id;
  134. }
  135. @NotNull
  136. @Override
  137. public String getSummary() {
  138. return summary;
  139. }
  140. public String getDescription() {
  141. return description;
  142. }
  143. @Override
  144. public TaskState getState() {
  145. return taskState;
  146. }
  147. @NotNull
  148. @Override
  149. public Comment[] getComments() {
  150. return new Comment[0];
  151. }
  152. @Override
  153. public Icon getIcon() {
  154. return BitbucketUtil.ICON;
  155. }
  156. @NotNull
  157. @Override
  158. public TaskType getType() {
  159. return taskType;
  160. }
  161. @Override
  162. public Date getUpdated() {
  163. return created.get();
  164. }
  165. @Override
  166. public Date getCreated() {
  167. return created.get();
  168. }
  169. @Override
  170. public boolean isClosed() {
  171. return isClosed;
  172. }
  173. @Override
  174. public TaskRepository getRepository() {
  175. return BitbucketIssueRepository.this;
  176. }
  177. @Override
  178. public String getPresentableName() {
  179. return MessageFormat.format("#{0}: {1}", getId(), getSummary());
  180. }
  181. });
  182. }
  183. private static Date parseDate(final Element element, final String name) throws ParseException {
  184. try {
  185. Method parseDateMethod = getParseDateMethod();
  186. if (parseDateMethod != null) {
  187. return (Date) parseDateMethod.invoke(null, element, name);
  188. } else { // fix for newer versions without PivotalTrackerRepository.parseDate() method
  189. String val = element.getChildText(name);
  190. return TaskUtil.parseDate(val);
  191. }
  192. } catch (Exception e) {
  193. throw new RuntimeException(e);
  194. }
  195. }
  196. private static Method getParseDateMethod() {
  197. final Class[] PARAMETER_TYPES = new Class[] { Element.class, String.class };
  198. for (Method method: PivotalTrackerRepository.class.getMethods()) {
  199. if ("parseDate".equals(method.getName()) && Arrays.equals(PARAMETER_TYPES, method.getParameterTypes())) {
  200. method.setAccessible(true);
  201. return method;
  202. }
  203. }
  204. return null;
  205. }
  206. //https://api.bitbucket.org/1.0/repositories/sylvanaar2/lua-for-idea/issues/1
  207. @Override
  208. public Task findTask(String s) throws Exception {
  209. log.debug("Find Task:" + s);
  210. final BitbucketSettings settings = BitbucketSettings.getInstance();
  211. String url = "/repositories/" + getRepositoryOwner() + "/" + getRepositoryName() + "/issues/" + s;
  212. Element element = BitbucketUtil.request(settings.getLogin(), settings.getPassword(), url, false, null);
  213. if (element == null) return null;
  214. return createIssue(element);
  215. }
  216. @Override
  217. public BaseRepository clone() {
  218. return new BitbucketIssueRepository(this);
  219. }
  220. @Nullable
  221. public String extractId(String taskName) {
  222. return taskName;
  223. }
  224. @Override
  225. @Nullable
  226. public String getTaskComment(Task task) {
  227. return MessageFormat.format("#{0}: {1}", task.getId(), task.getSummary());
  228. }
  229. @Override
  230. public String toString() {
  231. return "BitbucketIssueRepository{" + "myRepoName='" + myRepoName + '\'' + ", myRepoOwner='" + myRepoOwner +
  232. '\'' + '}';
  233. }
  234. @Override
  235. public String getUrl() {
  236. return BitbucketUtil.API_URL_BASE + "/" + "repositories" + "/" + getRepositoryOwner() + "/" +
  237. getRepositoryName();
  238. }
  239. }