Java tutorial
package de.codecentric.jira.jenkins.plugin.servlet; /** * Copyright 2012 codecentric GmbH * * 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. */ import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLException; import javax.net.ssl.KeyManager; import javax.net.ssl.TrustManager; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.httpclient.Credentials; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager; import org.apache.commons.httpclient.UsernamePasswordCredentials; import org.apache.commons.httpclient.auth.AuthScope; import org.apache.commons.httpclient.methods.PostMethod; import org.apache.commons.httpclient.protocol.Protocol; import org.apache.commons.httpclient.protocol.ProtocolSocketFactory; import org.apache.commons.httpclient.protocol.SSLProtocolSocketFactory; import org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory; import org.apache.commons.lang.StringUtils; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.Element; import org.dom4j.io.SAXReader; import com.atlassian.jira.security.JiraAuthenticationContext; import com.atlassian.jira.util.I18nHelper; import com.atlassian.sal.api.ApplicationProperties; import com.atlassian.sal.api.pluginsettings.PluginSettingsFactory; import com.atlassian.templaterenderer.TemplateRenderer; import de.codecentric.jira.jenkins.plugin.conditions.IsPriorToJiraVersion; import de.codecentric.jira.jenkins.plugin.model.BuildResult; import de.codecentric.jira.jenkins.plugin.model.DefaultTrustManager; import de.codecentric.jira.jenkins.plugin.model.JenkinsBuild; import de.codecentric.jira.jenkins.plugin.model.JenkinsServer; import de.codecentric.jira.jenkins.plugin.model.ServerList; import de.codecentric.jira.jenkins.plugin.util.NewUser; import de.codecentric.jira.jenkins.plugin.util.OldUser; import de.codecentric.jira.jenkins.plugin.util.URLEncoder; /** * This class gets information about jobs, views and builds from the Jenkins * Server and displays it. The data is collected over the Jenkins XML API. */ public class RecentBuildsServlet extends HttpServlet { private static final long serialVersionUID = 160578673725081899L; public static final String RSS_ALL = "/rssAll"; public static final String RSS_FAILS = "/rssFailed"; public static final String RSS_LATEST = "/rssLatest"; private static final String TEMPLATE_PATH = "/templates/recentbuilds.vm"; private final TemplateRenderer templateRenderer; private final JiraAuthenticationContext authenticationContext; private final boolean old; private ServerList serverList; private HttpClient client; private Credentials defaultcreds; public RecentBuildsServlet(TemplateRenderer templateRenderer, JiraAuthenticationContext authenticationContext, PluginSettingsFactory settingsFactory, ApplicationProperties applicationProperties) { this.templateRenderer = templateRenderer; this.authenticationContext = authenticationContext; this.client = new HttpClient(new MultiThreadedHttpConnectionManager()); this.serverList = new ServerList(settingsFactory); //test if jiraversion < 4.3 IsPriorToJiraVersion isPrior = new IsPriorToJiraVersion(applicationProperties); isPrior.setmaxMajorVersion(4); isPrior.setmaxMinorVersion(3); this.old = isPrior.shouldDisplay(null); client.getParams().setAuthenticationPreemptive(true); //set SSLContext to accept all certificates try { SSLContext ctx = SSLContext.getInstance("TLS"); ctx.init(new KeyManager[0], new TrustManager[] { new DefaultTrustManager() }, new SecureRandom()); SSLContext.setDefault(ctx); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (KeyManagementException e) { e.printStackTrace(); } SecureProtocolSocketFactory secureProtocolSocketFactory = new SSLProtocolSocketFactory(); Protocol.registerProtocol("https", new Protocol("https", (ProtocolSocketFactory) secureProtocolSocketFactory, 443)); } /** * This function takes post data and calls doGet() */ public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } /** * This function takes get data and renders the template */ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { Map<String, Object> velocityValues = new HashMap<String, Object>(); List<JenkinsBuild> builds = new ArrayList<JenkinsBuild>(); I18nHelper i18nHelper; if (old) { i18nHelper = OldUser.getI18nHelper(authenticationContext); } else { i18nHelper = NewUser.getI18nHelper(authenticationContext); } try { String urlJenkinsServer = req.getParameter("jenkinsUrl"); String view = req.getParameter("view"); String job = req.getParameter("job"); int maxBuilds = Integer.parseInt(req.getParameter("maxBuilds")); String userName = req.getParameter("userName"); String password = req.getParameter("password"); //check if urlJenkinsServer equals Server.name JenkinsServer server = serverList.find(urlJenkinsServer); if (server != null) { urlJenkinsServer = server.getUrl(); } if (urlJenkinsServer.lastIndexOf('/') < urlJenkinsServer.length() - 1) { urlJenkinsServer += "/"; } Document buildRss; //Test if authorization is available if (userName == "" && password == "" && !urlJenkinsServer.startsWith("https")) { buildRss = getBuildRss(urlJenkinsServer, view, job); velocityValues.put("user", "anonymous"); } else if (userName == "") { defaultcreds = new UsernamePasswordCredentials(userName, password); client.getState().setCredentials(new AuthScope(null, -1, AuthScope.ANY_REALM), defaultcreds); buildRss = getBuildRssAuth(urlJenkinsServer, view, job); velocityValues.put("user", "anonymous"); } else { defaultcreds = new UsernamePasswordCredentials(userName, password); client.getState().setCredentials(new AuthScope(null, -1, AuthScope.ANY_REALM), defaultcreds); buildRss = getBuildRssAuth(urlJenkinsServer, view, job); velocityValues.put("user", userName); } builds = readBuilds(buildRss, maxBuilds, i18nHelper); velocityValues.put("serverList", serverList.getServerList()); velocityValues.put("view", view); velocityValues.put("job", job); velocityValues.put("jenkinsUrl", urlJenkinsServer); velocityValues.put("builds", builds); velocityValues.put("context", this.getServletContext()); } catch (MalformedURLException e) { e.printStackTrace(); } catch (DocumentException e) { e.printStackTrace(); } catch (NumberFormatException e) { e.printStackTrace(); } resp.setContentType("text/html;charset=utf-8"); templateRenderer.render(TEMPLATE_PATH, velocityValues, resp.getWriter()); } @SuppressWarnings("unchecked") private List<JenkinsBuild> readBuilds(Document buildRss, int maxBuilds, I18nHelper i18nHelper) { List<JenkinsBuild> builds = new ArrayList<JenkinsBuild>(); //if jenkinsUrl is invalid but authorization was provided if (buildRss == null) { return builds; } SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss z"); List<Element> elements = buildRss.getRootElement().elements("entry"); Iterator<Element> it = elements.iterator(); while (it.hasNext() && builds.size() < maxBuilds) { Element rssElement = it.next(); JenkinsBuild build = new JenkinsBuild(); build.setI18nHelper(i18nHelper); String title = rssElement.elementText("title"); build.setName(title); String url = rssElement.element("link").attributeValue("href"); build.setUrl(url); try { String publishedDate = rssElement.elementText("published"); build.setTimestamp(df.parse(publishedDate.substring(0, publishedDate.length() - 1) + " UTC")); } catch (ParseException e) { e.printStackTrace(); } build.setNumber(url.substring(url.lastIndexOf('/', url.length() - 2) + 1, url.length() - 1)); String buildResult = title.substring(title.lastIndexOf('(') + 1, title.lastIndexOf(')')); if (buildResult.equals("Wieder normal")) { buildResult = "Stabil"; } else if (buildResult.substring(0, 6).equals("Defekt")) { buildResult = "FAILURE"; } build.setResult(BuildResult.valueOf(buildResult)); builds.add(build); } return builds; } /** * Gets BuldRss if authorization is required * @return BuildRss */ private Document getBuildRssAuth(String urlJenkinsServer, String view, String job) throws MalformedURLException, DocumentException { String url; // was there a certain job specified? if (StringUtils.isNotEmpty(job)) { url = (urlJenkinsServer + "job/" + URLEncoder.encodeForURL(job) + RSS_ALL); } else if (StringUtils.isNotEmpty(view)) { url = (urlJenkinsServer + "view/" + URLEncoder.encodeForURL(view) + RSS_ALL); } else { url = (urlJenkinsServer + RSS_ALL); } PostMethod post = new PostMethod(url); Document buildRss = null; post.setDoAuthentication(true); try { client.executeMethod(post); buildRss = new SAXReader().read(post.getResponseBodyAsStream()); } catch (MalformedURLException e) { e.printStackTrace(); } catch (SSLException e) { if (e.getMessage().equals("Unrecognized SSL message, plaintext connection?")) { urlJenkinsServer = urlJenkinsServer.replaceFirst("s", ""); this.getBuildRssAuth(urlJenkinsServer, view, job); } else { e.printStackTrace(); } } catch (IOException e) { e.printStackTrace(); } finally { post.releaseConnection(); } return buildRss; } /** * Gets BuldRss if no authorization is required * @return BuildRss */ private static Document getBuildRss(String urlJenkinsServer, String view, String job) throws MalformedURLException, DocumentException { URL url; // was there a certain job specified? if (StringUtils.isNotEmpty(job)) { url = new URL(urlJenkinsServer + "job/" + URLEncoder.encodeForURL(job) + RSS_ALL); } else if (StringUtils.isNotEmpty(view)) { url = new URL(urlJenkinsServer + "view/" + URLEncoder.encodeForURL(view) + RSS_ALL); } else { url = new URL(urlJenkinsServer + RSS_ALL); } return new SAXReader().read(url); } }