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

org.marvelution.jira.plugins.jenkins.panels.BuildPanelHelper Maven / Gradle / Ivy

There is a newer version: 2.3.1
Show newest version
/*
 * Copyright (c) 2012-present Marvelution B.V.
 *
 * 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 org.marvelution.jira.plugins.jenkins.panels;

import java.io.IOException;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.Nullable;
import javax.inject.Inject;
import javax.inject.Named;

import org.marvelution.jira.plugins.jenkins.model.Build;
import org.marvelution.jira.plugins.jenkins.model.Job;
import org.marvelution.jira.plugins.jenkins.services.BuildIssueFilter;
import org.marvelution.jira.plugins.jenkins.services.BuildService;
import org.marvelution.jira.plugins.jenkins.services.JenkinsPluginConfiguration;
import org.marvelution.jira.plugins.jenkins.services.JobService;
import org.marvelution.jira.plugins.jenkins.utils.VelocityUtils;

import com.atlassian.jira.issue.Issue;
import com.atlassian.jira.issue.action.IssueActionComparator;
import com.atlassian.jira.project.Project;
import com.atlassian.jira.software.api.conditions.IsSoftwareProjectCondition;
import com.atlassian.jira.software.api.conditions.ProjectDevToolsIntegrationFeatureCondition;
import com.atlassian.jira.user.ApplicationUser;
import com.atlassian.plugin.spring.scanner.annotation.imports.ComponentImport;
import com.atlassian.templaterenderer.TemplateRenderer;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import static com.google.common.collect.Lists.newArrayList;

/**
 * CI Build Panel Helper
 *
 * @author Mark Rekveld
 * @since 1.0.0
 */
@Named
public class BuildPanelHelper {

	private static final Logger LOGGER = LoggerFactory.getLogger(BuildPanelHelper.class);
	private final JenkinsPluginConfiguration pluginConfiguration;
	private final JobService jobService;
	private final BuildService buildService;
	private final VelocityUtils velocityUtils;
	private final TemplateRenderer templateRenderer;
	private final ProjectDevToolsIntegrationFeatureCondition projectDevToolsIntegrationFeatureCondition;
	private final IsSoftwareProjectCondition isSoftwareProjectCondition;

	@Inject
	public BuildPanelHelper(JenkinsPluginConfiguration pluginConfiguration, JobService jobService, BuildService buildService,
	                        VelocityUtils velocityUtils, @ComponentImport TemplateRenderer templateRenderer,
	                        ProjectDevToolsIntegrationFeatureCondition projectDevToolsIntegrationFeatureCondition,
	                        IsSoftwareProjectCondition isSoftwareProjectCondition) {
		this.pluginConfiguration = pluginConfiguration;
		this.jobService = jobService;
		this.buildService = buildService;
		this.velocityUtils = velocityUtils;
		this.templateRenderer = templateRenderer;
		this.projectDevToolsIntegrationFeatureCondition = projectDevToolsIntegrationFeatureCondition;
		this.isSoftwareProjectCondition = isSoftwareProjectCondition;
	}

	/**
	 * Getter for all the {@link Build}s related to the given {@link Issue}
	 *
	 * @param issue the {@link Issue} to get all the builds for
	 * @return the collection of {@link Build}s
	 */
	public Iterable getBuildsByRelation(Issue issue) {
		LOGGER.debug("Looking for builds related to issue [{}]", issue.getKey());
		BuildIssueFilter filter = new BuildIssueFilter();
		filter.getInIssueKeys().add(issue.getKey());
		return buildService.getLatestBuildsByFilter(pluginConfiguration.getMaximumBuildsPerPage(), filter);
	}

	/**
	 * Get {@link BuildAction}s for all the {@link Build}s given
	 *
	 * @param builds the {@link Build}s to get actions for
	 * @param sorted flag to sort the {@link BuildAction}s in reverse order, if false the list is not sorted!
	 * @return the {@link BuildAction}s
	 */
	public List getBuildActions(Iterable builds, boolean sorted) {
		List buildActions = new ArrayList<>();
		for (Build build : builds) {
			try {
				String html = getBuildActionHtml(build);
				if (StringUtils.isNotBlank(html)) {
					buildActions.add(new BuildAction(html, build.getBuildDate()));
				}
			} catch (Exception e) {
				LOGGER.debug("Failed to render HTML for Build [{}], {}", build, e.getMessage());
			}
		}
		if (buildActions.isEmpty()) {
			buildActions.add(BuildAction.NO_BUILDS_ACTION);
		}
		if (sorted) {
			Collections.sort(buildActions, IssueActionComparator.COMPARATOR);
			Collections.reverse(buildActions);
		}
		return buildActions;
	}

	/**
	 * Generate a HTML View for the {@link Build} given
	 *
	 * @param build the {@link Build} to generate the HTML view for
	 * @return the HTML string, may be {@code empty} but not {@code null}
	 * @throws Exception in case of errors rendering the HTML
	 */
	public String getBuildActionHtml(Build build) throws Exception {
		Job job = jobService.get(build.getJobId());
		if (job == null) {
			return "";
		}
		Map context = new HashMap<>();
		context.put("baseUrl", pluginConfiguration.getJIRABaseUrl().toASCIIString());
		context.put("velocityUtils", velocityUtils);
		context.put("build", build);
		context.put("buildUrl", jobService.getJobBuildUrl(job, build));
		context.put("job", job);
		context.put("jobUrl", jobService.getJobUrl(job));
		if (buildService.getRelatedIssueKeyCount(build) <= 5) {
			context.put("issueKeys", newArrayList(buildService.getRelatedIssueKeys(build)));
		} else {
			context.put("projectKeys", newArrayList(buildService.getRelatedProjectKeys(build)));
		}
		StringWriter writer = new StringWriter();
		try {
			templateRenderer.render("/templates/jenkins-build.vm", context, writer);
		} catch (IOException e) {
			LOGGER.warn("Failed to render html for build {} -> {}", build.getId(), e.getMessage());
		}
		return writer.toString();
	}

	/**
	 * Returns whether the panel should be shown for the given project and user
	 */
	public boolean showPanel(Project project, ApplicationUser user) {
		Map browseContext = getBrowseContext(project, user);
		return isSoftwareProjectCondition.shouldDisplay(browseContext) &&
				projectDevToolsIntegrationFeatureCondition.shouldDisplay(browseContext);
	}

	/**
	 * Returns whether the panel should be shown for the given issue and user
	 */
	public boolean showPanel(Issue issue, @Nullable ApplicationUser user) {
		Project project = issue.getProjectObject();
		return !(project == null || user == null) && showPanel(project, user);
	}

	/**
	 * Returns the context {@link Map} used for {@link ProjectDevToolsIntegrationFeatureCondition#shouldDisplay(Map)}
	 */
	private Map getBrowseContext(Project project, ApplicationUser user) {
		Map context = new HashMap<>();
		context.put(ProjectDevToolsIntegrationFeatureCondition.CONTEXT_KEY_PROJECT, project);
		context.put("user", user);
		return context;
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy