com.sfs.dao.bugreport.JiraBugReportHandler.java Source code

Java tutorial

Introduction

Here is the source code for com.sfs.dao.bugreport.JiraBugReportHandler.java

Source

/*******************************************************************************
 * Copyright (c) 2009 David Harrison.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Public License v3.0
 * which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/gpl-3.0.html
 *
 * Contributors:
 *     David Harrison - initial API and implementation
 ******************************************************************************/
package com.sfs.dao.bugreport;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.Hashtable;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.Vector;

import javax.annotation.Resource;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.apache.xmlrpc.XmlRpcException;
import org.apache.xmlrpc.client.XmlRpcClient;
import org.apache.xmlrpc.client.XmlRpcClientConfigImpl;
import org.apache.xmlrpc.client.XmlRpcSun15HttpTransportFactory;

import com.sfs.beans.BugReportBean;
import com.sfs.beans.ObjectTypeBean;
import com.sfs.dao.ObjectTypeDAO;
import com.sfs.dao.SFSDaoException;

/**
 * The Class JiraBugReportHandler.
 *
 * @author David Harrison
 */
public class JiraBugReportHandler implements BugReportHandler {

    /** The Constant XMLRPC_ENDPOINT. */
    private static final String XMLRPC_ENDPOINT = "rpc/xmlrpc";

    /** The Constant ISSUE_VIEW. */
    private static final String ISSUE_VIEW = "jira/browse/";

    /** The logger. */
    private static Logger logger = Logger.getLogger(JiraBugReportHandler.class);

    /** The debug mode. */
    private boolean debugMode = false;

    /** The jira base url. */
    private String jiraBaseUrl;

    /** The jira username. */
    private String jiraUsername;

    /** The jira password. */
    private String jiraPassword;

    /** The jira assignee. */
    private String jiraAssignee;

    /** The object type dao. */
    @Resource
    private ObjectTypeDAO objectTypeDAO;

    /**
     * Sets the debug mode.
     *
     * @param debugModeVal the new debug mode
     */
    public final void setDebugMode(final boolean debugModeVal) {
        this.debugMode = debugModeVal;
    }

    /**
     * Sets the jira base url.
     *
     * @param jiraBaseUrlVal the new jira base url
     */
    public final void setJiraBaseUrl(final String jiraBaseUrlVal) {
        this.jiraBaseUrl = jiraBaseUrlVal;
    }

    /**
     * Sets the jira username.
     *
     * @param jiraUsernameVal the new jira username
     */
    public final void setJiraUsername(final String jiraUsernameVal) {
        this.jiraUsername = jiraUsernameVal;
    }

    /**
     * Sets the jira password.
     *
     * @param jiraPasswordVal the new jira password
     */
    public final void setJiraPassword(final String jiraPasswordVal) {
        this.jiraPassword = jiraPasswordVal;
    }

    /**
     * Sets the jira assignee.
     *
     * @param jiraAssigneeVal the new jira assignee
     */
    public final void setJiraAssignee(final String jiraAssigneeVal) {
        this.jiraAssignee = jiraAssigneeVal;
    }

    /**
     * Submit the bug report.
     *
     * @param bugReport the bug report to submit
     *
     * @throws SFSDaoException the sfs dao exception
     */
    public final void submitReport(final BugReportBean bugReport) throws SFSDaoException {
        if (bugReport == null) {
            throw new SFSDaoException("BugReportBean cannot be null");
        }
        if (jiraBaseUrl == null) {
            throw new SFSDaoException("The Jira base url cannot be null");
        }
        if (jiraUsername == null) {
            throw new SFSDaoException("The Jira username cannot be null");
        }
        if (jiraPassword == null) {
            throw new SFSDaoException("The Jira password cannot be null");
        }
        if (bugReport.getUser() == null) {
            throw new SFSDaoException("Submission of a bug report requires a valid user object");
        }
        if (bugReport.getReportClass() == null) {
            throw new SFSDaoException("The bug report class cannot be null");
        }

        final String jiraReportUrl = buildUrl(XMLRPC_ENDPOINT);

        Hashtable<String, String> issue = new Hashtable<String, String>();

        /** Set the bug report type url parameters **/
        String bugTypeParameters = "";
        try {
            ObjectTypeBean objectType = this.objectTypeDAO.load("Bug Report Type", bugReport.getReportType(),
                    bugReport.getReportClass());
            bugTypeParameters = StringUtils.replace(objectType.getAbbreviation(), "&amp;", "&");
        } catch (SFSDaoException sde) {
            throw new SFSDaoException("Error submitting Jira report: " + sde.getMessage());
        }
        // Convert this string of bug report parameters to the array
        if (StringUtils.isNotBlank(bugTypeParameters)) {
            StringTokenizer st = new StringTokenizer(bugTypeParameters, "&");

            while (st.hasMoreElements()) {
                final String option = st.nextToken();
                final String parameter = option.substring(0, option.indexOf("="));
                final String value = option.substring(option.indexOf("=") + 1, option.length());

                logger.debug("Parameter: " + parameter + ", value: " + value);
                issue.put(parameter, value);
            }
        }

        /** Set the bug priority url parameters **/
        String priority = "";
        try {
            ObjectTypeBean objectType = this.objectTypeDAO.load("Bug Report Priority", "", bugReport.getPriority());
            priority = StringUtils.replace(objectType.getAbbreviation(), "&amp;", "&");
        } catch (SFSDaoException sde) {
            throw new SFSDaoException("Error submitting Jira report: " + sde.getMessage());
        }
        issue.put("priority", priority);

        /** Set the summary **/
        if (StringUtils.isBlank(bugReport.getTitle())) {
            bugReport.setTitle("Untitled issue");
        }
        issue.put("summary", bugReport.getTitle());

        /** Set the description **/
        issue.put("description", bugReport.getDescription());

        /** The username of the reporter **/
        issue.put("reporter", bugReport.getUser().getUserName().toLowerCase());

        /** Set the assignee - if none default set to automatic **/
        if (StringUtils.isNotBlank(this.jiraAssignee)) {
            issue.put("assignee", this.jiraAssignee);
        } else {
            // Set to automatic (-1 in Jira)
            issue.put("assignee", "-1");
        }

        if (!debugMode) {
            /** Post the bug report to Jira **/
            try {
                logger.info("Jira Report - submitting");
                logger.info("Jira URL: " + jiraReportUrl.toString());
                logger.info("Jira Parameters: " + issue.toString());

                final String response = this.performRestRequest(jiraReportUrl.toString(), issue);

                logger.info("Jira response: " + response);

            } catch (XmlRpcException xre) {
                throw new SFSDaoException("Error submitting Jira report via XMLRPC: " + xre.getMessage());
            } catch (MalformedURLException mue) {
                throw new SFSDaoException("Error with the Jira XMLRPC URL: " + mue.getMessage());
            }
        } else {
            logger.debug("Jira Report - debug mode");
            logger.debug("Jira URL: " + jiraReportUrl.toString());
            logger.debug("Jira Parameters: " + issue.toString());
        }
    }

    /**
     * Perform rest request.
     *
     * @param restUrl the rest url
     * @param issue the issue
     *
     * @return the string
     *
     * @throws XmlRpcException the xml rpc exception
     * @throws MalformedURLException the malformed url exception
     */
    private String performRestRequest(final String restUrl, final Hashtable<String, String> issue)
            throws XmlRpcException, MalformedURLException {

        final XmlRpcClientConfigImpl config = new XmlRpcClientConfigImpl();
        config.setServerURL(new URL(restUrl));
        final XmlRpcClient rpcClient = new XmlRpcClient();
        rpcClient.setConfig(config);

        final XmlRpcSun15HttpTransportFactory transport = new XmlRpcSun15HttpTransportFactory(rpcClient);

        /* set proxy or ssl factory */
        String proxyHost = System.getProperty("http.proxyHost);");
        String proxyPortString = System.getProperty("http.proxyPort");
        int proxyPort = -1;

        if (restUrl.startsWith("https")) {
            proxyHost = System.getProperty("https.proxyHost");
            proxyPortString = System.getProperty("https.proxyPort");
        }

        try {
            proxyPort = Integer.parseInt(proxyPortString);
        } catch (NumberFormatException nfe) {
            logger.debug("No proxy port defined", nfe);
            proxyPort = -1;
        }

        if (StringUtils.isNotBlank(proxyHost) && proxyPort > 0) {
            transport.setProxy(proxyHost, proxyPort);
        }

        // Login and retrieve logon token
        Vector<String> loginParams = new Vector<String>(2);
        loginParams.add(this.jiraUsername);
        loginParams.add(this.jiraPassword);
        String loginToken = (String) rpcClient.execute("jira1.login", loginParams);

        // Submit the new project
        Vector<Object> parameters = new Vector<Object>(2);
        parameters.add(loginToken);
        parameters.add(issue);
        Map<?, ?> response = (Map<?, ?>) rpcClient.execute("jira1.createIssue", parameters);

        final String key = (String) response.get("key");
        final String issueUrl = buildUrl(ISSUE_VIEW + key);

        final String message = "Issue created: " + issueUrl;

        logger.error(message);

        return message;
    }

    /**
     * Builds the url.
     *
     * @param request the request
     *
     * @return the string
     */
    private String buildUrl(final String request) {

        final StringBuffer url = new StringBuffer();

        if (StringUtils.isNotBlank(this.jiraBaseUrl)) {

            url.append(this.jiraBaseUrl);

            if (!this.jiraBaseUrl.endsWith("/")) {
                // The base url does not end with / add it
                url.append("/");
            }
        } else {
            url.append("/");
        }
        url.append(request);

        return url.toString();
    }
}