Java tutorial
package org.apache.maven.plugin.jira; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you 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. */ import org.apache.commons.httpclient.Credentials; import org.apache.commons.httpclient.Header; import org.apache.commons.httpclient.HostConfiguration; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.HttpException; import org.apache.commons.httpclient.HttpState; import org.apache.commons.httpclient.HttpStatus; import org.apache.commons.httpclient.StatusLine; import org.apache.commons.httpclient.UsernamePasswordCredentials; import org.apache.commons.httpclient.auth.AuthScope; import org.apache.commons.httpclient.cookie.CookiePolicy; import org.apache.commons.httpclient.methods.GetMethod; import org.apache.commons.httpclient.params.HttpClientParams; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.issues.Issue; import org.apache.maven.settings.Proxy; import org.codehaus.plexus.util.IOUtil; import org.codehaus.plexus.util.StringUtils; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.URLEncoder; import java.util.Collections; import java.util.List; import java.util.Map; /** * Gets relevant issues for a JIRA report via HTTP/RSS. * * @author mfranken@xebia.com * @author jruiz@exist.com * @version $Id$ */ public final class ClassicJiraDownloader extends AbstractJiraDownloader { public ClassicJiraDownloader() { } /** * Execute the query on the JIRA server. * * @throws Exception on error */ public void doExecute() throws Exception { try { HttpClient client = new HttpClient(); // MCHANGES-89 Allow circular redirects HttpClientParams clientParams = client.getParams(); clientParams.setBooleanParameter(HttpClientParams.ALLOW_CIRCULAR_REDIRECTS, true); clientParams.setCookiePolicy(CookiePolicy.BROWSER_COMPATIBILITY); //MCHANGES-237 HttpState state = new HttpState(); HostConfiguration hc = new HostConfiguration(); client.setHostConfiguration(hc); client.setState(state); String baseUrl = JiraHelper.getBaseUrl(project.getIssueManagement().getUrl()); getLog().debug("JIRA lives at: " + baseUrl); // Here we only need the host part of the URL determineProxy(baseUrl, client); prepareBasicAuthentication(client); boolean jiraAuthenticationSuccessful = false; if (isJiraAuthenticationConfigured()) { // Here we only need the parts up to and including the host part of the URL jiraAuthenticationSuccessful = doJiraAuthentication(client, baseUrl); } if ((isJiraAuthenticationConfigured() && jiraAuthenticationSuccessful) || !isJiraAuthenticationConfigured()) { String fullUrl; if (useJql) { fullUrl = getJqlQueryURL(); } else { fullUrl = getParameterBasedQueryURL(client); } if (log.isDebugEnabled()) { log.debug("download jira issues from url " + fullUrl); } // execute the GET download(client, fullUrl); } } catch (Exception e) { if (project.getIssueManagement() != null) { getLog().error("Error accessing " + project.getIssueManagement().getUrl(), e); } else { getLog().error("Error accessing mock project issues", e); } } } private String getJqlQueryURL() { // JQL is based on project names instead of project ID's Map<String, String> urlMap = JiraHelper.getJiraUrlAndProjectName(project.getIssueManagement().getUrl()); String jiraUrl = urlMap.get("url"); String jiraProject = urlMap.get("project"); if (jiraProject == null) { throw new RuntimeException("The issue management URL in the POM does not include a JIRA project name"); } else { // create the URL for getting the proper issues from JIRA String jqlQuery = new JqlQueryBuilder(log).project(jiraProject).fixVersion(getFixFor()) .fixVersionIds(fixVersionIds).statusIds(statusIds).priorityIds(priorityIds) .resolutionIds(resolutionIds).components(component).typeIds(typeIds) .sortColumnNames(sortColumnNames).build(); String url = new UrlBuilder(jiraUrl, "sr/jira.issueviews:searchrequest-xml/temp/SearchRequest.xml") .addParameter("tempMax", nbEntriesMax).addParameter("reset", "true") .addParameter("jqlQuery", jqlQuery).build(); return url; } } private String getParameterBasedQueryURL(HttpClient client) { Map<String, String> urlMap = JiraHelper.getJiraUrlAndProjectId(project.getIssueManagement().getUrl()); String jiraUrl = urlMap.get("url"); String jiraId = urlMap.get("id"); if (jiraId == null || jiraId.length() == 0) { log.debug("The JIRA URL " + project.getIssueManagement().getUrl() + " doesn't include a pid, trying to extract it from JIRA."); jiraId = JiraHelper.getPidFromJira(log, project.getIssueManagement().getUrl(), client); } if (jiraId == null) { throw new RuntimeException("The issue management URL in the POM does not include a pid," + " and it was not possible to extract it from the page at that URL."); } else { // create the URL for getting the proper issues from JIRA String fullURL = jiraUrl + "/secure/IssueNavigator.jspa?view=rss&pid=" + jiraId; if (getFixFor() != null) { fullURL += "&fixfor=" + getFixFor(); } String createdFilter = new ParameterQueryBuilder(log).fixVersionIds(fixVersionIds).statusIds(statusIds) .priorityIds(priorityIds).resolutionIds(resolutionIds).components(component).typeIds(typeIds) .sortColumnNames(sortColumnNames).filter(filter).build(); if (createdFilter.charAt(0) != '&') { fullURL += "&"; } fullURL += createdFilter; fullURL += ("&tempMax=" + nbEntriesMax + "&reset=true&decorator=none"); return fullURL; } } /** * Check and prepare for basic authentication. * * @param client The client to prepare */ private void prepareBasicAuthentication(HttpClient client) { if ((webUser != null) && (webUser.length() > 0)) { client.getParams().setAuthenticationPreemptive(true); Credentials defaultcreds = new UsernamePasswordCredentials(webUser, webPassword); getLog().debug("Using username: " + webUser + " for Basic Authentication."); client.getState().setCredentials(new AuthScope(null, AuthScope.ANY_PORT, null, AuthScope.ANY_SCHEME), defaultcreds); } } /** * Authenticate against JIRA. This method relies on jiraUser and * jiraPassword being set. You can check this by calling * isJiraAuthenticationConfigured(). * * @param client the HttpClient * @param jiraUrl the JIRA installation * @return <code>true</code> if the authentication was successful, otherwise <code>false</code> */ private boolean doJiraAuthentication(HttpClient client, final String jiraUrl) { // log into JIRA if we have to String loginUrl; StringBuilder loginLink = new StringBuilder(jiraUrl); loginLink.append("/login.jsp?os_destination=/secure/"); try { loginLink.append("&os_username=").append(URLEncoder.encode(jiraUser, UTF_8)); String password = null; if (jiraPassword != null) { password = StringUtils.repeat("*", jiraPassword.length()); } getLog().debug("Login URL: " + loginLink + "&os_password=" + password); loginLink.append("&os_password=").append(URLEncoder.encode(jiraPassword, UTF_8)); loginUrl = loginLink.toString(); // execute the login GetMethod loginGet = new GetMethod(loginUrl); client.executeMethod(loginGet); if (loginSucceeded(loginGet)) { getLog().debug("Successfully logged in into JIRA."); return true; } else { getLog().warn("Was unable to login into JIRA: wrong username and/or password."); } } catch (Exception e) { if (getLog().isDebugEnabled()) { getLog().error("Error trying to login into JIRA.", e); } else { getLog().error("Error trying to login into JIRA. Cause is: " + e.getLocalizedMessage()); } } return false; } /** * Evaluate if the login attempt to JIRA was successful or not. We can't * use the status code because JIRA returns 200 even if the login fails. * * @param loginGet The method that was executed * @return <code>false</code> if we find an error message in the response body, otherwise <code>true</code> * @todo There must be a nicer way to know whether we were able to login or not */ private boolean loginSucceeded(GetMethod loginGet) throws IOException { final String loginFailureResponse = "your username and password are incorrect"; return !loginGet.getResponseBodyAsString().contains(loginFailureResponse); } /** * Setup proxy access if we have to. * * @param client the HttpClient */ private void determineProxy(String jiraUrl, HttpClient client) { // see whether there is any proxy defined in maven getProxyInfo(jiraUrl); if (proxyHost != null) { client.getHostConfiguration().setProxy(proxyHost, proxyPort); getLog().debug("Using proxy: " + proxyHost + " at port " + proxyPort); if (proxyUser != null) { getLog().debug("Using proxy user: " + proxyUser); client.getState().setProxyCredentials( new AuthScope(null, AuthScope.ANY_PORT, null, AuthScope.ANY_SCHEME), new UsernamePasswordCredentials(proxyUser, proxyPass)); } } } /** * Downloads the given link using the configured HttpClient, possibly following redirects. * * @param cl the HttpClient * @param link the URL to JIRA */ private void download(final HttpClient cl, final String link) { try { GetMethod gm = new GetMethod(link); getLog().info("Downloading from JIRA at: " + link); gm.setFollowRedirects(true); cl.executeMethod(gm); StatusLine sl = gm.getStatusLine(); if (sl == null) { getLog().error("Unknown error validating link: " + link); return; } // if we get a redirect, do so if (gm.getStatusCode() == HttpStatus.SC_MOVED_TEMPORARILY) { Header locationHeader = gm.getResponseHeader("Location"); if (locationHeader == null) { getLog().warn("Site sent redirect, but did not set Location header"); } else { String newLink = locationHeader.getValue(); getLog().debug("Following redirect to " + newLink); download(cl, newLink); } } if (gm.getStatusCode() == HttpStatus.SC_OK) { final InputStream responseBodyStream = gm.getResponseBodyAsStream(); if (!output.getParentFile().exists()) { output.getParentFile().mkdirs(); } // write the response to file OutputStream out = null; try { out = new FileOutputStream(output); IOUtil.copy(responseBodyStream, out); } finally { IOUtil.close(out); IOUtil.close(responseBodyStream); } getLog().debug("Downloading from JIRA was successful"); } else { getLog().warn("Downloading from JIRA failed. Received: [" + gm.getStatusCode() + "]"); } } catch (HttpException e) { if (getLog().isDebugEnabled()) { getLog().error("Error downloading issues from JIRA:", e); } else { getLog().error("Error downloading issues from JIRA url: " + e.getLocalizedMessage()); } } catch (IOException e) { if (getLog().isDebugEnabled()) { getLog().error("Error downloading issues from JIRA:", e); } else { getLog().error("Error downloading issues from JIRA. Cause is " + e.getLocalizedMessage()); } } } public List<Issue> getIssueList() throws MojoExecutionException { if (output.isFile()) { JiraXML jira = new JiraXML(log, jiraDatePattern); jira.parseXML(output); getLog().info("The JIRA version is '" + jira.getJiraVersion() + "'"); return jira.getIssueList(); } else { getLog().warn("JIRA file " + output.getPath() + " doesn't exist."); return Collections.emptyList(); } } }