/**
* Hudson Serenitec plugin
*
* @author Georges Bossert <gbossert@gmail.com>
* @version $Revision: 1.5 $
* @since $Date: 2008/07/24 09:44:13 ${date}
* @copyright Universit� de Rennes 1
*/
package hudson.plugins.serenitec;
import hudson.model.AbstractBuild;
import hudson.model.AbstractProject;
import hudson.model.Action;
import hudson.plugins.serenitec.util.ResultAction;
import java.io.IOException;
import java.util.List;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import org.kohsuke.stapler.Ancestor;
import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.StaplerResponse;
/**
* The class SerenitecProjectAction.
*
* @version $Revision: 1.5 $
* @since $Date: 2008/07/24 09:44:13 ${date}
*/
public class SerenitecProjectAction implements Action
{
/**
* SERIAL UID
*/
private static final long serialVersionUID = -2512038161663973656L;
/** One year (in seconds). */
private static final int ONE_YEAR = 60 * 60 * 24 * 365;
/** Determines the height of the trend graph. */
private final int height;
/**
* The icon URL of this action: it will be shown as soon as a result is available.
*/
private final String iconUrl;
/** Project that owns this action. */
@SuppressWarnings("Se")
private final AbstractProject<?, ?> project;
/** Plug-in results URL. */
private final String resultUrl;
/** Plug-in URL. */
private final String url;
/**
* Instantiates a new find bugs project action.
*
* @param project
* the project that owns this action
* @param height
* the height of the trend graph
*/
public SerenitecProjectAction(final AbstractProject<?, ?> project, final int height) {
this(project, SerenitecPublisher.SERENITEC_DESCRIPTOR, height);
}
/**
* Creates a new instance of <code>SerenitecProjectAction</code>.
*
* @param project
* the project that owns this action
* @param resultActionType
* the type of the result action
* @param plugin
* the plug-in that owns this action
* @param height
* the height of the trend graph
*/
public SerenitecProjectAction(final AbstractProject<?, ?> project, final SerenitecDescriptor plugin, final int height) {
this.project = project;
this.height = height;
iconUrl = plugin.getIconUrl();
url = plugin.getPluginName();
resultUrl = plugin.getPluginResultUrlName();
}
/**
* Creates a trend graph or map.
*
* @param request
* Stapler request
* @param response
* Stapler response
* @throws IOException
* in case of an error in {@link ResultAction#doGraph(StaplerRequest, StaplerResponse, int)}
*/
private void createGraph(final StaplerRequest request, final StaplerResponse response) throws IOException {
final ResultAction<?> action = getLastAction();
if (action == null) {
response.setStatus(HttpServletResponse.SC_NOT_FOUND);
} else {
action.doGraph(request, response, height);
}
}
/**
* Changes the trend graph display mode.
*
* @param request
* Stapler request
* @param response
* Stapler response
* @throws IOException
* in case of an error
*/
public void doFlipTrend(final StaplerRequest request, final StaplerResponse response) throws IOException {
boolean useHealthBuilder = false;
final Cookie[] cookies = request.getCookies();
if (cookies != null) {
for (final Cookie cookie : cookies) {
if (cookie.getName().equals(getCookieName())) {
useHealthBuilder = Boolean.parseBoolean(cookie.getValue());
}
}
}
useHealthBuilder = !useHealthBuilder;
final Cookie cookie = new Cookie(getCookieName(), String.valueOf(useHealthBuilder));
final List<?> ancestors = request.getAncestors();
final Ancestor ancestor = (Ancestor) ancestors.get(ancestors.size() - 2);
cookie.setPath(ancestor.getUrl());
cookie.setMaxAge(ONE_YEAR);
response.addCookie(cookie);
response.sendRedirect("..");
}
/**
* Redirects the index page to the last result.
*
* @param request
* Stapler request
* @param response
* Stapler response
* @throws IOException
* in case of an error
*/
public void doIndex(final StaplerRequest request, final StaplerResponse response) throws IOException {
final AbstractBuild<?, ?> build = getLastFinishedBuild();
if (build != null) {
response.sendRedirect2(String.format("../%d/%s", build.getNumber(), resultUrl));
}
}
/**
* Display the trend graph. Delegates to the the associated {@link ResultAction}.
*
* @param request
* Stapler request
* @param response
* Stapler response
* @throws IOException
* in case of an error in {@link ResultAction#doGraph(StaplerRequest, StaplerResponse, int)}
*/
public void doTrend(final StaplerRequest request, final StaplerResponse response) throws IOException {
createGraph(request, response);
}
/**
* Display the trend map. Delegates to the the associated {@link ResultAction}.
*
* @param request
* Stapler request
* @param response
* Stapler response
* @throws IOException
* in case of an error
*/
public void doTrendMap(final StaplerRequest request, final StaplerResponse response) throws IOException {
final ResultAction<?> action = getLastAction();
if (action == null) {
response.setStatus(HttpServletResponse.SC_NOT_FOUND);
} else {
action.doGraphMap(request, response, height);
}
}
/**
* Return the cookie name
*
* @return cookie Name
*/
public String getCookieName() {
return "Serenitec_plugin";
}
/**
* return the Display name
*
* @return display Name
*/
public String getDisplayName() {
return "Plugin Serenitec";
}
/**
* Returns the icon URL for the side-panel in the project screen. If there is yet no valid result, then <code>null</code> is returned.
*
* @return the icon URL for the side-panel in the project screen
*/
public String getIconFileName() {
String resultat;
if (getLastAction() != null) {
resultat = iconUrl;
} else {
resultat = null;
}
return resultat;
}
/**
* Returns the last valid result action.
*
* @return the last valid result action, or <code>null</code> if no such action is found
*/
public ResultAction<?> getLastAction() {
final AbstractBuild<?, ?> lastBuild = getLastFinishedBuild();
ResultAction<?> resultat = null;
if (lastBuild != null) {
resultat = lastBuild.getAction(SerenitecResultAction.class);
}
return resultat;
}
/**
* Returns the last finished build.
*
* @return the last finished build or <code>null</code> if there is no such build
*/
public AbstractBuild<?, ?> getLastFinishedBuild() {
AbstractBuild<?, ?> lastBuild = project.getLastBuild();
while (lastBuild != null && (lastBuild.isBuilding() || lastBuild.getAction(SerenitecResultAction.class) == null)) {
lastBuild = lastBuild.getPreviousBuild();
}
return lastBuild;
}
/**
* Returns the project.
*
* @return the project
*/
public final AbstractProject<?, ?> getProject() {
return project;
}
/** {@inheritDoc} */
public final String getUrlName() {
return url;
}
/**
* Returns whether we have enough valid results in order to draw a meaningful graph.
*
* @return <code>true</code> if the results are valid in order to draw a graph
*/
public final boolean hasValidResults() {
final AbstractBuild<?, ?> build = getLastFinishedBuild();
Boolean resultat = false;
if (build != null) {
final ResultAction<?> resultAction = build.getAction(SerenitecResultAction.class);
if (resultAction != null) {
resultat = resultAction.hasPreviousResultAction();
}
}
return resultat;
}
/**
* Returns whether we should display the toggle graph type links.
*
* @return <code>true</code> if we should display the toggle graph type links
*/
public final boolean isHealthinessEnabled() {
final ResultAction<?> lastAction = getLastAction();
boolean resultat = false;
if (lastAction != null) {
resultat = lastAction.getHealthReportBuilder().isEnabled();
}
return resultat;
}
}