All Downloads are FREE. Search and download functionalities are using the official Maven repository.

guru.nidi.atlassian.remote.jira.rest.JiraRestService Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (C) 2013 Stefan Niederhauser ([email protected])
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package guru.nidi.atlassian.remote.jira.rest;

import com.atlassian.jira.rpc.soap.beans.*;
import guru.nidi.atlassian.remote.jira.RemoteIssueExt;
import guru.nidi.atlassian.remote.rest.RestException;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.HttpGet;

import java.io.IOException;
import java.io.InputStream;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 *
 */
public class JiraRestService {
    private final JiraRestAccess access;

    public JiraRestService(String baseUrl, String username, String password) {
        access = new JiraRestAccess(baseUrl, username, password);
    }

    public Object executePost(String command, Object parameters) throws RestException, IOException {
        return access.executePost(command, parameters);
    }

    public Object executeGet(String command) throws RestException, IOException {
        return access.executeGet(command);
    }

    public List getIssueLinkTypes() throws IOException, RestException {
        HttpGet method = access.get("issueLinkType");
        HttpResponse response = access.executeMethod(method);
        if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
            Map errorMsg = access.readResponse(response, JiraRestAccess.MAP_TYPE_REFERENCE);
            throw new RestException(errorMsg);
        }

        Map> res = access.readResponse(response, JiraRestAccess.MAP_WITH_LINKTYPES_TYPE_REFERENCE);
        return res.get("issueLinkTypes");
    }

    public void linkIssues(IssueLink issueLink) throws IOException, RestException {
        access.executePost("issueLink", issueLink);
    }

    public InputStream loadAttachment(RemoteAttachment attachment) throws IOException, RestException {
        Map info = (Map) access.executeGet("attachment/" + attachment.getId());
        String url = (String) info.get("content");
        HttpGet get = new HttpGet(url);
        HttpResponse response = access.executeMethod(get);
        if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
            throw new IOException("Could not load attachment. Status: " + response.getStatusLine().getStatusCode() + ", " + response.getStatusLine().getReasonPhrase());
        }
        return response.getEntity().getContent();
    }

    public List getAllProjects() throws IOException, RestException {
        final List> projects = (List>) access.executeGet("project");
        List res = new ArrayList();

        for (Map project : projects) {
            res.add(mapRequestToProject(project));
        }
        return res;
    }

    public RemoteProject getProjectByKey(String projectKey) throws IOException, RestException {
        final Map project = (Map) access.executeGet("project/" + projectKey);

        return mapRequestToProject(project);
    }

    public List getProjectsByKey(String... keys) throws IOException, RestException {
        final List projects = getAllProjects();
        for (Iterator i = projects.iterator(); i.hasNext(); ) {
            RemoteProject project = i.next();
            boolean found = false;
            for (String key : keys) {
                if (project.getKey().equals(key)) {
                    found = true;
                    break;
                }
            }
            if (!found) {
                i.remove();
            }
        }
        return projects;
    }

    public Map getIssue(String keyOrId, String fields, String expand) throws IOException, RestException {
        final Map params = stdQueryParams(new HashMap(), fields, expand);
        return (Map) access.executeGet("issue/" + keyOrId, params, Map.class);
    }

    private Map stdQueryParams(Map params, String fields, String expand) {
        if (fields != null) {
            params.put("fields", fields.split("\\s*,\\s*"));
        }
        if (expand != null) {
            params.put("expand", expand.split("\\s*,\\s*"));
        }
        return params;
    }

    public RemoteIssueExt getIssue(String keyOrId) throws IOException, RestException {
        return remoteIssueFromJson(getIssue(keyOrId, null, null));
    }

    public RemoteIssueExt[] getIssuesFromFilter(String filter) throws IOException, RestException {
        return getIssuesByJql("filter='" + filter + "'", 0, 500);
    }

    public List> getAllIssuesByJql(String jql, String fields, String expand) throws IOException, RestException {
        List> res = new ArrayList>();
        int start = 0;
        List> result;
        do {
            result = getIssuesByJql(jql, start, 500, fields, expand);
            res.addAll(result);
            start += result.size();
        } while (!result.isEmpty());
        return res;
    }

    public List> getIssuesByJql(String jql, int startAt, int maxResults, String fields, String expand) throws IOException, RestException {
        final Map req = stdQueryParams(new HashMap(), fields, expand);
        req.put("jql", jql);
        req.put("startAt", startAt);
        req.put("maxResults", Math.min(maxResults, 500));
        final Map res = (Map) access.executePost("search", req);
        final List> issues = (List>) res.get("issues");
        final int read = startAt + issues.size();
        if (read < (Integer) res.get("total") && read < maxResults) {
            issues.addAll(getIssuesByJql(jql, read, maxResults, fields, expand));
        }
        return issues;
    }

    public RemoteIssueExt[] getIssuesByJql(String jql, int startAt, int maxResults) throws IOException, RestException {
        List> issues = getIssuesByJql(jql, startAt, maxResults, null, null);
        RemoteIssueExt[] res = new RemoteIssueExt[issues.size()];
        int index = 0;
        for (Map issue : issues) {
            res[index] = remoteIssueFromJson(issue);
            index++;
        }
        return res;
    }

    public RemoteVersion[] getVersions(String projectKey) throws IOException, RestException {
        final List> versions = (List>) access.executeGet("project/" + projectKey + "/versions");
        return versions(versions);
    }

    private RemoteIssueExt remoteIssueFromJson(Map issue) {
        Map fields = (Map) issue.get("fields");
        return new RemoteIssueExt((String) issue.get("id"),
                versions(access(fields, "versions")),
                access(fields, "assignee", "name"),
                null, components(fields),
                calendar((String) fields.get("created")),
                customFields(fields),
                (String) fields.get("description"),
                calendar((String) fields.get("duedate")),
                (String) fields.get("environment"),
                versions(access(fields, "fixVersions")),
                (String) issue.get("key"),
                access(fields, "priority", "id"),
                access(fields, "project", "key"),
                access(fields, "reporter", "name"),
                access(fields, "resolution", "id"),
                access(fields, "status", "id"),
                (String) fields.get("summary"),
                access(fields, "issuetype", "id"),
                calendar((String) fields.get("updated")),
                longOf(((Map) fields.get("votes")).get("votes")),
                (Integer) fields.get("aggregatetimeoriginalestimate"),
                (Integer) fields.get("timeoriginalestimate"),
                (Integer) fields.get("aggregatetimespent"),
                (Integer) fields.get("timespent"));
    }

    private String access(Map fields, String key, String sub) {
        Map map = (Map) fields.get(key);
        return map == null ? null : map.get(sub);
    }

    private List> access(Map fields, String key) {
        return (List>) fields.get(key);
    }

    private RemoteVersion[] versions(List> versions) {
        List vs = new ArrayList();
        for (Map version : versions) {
            vs.add(new RemoteVersion((String) version.get("id"), (String) version.get("name"), (Boolean) version.get("archived"), calendar((String) version.get("releaseDate")), (Boolean) version.get("released"), null));
        }
        return vs.toArray(new RemoteVersion[vs.size()]);
    }

    private RemoteComponent[] components(Map fields) {
        List components = new ArrayList();
        for (Map comp : (List>) fields.get("components")) {
            components.add(new RemoteComponent(comp.get("id"), comp.get("name")));
        }
        return components.toArray(new RemoteComponent[components.size()]);
    }

    private RemoteCustomFieldValue[] customFields(Map fields) {
        List customFieldValues = new ArrayList();
        for (Map.Entry entry : fields.entrySet()) {
            if (entry.getKey().startsWith("customfield_")) {
                if (entry.getValue() != null) {
                    customFieldValues.add(createCustomField(entry));
                }
            }
        }
        return customFieldValues.toArray(new RemoteCustomFieldValue[customFieldValues.size()]);
    }

    private RemoteCustomFieldValue createCustomField(Map.Entry entry) {
        if (entry.getValue() instanceof Map) {
            Map v = (Map) entry.getValue();
            Object value = v.get("value");
            return new RemoteCustomFieldValue(entry.getKey(), v.get("id"), (value instanceof String[]) ? (String[]) value : new String[]{(String) value});
        }
        return new RemoteCustomFieldValue(entry.getKey(), null, new String[]{entry.getValue().toString()});
    }

    private Calendar calendar(String value) {
        if (value == null) {
            return null;
        }
        try {
            DateFormat format = (value.length() == 10)
                    ? new SimpleDateFormat("yyyy-MM-dd")
                    : new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
            Date date = format.parse(value);
            Calendar cal = Calendar.getInstance();
            cal.setTime(date);
            return cal;
        } catch (ParseException e) {
            return null;
        }
    }

    private Long longOf(Integer value) {
        return value == null ? null : Long.valueOf(value);
    }

    private RemoteProject mapRequestToProject(Map project) {
        return new RemoteProject((String) project.get("id"), (String) project.get("name"), null, null,
                (String) project.get("key"), null, null, null, null, null);
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy