package hudson.plugins.crap4j; import hudson.XmlFile; import hudson.model.AbstractBuild; import hudson.model.ModelObject; import hudson.plugins.crap4j.display.DecreasingCrapLoadComparator; import hudson.plugins.crap4j.model.ICrapMethodPresentation; import hudson.plugins.crap4j.model.IMethodCrap; import hudson.plugins.crap4j.model.ProjectCrapBean; import hudson.util.XStream2; import java.io.File; import java.io.IOException; import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import org.kohsuke.stapler.StaplerRequest; import org.kohsuke.stapler.StaplerResponse; import com.thoughtworks.xstream.XStream; import hudson.model.Hudson; public class CrapBuildResult implements ModelObject, ICrapMethodPresentation { private transient WeakReference<ProjectCrapBean> crap; private AbstractBuild<?, ?> owner; /** Logger. */ private static final Logger LOGGER = Logger.getLogger(CrapBuildResult.class.getName()); /** Serialization provider. */ private static final XStream XSTREAM = new XStream2(); static { XSTREAM.alias("crap", ProjectCrapBean.class); } public CrapBuildResult(AbstractBuild<?, ?> owner, ProjectCrapBean crap) { super(); this.owner = owner; this.crap = new WeakReference<ProjectCrapBean>(crap); try { getDataFile().write(crap); } catch (IOException e) { LOGGER.log(Level.WARNING, "Failed to serialize the crap4j result.", e); } } public void setOwner(AbstractBuild<?, ?> owner) { this.owner = owner; } public AbstractBuild<?, ?> getOwner() { return this.owner; } public ProjectCrapBean getResultData() { if (null == this.crap) { loadCrap(); } ProjectCrapBean result = this.crap.get(); if (null == result) { loadCrap(); } return this.crap.get(); } private void loadCrap() { try { this.crap = new WeakReference<ProjectCrapBean>((ProjectCrapBean) getDataFile().read()); } catch (IOException e) { LOGGER.log(Level.WARNING, "Failed to load " + getDataFile(), e); } } public String getSummary() { return buildSummary(); } public String getDetails() { return buildDetails(); } //@Override public String getDisplayName() { return "Crap Report"; } //@Override public String getTitle() { return "All Crappy Methods for <a href=\"" + Hudson.getInstance().getRootUrlFromRequest() + getOwner().getUrl() + "\">" + getOwner().getDisplayName() + "</a>"; } //@Override public Collection<IMethodCrap> getMethods() { List<IMethodCrap> result = new ArrayList<IMethodCrap>(); Collections.addAll(result, getResultData().getCrapMethods()); Collections.sort(result, new DecreasingCrapLoadComparator()); return result; } private String buildListEntry(String url, int count, String denotation) { StringBuilder result = new StringBuilder(); result.append("<li><a href=\""); result.append(url); result.append("\">"); result.append(count); result.append(" "); result.append(denotation); result.append("</a></li>"); return result.toString(); } public boolean hasNewCrappyMethods() { return (getResultData().getNewCrapMethodsCount() > 0); } public boolean hasFixedCrappyMethods() { return (getResultData().getFixedCrapMethodsCount() > 0); } public boolean hasChangesAtCrappyMethods() { return (hasNewCrappyMethods() || hasFixedCrappyMethods()); } private String buildDetails() { StringBuilder result = new StringBuilder(); if (hasNewCrappyMethods()) { result.append(buildListEntry("crapResult/new", getResultData().getNewCrapMethodsCount(), "new crap methods")); } if (hasFixedCrappyMethods()) { result.append(buildListEntry("crapResult/fixed", getResultData().getFixedCrapMethodsCount(), "fewer crap methods")); } return result.toString(); } private String buildSummary() { StringBuilder result = new StringBuilder(); result.append("Crap4J: "); int crapMethods = getResultData().getCrapMethodCount(); if (0 == crapMethods) { result.append("No crappy methods in this project."); } else { result.append("<a href=\"crapResult\">"); result.append(crapMethods); result.append(" crappy methods ("); result.append(getResultData().getCrapMethodPercent()); result.append("%)</a> out of "); result.append(getResultData().getMethodCount()); result.append(" methods in this project."); } return result.toString(); } public ICrapMethodPresentation getDynamic(final String link, final StaplerRequest request, final StaplerResponse response) { if ("new".equals(link)) { return new NewCrapMethodsResult(getOwner(), getResultData().getNewMethods(getPreviousCrap())); } if ("fixed".equals(link)) { return new FixedCrapMethodsResult(getOwner(), getResultData().getFixedMethods(getPreviousCrap())); } return this; } private XmlFile getDataFile() { return new XmlFile(new File(getOwner().getRootDir(), "crap.xml")); } private ProjectCrapBean getPreviousCrap() { CrapBuildResult previousResult = getPrevious(); if (null == previousResult) { return null; } return previousResult.getResultData(); } public CrapBuildResult getPrevious() { return getPrevious(getOwner()); } public static CrapBuildResult getPrevious(AbstractBuild<?, ?> currentBuild) { AbstractBuild<?,?> previous = currentBuild.getPreviousBuild(); while (null != previous) { Crap4JBuildAction action = previous.getAction(Crap4JBuildAction.class); if (null != action) { return action.getResult(); } previous = previous.getPreviousBuild(); } return null; } }