1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package com.atlassian.theplugin.jira.api.soap;
18
19 import com.atlassian.theplugin.commons.configuration.ConfigurationFactory;
20 import com.atlassian.theplugin.commons.remoteapi.RemoteApiException;
21 import com.atlassian.theplugin.commons.remoteapi.RemoteApiLoginException;
22 import com.atlassian.theplugin.commons.remoteapi.ServerData;
23 import com.atlassian.theplugin.commons.remoteapi.rest.AbstractHttpSession;
24 import com.atlassian.theplugin.commons.util.HttpConfigurableAdapter;
25 import com.atlassian.theplugin.jira.api.*;
26 import com.atlassian.theplugin.jira.api.soap.axis.*;
27 import com.atlassian.theplugin.jira.model.JIRAServerCache;
28 import com.atlassian.theplugin.util.PluginUtil;
29 import com.intellij.openapi.diagnostic.Logger;
30 import org.apache.axis.AxisProperties;
31 import org.xml.sax.SAXException;
32
33 import javax.xml.rpc.ServiceException;
34 import java.net.MalformedURLException;
35 import java.net.URL;
36 import java.rmi.RemoteException;
37 import java.util.ArrayList;
38 import java.util.Calendar;
39 import java.util.List;
40 import java.util.concurrent.CopyOnWriteArrayList;
41
42 public class JIRASessionImpl implements JIRASession {
43
44 private String token;
45 private JiraSoapService service;
46 private ServerData server;
47 private URL portAddress;
48
49 public static final int ONE_DAY_AGO = -24;
50
51 private boolean loggedIn;
52
53
54
55
56
57 private void setAxisProperty(String name, String value) {
58 if (value == null) {
59 if (AxisProperties.getProperty(name) != null) {
60 try {
61 AxisProperties.setProperty(name, "");
62 } catch (NullPointerException e) {
63 Logger.getInstance(getClass().getName()).info("Setting AXIS property " + name + " to empty", e);
64 }
65 }
66 } else {
67 AxisProperties.setProperty(name, value);
68 }
69 }
70
71 private void setSystemProperty(String name, String value) {
72
73 if (value == null) {
74
75 try {
76 System.setProperty(name, "");
77 } catch (NullPointerException e) {
78 Logger.getInstance(getClass().getName()).info("Setting system property " + name + " to empty", e);
79 }
80
81 } else {
82 System.setProperty(name, value);
83 }
84 }
85
86 private void setProxy() {
87 boolean useIdeaProxySettings =
88 ConfigurationFactory.getConfiguration().getGeneralConfigurationData().getUseIdeaProxySettings();
89 HttpConfigurableAdapter proxyInfo = ConfigurationFactory.getConfiguration().transientGetHttpConfigurable();
90 String host = null;
91 String port = null;
92 String user = null;
93 String password = null;
94 if (useIdeaProxySettings && proxyInfo.isUseHttpProxy()) {
95 host = proxyInfo.getProxyHost();
96 port = String.valueOf(proxyInfo.getProxyPort());
97 if (proxyInfo.isProxyAuthentication()) {
98 user = proxyInfo.getProxyLogin();
99 password = proxyInfo.getPlainProxyPassword();
100 }
101 }
102
103
104
105
106
107
108
109 setAxisProperty("http.proxyHost", host);
110 setAxisProperty("http.proxyPort", port);
111
112 setSystemProperty("http.proxyHost", host);
113 setSystemProperty("http.proxyPort", port);
114
115 setAxisProperty("http.proxyUser", user);
116 setSystemProperty("http.proxyUser", user);
117
118 setAxisProperty("http.proxyPassword", password);
119 setSystemProperty("http.proxyPassword", password);
120
121 }
122
123 public JIRASessionImpl(ServerData server) throws ServiceException, MalformedURLException {
124 portAddress = new URL(server.getUrl() + "/rpc/soap/jirasoapservice-v2");
125 JiraSoapServiceServiceLocator loc = new JiraSoapServiceServiceLocator();
126 AbstractHttpSession.setUrl(portAddress);
127 service = loc.getJirasoapserviceV2(portAddress);
128 setProxy();
129
130 this.server = server;
131 }
132
133 public void login(String userName, String password) throws RemoteApiException {
134 try {
135 token = service.login(userName, password);
136 } catch (RemoteAuthenticationException e) {
137 throw new RemoteApiLoginException("Authentication failed");
138 } catch (RemoteException e) {
139 throw new RemoteApiException(e.toString());
140 }
141 loggedIn = true;
142 }
143
144 public void logout() {
145 try {
146 if (service.logout(token)) {
147 token = null;
148 loggedIn = false;
149 }
150 } catch (java.rmi.RemoteException e) {
151
152 }
153 }
154
155 public void logWork(JIRAIssue issue, String timeSpent, Calendar startDate, String comment,
156 boolean updateEstimate, String newEstimate)
157 throws RemoteApiException {
158 RemoteWorklog workLog = new RemoteWorklog();
159 workLog.setStartDate(startDate);
160 workLog.setTimeSpent(timeSpent);
161 if (comment != null) {
162 workLog.setComment(comment);
163 }
164 try {
165 if (updateEstimate) {
166 if (newEstimate != null) {
167 service.addWorklogWithNewRemainingEstimate(token, issue.getKey(), workLog, newEstimate);
168 } else {
169 service.addWorklogAndAutoAdjustRemainingEstimate(token, issue.getKey(), workLog);
170 }
171 } else {
172 service.addWorklogAndRetainRemainingEstimate(token, issue.getKey(), workLog);
173 }
174 } catch (RemoteException e) {
175 throw new RemoteApiException(e.toString(), e);
176 }
177 }
178
179 public JIRAIssue createIssue(JIRAIssue issue) throws RemoteApiException {
180 RemoteIssue remoteIssue = new RemoteIssue();
181
182 remoteIssue.setProject(issue.getProjectKey());
183 remoteIssue.setType(String.valueOf(issue.getTypeConstant().getId()));
184 remoteIssue.setSummary(issue.getSummary());
185 if (issue.getPriorityConstant().getId() != JIRAServerCache.ANY_ID) {
186 remoteIssue.setPriority(String.valueOf(issue.getPriorityConstant().getId()));
187 }
188
189 if (issue.getDescription() != null) {
190 remoteIssue.setDescription(issue.getDescription());
191 }
192 if (issue.getAssignee() != null) {
193 remoteIssue.setAssignee(issue.getAssignee());
194 }
195
196 final List<JIRAConstant> components = issue.getComponents();
197 if (components != null && components.size() > 0) {
198 RemoteComponent[] remoteComponents = new RemoteComponent[components.size()];
199 int i = 0;
200 for (JIRAConstant component : components) {
201 remoteComponents[i] = new RemoteComponent(String.valueOf(component.getId()), component.getName());
202 i++;
203 }
204 remoteIssue.setComponents(remoteComponents);
205 }
206
207 final List<JIRAConstant> versions = issue.getAffectsVersions();
208 if (versions != null && versions.size() > 0) {
209 RemoteVersion[] remoteVersions = new RemoteVersion[versions.size()];
210 int i = 0;
211 for (JIRAConstant version : versions) {
212 remoteVersions[i] = new RemoteVersion();
213 remoteVersions[i].setId(String.valueOf(version.getId()));
214 ++i;
215 }
216 remoteIssue.setAffectsVersions(remoteVersions);
217 }
218
219 try {
220 remoteIssue = service.createIssue(token, remoteIssue);
221 } catch (RemoteException e) {
222 throw new RemoteApiException(e.toString(), e);
223 }
224
225
226 JIRAIssueBean retVal = new JIRAIssueBean(server);
227 retVal.setKey(remoteIssue.getKey());
228 return retVal;
229 }
230
231 public JIRAIssue getIssueDetails(JIRAIssue issue) throws RemoteApiException {
232 RemoteSecurityLevel securityLevel = null;
233
234 try {
235 securityLevel = service.getSecurityLevel(token, issue.getKey());
236 } catch (RemoteException e) {
237 PluginUtil.getLogger().warn(
238 "Soap method 'getSecurityLevel' thrown exception. "
239 + "Probably there is no 'SecurityLevel' on JIRA (non enterprise version of JIRA).", e);
240 } catch (ClassCastException e) {
241 PluginUtil.getLogger().warn(
242 "Soap method 'getSecurityLevel' thrown ClassCastException. Probably some JIRA error.", e);
243 } catch (Exception e) {
244
245 if (e instanceof SAXException) {
246 PluginUtil.getLogger().warn(
247 "Soap method 'getSecurityLevel' thrown SAXException. Probably some JIRA error.", e);
248 } else {
249 throw new RemoteApiException(e);
250 }
251 }
252
253 try {
254 RemoteIssue rIssue = service.getIssue(token, issue.getKey());
255
256
257 if (rIssue == null) {
258 throw new RemoteApiException("Unable to retrieve issue details");
259 }
260 JIRAIssueBean issueBean = new JIRAIssueBean(issue);
261
262 if (securityLevel != null) {
263 issueBean.setSecurityLevel(
264 new JIRASecurityLevelBean(Long.valueOf(securityLevel.getId()), securityLevel.getName()));
265 }
266
267 RemoteVersion[] aVers = rIssue.getAffectsVersions();
268 List<JIRAConstant> av = new ArrayList<JIRAConstant>();
269 for (RemoteVersion v : aVers) {
270 av.add(new JIRAVersionBean(Long.valueOf(v.getId()), v.getName()));
271 }
272 issueBean.setAffectsVersions(av);
273
274 RemoteVersion[] fVers = rIssue.getFixVersions();
275 List<JIRAConstant> fv = new ArrayList<JIRAConstant>();
276 for (RemoteVersion v : fVers) {
277 fv.add(new JIRAVersionBean(Long.valueOf(v.getId()), v.getName()));
278 }
279 issueBean.setFixVersions(fv);
280
281 RemoteComponent[] comps = rIssue.getComponents();
282 List<JIRAConstant> c = new ArrayList<JIRAConstant>();
283 for (RemoteComponent rc : comps) {
284 c.add(new JIRAComponentBean(Long.valueOf(rc.getId()), rc.getName()));
285 }
286 issueBean.setComponents(c);
287
288 issueBean.setProjectKey(rIssue.getProject());
289 issueBean.setSummary(rIssue.getSummary());
290
291 issueBean.setRawSoapIssue(rIssue);
292
293 return issueBean;
294
295 } catch (RemoteException e) {
296 throw new RemoteApiException(e.toString(), e);
297 } catch (ClassCastException e) {
298 throw new RemoteApiException(e.toString(), e);
299 }
300
301 }
302
303 public void addComment(String issueKey, String comment) throws RemoteApiException {
304 try {
305 RemoteComment rComment = new RemoteComment();
306 rComment.setBody(comment);
307 service.addComment(token, issueKey, rComment);
308 } catch (RemoteException e) {
309 throw new RemoteApiException(e.toString(), e);
310 }
311 }
312
313 public List<JIRAProject> getProjects() throws RemoteApiException {
314 try {
315 RemoteProject[] projects = service.getProjectsNoSchemes(token);
316 List<JIRAProject> projectList = new ArrayList<JIRAProject>(projects.length);
317
318 for (RemoteProject p : projects) {
319 JIRAProjectBean project = new JIRAProjectBean();
320
321 project.setName(p.getName());
322 project.setKey(p.getKey());
323 project.setDescription(p.getDescription());
324 project.setUrl(p.getUrl());
325 project.setLead(p.getLead());
326 project.setId(Long.valueOf(p.getId()));
327
328 projectList.add(project);
329 }
330
331 return projectList;
332 } catch (RemoteException e) {
333 throw new RemoteApiException(e.toString(), e);
334 }
335 }
336
337 private List<JIRAConstant> issueTableToList(RemoteIssueType[] types) throws MalformedURLException {
338 List<JIRAConstant> typesList = new ArrayList<JIRAConstant>();
339 for (RemoteIssueType type : types) {
340 typesList.add(new JIRAIssueTypeBean(Long.valueOf(type.getId()), type.getName(), new URL(type.getIcon())));
341 }
342 return typesList;
343 }
344
345 public List<JIRAConstant> getIssueTypes() throws RemoteApiException {
346 try {
347 return issueTableToList(service.getIssueTypes(token));
348 } catch (RemoteException e) {
349 throw new RemoteApiException(e.toString(), e);
350 } catch (MalformedURLException e) {
351 throw new RemoteApiException(e.toString(), e);
352 }
353
354 }
355
356 public List<JIRAConstant> getIssueTypesForProject(String project) throws RemoteApiException {
357 try {
358 return issueTableToList(service.getIssueTypesForProject(token, project));
359 } catch (RemoteException e) {
360 throw new RemoteApiException(e.toString(), e);
361 } catch (MalformedURLException e) {
362 throw new RemoteApiException(e.toString(), e);
363 }
364 }
365
366 public List<JIRAConstant> getSubtaskIssueTypes() throws RemoteApiException {
367 try {
368 return issueTableToList(service.getSubTaskIssueTypes(token));
369 } catch (RemoteException e) {
370 throw new RemoteApiException(e.toString(), e);
371 } catch (MalformedURLException e) {
372 throw new RemoteApiException(e.toString(), e);
373 }
374
375 }
376
377 public List<JIRAConstant> getSubtaskIssueTypesForProject(String project) throws RemoteApiException {
378 try {
379 return issueTableToList(service.getSubTaskIssueTypesForProject(token, project));
380 } catch (RemoteException e) {
381 throw new RemoteApiException(e.toString(), e);
382 } catch (MalformedURLException e) {
383 throw new RemoteApiException(e.toString(), e);
384 }
385 }
386
387 public List<JIRAConstant> getStatuses() throws RemoteApiException {
388 try {
389 RemoteStatus[] statuses = service.getStatuses(token);
390
391 List<JIRAConstant> statusesList = new ArrayList<JIRAConstant>(statuses.length);
392 for (RemoteStatus status : statuses) {
393 statusesList.add(new JIRAStatusBean(
394 Long.valueOf(status.getId()), status.getName(), new URL(status.getIcon())));
395 }
396 return statusesList;
397 } catch (RemoteException e) {
398 throw new RemoteApiException(e.toString(), e);
399 } catch (MalformedURLException e) {
400 throw new RemoteApiException(e.toString(), e);
401 }
402 }
403
404 public List<JIRAComponentBean> getComponents(String projectKey) throws RemoteApiException {
405 try {
406 RemoteComponent[] components = service.getComponents(token, projectKey);
407
408 List<JIRAComponentBean> componentsList = new ArrayList<JIRAComponentBean>(components.length);
409 for (RemoteComponent c : components) {
410 componentsList.add(new JIRAComponentBean(Long.valueOf(c.getId()), c.getName()));
411 }
412 return componentsList;
413 } catch (RemoteException e) {
414 throw new RemoteApiException(e.toString(), e);
415 }
416 }
417
418 public List<JIRAVersionBean> getVersions(String projectKey) throws RemoteApiException {
419 try {
420 RemoteVersion[] versions = service.getVersions(token, projectKey);
421
422 List<JIRAVersionBean> versionsList = new ArrayList<JIRAVersionBean>(versions.length);
423 for (RemoteVersion v : versions) {
424 versionsList.add(new JIRAVersionBean(Long.valueOf(v.getId()), v.getName()));
425 }
426 return versionsList;
427 } catch (RemoteException e) {
428 throw new RemoteApiException(e.toString(), e);
429 }
430 }
431
432 public List<JIRAConstant> getPriorities() throws RemoteApiException {
433 try {
434 RemotePriority[] priorities = service.getPriorities(token);
435
436 List<JIRAConstant> prioritiesList = new ArrayList<JIRAConstant>(priorities.length);
437 for (RemotePriority p : priorities) {
438 prioritiesList.add(new JIRAPriorityBean(Long.valueOf(p.getId()), p.getName(), new URL(p.getIcon())));
439 }
440 return prioritiesList;
441 } catch (RemoteException e) {
442 throw new RemoteApiException(e.toString(), e);
443 } catch (MalformedURLException e) {
444 throw new RemoteApiException(e.toString(), e);
445 }
446 }
447
448 public List<JIRAResolutionBean> getResolutions() throws RemoteApiException {
449 try {
450 RemoteResolution[] resolutions = service.getResolutions(token);
451
452 List<JIRAResolutionBean> resolutionsList = new ArrayList<JIRAResolutionBean>(resolutions.length);
453 for (RemoteResolution p : resolutions) {
454 resolutionsList.add(new JIRAResolutionBean(Long.valueOf(p.getId()), p.getName()));
455 }
456 return resolutionsList;
457 } catch (RemoteException e) {
458 throw new RemoteApiException(e.toString(), e);
459 }
460 }
461
462 public List<JIRAQueryFragment> getSavedFilters() throws RemoteApiException {
463 try {
464 RemoteFilter[] filters = service.getSavedFilters(token);
465
466 List<JIRAQueryFragment> filtersList = new ArrayList<JIRAQueryFragment>(filters.length);
467 for (RemoteFilter f : filters) {
468 filtersList.add(new JIRASavedFilterBean(f.getName(), Long.valueOf(f.getId())));
469 }
470 return filtersList;
471 } catch (RemoteException e) {
472 throw new RemoteApiException(e.toString(), e);
473 }
474
475 }
476
477 public void setAssignee(JIRAIssue issue, String assignee) throws RemoteApiException {
478 RemoteFieldValue v = new RemoteFieldValue();
479 RemoteFieldValue[] vTable = {v};
480 v.setId("assignee");
481 v.setValues(new String[]{assignee});
482 try {
483 service.updateIssue(token, issue.getKey(), vTable);
484 } catch (RemoteException e) {
485 throw new RemoteApiException(e.toString(), e);
486 }
487 }
488
489 public List<JIRAAction> getAvailableActions(JIRAIssue issue) throws RemoteApiException {
490 try {
491 RemoteNamedObject[] actions = service.getAvailableActions(token, issue.getKey());
492 List<JIRAAction> actionList = new ArrayList<JIRAAction>(actions != null ? actions.length : 0);
493 if (actions != null) {
494 for (RemoteNamedObject action : actions) {
495 actionList.add(new JIRAActionBean(Long.valueOf(action.getId()), action.getName()));
496 }
497 }
498 return actionList;
499 } catch (RemoteException e) {
500 throw new RemoteApiException(e.toString(), e);
501 } catch (ClassCastException e) {
502 throw new RemoteApiException(e.toString(), e);
503 }
504 }
505
506 public List<JIRAActionField> getFieldsForAction(JIRAIssue issue, JIRAAction action) throws RemoteApiException {
507 try {
508 RemoteField[] fields = service.getFieldsForAction(
509 token, issue.getKey(), Long.valueOf(action.getId()).toString());
510 List<JIRAActionField> fieldList = new ArrayList<JIRAActionField>(fields.length);
511 for (RemoteField f : fields) {
512 fieldList.add(new JIRAActionFieldBean(f.getId(), f.getName()));
513 }
514 return fieldList;
515 } catch (RemoteException e) {
516 throw new RemoteApiException(e.toString(), e);
517 }
518 }
519
520 public void progressWorkflowAction(JIRAIssue issue, JIRAAction action, List<JIRAActionField> fields)
521 throws RemoteApiException {
522 try {
523 if (fields == null) {
524 RemoteFieldValue[] dummyValues = new RemoteFieldValue[0];
525 service.progressWorkflowAction(token, issue.getKey(), String.valueOf(action.getId()), dummyValues);
526 } else {
527
528 CopyOnWriteArrayList<JIRAActionField> safeFields = new CopyOnWriteArrayList<JIRAActionField>(fields);
529
530 for (JIRAActionField field : safeFields) {
531 if (field.getValues() == null) {
532 safeFields.remove(field);
533 }
534 }
535
536 int i = 0;
537 RemoteFieldValue[] values = new RemoteFieldValue[safeFields.size()];
538
539 for (JIRAActionField field : safeFields) {
540 List<String> fieldValues = field.getValues();
541 String[] fieldValueTable = fieldValues.toArray(new String[fieldValues.size()]);
542 values[i] = new RemoteFieldValue(field.getFieldId(), fieldValueTable);
543 ++i;
544 }
545 service.progressWorkflowAction(token, issue.getKey(), String.valueOf(action.getId()), values);
546 }
547 } catch (RemoteException e) {
548 throw new RemoteApiException(e.toString(), e);
549 }
550 }
551
552 public List<JIRAComment> getComments(JIRAIssue issue) throws RemoteApiException {
553 try {
554 RemoteComment[] comments = service.getComments(token, issue.getKey());
555 if (comments == null) {
556 throw new RemoteApiException("Unable to retrieve comments");
557 }
558
559 List<JIRAComment> commentsList = new ArrayList<JIRAComment>(comments.length);
560 for (RemoteComment c : comments) {
561 commentsList.add(new JIRACommentBean(c.getId(), c.getAuthor(), c.getBody(), c.getCreated()));
562 }
563 return commentsList;
564 } catch (RemoteException e) {
565 throw new RemoteApiException(e.toString(), e);
566 }
567 }
568
569 public JIRAUserBean getUser(String loginName) throws RemoteApiException, JiraUserNotFoundException {
570 try {
571 RemoteUser ru = service.getUser(token, loginName);
572 if (ru == null) {
573 throw new JiraUserNotFoundException("User Name for " + loginName + " not found");
574 }
575 return new JIRAUserBean(-1, ru.getFullname(), ru.getName()) {
576 @Override
577 public String getQueryStringFragment() {
578 return null;
579 }
580
581 public JIRAQueryFragment getClone() {
582 return null;
583 }
584 };
585 } catch (RemoteException e) {
586 throw new RemoteApiException(e.toString(), e);
587 } catch (ClassCastException e) {
588 throw new RemoteApiException(e.toString(), e);
589 }
590 }
591
592 public boolean isLoggedIn() {
593 return loggedIn;
594 }
595 }