/*
This file is part of Delivery Pipeline Plugin.
Delivery Pipeline Plugin is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Delivery Pipeline Plugin is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Delivery Pipeline Plugin.
If not, see <http://www.gnu.org/licenses/>.
*/
package se.diabol.jenkins.pipeline.domain.status.promotion;
import hudson.Extension;
import hudson.model.AbstractBuild;
import hudson.model.BooleanParameterValue;
import hudson.model.FileParameterValue;
import hudson.model.ParameterValue;
import hudson.model.StringParameterValue;
import hudson.plugins.promoted_builds.PromotedBuildAction;
import hudson.plugins.promoted_builds.Promotion;
import hudson.plugins.promoted_builds.Status;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
@Extension(optional = true)
public class PromotionStatusProvider extends AbstractPromotionStatusProvider {
// Force a classloading error plugin isn't available
public static final Class<PromotedBuildAction> CLASS = PromotedBuildAction.class;
static final String DEFAULT_ICON_SIZE = "16x16";
private PromotionStatusWrapper promotionStatusWrapper = new PromotionStatusWrapper();
private PromotedBuildActionWrapper promotedBuildActionWrapper = new PromotedBuildActionWrapper();
// public
public boolean isBuildPromoted(AbstractBuild<?, ?> build) {
final Object action = build.getAction(PromotedBuildAction.class);
if (action != null) {
return (CollectionUtils.isNotEmpty(promotedBuildActionWrapper.getPromotions(action)));
}
return false;
}
public List<PromotionStatus> getPromotionStatusList(AbstractBuild<?, ?> build) {
final List<PromotionStatus> promotionStatusList = new ArrayList<PromotionStatus>();
final Object action = build.getAction(PromotedBuildAction.class);
if (action != null) {
for (Object status : promotedBuildActionWrapper.getPromotions(action)) {
final List<String> params = new ArrayList<String>();
for (Promotion promotion : (Collection<Promotion>) promotionStatusWrapper.getPromotionBuilds(status)) {
populatePromotionParameters(params, promotion);
promotionStatusList.add(buildNewPromotionStatus(build, status, params, promotion));
}
}
sortPromotionStatusListByStartTimeInDescOrder(promotionStatusList);
}
return promotionStatusList;
}
// private
private PromotionStatus buildNewPromotionStatus(AbstractBuild<?, ?> build, Object status,
List<String> params, Object promotionObj) {
final Promotion promotion = (Promotion) promotionObj;
final String name = promotionStatusWrapper.getName(status);
final long startTime = promotion.getStartTimeInMillis();
final long duration = promotion.getTime().getTime() - build.getTimeInMillis();
final String userName = promotion.getUserName();
final String icon = promotionStatusWrapper.getIcon(status, DEFAULT_ICON_SIZE);
return new PromotionStatus(name, startTime, duration, userName, icon, params);
}
private void populatePromotionParameters(List<String> params, Object promotionObj) {
final Promotion promotion = (Promotion) promotionObj;
for (ParameterValue value : promotion.getParameterValues()) {
if (value instanceof StringParameterValue) {
if (StringUtils.isNotBlank(((StringParameterValue) value).value)) {
params.add("<strong>" + value.getName() + "</strong>: " + ((StringParameterValue) value).value);
}
} else if (value instanceof FileParameterValue) {
params.add("<strong>" + value.getName() + "</strong>: " + ((FileParameterValue) value).getLocation());
} else if (value instanceof BooleanParameterValue) {
if (((BooleanParameterValue) value).value) {
params.add("<strong>" + value.getName() + "</strong>: "
+ Boolean.toString(((BooleanParameterValue) value).value));
}
}
// TODO: there are more types
}
}
private void sortPromotionStatusListByStartTimeInDescOrder(List<PromotionStatus> promotionStatusList) {
Collections.sort(promotionStatusList, new Comparator<Object>() {
@Override
public int compare(Object o1, Object o2) {
return (int) (promotionStatusWrapper.getStartTime(o2) - promotionStatusWrapper.getStartTime(o1));
}
});
}
// Decorators to make code unit-testable
static class PromotedBuildActionWrapper {
public List<Status> getPromotions(Object action) {
return ((PromotedBuildAction) action).getPromotions();
}
}
static class PromotionStatusWrapper {
public Collection<Promotion> getPromotionBuilds(Object status) {
return ((hudson.plugins.promoted_builds.Status) status).getPromotionBuilds();
}
public String getName(Object status) {
return ((hudson.plugins.promoted_builds.Status) status).getName();
}
public String getIcon(Object status, String size) {
return ((hudson.plugins.promoted_builds.Status) status).getIcon(size);
}
public long getStartTime(Object status) {
return ((PromotionStatus) status).getStartTime();
}
public long getDuration(Object status) {
return ((PromotionStatus) status).getDuration();
}
}
// package scope setters for unit testing
void setPromotionStatusWrapper(PromotionStatusWrapper promotionStatusWrapper) {
this.promotionStatusWrapper = promotionStatusWrapper;
}
void setPromotedBuildActionWrapper(PromotedBuildActionWrapper promotedBuildActionWrapper) {
this.promotedBuildActionWrapper = promotedBuildActionWrapper;
}
}