| author | Henrik Lynggaard Hansen | 2012-07-15 14:21:22 (EDT) |
|---|---|---|
| committer | Henrik Lynggaard Hansen | 2012-07-15 14:21:22 (EDT) |
| commit | 97587dde35e862fabbd8b5b4b0136a786cfcff37 (patch) (side-by-side diff) | |
| tree | caa64b957124674049e89a5b5774473d377d616e | |
| parent | 2e3f55d880a7c54c95afb2f243678f960c79c6bf (diff) | |
| download | org.eclipse.hudson.core-97587dde35e862fabbd8b5b4b0136a786cfcff37.zip org.eclipse.hudson.core-97587dde35e862fabbd8b5b4b0136a786cfcff37.tar.gz org.eclipse.hudson.core-97587dde35e862fabbd8b5b4b0136a786cfcff37.tar.bz2 | |
Reformat hudson.tasks and sub packages.refs/changes/89/6789/1
Change-Id: I663b6d75c8951f5ca37bd446d21e4d8ae73f3fe0
Signed-off-by: Henrik Lynggaard Hansen <henrik@hlyh.dk>
68 files changed, 2619 insertions, 2424 deletions
diff --git a/hudson-core/src/main/java/hudson/tasks/Ant.java b/hudson-core/src/main/java/hudson/tasks/Ant.java index 636e00b..f729178 100644 --- a/hudson-core/src/main/java/hudson/tasks/Ant.java +++ b/hudson-core/src/main/java/hudson/tasks/Ant.java @@ -7,10 +7,10 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: + * Contributors: * * Kohsuke Kawaguchi, Tom Huybrechts, Yahoo! Inc., Nikita Levyankov - * + * * *******************************************************************************/ @@ -65,35 +65,33 @@ import java.util.Set; * @author Kohsuke Kawaguchi */ public class Ant extends Builder { + /** - * The targets, properties, and other Ant options. - * Either separated by whitespace or newline. + * The targets, properties, and other Ant options. Either separated by + * whitespace or newline. */ private final String targets; - /** * Identifies {@link AntInstallation} to be used. */ private final String antName; - /** * ANT_OPTS if not null. */ private final String antOpts; - /** - * Optional build script path relative to the workspace. - * Used for the Ant '-f' option. + * Optional build script path relative to the workspace. Used for the Ant + * '-f' option. */ private final String buildFile; - /** - * Optional properties to be passed to Ant. Follows {@link Properties} syntax. + * Optional properties to be passed to Ant. Follows {@link Properties} + * syntax. */ private final String properties; - + @DataBoundConstructor - public Ant(String targets,String antName, String antOpts, String buildFile, String properties) { + public Ant(String targets, String antName, String antOpts, String buildFile, String properties) { this.targets = targets; this.antName = antName; this.antOpts = StringUtils.trimToNull(antOpts); @@ -101,26 +99,26 @@ public class Ant extends Builder { this.properties = StringUtils.trimToNull(properties); } - public String getBuildFile() { - return buildFile; - } + public String getBuildFile() { + return buildFile; + } - public String getProperties() { - return properties; - } + public String getProperties() { + return properties; + } public String getTargets() { return targets; } /** - * Gets the Ant to invoke, - * or null to invoke the default one. + * Gets the Ant to invoke, or null to invoke the default one. */ public AntInstallation getAnt() { - for( AntInstallation i : getDescriptor().getInstallations() ) { - if(antName!=null && antName.equals(i.getName())) + for (AntInstallation i : getDescriptor().getInstallations()) { + if (antName != null && antName.equals(i.getName())) { return i; + } } return null; } @@ -133,19 +131,19 @@ public class Ant extends Builder { } @Override - public boolean perform(AbstractBuild<?,?> build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException { + public boolean perform(AbstractBuild<?, ?> build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException { ArgumentListBuilder args = new ArgumentListBuilder(); EnvVars env = build.getEnvironment(listener); - + AntInstallation ai = getAnt(); - if(ai==null) { + if (ai == null) { args.add(launcher.isUnix() ? "ant" : "ant.bat"); } else { ai = ai.forNode(Computer.currentComputer().getNode(), listener); ai = ai.forEnvironment(env); String exe = ai.getExecutable(launcher); - if (exe==null) { + if (exe == null) { listener.fatalError(Messages.Ant_ExecutableNotFound(ai.getName())); return false; } @@ -156,10 +154,10 @@ public class Ant extends Builder { String buildFile = env.expand(this.buildFile); String targets = Util.replaceMacro(env.expand(this.targets), vr); - + FilePath buildFilePath = buildFilePath(build.getModuleRoot(), buildFile, targets); - if(!buildFilePath.exists()) { + if (!buildFilePath.exists()) { // because of the poor choice of getModuleRoot() with CVS/Subversion, people often get confused // with where the build file path is relative to. Now it's too late to change this behavior // due to compatibility issue, but at least we can make this less painful by looking for errors @@ -167,34 +165,36 @@ public class Ant extends Builder { // first check if this appears to be a valid relative path from workspace root FilePath buildFilePath2 = buildFilePath(build.getWorkspace(), buildFile, targets); - if(buildFilePath2.exists()) { + if (buildFilePath2.exists()) { // This must be what the user meant. Let it continue. buildFilePath = buildFilePath2; } else { // neither file exists. So this now really does look like an error. - listener.fatalError("Unable to find build script at "+buildFilePath); + listener.fatalError("Unable to find build script at " + buildFilePath); return false; } } - if(buildFile!=null) { + if (buildFile != null) { args.add("-file", buildFilePath.getName()); } Set<String> sensitiveVars = build.getSensitiveBuildVariables(); - args.addKeyValuePairs("-D",build.getBuildVariables(),sensitiveVars); + args.addKeyValuePairs("-D", build.getBuildVariables(), sensitiveVars); - args.addKeyValuePairsFromPropertyString("-D",properties,vr,sensitiveVars); + args.addKeyValuePairsFromPropertyString("-D", properties, vr, sensitiveVars); - args.addTokenized(targets.replaceAll("[\t\r\n]+"," ")); + args.addTokenized(targets.replaceAll("[\t\r\n]+", " ")); - if(ai!=null) - env.put("ANT_HOME",ai.getHome()); - if(antOpts!=null) - env.put("ANT_OPTS",env.expand(antOpts)); + if (ai != null) { + env.put("ANT_HOME", ai.getHome()); + } + if (antOpts != null) { + env.put("ANT_OPTS", env.expand(antOpts)); + } - if(!launcher.isUnix()) { + if (!launcher.isUnix()) { args = args.toWindowsCommand(); // For some reason, ant on windows rejects empty parameters but unix does not. // Add quotes for any empty parameter values: @@ -206,51 +206,56 @@ public class Ant extends Builder { long startTime = System.currentTimeMillis(); try { - AntConsoleAnnotator aca = new AntConsoleAnnotator(listener.getLogger(),build.getCharset()); + AntConsoleAnnotator aca = new AntConsoleAnnotator(listener.getLogger(), build.getCharset()); int r; try { r = launcher.launch().cmds(args).envs(env).stdout(aca).pwd(buildFilePath.getParent()).join(); } finally { aca.forceEol(); } - return r==0; + return r == 0; } catch (IOException e) { - Util.displayIOException(e,listener); + Util.displayIOException(e, listener); String errorMessage = Messages.Ant_ExecFailed(); - if(ai==null && (System.currentTimeMillis()-startTime)<1000) { - if(getDescriptor().getInstallations()==null) - // looks like the user didn't configure any Ant installation + if (ai == null && (System.currentTimeMillis() - startTime) < 1000) { + if (getDescriptor().getInstallations() == null) // looks like the user didn't configure any Ant installation + { errorMessage += Messages.Ant_GlobalConfigNeeded(); - else - // There are Ant installations configured but the project didn't pick it + } else // There are Ant installations configured but the project didn't pick it + { errorMessage += Messages.Ant_ProjectConfigNeeded(); + } } - e.printStackTrace( listener.fatalError(errorMessage) ); + e.printStackTrace(listener.fatalError(errorMessage)); return false; } } private static FilePath buildFilePath(FilePath base, String buildFile, String targets) { - if(buildFile!=null) return base.child(buildFile); + if (buildFile != null) { + return base.child(buildFile); + } // some users specify the -f option in the targets field, so take that into account as well. // see String[] tokens = Util.tokenize(targets); - for (int i = 0; i<tokens.length-1; i++) { + for (int i = 0; i < tokens.length - 1; i++) { String a = tokens[i]; - if(a.equals("-f") || a.equals("-file") || a.equals("-buildfile")) - return base.child(tokens[i+1]); + if (a.equals("-f") || a.equals("-file") || a.equals("-buildfile")) { + return base.child(tokens[i + 1]); + } } return base.child("build.xml"); } @Override public DescriptorImpl getDescriptor() { - return (DescriptorImpl)super.getDescriptor(); + return (DescriptorImpl) super.getDescriptor(); } @Extension public static class DescriptorImpl extends BuildStepDescriptor<Builder> { + @CopyOnWrite private volatile AntInstallation[] installations = new AntInstallation[0]; @@ -288,7 +293,7 @@ public class Ant extends Builder { @Override public Ant newInstance(StaplerRequest req, JSONObject formData) throws FormException { - return (Ant)req.bindJSON(clazz,formData); + return (Ant) req.bindJSON(clazz, formData); } public void setInstallations(AntInstallation... antInstallations) { @@ -303,6 +308,7 @@ public class Ant extends Builder { public static final class AntInstallation extends ToolInstallation implements EnvironmentSpecific<AntInstallation>, NodeSpecific<AntInstallation> { // to remain backward compatible with earlier Hudson that stored this field here. + @Deprecated private transient String antHome; @@ -312,18 +318,18 @@ public class Ant extends Builder { } /** - * @deprecated as of 1.308 - * Use {@link #AntInstallation(String, String, List)} + * @deprecated as of 1.308 Use + * {@link #AntInstallation(String, String, List)} */ public AntInstallation(String name, String home) { - this(name,home,Collections.<ToolProperty<?>>emptyList()); + this(name, home, Collections.<ToolProperty<?>>emptyList()); } private static String launderHome(String home) { - if(home.endsWith("/") || home.endsWith("\\")) { + if (home.endsWith("/") || home.endsWith("\\")) { // see https://issues.apache.org/bugzilla/show_bug.cgi?id=26947 // Ant doesn't like the trailing slash, especially on Windows - return home.substring(0,home.length()-1); + return home.substring(0, home.length() - 1); } else { return home; } @@ -342,11 +348,12 @@ public class Ant extends Builder { * Gets the executable path of this Ant on the given target system. */ public String getExecutable(Launcher launcher) throws IOException, InterruptedException { - return launcher.getChannel().call(new Callable<String,IOException>() { + return launcher.getChannel().call(new Callable<String, IOException>() { public String call() throws IOException { File exe = getExeFile(); - if(exe.exists()) + if (exe.exists()) { return exe.getPath(); + } return null; } }); @@ -356,16 +363,15 @@ public class Ant extends Builder { String execName = Functions.isWindows() ? "ant.bat" : "ant"; String home = Util.replaceMacro(getHome(), EnvVars.masterEnvVars); - return new File(home,"bin/"+execName); + return new File(home, "bin/" + execName); } /** * Returns true if the executable exists. */ public boolean getExists() throws IOException, InterruptedException { - return getExecutable(new Launcher.LocalLauncher(TaskListener.NULL))!=null; + return getExecutable(new Launcher.LocalLauncher(TaskListener.NULL)) != null; } - private static final long serialVersionUID = 1L; public AntInstallation forEnvironment(EnvVars environment) { @@ -405,18 +411,22 @@ public class Ant extends Builder { */ public FormValidation doCheckHome(@QueryParameter File value) { // this can be used to check the existence of a file on the server, so needs to be protected - if(!Hudson.getInstance().hasPermission(Hudson.ADMINISTER)) + if (!Hudson.getInstance().hasPermission(Hudson.ADMINISTER)) { return FormValidation.ok(); + } - if(value.getPath().equals("")) + if (value.getPath().equals("")) { return FormValidation.ok(); + } - if(!value.isDirectory()) + if (!value.isDirectory()) { return FormValidation.error(Messages.Ant_NotADirectory(value)); + } - File antJar = new File(value,"lib/ant.jar"); - if(!antJar.exists()) + File antJar = new File(value, "lib/ant.jar"); + if (!antJar.exists()) { return FormValidation.error(Messages.Ant_NotAntDirectory(value)); + } return FormValidation.ok(); } @@ -427,9 +437,14 @@ public class Ant extends Builder { } public static class ConverterImpl extends ToolConverter { - public ConverterImpl(XStream2 xstream) { super(xstream); } - @Override protected String oldHomeField(ToolInstallation obj) { - return ((AntInstallation)obj).antHome; + + public ConverterImpl(XStream2 xstream) { + super(xstream); + } + + @Override + protected String oldHomeField(ToolInstallation obj) { + return ((AntInstallation) obj).antHome; } } } @@ -438,6 +453,7 @@ public class Ant extends Builder { * Automatic Ant installer from apache.org. */ public static class AntInstaller extends DownloadFromUrlInstaller { + @DataBoundConstructor public AntInstaller(String id) { super(id); @@ -445,13 +461,14 @@ public class Ant extends Builder { @Extension public static final class DescriptorImpl extends DownloadFromUrlInstaller.DescriptorImpl<AntInstaller> { + public String getDisplayName() { return Messages.InstallFromApache(); } @Override public boolean isApplicable(Class<? extends ToolInstallation> toolType) { - return toolType==AntInstallation.class; + return toolType == AntInstallation.class; } } } @@ -466,22 +483,22 @@ public class Ant extends Builder { } Ant that = (Ant) o; return new EqualsBuilder() - .append(antName, that.antName) - .append(antOpts, that.antOpts) - .append(buildFile, that.buildFile) - .append(properties, that.properties) - .append(targets, that.targets) - .isEquals(); + .append(antName, that.antName) + .append(antOpts, that.antOpts) + .append(buildFile, that.buildFile) + .append(properties, that.properties) + .append(targets, that.targets) + .isEquals(); } @Override public int hashCode() { return new HashCodeBuilder() - .append(targets) - .append(antName) - .append(antOpts) - .append(buildFile) - .append(properties) - .toHashCode(); + .append(targets) + .append(antName) + .append(antOpts) + .append(buildFile) + .append(properties) + .toHashCode(); } } diff --git a/hudson-core/src/main/java/hudson/tasks/ArtifactArchiver.java b/hudson-core/src/main/java/hudson/tasks/ArtifactArchiver.java index 6037634..37b6da2 100644 --- a/hudson-core/src/main/java/hudson/tasks/ArtifactArchiver.java +++ b/hudson-core/src/main/java/hudson/tasks/ArtifactArchiver.java @@ -7,10 +7,10 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: + * Contributors: * * Inc., Kohsuke Kawaguchi, Brian Westrich, Jean-Baptiste Quenot, Anton Kozak - * + * * *******************************************************************************/ @@ -42,29 +42,26 @@ import org.kohsuke.stapler.StaplerRequest; public class ArtifactArchiver extends Recorder { /** - * Comma- or space-separated list of patterns of files/directories to be archived. + * Comma- or space-separated list of patterns of files/directories to be + * archived. */ private final String artifacts; - /** * Possibly null 'excludes' pattern as in Ant. */ private final String excludes; - /** - * Type of compression with will be applied to artifacts before master<->slave transfer. + * Type of compression with will be applied to artifacts before + * master<->slave transfer. */ private FilePath.TarCompression compressionType; - /** * Just keep the last successful artifact set, no more. */ private final boolean latestOnly; - private final boolean autoValidateFileMask; - - private static final Boolean allowEmptyArchive = - Boolean.getBoolean(ArtifactArchiver.class.getName()+".warnOnEmpty"); + private static final Boolean allowEmptyArchive = + Boolean.getBoolean(ArtifactArchiver.class.getName() + ".warnOnEmpty"); /** * @deprecated as of 2.0.1 @@ -73,6 +70,7 @@ public class ArtifactArchiver extends Recorder { public ArtifactArchiver(String artifacts, String excludes, boolean latestOnly) { this(artifacts, excludes, latestOnly, FilePath.TarCompression.GZIP.name()); } + /** * @deprecated as of 2.0.2 */ @@ -83,7 +81,7 @@ public class ArtifactArchiver extends Recorder { @DataBoundConstructor public ArtifactArchiver(String artifacts, String excludes, boolean latestOnly, String compressionType, - boolean autoValidateFileMask) { + boolean autoValidateFileMask) { this.artifacts = Util.fixEmptyAndTrim(artifacts); this.excludes = Util.fixEmptyAndTrim(excludes); this.latestOnly = latestOnly; @@ -132,8 +130,8 @@ public class ArtifactArchiver extends Recorder { */ public void setCompressionType(String compression) { try { - compressionType = (compression != null ? FilePath.TarCompression.valueOf( compression) : - FilePath.TarCompression.GZIP); + compressionType = (compression != null ? FilePath.TarCompression.valueOf(compression) + : FilePath.TarCompression.GZIP); } catch (IllegalArgumentException e) { compressionType = FilePath.TarCompression.GZIP; } @@ -149,7 +147,7 @@ public class ArtifactArchiver extends Recorder { @Override public boolean perform(AbstractBuild<?, ?> build, Launcher launcher, BuildListener listener) - throws InterruptedException { + throws InterruptedException { if (artifacts.length() == 0) { listener.error(Messages.ArtifactArchiver_NoIncludes()); build.setResult(Result.FAILURE); @@ -199,16 +197,16 @@ public class ArtifactArchiver extends Recorder { @Override public boolean prebuild(AbstractBuild<?, ?> build, BuildListener listener) { - if(latestOnly) { - AbstractBuild<?,?> b = build.getProject().getLastCompletedBuild(); + if (latestOnly) { + AbstractBuild<?, ?> b = build.getProject().getLastCompletedBuild(); Result bestResultSoFar = Result.NOT_BUILT; - while(b!=null) { + while (b != null) { if (b.getResult().isBetterThan(bestResultSoFar)) { bestResultSoFar = b.getResult(); } else { // remove old artifacts File ad = b.getArtifactsDir(); - if(ad.exists()) { + if (ad.exists()) { listener.getLogger().println(Messages.ArtifactArchiver_DeletingOld(b.getDisplayName())); try { Util.deleteRecursive(ad); @@ -226,16 +224,16 @@ public class ArtifactArchiver extends Recorder { public BuildStepMonitor getRequiredMonitorService() { return BuildStepMonitor.NONE; } - /** - * @deprecated as of 1.286 - * Some plugin depends on this, so this field is left here and points to the last created instance. - * Use {@link Hudson#getDescriptorByType(Class)} instead. + * @deprecated as of 1.286 Some plugin depends on this, so this field is + * left here and points to the last created instance. Use + * {@link Hudson#getDescriptorByType(Class)} instead. */ public static volatile DescriptorImpl DESCRIPTOR; @Extension public static class DescriptorImpl extends BuildStepDescriptor<Publisher> { + public DescriptorImpl() { DESCRIPTOR = this; // backward compatibility } @@ -248,8 +246,8 @@ public class ArtifactArchiver extends Recorder { * Performs on-the-fly validation on the file mask wildcard. */ public FormValidation doCheckArtifacts(@AncestorInPath AbstractProject project, - @QueryParameter String artifacts, - @QueryParameter boolean force) throws IOException { + @QueryParameter String artifacts, + @QueryParameter boolean force) throws IOException { if (!force) { return FormValidation.ok(); } @@ -258,7 +256,7 @@ public class ArtifactArchiver extends Recorder { @Override public ArtifactArchiver newInstance(StaplerRequest req, JSONObject formData) throws FormException { - return req.bindJSON(ArtifactArchiver.class,formData); + return req.bindJSON(ArtifactArchiver.class, formData); } public boolean isApplicable(Class<? extends AbstractProject> jobType) { diff --git a/hudson-core/src/main/java/hudson/tasks/BatchFile.java b/hudson-core/src/main/java/hudson/tasks/BatchFile.java index 6e81186..91c4a65 100644 --- a/hudson-core/src/main/java/hudson/tasks/BatchFile.java +++ b/hudson-core/src/main/java/hudson/tasks/BatchFile.java @@ -7,10 +7,10 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: + * Contributors: * * Kohsuke Kawaguchi - * + * * *******************************************************************************/ @@ -29,17 +29,18 @@ import org.kohsuke.stapler.StaplerRequest; * @author Kohsuke Kawaguchi */ public class BatchFile extends CommandInterpreter { + @DataBoundConstructor public BatchFile(String command) { super(command); } public String[] buildCommandLine(FilePath script) { - return new String[] {"cmd","/c","call",script.getRemote()}; + return new String[]{"cmd", "/c", "call", script.getRemote()}; } protected String getContents() { - return command+"\r\nexit %ERRORLEVEL%"; + return command + "\r\nexit %ERRORLEVEL%"; } protected String getFileExtension() { @@ -48,6 +49,7 @@ public class BatchFile extends CommandInterpreter { @Extension public static final class DescriptorImpl extends BuildStepDescriptor<Builder> { + @Override public String getHelpFile() { return "/help/project-config/batch.html"; diff --git a/hudson-core/src/main/java/hudson/tasks/BuildStep.java b/hudson-core/src/main/java/hudson/tasks/BuildStep.java index 28b0495..9fbd302 100644 --- a/hudson-core/src/main/java/hudson/tasks/BuildStep.java +++ b/hudson-core/src/main/java/hudson/tasks/BuildStep.java @@ -7,10 +7,10 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: -* -* Kohsuke Kawaguchi - * + * Contributors: + * + * Kohsuke Kawaguchi + * * *******************************************************************************/ @@ -33,19 +33,17 @@ import java.util.WeakHashMap; /** * One step of the whole build process. * - * <h2>Persistence</h2> - * <p> - * These objects are persisted as a part of {@link Project} by XStream. - * The save operation happens without any notice, and the restore operation - * happens without calling the constructor, just like Java serialization. + * <h2>Persistence</h2> <p> These objects are persisted as a part of + * {@link Project} by XStream. The save operation happens without any notice, + * and the restore operation happens without calling the constructor, just like + * Java serialization. * - * <p> - * So generally speaking, derived classes should use instance variables - * only for keeping configuration. You can still store objects you use - * for processing, like a parser of some sort, but they need to be marked - * as <tt>transient</tt>, and the code needs to be aware that they might - * be null (which is the case when you access the field for the first time - * the object is restored.) + * <p> So generally speaking, derived classes should use instance variables only + * for keeping configuration. You can still store objects you use for + * processing, like a parser of some sort, but they need to be marked as + * <tt>transient</tt>, and the code needs to be aware that they might be null + * (which is the case when you access the field for the first time the object is + * restored.) * * @author Kohsuke Kawaguchi */ @@ -54,156 +52,139 @@ public interface BuildStep { /** * Runs before the build begins. * - * @return - * true if the build can continue, false if there was an error - * and the build needs to be aborted. + * @return true if the build can continue, false if there was an error and + * the build needs to be aborted. */ - boolean prebuild( AbstractBuild<?,?> build, BuildListener listener ); + boolean prebuild(AbstractBuild<?, ?> build, BuildListener listener); /** - * Runs the step over the given build and reports the progress to the listener. + * Runs the step over the given build and reports the progress to the + * listener. * - * <p> - * A plugin can contribute the action object to {@link Build#getActions()} - * so that a 'report' becomes a part of the persisted data of {@link Build}. - * This is how JUnit plugin attaches the test report to a build page, for example. + * <p> A plugin can contribute the action object to + * {@link Build#getActions()} so that a 'report' becomes a part of the + * persisted data of {@link Build}. This is how JUnit plugin attaches the + * test report to a build page, for example. * - * @return - * true if the build can continue, false if there was an error - * and the build needs to be aborted. + * @return true if the build can continue, false if there was an error and + * the build needs to be aborted. * - * @throws InterruptedException - * If the build is interrupted by the user (in an attempt to abort the build.) - * Normally the {@link BuildStep} implementations may simply forward the exception - * it got from its lower-level functions. - * @throws IOException - * If the implementation wants to abort the processing when an {@link IOException} - * happens, it can simply propagate the exception to the caller. This will cause - * the build to fail, with the default error message. - * Implementations are encouraged to catch {@link IOException} on its own to - * provide a better error message, if it can do so, so that users have better - * understanding on why it failed. + * @throws InterruptedException If the build is interrupted by the user (in + * an attempt to abort the build.) Normally the {@link BuildStep} + * implementations may simply forward the exception it got from its + * lower-level functions. + * @throws IOException If the implementation wants to abort the processing + * when an {@link IOException} happens, it can simply propagate the + * exception to the caller. This will cause the build to fail, with the + * default error message. Implementations are encouraged to catch + * {@link IOException} on its own to provide a better error message, if it + * can do so, so that users have better understanding on why it failed. */ - boolean perform(AbstractBuild<?,?> build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException; + boolean perform(AbstractBuild<?, ?> build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException; /** - * @deprecated as of 1.341. - * Use {@link #getProjectActions(AbstractProject)} instead. + * @deprecated as of 1.341. Use {@link #getProjectActions(AbstractProject)} + * instead. */ - Action getProjectAction(AbstractProject<?,?> project); + Action getProjectAction(AbstractProject<?, ?> project); /** - * Returns action objects if this {@link BuildStep} has actions - * to contribute to a {@link Project}. + * Returns action objects if this {@link BuildStep} has actions to + * contribute to a {@link Project}. * - * <p> - * {@link Project} calls this method for every {@link BuildStep} that - * it owns when the rendering is requested. + * <p> {@link Project} calls this method for every {@link BuildStep} that it + * owns when the rendering is requested. * - * <p> - * This action can have optional <tt>jobMain.jelly</tt> view, which will be - * aggregated into the main panel of the job top page. The jelly file + * <p> This action can have optional <tt>jobMain.jelly</tt> view, which will + * be aggregated into the main panel of the job top page. The jelly file * should have an <h2> tag that shows the section title, followed by some * block elements to render the details of the section. * - * @param project - * {@link Project} that owns this build step, - * since {@link BuildStep} object doesn't usually have this "parent" pointer. + * @param project {@link Project} that owns this build step, since + * {@link BuildStep} object doesn't usually have this "parent" pointer. * - * @return - * can be empty but never null. + * @return can be empty but never null. */ - Collection<? extends Action> getProjectActions(AbstractProject<?,?> project); - + Collection<? extends Action> getProjectActions(AbstractProject<?, ?> project); /** - * Declares the scope of the synchronization monitor this {@link BuildStep} expects from outside. + * Declares the scope of the synchronization monitor this {@link BuildStep} + * expects from outside. * - * <p> - * This method is introduced for preserving compatibility with plugins written for earlier versions of Hudson, - * which never run multiple builds of the same job in parallel. Such plugins often assume that the outcome - * of the previous build is completely available, which is no longer true when we do concurrent builds. + * <p> This method is introduced for preserving compatibility with plugins + * written for earlier versions of Hudson, which never run multiple builds + * of the same job in parallel. Such plugins often assume that the outcome + * of the previous build is completely available, which is no longer true + * when we do concurrent builds. * - * <p> - * To minimize the necessary code change for such plugins, {@link BuildStep} implementations can request - * Hudson to externally perform synchronization before executing them. This behavior is as follows: + * <p> To minimize the necessary code change for such plugins, + * {@link BuildStep} implementations can request Hudson to externally + * perform synchronization before executing them. This behavior is as + * follows: * - * <dl> - * <dt>{@link BuildStepMonitor#BUILD} - * <dd> - * This {@link BuildStep} is only executed after the previous build is fully - * completed (thus fully restoring the earlier semantics of one build at a time.) + * <dl> <dt>{@link BuildStepMonitor#BUILD} <dd> This {@link BuildStep} is + * only executed after the previous build is fully completed (thus fully + * restoring the earlier semantics of one build at a time.) * - * <dt>{@link BuildStepMonitor#STEP} - * <dd> - * This {@link BuildStep} is only executed after the same step in the previous build is completed. - * For build steps that use a weaker assumption and only rely on the output from the same build step of - * the early builds, this improves the concurrency. + * <dt>{@link BuildStepMonitor#STEP} <dd> This {@link BuildStep} is only + * executed after the same step in the previous build is completed. For + * build steps that use a weaker assumption and only rely on the output from + * the same build step of the early builds, this improves the concurrency. * - * <dt>{@link BuildStepMonitor#NONE} - * <dd> - * No external synchronization is performed on this build step. This is the most efficient, and thus - * <b>the recommended value for newer plugins</b>. Wherever necessary, you can directly use {@link CheckPoint}s - * to perform necessary synchronizations. + * <dt>{@link BuildStepMonitor#NONE} <dd> No external synchronization is + * performed on this build step. This is the most efficient, and thus <b>the + * recommended value for newer plugins</b>. Wherever necessary, you can + * directly use {@link CheckPoint}s to perform necessary synchronizations. * </dl> * - * <h2>Migrating Older Implementation</h2> - * <p> - * If you are migrating {@link BuildStep} implementations written for earlier versions of Hudson, + * <h2>Migrating Older Implementation</h2> <p> If you are migrating + * {@link BuildStep} implementations written for earlier versions of Hudson, * here's what you can do: * - * <ul> - * <li> - * Just return {@link BuildStepMonitor#BUILD} to demand the backward compatible behavior from Hudson, - * and make no other changes to the code. This will prevent users from reaping the benefits of concurrent - * builds, but at least your plugin will work correctly, and therefore this is a good easy first step. - * <li> - * If your build step doesn't use anything from a previous build (for example, if you don't even call - * {@link Run#getPreviousBuild()}), then you can return {@link BuildStepMonitor#NONE} without making further - * code changes and you are done with migration. - * <li> - * If your build step only depends on {@link Action}s that you added in the previous build by yourself, - * then you only need {@link BuildStepMonitor#STEP} scope synchronization. Return it from this method - * ,and you are done with migration without any further code changes. - * <li> - * If your build step makes more complex assumptions, return {@link BuildStepMonitor#NONE} and use - * {@link CheckPoint}s directly in your code. The general idea is to call {@link CheckPoint#block()} before - * you try to access the state from the previous build. - * </ul> + * <ul> <li> Just return {@link BuildStepMonitor#BUILD} to demand the + * backward compatible behavior from Hudson, and make no other changes to + * the code. This will prevent users from reaping the benefits of concurrent + * builds, but at least your plugin will work correctly, and therefore this + * is a good easy first step. <li> If your build step doesn't use anything + * from a previous build (for example, if you don't even call + * {@link Run#getPreviousBuild()}), then you can return + * {@link BuildStepMonitor#NONE} without making further code changes and you + * are done with migration. <li> If your build step only depends on + * {@link Action}s that you added in the previous build by yourself, then + * you only need {@link BuildStepMonitor#STEP} scope synchronization. Return + * it from this method ,and you are done with migration without any further + * code changes. <li> If your build step makes more complex assumptions, + * return {@link BuildStepMonitor#NONE} and use {@link CheckPoint}s directly + * in your code. The general idea is to call {@link CheckPoint#block()} + * before you try to access the state from the previous build. </ul> * - * <h2>Note to caller</h2> - * <p> - * For plugins written against earlier versions of Hudson, calling this method results in - * {@link AbstractMethodError}. + * <h2>Note to caller</h2> <p> For plugins written against earlier versions + * of Hudson, calling this method results in {@link AbstractMethodError}. * * @since 1.319 */ BuildStepMonitor getRequiredMonitorService(); - /** * List of all installed builders. * * Builders are invoked to perform the build itself. * - * @deprecated as of 1.286. - * Use {@link Builder#all()} for read access, and use - * {@link Extension} for registration. + * @deprecated as of 1.286. Use {@link Builder#all()} for read access, and + * use {@link Extension} for registration. */ public static final List<Descriptor<Builder>> BUILDERS = new DescriptorList<Builder>(Builder.class); - /** * List of all installed publishers. * * Publishers are invoked after the build is completed, normally to perform - * some post-actions on build results, such as sending notifications, collecting - * results, etc. + * some post-actions on build results, such as sending notifications, + * collecting results, etc. * * @see PublisherList#addNotifier(Descriptor) * @see PublisherList#addRecorder(Descriptor) * - * @deprecated as of 1.286. - * Use {@link Publisher#all()} for read access, and use - * {@link Extension} for registration. + * @deprecated as of 1.286. Use {@link Publisher#all()} for read access, and + * use {@link Extension} for registration. */ public static final PublisherList PUBLISHERS = new PublisherList(); @@ -211,48 +192,47 @@ public interface BuildStep { * List of publisher descriptor. */ public static final class PublisherList extends AbstractList<Descriptor<Publisher>> { + /** - * {@link Descriptor}s are actually stored in here. - * Since {@link PublisherList} lives longer than {@link Hudson} we cannot directly use {@link ExtensionList}. + * {@link Descriptor}s are actually stored in here. Since + * {@link PublisherList} lives longer than {@link Hudson} we cannot + * directly use {@link ExtensionList}. */ private final DescriptorList<Publisher> core = new DescriptorList<Publisher>(Publisher.class); - /** - * For descriptors that are manually registered, remember what kind it was since - * older plugins don't extend from neither {@link Recorder} nor {@link Notifier}. + * For descriptors that are manually registered, remember what kind it + * was since older plugins don't extend from neither {@link Recorder} + * nor {@link Notifier}. */ - /*package*/ static final WeakHashMap<Descriptor<Publisher>,Class<? extends Publisher>/*either Recorder.class or Notifier.class*/> - KIND = new WeakHashMap<Descriptor<Publisher>, Class<? extends Publisher>>(); + /*package*/ static final WeakHashMap<Descriptor<Publisher>, Class<? extends Publisher>/*either Recorder.class or Notifier.class*/> KIND = new WeakHashMap<Descriptor<Publisher>, Class<? extends Publisher>>(); private PublisherList() { } /** - * Adds a new publisher descriptor, which (generally speaking) - * shouldn't alter the build result, but just report the build result - * by some means, such as e-mail, IRC, etc. + * Adds a new publisher descriptor, which (generally speaking) shouldn't + * alter the build result, but just report the build result by some + * means, such as e-mail, IRC, etc. * - * <p> - * This method adds the descriptor after all the "recorders". + * <p> This method adds the descriptor after all the "recorders". * * @see #addRecorder(Descriptor) */ - public void addNotifier( Descriptor<Publisher> d ) { - KIND.put(d,Notifier.class); + public void addNotifier(Descriptor<Publisher> d) { + KIND.put(d, Notifier.class); core.add(d); } - + /** - * Adds a new publisher descriptor, which (generally speaking) - * alter the build result based on some artifacts of the build. + * Adds a new publisher descriptor, which (generally speaking) alter the + * build result based on some artifacts of the build. * - * <p> - * This method adds the descriptor before all the "notifiers". + * <p> This method adds the descriptor before all the "notifiers". * - * @see #addNotifier(Descriptor) + * @see #addNotifier(Descriptor) */ - public void addRecorder( Descriptor<Publisher> d ) { - KIND.put(d,Recorder.class); + public void addRecorder(Descriptor<Publisher> d) { + KIND.put(d, Recorder.class); core.add(d); } @@ -263,7 +243,9 @@ public interface BuildStep { @Override public void add(int index, Descriptor<Publisher> d) { - if(!contains(d)) core.add(d); + if (!contains(d)) { + core.add(d); + } } public Descriptor<Publisher> get(int index) { diff --git a/hudson-core/src/main/java/hudson/tasks/BuildStepCompatibilityLayer.java b/hudson-core/src/main/java/hudson/tasks/BuildStepCompatibilityLayer.java index 6077110..0db8148 100644 --- a/hudson-core/src/main/java/hudson/tasks/BuildStepCompatibilityLayer.java +++ b/hudson-core/src/main/java/hudson/tasks/BuildStepCompatibilityLayer.java @@ -7,10 +7,10 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: -* -* Kohsuke Kawaguchi - * + * Contributors: + * + * Kohsuke Kawaguchi + * * *******************************************************************************/ @@ -29,8 +29,8 @@ import java.util.Collection; import java.util.Collections; /** - * Provides compatibility with {@link BuildStep} before 1.150 - * so that old plugin binaries can continue to function with new Hudson. + * Provides compatibility with {@link BuildStep} before 1.150 so that old plugin + * binaries can continue to function with new Hudson. * * @author Kohsuke Kawaguchi * @since 1.150 @@ -40,59 +40,62 @@ public abstract class BuildStepCompatibilityLayer implements BuildStep { // // new definitions >= 1.150 // - public boolean prebuild(AbstractBuild<?,?> build, BuildListener listener) { - if (build instanceof Build) - return prebuild((Build)build,listener); - else + + public boolean prebuild(AbstractBuild<?, ?> build, BuildListener listener) { + if (build instanceof Build) { + return prebuild((Build) build, listener); + } else { return true; + } } - public boolean perform(AbstractBuild<?,?> build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException { - if (build instanceof Build) - return perform((Build)build,launcher,listener); - else + public boolean perform(AbstractBuild<?, ?> build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException { + if (build instanceof Build) { + return perform((Build) build, launcher, listener); + } else { return true; + } } public Action getProjectAction(AbstractProject<?, ?> project) { - if (project instanceof Project) + if (project instanceof Project) { return getProjectAction((Project) project); - else + } else { return null; + } } public Collection<? extends Action> getProjectActions(AbstractProject<?, ?> project) { // delegate to getJobAction (singular) for backward compatible behavior Action a = getProjectAction(project); - if (a==null) return Collections.emptyList(); + if (a == null) { + return Collections.emptyList(); + } return Collections.singletonList(a); } - // // old definitions < 1.150 // /** - * @deprecated - * Use {@link #prebuild(AbstractBuild, BuildListener)} instead. + * @deprecated Use {@link #prebuild(AbstractBuild, BuildListener)} instead. */ - public boolean prebuild(Build<?,?> build, BuildListener listener) { + public boolean prebuild(Build<?, ?> build, BuildListener listener) { return true; } /** - * @deprecated - * Use {@link #perform(AbstractBuild, Launcher, BuildListener)} instead. + * @deprecated Use {@link #perform(AbstractBuild, Launcher, BuildListener)} + * instead. */ - public boolean perform(Build<?,?> build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException { + public boolean perform(Build<?, ?> build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException { throw new UnsupportedOperationException(); } /** - * @deprecated - * Use {@link #getProjectAction(AbstractProject)} instead. + * @deprecated Use {@link #getProjectAction(AbstractProject)} instead. */ - public Action getProjectAction(Project<?,?> project) { + public Action getProjectAction(Project<?, ?> project) { return null; } } diff --git a/hudson-core/src/main/java/hudson/tasks/BuildStepDescriptor.java b/hudson-core/src/main/java/hudson/tasks/BuildStepDescriptor.java index 386778e..7309e7a 100644 --- a/hudson-core/src/main/java/hudson/tasks/BuildStepDescriptor.java +++ b/hudson-core/src/main/java/hudson/tasks/BuildStepDescriptor.java @@ -7,10 +7,10 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: -* -* Kohsuke Kawaguchi - * + * Contributors: + * + * Kohsuke Kawaguchi + * * *******************************************************************************/ @@ -28,21 +28,23 @@ import java.util.ArrayList; /** * {@link Descriptor} for {@link Builder} and {@link Publisher}. * - * <p> - * For compatibility reasons, plugins developed before 1.150 may not extend from this descriptor type. + * <p> For compatibility reasons, plugins developed before 1.150 may not extend + * from this descriptor type. * * @author Kohsuke Kawaguchi * @since 1.150 */ public abstract class BuildStepDescriptor<T extends BuildStep & Describable<T>> extends Descriptor<T> { + protected BuildStepDescriptor(Class<? extends T> clazz) { super(clazz); } /** - * Infers the type of the corresponding {@link BuildStep} from the outer class. - * This version works when you follow the common convention, where a descriptor - * is written as the static nested class of the describable class. + * Infers the type of the corresponding {@link BuildStep} from the outer + * class. This version works when you follow the common convention, where a + * descriptor is written as the static nested class of the describable + * class. * * @since 1.278 */ @@ -52,29 +54,31 @@ public abstract class BuildStepDescriptor<T extends BuildStep & Describable<T>> /** * Returns true if this task is applicable to the given project. * - * @return - * true to allow user to configure this post-promotion task for the given project. - * @see AbstractProjectDescriptor#isApplicable(Descriptor) + * @return true to allow user to configure this post-promotion task for the + * given project. + * @see AbstractProjectDescriptor#isApplicable(Descriptor) */ public abstract boolean isApplicable(Class<? extends AbstractProject> jobType); - /** - * Filters a descriptor for {@link BuildStep}s by using {@link BuildStepDescriptor#isApplicable(Class)}. + * Filters a descriptor for {@link BuildStep}s by using + * {@link BuildStepDescriptor#isApplicable(Class)}. */ - public static <T extends BuildStep&Describable<T>> - List<Descriptor<T>> filter(List<Descriptor<T>> base, Class<? extends AbstractProject> type) { + public static <T extends BuildStep & Describable<T>> List<Descriptor<T>> filter(List<Descriptor<T>> base, Class<? extends AbstractProject> type) { // descriptor of the project Descriptor pd = Hudson.getInstance().getDescriptor((Class) type); List<Descriptor<T>> r = new ArrayList<Descriptor<T>>(base.size()); for (Descriptor<T> d : base) { - if (pd instanceof AbstractProjectDescriptor && !((AbstractProjectDescriptor)pd).isApplicable(d)) + if (pd instanceof AbstractProjectDescriptor && !((AbstractProjectDescriptor) pd).isApplicable(d)) { continue; + } if (d instanceof BuildStepDescriptor) { BuildStepDescriptor<T> bd = (BuildStepDescriptor<T>) d; - if(!bd.isApplicable(type)) continue; + if (!bd.isApplicable(type)) { + continue; + } r.add(bd); } else { // old plugins built before 1.150 may not implement BuildStepDescriptor diff --git a/hudson-core/src/main/java/hudson/tasks/BuildStepMonitor.java b/hudson-core/src/main/java/hudson/tasks/BuildStepMonitor.java index 6e43a9c..0fb5915 100644 --- a/hudson-core/src/main/java/hudson/tasks/BuildStepMonitor.java +++ b/hudson-core/src/main/java/hudson/tasks/BuildStepMonitor.java @@ -8,7 +8,7 @@ * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * + * * *******************************************************************************/ @@ -28,17 +28,18 @@ import java.io.IOException; * @since 1.319 */ public enum BuildStepMonitor { + NONE { public boolean perform(BuildStep bs, AbstractBuild build, Launcher launcher, BuildListener listener) throws IOException, InterruptedException { - return bs.perform(build,launcher,listener); + return bs.perform(build, launcher, listener); } }, STEP { public boolean perform(BuildStep bs, AbstractBuild build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException { - CheckPoint cp = new CheckPoint(bs.getClass().getName(),bs.getClass()); + CheckPoint cp = new CheckPoint(bs.getClass().getName(), bs.getClass()); cp.block(); try { - return bs.perform(build,launcher,listener); + return bs.perform(build, launcher, listener); } finally { cp.report(); } @@ -47,12 +48,13 @@ public enum BuildStepMonitor { BUILD { public boolean perform(BuildStep bs, AbstractBuild build, Launcher launcher, BuildListener listener) throws IOException, InterruptedException { CheckPoint.COMPLETED.block(); - return bs.perform(build,launcher,listener); + return bs.perform(build, launcher, listener); } }; /** - * Calls {@link BuildStep#perform(AbstractBuild, Launcher, BuildListener)} with the proper synchronization. + * Calls {@link BuildStep#perform(AbstractBuild, Launcher, BuildListener)} + * with the proper synchronization. */ public abstract boolean perform(BuildStep bs, AbstractBuild build, Launcher launcher, BuildListener listener) throws IOException, InterruptedException; } diff --git a/hudson-core/src/main/java/hudson/tasks/BuildTrigger.java b/hudson-core/src/main/java/hudson/tasks/BuildTrigger.java index 5ea82da..7a00623 100644 --- a/hudson-core/src/main/java/hudson/tasks/BuildTrigger.java +++ b/hudson-core/src/main/java/hudson/tasks/BuildTrigger.java @@ -7,10 +7,10 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: -* -* Kohsuke Kawaguchi, Brian Westrich, Martin Eigenbrodt - * + * Contributors: + * + * Kohsuke Kawaguchi, Brian Westrich, Martin Eigenbrodt + * * *******************************************************************************/ @@ -60,15 +60,14 @@ import java.util.logging.Logger; /** * Triggers builds of other projects. * - * <p> - * Despite what the name suggests, this class doesn't actually trigger other jobs - * as a part of {@link #perform} method. Its main job is to simply augument + * <p> Despite what the name suggests, this class doesn't actually trigger other + * jobs as a part of {@link #perform} method. Its main job is to simply augument * {@link DependencyGraph}. Jobs are responsible for triggering downstream jobs * on its own, because dependencies may come from other sources. * - * <p> - * This class, however, does provide the {@link #execute(AbstractBuild, BuildListener, BuildTrigger)} - * method as a convenience method to invoke downstream builds. + * <p> This class, however, does provide the + * {@link #execute(AbstractBuild, BuildListener, BuildTrigger)} method as a + * convenience method to invoke downstream builds. * * @author Kohsuke Kawaguchi */ @@ -78,33 +77,33 @@ public class BuildTrigger extends Recorder implements DependecyDeclarer { * Comma-separated list of other projects to be scheduled. */ private String childProjects; - /** * Threshold status to trigger other builds. * - * For compatibility reasons, this field could be null, in which case - * it should read as "SUCCESS". + * For compatibility reasons, this field could be null, in which case it + * should read as "SUCCESS". */ private final Result threshold; @DataBoundConstructor public BuildTrigger(String childProjects, boolean evenIfUnstable) { - this(childProjects,evenIfUnstable ? Result.UNSTABLE : Result.SUCCESS); + this(childProjects, evenIfUnstable ? Result.UNSTABLE : Result.SUCCESS); } public BuildTrigger(String childProjects, Result threshold) { - if(childProjects==null) + if (childProjects == null) { throw new IllegalArgumentException(); + } this.childProjects = childProjects; this.threshold = threshold; } public BuildTrigger(List<AbstractProject> childProjects, Result threshold) { - this((Collection<AbstractProject>)childProjects,threshold); + this((Collection<AbstractProject>) childProjects, threshold); } public BuildTrigger(Collection<? extends AbstractProject> childProjects, Result threshold) { - this(Items.toNameList(childProjects),threshold); + this(Items.toNameList(childProjects), threshold); } public String getChildProjectsValue() { @@ -112,26 +111,28 @@ public class BuildTrigger extends Recorder implements DependecyDeclarer { } public Result getThreshold() { - if(threshold==null) + if (threshold == null) { return Result.SUCCESS; - else + } else { return threshold; + } } public List<AbstractProject> getChildProjects() { - return Items.fromNameList(childProjects,AbstractProject.class); + return Items.fromNameList(childProjects, AbstractProject.class); } public BuildStepMonitor getRequiredMonitorService() { return BuildStepMonitor.NONE; } - + /** - * Checks if this trigger has the exact same set of children as the given list. + * Checks if this trigger has the exact same set of children as the given + * list. */ public boolean hasSame(Collection<? extends AbstractProject> projects) { List<AbstractProject> children = getChildProjects(); - return children.size()==projects.size() && children.containsAll(projects); + return children.size() == projects.size() && children.containsAll(projects); } @Override @@ -140,7 +141,8 @@ public class BuildTrigger extends Recorder implements DependecyDeclarer { } /** - * @deprecated since 1.341; use {@link #execute(AbstractBuild,BuildListener)} + * @deprecated since 1.341; use + * {@link #execute(AbstractBuild,BuildListener)} */ @Deprecated public static boolean execute(AbstractBuild build, BuildListener listener, BuildTrigger trigger) { @@ -150,10 +152,8 @@ public class BuildTrigger extends Recorder implements DependecyDeclarer { /** * Convenience method to trigger downstream builds. * - * @param build - * The current build. Its downstreams will be triggered. - * @param listener - * Receives the progress report. + * @param build The current build. Its downstreams will be triggered. + * @param listener Receives the progress report. */ public static boolean execute(AbstractBuild build, BuildListener listener) { PrintStream logger = listener.getLogger(); @@ -179,9 +179,9 @@ public class BuildTrigger extends Recorder implements DependecyDeclarer { if (dep.shouldTriggerBuild(build, listener, buildActions)) { // this is not completely accurate, as a new build might be triggered // between these calls - String name = p.getName()+" #"+p.getNextBuildNumber(); - if(p.scheduleBuild(p.getQuietPeriod(), new UpstreamCause((Run)build), - buildActions.toArray(new Action[buildActions.size()]))) { + String name = p.getName() + " #" + p.getNextBuildNumber(); + if (p.scheduleBuild(p.getQuietPeriod(), new UpstreamCause((Run) build), + buildActions.toArray(new Action[buildActions.size()]))) { logger.println(Messages.BuildTrigger_Triggering(name)); } else { logger.println(Messages.BuildTrigger_InQueue(name)); @@ -198,7 +198,7 @@ public class BuildTrigger extends Recorder implements DependecyDeclarer { graph.addDependency(new Dependency(owner, p) { @Override public boolean shouldTriggerBuild(AbstractBuild build, TaskListener listener, - List<Action> actions) { + List<Action> actions) { return build.getResult().isBetterOrEqualTo(threshold); } }); @@ -212,30 +212,36 @@ public class BuildTrigger extends Recorder implements DependecyDeclarer { } /** - * Called from {@link hudson.tasks.BuildTrigger.DescriptorImpl.ItemListenerImpl} when a job is renamed. + * Called from + * {@link hudson.tasks.BuildTrigger.DescriptorImpl.ItemListenerImpl} when a + * job is renamed. * - * @return true if this {@link BuildTrigger} is changed and needs to be saved. + * @return true if this {@link BuildTrigger} is changed and needs to be + * saved. */ public boolean onJobRenamed(String oldName, String newName) { // quick test - if(!childProjects.contains(oldName)) + if (!childProjects.contains(oldName)) { return false; + } boolean changed = false; // we need to do this per string, since old Project object is already gone. String[] projects = childProjects.split(","); - for( int i=0; i<projects.length; i++ ) { - if(projects[i].trim().equals(oldName)) { + for (int i = 0; i < projects.length; i++) { + if (projects[i].trim().equals(oldName)) { projects[i] = newName; changed = true; } } - if(changed) { + if (changed) { StringBuilder b = new StringBuilder(); for (String p : projects) { - if(b.length()>0) b.append(','); + if (b.length() > 0) { + b.append(','); + } b.append(p); } childProjects = b.toString(); @@ -248,13 +254,15 @@ public class BuildTrigger extends Recorder implements DependecyDeclarer { * Correct broken data gracefully (#1537) */ private Object readResolve() { - if(childProjects==null) - return childProjects=""; + if (childProjects == null) { + return childProjects = ""; + } return this; } @Extension public static class DescriptorImpl extends BuildStepDescriptor<Publisher> { + public String getDisplayName() { return Messages.BuildTrigger_DisplayName(); } @@ -267,8 +275,8 @@ public class BuildTrigger extends Recorder implements DependecyDeclarer { @Override public Publisher newInstance(StaplerRequest req, JSONObject formData) throws FormException { return new BuildTrigger( - formData.getString("childProjects"), - formData.has("evenIfUnstable") && formData.getBoolean("evenIfUnstable")); + formData.getString("childProjects"), + formData.has("evenIfUnstable") && formData.getBoolean("evenIfUnstable")); } @Override @@ -285,18 +293,22 @@ public class BuildTrigger extends Recorder implements DependecyDeclarer { * Form validation method. */ public FormValidation doCheck(@AncestorInPath AccessControlled subject, @AncestorInPath AbstractProject current, - @QueryParameter String value ) { + @QueryParameter String value) { // Require CONFIGURE permission on this project - if(!subject.hasPermission(Item.CONFIGURE)) return FormValidation.ok(); + if (!subject.hasPermission(Item.CONFIGURE)) { + return FormValidation.ok(); + } - StringTokenizer tokens = new StringTokenizer(Util.fixNull(value),","); - while(tokens.hasMoreTokens()) { + StringTokenizer tokens = new StringTokenizer(Util.fixNull(value), ","); + while (tokens.hasMoreTokens()) { String projectName = tokens.nextToken().trim(); - Item item = Hudson.getInstance().getItemByFullName(projectName,Item.class); - if(item==null) - return FormValidation.error(Messages.BuildTrigger_NoSuchProject(projectName,AbstractProject.findNearest(projectName).getName())); - if(!(item instanceof AbstractProject)) + Item item = Hudson.getInstance().getItemByFullName(projectName, Item.class); + if (item == null) { + return FormValidation.error(Messages.BuildTrigger_NoSuchProject(projectName, AbstractProject.findNearest(projectName).getName())); + } + if (!(item instanceof AbstractProject)) { return FormValidation.error(Messages.BuildTrigger_NotBuildable(projectName)); + } if (StringUtils.equals(projectName, current.getName())) { return FormValidation.error(Messages.BuildTrigger_FailedUsingCurrentProject()); } @@ -322,18 +334,19 @@ public class BuildTrigger extends Recorder implements DependecyDeclarer { @Extension public static class ItemListenerImpl extends ItemListener { + @Override public void onRenamed(Item item, String oldName, String newName) { // update BuildTrigger of other projects that point to this object. // can't we generalize this? - for( Project<?,?> p : Hudson.getInstance().getProjects() ) { + for (Project<?, ?> p : Hudson.getInstance().getProjects()) { BuildTrigger t = p.getPublishersList().get(BuildTrigger.class); - if(t!=null) { - if(t.onJobRenamed(oldName,newName)) { + if (t != null) { + if (t.onJobRenamed(oldName, newName)) { try { p.save(); } catch (IOException e) { - LOGGER.log(Level.WARNING, "Failed to persist project setting during rename from "+oldName+" to "+newName,e); + LOGGER.log(Level.WARNING, "Failed to persist project setting during rename from " + oldName + " to " + newName, e); } } } @@ -341,6 +354,5 @@ public class BuildTrigger extends Recorder implements DependecyDeclarer { } } } - private static final Logger LOGGER = Logger.getLogger(BuildTrigger.class.getName()); } diff --git a/hudson-core/src/main/java/hudson/tasks/BuildWrapper.java b/hudson-core/src/main/java/hudson/tasks/BuildWrapper.java index deb621b..cd517b6 100644 --- a/hudson-core/src/main/java/hudson/tasks/BuildWrapper.java +++ b/hudson-core/src/main/java/hudson/tasks/BuildWrapper.java @@ -7,10 +7,10 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: + * Contributors: * * Kohsuke Kawaguchi, Yahoo! Inc. - * + * * *******************************************************************************/ @@ -33,66 +33,65 @@ import java.util.Set; /** * Pluggability point for performing pre/post actions for the build process. * - * <p> - * This extension point enables a plugin to set up / tear down additional - * services needed to perform a build, such as setting up local X display, - * or launching and stopping application servers for testing. + * <p> This extension point enables a plugin to set up / tear down additional + * services needed to perform a build, such as setting up local X display, or + * launching and stopping application servers for testing. * - * <p> - * An instance of {@link BuildWrapper} is associated with a {@link Project} - * with configuration information as its state. An instance is persisted - * along with {@link Project}. + * <p> An instance of {@link BuildWrapper} is associated with a {@link Project} + * with configuration information as its state. An instance is persisted along + * with {@link Project}. * - * <p> - * The {@link #setUp(Build,Launcher,BuildListener)} method is invoked for each build. + * <p> The {@link #setUp(Build,Launcher,BuildListener)} method is invoked for + * each build. * * @author Kohsuke Kawaguchi */ public abstract class BuildWrapper extends AbstractDescribableImpl<BuildWrapper> implements ExtensionPoint { + /** - * Represents the environment set up by {@link BuildWrapper#setUp(Build,Launcher,BuildListener)}. + * Represents the environment set up by + * {@link BuildWrapper#setUp(Build,Launcher,BuildListener)}. * - * <p> - * It is expected that the subclasses of {@link BuildWrapper} extends this - * class and implements its own semantics. + * <p> It is expected that the subclasses of {@link BuildWrapper} extends + * this class and implements its own semantics. */ public abstract class Environment extends hudson.model.Environment { + /** * Runs after the {@link Builder} completes, and performs a tear down. * - * <p> - * This method is invoked even when the build failed, so that the + * <p> This method is invoked even when the build failed, so that the * clean up operation can be performed regardless of the build result * (for example, you'll want to stop application server even if a build - * fails.) {@link Build#getResult} in this case will return Result.FAILURE - * (since 1.339), and a null result indicates SUCCESS-so-far (post-build - * actions may still affect the final result). + * fails.) {@link Build#getResult} in this case will return + * Result.FAILURE (since 1.339), and a null result indicates + * SUCCESS-so-far (post-build actions may still affect the final + * result). * - * @param build - * The same {@link Build} object given to the set up method. - * @param listener - * The same {@link BuildListener} object given to the set up method. - * @return - * true if the build can continue, false if there was an error - * and the build needs to be aborted. - * @throws IOException - * terminates the build abnormally. Hudson will handle the exception - * and reports a nice error message. + * @param build The same {@link Build} object given to the set up + * method. + * @param listener The same {@link BuildListener} object given to the + * set up method. + * @return true if the build can continue, false if there was an error + * and the build needs to be aborted. + * @throws IOException terminates the build abnormally. Hudson will + * handle the exception and reports a nice error message. * @since 1.150 */ - public boolean tearDown( AbstractBuild build, BuildListener listener ) throws IOException, InterruptedException { - if (build instanceof Build) - return tearDown((Build)build, listener); - else + public boolean tearDown(AbstractBuild build, BuildListener listener) throws IOException, InterruptedException { + if (build instanceof Build) { + return tearDown((Build) build, listener); + } else { return true; + } } /** - * @deprecated since 2007-10-28. - * Use {@link #tearDown(AbstractBuild, BuildListener)} instead. + * @deprecated since 2007-10-28. Use + * {@link #tearDown(AbstractBuild, BuildListener)} instead. */ @Deprecated - public boolean tearDown( Build build, BuildListener listener ) throws IOException, InterruptedException { + public boolean tearDown(Build build, BuildListener listener) throws IOException, InterruptedException { return true; } } @@ -100,67 +99,64 @@ public abstract class BuildWrapper extends AbstractDescribableImpl<BuildWrapper> /** * Runs before the {@link Builder} runs, and performs a set up. * - * @param build - * The build in progress for which an {@link Environment} object is created. - * Never null. - * @param launcher - * This launcher can be used to launch processes for this build. - * If the build runs remotely, launcher will also run a job on that remote machine. - * Never null. - * @param listener - * Can be used to send any message. - * @return - * non-null if the build can continue, null if there was an error - * and the build needs to be aborted. - * @throws IOException - * terminates the build abnormally. Hudson will handle the exception - * and reports a nice error message. + * @param build The build in progress for which an {@link Environment} + * object is created. Never null. + * @param launcher This launcher can be used to launch processes for this + * build. If the build runs remotely, launcher will also run a job on that + * remote machine. Never null. + * @param listener Can be used to send any message. + * @return non-null if the build can continue, null if there was an error + * and the build needs to be aborted. + * @throws IOException terminates the build abnormally. Hudson will handle + * the exception and reports a nice error message. * @since 1.150 */ - public Environment setUp( AbstractBuild build, Launcher launcher, BuildListener listener ) throws IOException, InterruptedException { - if (build instanceof Build) - return setUp((Build)build,launcher,listener); - else - throw new AssertionError("The plugin '" + this.getClass().getName() + "' still uses " + - "deprecated setUp(Build,Launcher,BuildListener) method. " + - "Update the plugin to use setUp(AbstractBuild, Launcher, BuildListener) instead."); + public Environment setUp(AbstractBuild build, Launcher launcher, BuildListener listener) throws IOException, InterruptedException { + if (build instanceof Build) { + return setUp((Build) build, launcher, listener); + } else { + throw new AssertionError("The plugin '" + this.getClass().getName() + "' still uses " + + "deprecated setUp(Build,Launcher,BuildListener) method. " + + "Update the plugin to use setUp(AbstractBuild, Launcher, BuildListener) instead."); + } } /** - * @deprecated since 2007-10-28. - * Use {@link #setUp(AbstractBuild, Launcher, BuildListener)} instead. + * @deprecated since 2007-10-28. Use + * {@link #setUp(AbstractBuild, Launcher, BuildListener)} instead. */ @Deprecated - public Environment setUp( Build build, Launcher launcher, BuildListener listener ) throws IOException, InterruptedException { - throw new UnsupportedOperationException(getClass()+" needs to implement the setUp method"); + public Environment setUp(Build build, Launcher launcher, BuildListener listener) throws IOException, InterruptedException { + throw new UnsupportedOperationException(getClass() + " needs to implement the setUp method"); } /** - * Provides an opportunity for a {@link BuildWrapper} to decorate a {@link Launcher} to be used in the build. + * Provides an opportunity for a {@link BuildWrapper} to decorate a + * {@link Launcher} to be used in the build. * - * <p> - * This hook is called very early on in the build (even before {@link #setUp(AbstractBuild, Launcher, BuildListener)} is invoked.) - * The typical use of {@link Launcher} decoration involves in modifying the environment that processes run, - * such as the use of sudo/pfexec/chroot, or manipulating environment variables. + * <p> This hook is called very early on in the build (even before + * {@link #setUp(AbstractBuild, Launcher, BuildListener)} is invoked.) The + * typical use of {@link Launcher} decoration involves in modifying the + * environment that processes run, such as the use of sudo/pfexec/chroot, or + * manipulating environment variables. * - * <p> - * The default implementation is no-op, which just returns the {@code launcher} parameter as-is. + * <p> The default implementation is no-op, which just returns the + * {@code launcher} parameter as-is. * - * @param build - * The build in progress for which this {@link BuildWrapper} is called. Never null. - * @param launcher - * The default launcher. Never null. This method is expected to wrap this launcher. - * This makes sure that when multiple {@link BuildWrapper}s attempt to decorate the same launcher - * it will sort of work. But if you are developing a plugin where such collision is not a concern, - * you can also simply discard this {@link Launcher} and create an entirely different {@link Launcher} - * and return it, too. - * @param listener - * Connected to the build output. Never null. Can be used for error reporting. - * @return - * Must not be null. If a fatal error happens, throw an exception. - * @throws RunnerAbortedException - * If a fatal error is detected but the implementation handled it gracefully, throw this exception - * to suppress stack trace. + * @param build The build in progress for which this {@link BuildWrapper} is + * called. Never null. + * @param launcher The default launcher. Never null. This method is expected + * to wrap this launcher. This makes sure that when multiple + * {@link BuildWrapper}s attempt to decorate the same launcher it will sort + * of work. But if you are developing a plugin where such collision is not a + * concern, you can also simply discard this {@link Launcher} and create an + * entirely different {@link Launcher} and return it, too. + * @param listener Connected to the build output. Never null. Can be used + * for error reporting. + * @return Must not be null. If a fatal error happens, throw an exception. + * @throws RunnerAbortedException If a fatal error is detected but the + * implementation handled it gracefully, throw this exception to suppress + * stack trace. * @since 1.280 * @see LauncherDecorator */ @@ -169,25 +165,25 @@ public abstract class BuildWrapper extends AbstractDescribableImpl<BuildWrapper> } /** - * Provides an opportunity for a {@link BuildWrapper} to decorate the {@link BuildListener} logger to be used by the build. - * - * <p> - * This hook is called very early on in the build (even before {@link #setUp(AbstractBuild, Launcher, BuildListener)} is invoked.) - * - * <p> - * The default implementation is no-op, which just returns the {@code logger} parameter as-is. + * Provides an opportunity for a {@link BuildWrapper} to decorate the + * {@link BuildListener} logger to be used by the build. + * + * <p> This hook is called very early on in the build (even before + * {@link #setUp(AbstractBuild, Launcher, BuildListener)} is invoked.) * - * @param build - * The build in progress for which this {@link BuildWrapper} is called. Never null. - * @param logger - * The default logger. Never null. This method is expected to wrap this logger. - * This makes sure that when multiple {@link BuildWrapper}s attempt to decorate the same logger - * it will sort of work. - * @return - * Must not be null. If a fatal error happens, throw an exception. - * @throws RunnerAbortedException - * If a fatal error is detected but the implementation handled it gracefully, throw this exception - * to suppress stack trace. + * <p> The default implementation is no-op, which just returns the + * {@code logger} parameter as-is. + * + * @param build The build in progress for which this {@link BuildWrapper} is + * called. Never null. + * @param logger The default logger. Never null. This method is expected to + * wrap this logger. This makes sure that when multiple + * {@link BuildWrapper}s attempt to decorate the same logger it will sort of + * work. + * @return Must not be null. If a fatal error happens, throw an exception. + * @throws RunnerAbortedException If a fatal error is detected but the + * implementation handled it gracefully, throw this exception to suppress + * stack trace. * @since 1.374 */ public OutputStream decorateLogger(AbstractBuild build, OutputStream logger) throws IOException, InterruptedException, RunnerAbortedException { @@ -197,13 +193,11 @@ public abstract class BuildWrapper extends AbstractDescribableImpl<BuildWrapper> /** * {@link Action} to be displayed in the job page. * - * @param job - * This object owns the {@link BuildWrapper}. The returned action will be added to this object. - * @return - * null if there's no such action. + * @param job This object owns the {@link BuildWrapper}. The returned action + * will be added to this object. + * @return null if there's no such action. * @since 1.226 - * @deprecated - * Use {@link #getProjectActions(AbstractProject)} instead. + * @deprecated Use {@link #getProjectActions(AbstractProject)} instead. */ public Action getProjectAction(AbstractProject job) { return null; @@ -212,16 +206,17 @@ public abstract class BuildWrapper extends AbstractDescribableImpl<BuildWrapper> /** * {@link Action}s to be displayed in the job page. * - * @param job - * This object owns the {@link BuildWrapper}. The returned action will be added to this object. - * @return - * can be empty but never null + * @param job This object owns the {@link BuildWrapper}. The returned action + * will be added to this object. + * @return can be empty but never null * @since 1.341 */ public Collection<? extends Action> getProjectActions(AbstractProject job) { // delegate to getJobAction (singular) for backward compatible behavior Action a = getProjectAction(job); - if (a==null) return Collections.emptyList(); + if (a == null) { + return Collections.emptyList(); + } return Collections.singletonList(a); } @@ -230,15 +225,14 @@ public abstract class BuildWrapper extends AbstractDescribableImpl<BuildWrapper> * * This provides an opportunity for a BuildWrapper to append any additional * build variables defined for the current build. - * - * @param build - * The build in progress for which this {@link BuildWrapper} is called. Never null. - * @param variables - * Contains existing build variables. Add additional build variables that you contribute - * to this map. + * + * @param build The build in progress for which this {@link BuildWrapper} is + * called. Never null. + * @param variables Contains existing build variables. Add additional build + * variables that you contribute to this map. */ - public void makeBuildVariables(AbstractBuild build, Map<String,String> variables) { - // noop + public void makeBuildVariables(AbstractBuild build, Map<String, String> variables) { + // noop } /** @@ -246,23 +240,23 @@ public abstract class BuildWrapper extends AbstractDescribableImpl<BuildWrapper> * for a BuildWrapper to denote the names of variables that are sensitive in * nature and should not be exposed in output. * - * @param build - * The build in progress for which this {@link BuildWrapper} is called. Never null. - * @param sensitiveVariables - * Contains names of sensitive build variables. Names of sensitive variables - * that were added with {@link #makeBuildVariables(hudson.model.AbstractBuild, java.util.Map)} + * @param build The build in progress for which this {@link BuildWrapper} is + * called. Never null. + * @param sensitiveVariables Contains names of sensitive build variables. + * Names of sensitive variables that were added with + * {@link #makeBuildVariables(hudson.model.AbstractBuild, java.util.Map)} * @since 1.378 */ public void makeSensitiveBuildVariables(AbstractBuild build, Set<String> sensitiveVariables) { // noop } - + /** * Returns all the registered {@link BuildWrapper} descriptors. */ // for compatibility we can't use BuildWrapperDescriptor - public static DescriptorExtensionList<BuildWrapper,Descriptor<BuildWrapper>> all() { + public static DescriptorExtensionList<BuildWrapper, Descriptor<BuildWrapper>> all() { // use getDescriptorList and not getExtensionList to pick up legacy instances - return Hudson.getInstance().<BuildWrapper,Descriptor<BuildWrapper>>getDescriptorList(BuildWrapper.class); + return Hudson.getInstance().<BuildWrapper, Descriptor<BuildWrapper>>getDescriptorList(BuildWrapper.class); } } diff --git a/hudson-core/src/main/java/hudson/tasks/BuildWrapperDescriptor.java b/hudson-core/src/main/java/hudson/tasks/BuildWrapperDescriptor.java index f98496d..a147647 100644 --- a/hudson-core/src/main/java/hudson/tasks/BuildWrapperDescriptor.java +++ b/hudson-core/src/main/java/hudson/tasks/BuildWrapperDescriptor.java @@ -7,10 +7,10 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: -* -* Kohsuke Kawaguchi - * + * Contributors: + * + * Kohsuke Kawaguchi + * * *******************************************************************************/ @@ -28,14 +28,16 @@ import hudson.model.AbstractProject.AbstractProjectDescriptor; * @since 1.150 */ public abstract class BuildWrapperDescriptor extends Descriptor<BuildWrapper> { + protected BuildWrapperDescriptor(Class<? extends BuildWrapper> clazz) { super(clazz); } /** - * Infers the type of the corresponding {@link Describable} from the outer class. - * This version works when you follow the common convention, where a descriptor - * is written as the static nested class of the describable class. + * Infers the type of the corresponding {@link Describable} from the outer + * class. This version works when you follow the common convention, where a + * descriptor is written as the static nested class of the describable + * class. * * @since 1.278 */ @@ -45,10 +47,9 @@ public abstract class BuildWrapperDescriptor extends Descriptor<BuildWrapper> { /** * Returns true if this task is applicable to the given project. * - * @return - * true to allow user to configure this post-promotion task for the given project. - * @see AbstractProjectDescriptor#isApplicable(Descriptor) + * @return true to allow user to configure this post-promotion task for the + * given project. + * @see AbstractProjectDescriptor#isApplicable(Descriptor) */ - public abstract boolean isApplicable(AbstractProject<?,?> item); + public abstract boolean isApplicable(AbstractProject<?, ?> item); } - diff --git a/hudson-core/src/main/java/hudson/tasks/BuildWrappers.java b/hudson-core/src/main/java/hudson/tasks/BuildWrappers.java index 8008ce3..881f70a 100644 --- a/hudson-core/src/main/java/hudson/tasks/BuildWrappers.java +++ b/hudson-core/src/main/java/hudson/tasks/BuildWrappers.java @@ -7,10 +7,10 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: -* -* Kohsuke Kawaguchi - * + * Contributors: + * + * Kohsuke Kawaguchi + * * *******************************************************************************/ @@ -32,31 +32,34 @@ import java.util.List; * @author Kohsuke Kawaguchi */ public class BuildWrappers { + /** - * @deprecated - * as of 1.281. Use {@link Extension} for registration, and use {@link BuildWrapper#all()} - * for listing them. + * @deprecated as of 1.281. Use {@link Extension} for registration, and use + * {@link BuildWrapper#all()} for listing them. */ public static final List<Descriptor<BuildWrapper>> WRAPPERS = new DescriptorList<BuildWrapper>(BuildWrapper.class); /** - * List up all {@link BuildWrapperDescriptor}s that are applicable for the given project. + * List up all {@link BuildWrapperDescriptor}s that are applicable for the + * given project. * - * @return - * The signature doesn't use {@link BuildWrapperDescriptor} to maintain compatibility - * with {@link BuildWrapper} implementations before 1.150. + * @return The signature doesn't use {@link BuildWrapperDescriptor} to + * maintain compatibility with {@link BuildWrapper} implementations before + * 1.150. */ public static List<Descriptor<BuildWrapper>> getFor(AbstractProject<?, ?> project) { List<Descriptor<BuildWrapper>> result = new ArrayList<Descriptor<BuildWrapper>>(); - Descriptor pd = Hudson.getInstance().getDescriptor((Class)project.getClass()); + Descriptor pd = Hudson.getInstance().getDescriptor((Class) project.getClass()); for (Descriptor<BuildWrapper> w : BuildWrapper.all()) { - if (pd instanceof AbstractProjectDescriptor && !((AbstractProjectDescriptor)pd).isApplicable(w)) + if (pd instanceof AbstractProjectDescriptor && !((AbstractProjectDescriptor) pd).isApplicable(w)) { continue; + } if (w instanceof BuildWrapperDescriptor) { BuildWrapperDescriptor bwd = (BuildWrapperDescriptor) w; - if(bwd.isApplicable(project)) + if (bwd.isApplicable(project)) { result.add(bwd); + } } else { // old BuildWrapper that doesn't implement BuildWrapperDescriptor result.add(w); diff --git a/hudson-core/src/main/java/hudson/tasks/Builder.java b/hudson-core/src/main/java/hudson/tasks/Builder.java index 28c133d..b48ee0a 100644 --- a/hudson-core/src/main/java/hudson/tasks/Builder.java +++ b/hudson-core/src/main/java/hudson/tasks/Builder.java @@ -7,10 +7,10 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: -* + * Contributors: + * * Kohsuke Kawaguchi - * + * * *******************************************************************************/ @@ -25,18 +25,15 @@ import hudson.model.Describable; import hudson.model.Descriptor; import hudson.model.Hudson; - /** * {@link BuildStep}s that perform the actual build. * - * <p> - * To register a custom {@link Builder} from a plugin, - * put {@link Extension} on your descriptor. + * <p> To register a custom {@link Builder} from a plugin, put {@link Extension} + * on your descriptor. * * @author Kohsuke Kawaguchi */ public abstract class Builder extends BuildStepCompatibilityLayer implements BuildStep, Describable<Builder>, ExtensionPoint { - // // these two methods need to remain to keep binary compatibility with plugins built with Hudson < 1.150 @@ -49,8 +46,8 @@ public abstract class Builder extends BuildStepCompatibilityLayer implements Bui } /** - * Returns {@link BuildStepMonitor#NONE} by default, as {@link Builder}s normally don't depend - * on its previous result. + * Returns {@link BuildStepMonitor#NONE} by default, as {@link Builder}s + * normally don't depend on its previous result. */ public BuildStepMonitor getRequiredMonitorService() { return BuildStepMonitor.NONE; @@ -64,7 +61,7 @@ public abstract class Builder extends BuildStepCompatibilityLayer implements Bui * Returns all the registered {@link Builder} descriptors. */ // for backward compatibility, the signature is not BuildStepDescriptor - public static DescriptorExtensionList<Builder,Descriptor<Builder>> all() { - return Hudson.getInstance().<Builder,Descriptor<Builder>>getDescriptorList(Builder.class); + public static DescriptorExtensionList<Builder, Descriptor<Builder>> all() { + return Hudson.getInstance().<Builder, Descriptor<Builder>>getDescriptorList(Builder.class); } } diff --git a/hudson-core/src/main/java/hudson/tasks/CommandInterpreter.java b/hudson-core/src/main/java/hudson/tasks/CommandInterpreter.java index 9ce027b..537e4c2 100644 --- a/hudson-core/src/main/java/hudson/tasks/CommandInterpreter.java +++ b/hudson-core/src/main/java/hudson/tasks/CommandInterpreter.java @@ -7,10 +7,10 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: -* + * Contributors: + * * Kohsuke Kawaguchi, Tom Huybrechts, Nikita Levyankov - * + * * *******************************************************************************/ @@ -30,12 +30,14 @@ import org.apache.commons.lang3.StringUtils; /** * Common part between {@link Shell} and {@link BatchFile}. - * + * * @author Kohsuke Kawaguchi */ public abstract class CommandInterpreter extends Builder { + /** - * Command to execute. The format depends on the actual {@link CommandInterpreter} implementation. + * Command to execute. The format depends on the actual + * {@link CommandInterpreter} implementation. */ protected final String command; @@ -48,18 +50,18 @@ public abstract class CommandInterpreter extends Builder { } @Override - public boolean perform(AbstractBuild<?,?> build, Launcher launcher, BuildListener listener) throws InterruptedException { - return perform(build,launcher,(TaskListener)listener); + public boolean perform(AbstractBuild<?, ?> build, Launcher launcher, BuildListener listener) throws InterruptedException { + return perform(build, launcher, (TaskListener) listener); } - public boolean perform(AbstractBuild<?,?> build, Launcher launcher, TaskListener listener) throws InterruptedException { + public boolean perform(AbstractBuild<?, ?> build, Launcher launcher, TaskListener listener) throws InterruptedException { FilePath ws = build.getWorkspace(); - FilePath script=null; + FilePath script = null; try { try { script = createScriptFile(ws); } catch (IOException e) { - Util.displayIOException(e,listener); + Util.displayIOException(e, listener); e.printStackTrace(listener.fatalError(Messages.CommandInterpreter_UnableToProduceScript())); return false; } @@ -70,28 +72,29 @@ public abstract class CommandInterpreter extends Builder { // on Windows environment variables are converted to all upper case, // but no such conversions are done on Unix, so to make this cross-platform, // convert variables to all upper cases. - for(Map.Entry<String,String> e : build.getBuildVariables().entrySet()) - envVars.put(e.getKey(),e.getValue()); + for (Map.Entry<String, String> e : build.getBuildVariables().entrySet()) { + envVars.put(e.getKey(), e.getValue()); + } r = launcher.launch().cmds(buildCommandLine(script)).envs(envVars).stdout(listener).pwd(ws).join(); } catch (IOException e) { - Util.displayIOException(e,listener); + Util.displayIOException(e, listener); e.printStackTrace(listener.fatalError(Messages.CommandInterpreter_CommandFailed())); r = -1; } - return r==0; + return r == 0; } finally { try { - if(script!=null) - script.delete(); + if (script != null) { + script.delete(); + } } catch (IOException e) { - Util.displayIOException(e,listener); - e.printStackTrace( listener.fatalError(Messages.CommandInterpreter_UnableToDelete(script)) ); + Util.displayIOException(e, listener); + e.printStackTrace(listener.fatalError(Messages.CommandInterpreter_UnableToDelete(script))); } } } - @Override public boolean equals(Object o) { if (this == o) { diff --git a/hudson-core/src/main/java/hudson/tasks/Fingerprinter.java b/hudson-core/src/main/java/hudson/tasks/Fingerprinter.java index ee91001..e71b871 100644 --- a/hudson-core/src/main/java/hudson/tasks/Fingerprinter.java +++ b/hudson-core/src/main/java/hudson/tasks/Fingerprinter.java @@ -7,10 +7,10 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: + * Contributors: * * Kohsuke Kawaguchi - * + * * *******************************************************************************/ @@ -71,7 +71,6 @@ public class Fingerprinter extends Recorder implements Serializable { * Comma-separated list of files/directories to be fingerprinted. */ private final String targets; - /** * Also record all the finger prints of the build artifacts. */ @@ -92,25 +91,26 @@ public class Fingerprinter extends Recorder implements Serializable { } @Override - public boolean perform(AbstractBuild<?,?> build, Launcher launcher, BuildListener listener) throws InterruptedException { + public boolean perform(AbstractBuild<?, ?> build, Launcher launcher, BuildListener listener) throws InterruptedException { try { listener.getLogger().println(Messages.Fingerprinter_Recording()); - Map<String,String> record = new HashMap<String,String>(); + Map<String, String> record = new HashMap<String, String>(); - if(targets.length()!=0) + if (targets.length() != 0) { record(build, listener, record, targets); + } - if(recordBuildArtifacts) { + if (recordBuildArtifacts) { ArtifactArchiver aa = build.getProject().getPublishersList().get(ArtifactArchiver.class); - if(aa==null) { + if (aa == null) { // configuration error listener.error(Messages.Fingerprinter_NoArchiving()); build.setResult(Result.FAILURE); return true; } - record(build, listener, record, aa.getArtifacts() ); + record(build, listener, record, aa.getArtifacts()); } FingerprintAction.add(build, record); @@ -128,8 +128,9 @@ public class Fingerprinter extends Recorder implements Serializable { return BuildStepMonitor.NONE; } - private void record(AbstractBuild<?,?> build, BuildListener listener, Map<String,String> record, final String targets) throws IOException, InterruptedException { + private void record(AbstractBuild<?, ?> build, BuildListener listener, Map<String, String> record, final String targets) throws IOException, InterruptedException { final class Record implements Serializable { + final boolean produced; final String relativePath; final String fileName; @@ -144,16 +145,15 @@ public class Fingerprinter extends Recorder implements Serializable { Fingerprint addRecord(AbstractBuild build) throws IOException { FingerprintMap map = Hudson.getInstance().getFingerprintMap(); - return map.getOrCreate(produced?build:null, fileName, md5sum); + return map.getOrCreate(produced ? build : null, fileName, md5sum); } - private static final long serialVersionUID = 1L; } final long buildTimestamp = build.getTimeInMillis(); FilePath ws = build.getWorkspace(); - if(ws==null) { + if (ws == null) { listener.error(Messages.Fingerprinter_NoWorkspace()); build.setResult(Result.FAILURE); return; @@ -163,23 +163,23 @@ public class Fingerprinter extends Recorder implements Serializable { public List<Record> invoke(File baseDir, VirtualChannel channel) throws IOException { List<Record> results = new ArrayList<Record>(); - FileSet src = Util.createFileSet(baseDir,targets); + FileSet src = Util.createFileSet(baseDir, targets); DirectoryScanner ds = src.getDirectoryScanner(); - for( String f : ds.getIncludedFiles() ) { - File file = new File(baseDir,f); + for (String f : ds.getIncludedFiles()) { + File file = new File(baseDir, f); // consider the file to be produced by this build only if the timestamp // is newer than when the build has started. // 2000ms is an error margin since since VFAT only retains timestamp at 2sec precision - boolean produced = buildTimestamp <= file.lastModified()+2000; + boolean produced = buildTimestamp <= file.lastModified() + 2000; try { - results.add(new Record(produced,f,file.getName(),new FilePath(file).digest())); + results.add(new Record(produced, f, file.getName(), new FilePath(file).digest())); } catch (IOException e) { - throw new IOException2(Messages.Fingerprinter_DigestFailed(file),e); + throw new IOException2(Messages.Fingerprinter_DigestFailed(file), e); } catch (InterruptedException e) { - throw new IOException2(Messages.Fingerprinter_Aborted(),e); + throw new IOException2(Messages.Fingerprinter_Aborted(), e); } } @@ -189,17 +189,18 @@ public class Fingerprinter extends Recorder implements Serializable { for (Record r : records) { Fingerprint fp = r.addRecord(build); - if(fp==null) { + if (fp == null) { listener.error(Messages.Fingerprinter_FailedFor(r.relativePath)); continue; } fp.add(build); - record.put(r.relativePath,fp.getHashString()); + record.put(r.relativePath, fp.getHashString()); } } @Extension public static class DescriptorImpl extends BuildStepDescriptor<Publisher> { + public String getDisplayName() { return Messages.Fingerprinter_DisplayName(); } @@ -213,7 +214,7 @@ public class Fingerprinter extends Recorder implements Serializable { * Performs on-the-fly validation on the file mask wildcard. */ public FormValidation doCheck(@AncestorInPath AbstractProject project, @QueryParameter String value) throws IOException { - return FilePath.validateFileMask(project.getSomeWorkspace(),value); + return FilePath.validateFileMask(project.getSomeWorkspace(), value); } @Override @@ -228,19 +229,20 @@ public class Fingerprinter extends Recorder implements Serializable { /** * Action for displaying fingerprints. - * - * To ensure there is only one per build use {@link FingerprintAction#add(AbstractBuild, Map)}. - * This allows for additional fingerprint contributions outside of the {@link Fingerprinter}. + * + * To ensure there is only one per build use + * {@link FingerprintAction#add(AbstractBuild, Map)}. This allows for + * additional fingerprint contributions outside of the + * {@link Fingerprinter}. */ public static final class FingerprintAction implements RunAction { - private final AbstractBuild build; + private final AbstractBuild build; /** * From file name to the digest. */ - private /*almost final*/ Map<String,String> record; - - private transient WeakReference<Map<String,Fingerprint>> ref; + private /*almost final*/ Map<String, String> record; + private transient WeakReference<Map<String, Fingerprint>> ref; public FingerprintAction(AbstractBuild build, Map<String, String> record) { this.build = checkNotNull(build); @@ -248,21 +250,22 @@ public class Fingerprinter extends Recorder implements Serializable { } /** - * Add fingerprint records to this Action. Assumes the records came from the same build that initially - * created the {@link FingerprintAction}. + * Add fingerprint records to this Action. Assumes the records came from + * the same build that initially created the {@link FingerprintAction}. */ - public void add(Map<String,String> moreRecords) { - Map<String,String> r = new HashMap<String, String>(record); + public void add(Map<String, String> moreRecords) { + Map<String, String> r = new HashMap<String, String>(record); r.putAll(moreRecords); record = PackedMap.of(checkNotNull(r)); ref = null; } /** - * Adds the record to a {@link FingerprintAction} corresponding to the build. + * Adds the record to a {@link FingerprintAction} corresponding to the + * build. * - * Safely consolidates multiple sources of records (e.g. from different post build actions) into a single - * {@link FingerprintAction}. + * Safely consolidates multiple sources of records (e.g. from different + * post build actions) into a single {@link FingerprintAction}. * * @param build to add the FingerprintAction and records to * @param record to add @@ -274,10 +277,10 @@ public class Fingerprinter extends Recorder implements Serializable { checkNotNull(record); FingerprintAction action = build.getAction(FingerprintAction.class); - if(action != null) { + if (action != null) { action.add(record); } else { - build.addAction(new FingerprintAction(build,record)); + build.addAction(new FingerprintAction(build, record)); } } @@ -300,16 +303,17 @@ public class Fingerprinter extends Recorder implements Serializable { /** * Obtains the raw data. */ - public Map<String,String> getRecords() { + public Map<String, String> getRecords() { return record; } public void onLoad() { Run pb = build.getPreviousBuild(); - if (pb!=null) { + if (pb != null) { FingerprintAction a = pb.getAction(FingerprintAction.class); - if (a!=null) + if (a != null) { compact(a); + } } } @@ -321,84 +325,97 @@ public class Fingerprinter extends Recorder implements Serializable { } /** - * Reuse string instances from another {@link FingerprintAction} to reduce memory footprint. + * Reuse string instances from another {@link FingerprintAction} to + * reduce memory footprint. */ protected void compact(FingerprintAction a) { - Map<String,String> intern = new HashMap<String, String>(); // string intern map + Map<String, String> intern = new HashMap<String, String>(); // string intern map for (Entry<String, String> e : a.record.entrySet()) { - intern.put(e.getKey(),e.getKey()); - intern.put(e.getValue(),e.getValue()); + intern.put(e.getKey(), e.getKey()); + intern.put(e.getValue(), e.getValue()); } - Map<String,String> b = new HashMap<String, String>(); - for (Entry<String,String> e : record.entrySet()) { + Map<String, String> b = new HashMap<String, String>(); + for (Entry<String, String> e : record.entrySet()) { String k = intern.get(e.getKey()); - if (k==null) k = e.getKey(); + if (k == null) { + k = e.getKey(); + } String v = intern.get(e.getValue()); - if (v==null) v = e.getValue(); + if (v == null) { + v = e.getValue(); + } - b.put(k,v); + b.put(k, v); } record = PackedMap.of(b); } /** - * Map from file names of the fingerprinted file to its fingerprint record. + * Map from file names of the fingerprinted file to its fingerprint + * record. */ - public synchronized Map<String,Fingerprint> getFingerprints() { - if(ref!=null) { - Map<String,Fingerprint> m = ref.get(); - if(m!=null) + public synchronized Map<String, Fingerprint> getFingerprints() { + if (ref != null) { + Map<String, Fingerprint> m = ref.get(); + if (m != null) { return m; + } } Hudson h = Hudson.getInstance(); - Map<String,Fingerprint> m = new TreeMap<String,Fingerprint>(); + Map<String, Fingerprint> m = new TreeMap<String, Fingerprint>(); for (Entry<String, String> r : record.entrySet()) { try { Fingerprint fp = h._getFingerprint(r.getValue()); - if(fp!=null) + if (fp != null) { m.put(r.getKey(), fp); + } } catch (IOException e) { - logger.log(Level.WARNING,e.getMessage(),e); + logger.log(Level.WARNING, e.getMessage(), e); } } m = ImmutableMap.copyOf(m); - ref = new WeakReference<Map<String,Fingerprint>>(m); + ref = new WeakReference<Map<String, Fingerprint>>(m); return m; } /** - * Gets the dependency to other builds in a map. - * Returns build numbers instead of {@link Build}, since log records may be gone. + * Gets the dependency to other builds in a map. Returns build numbers + * instead of {@link Build}, since log records may be gone. */ - public Map<AbstractProject,Integer> getDependencies() { - Map<AbstractProject,Integer> r = new HashMap<AbstractProject,Integer>(); + public Map<AbstractProject, Integer> getDependencies() { + Map<AbstractProject, Integer> r = new HashMap<AbstractProject, Integer>(); for (Fingerprint fp : getFingerprints().values()) { BuildPtr bp = fp.getOriginal(); - if(bp==null) continue; // outside Hudson - if(bp.is(build)) continue; // we are the owner + if (bp == null) { + continue; // outside Hudson + } + if (bp.is(build)) { + continue; // we are the owner + } AbstractProject job = bp.getJob(); - if (job==null) continue; // no longer exists - if (job.getParent()==build.getParent()) + if (job == null) { + continue; // no longer exists + } + if (job.getParent() == build.getParent()) { continue; // we are the parent of the build owner, that is almost like we are the owner - + } Integer existing = r.get(job); - if(existing!=null && existing>bp.getNumber()) + if (existing != null && existing > bp.getNumber()) { continue; // the record in the map is already up to date - r.put(job,bp.getNumber()); + } + r.put(job, bp.getNumber()); } - + return r; } } - private static final Logger logger = Logger.getLogger(Fingerprinter.class.getName()); - private static final long serialVersionUID = 1L; } diff --git a/hudson-core/src/main/java/hudson/tasks/HudsonMimeMessage.java b/hudson-core/src/main/java/hudson/tasks/HudsonMimeMessage.java index 6195652..20e0603 100644 --- a/hudson-core/src/main/java/hudson/tasks/HudsonMimeMessage.java +++ b/hudson-core/src/main/java/hudson/tasks/HudsonMimeMessage.java @@ -6,13 +6,15 @@ import javax.mail.Session; import javax.mail.internet.MimeMessage; /** - * Class extends MimeMessage from javax.mail, because parent doesn't provide with appropriate getters. + * Class extends MimeMessage from javax.mail, because parent doesn't provide + * with appropriate getters. * <p/> * Date: 7/25/11 * * @author Nikita Levyankov */ public class HudsonMimeMessage extends MimeMessage { + public HudsonMimeMessage(Session session) { super(session); } @@ -23,6 +25,7 @@ public class HudsonMimeMessage extends MimeMessage { /** * Returns {@link Session} instance + * * @return session. */ public Session getSession() { diff --git a/hudson-core/src/main/java/hudson/tasks/JavadocArchiver.java b/hudson-core/src/main/java/hudson/tasks/JavadocArchiver.java index f985755..3d3f1a7 100644 --- a/hudson-core/src/main/java/hudson/tasks/JavadocArchiver.java +++ b/hudson-core/src/main/java/hudson/tasks/JavadocArchiver.java @@ -7,10 +7,10 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: -* -* Kohsuke Kawaguchi, Martin Eigenbrodt, Peter Hayes - * + * Contributors: + * + * Kohsuke Kawaguchi, Martin Eigenbrodt, Peter Hayes + * * *******************************************************************************/ @@ -37,11 +37,12 @@ import java.util.Collection; import java.util.Collections; /** - * Saves Javadoc for the project and publish them. + * Saves Javadoc for the project and publish them. * * @author Kohsuke Kawaguchi */ public class JavadocArchiver extends Recorder { + /** * Path to the Javadoc directory in the workspace. */ @@ -50,7 +51,7 @@ public class JavadocArchiver extends Recorder { * If true, retain javadoc for all the successful builds. */ private final boolean keepAll; - + @DataBoundConstructor public JavadocArchiver(String javadoc_dir, boolean keep_all) { this.javadocDir = javadoc_dir; @@ -78,45 +79,46 @@ public class JavadocArchiver extends Recorder { * Gets the directory where the Javadoc is stored for the given project. */ private static File getJavadocDir(AbstractItem project) { - return new File(project.getRootDir(),"javadoc"); + return new File(project.getRootDir(), "javadoc"); } /** * Gets the directory where the Javadoc is stored for the given build. */ private static File getJavadocDir(Run run) { - return new File(run.getRootDir(),"javadoc"); + return new File(run.getRootDir(), "javadoc"); } - public boolean perform(AbstractBuild<?,?> build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException { + public boolean perform(AbstractBuild<?, ?> build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException { listener.getLogger().println(Messages.JavadocArchiver_Publishing()); EnvVars env = build.getEnvironment(listener); - + FilePath javadoc = build.getWorkspace().child(env.expand(javadocDir)); FilePath target = new FilePath(keepAll ? getJavadocDir(build) : getJavadocDir(build.getProject())); try { - if (javadoc.copyRecursiveTo("**/*",target)==0) { - if(build.getResult().isBetterOrEqualTo(Result.UNSTABLE)) { + if (javadoc.copyRecursiveTo("**/*", target) == 0) { + if (build.getResult().isBetterOrEqualTo(Result.UNSTABLE)) { // If the build failed, don't complain that there was no javadoc. // The build probably didn't even get to the point where it produces javadoc. - listener.error(Messages.JavadocArchiver_NoMatchFound(javadoc,javadoc.validateAntFileMask("**/*"))); + listener.error(Messages.JavadocArchiver_NoMatchFound(javadoc, javadoc.validateAntFileMask("**/*"))); } build.setResult(Result.FAILURE); return true; } } catch (IOException e) { - Util.displayIOException(e,listener); - e.printStackTrace(listener.fatalError(Messages.JavadocArchiver_UnableToCopy(javadoc,target))); + Util.displayIOException(e, listener); + e.printStackTrace(listener.fatalError(Messages.JavadocArchiver_UnableToCopy(javadoc, target))); build.setResult(Result.FAILURE); - return true; + return true; } - + // add build action, if javadoc is recorded for each build - if(keepAll) + if (keepAll) { build.addAction(new JavadocBuildAction(build)); - + } + return true; } @@ -128,32 +130,35 @@ public class JavadocArchiver extends Recorder { public BuildStepMonitor getRequiredMonitorService() { return BuildStepMonitor.NONE; } - + protected static abstract class BaseJavadocAction implements Action { + public String getUrlName() { return "javadoc"; } public String getDisplayName() { - if (new File(dir(), "help-doc.html").exists()) + if (new File(dir(), "help-doc.html").exists()) { return Messages.JavadocArchiver_DisplayName_Javadoc(); - else + } else { return Messages.JavadocArchiver_DisplayName_Generic(); + } } public String getIconFileName() { - if(dir().exists()) + if (dir().exists()) { return "help.png"; - else - // hide it since we don't have javadoc yet. + } else // hide it since we don't have javadoc yet. + { return null; + } } /** * Serves javadoc. */ public void doDynamic(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { - new DirectoryBrowserSupport(this, new FilePath(dir()), getTitle(), "help.png", false).generateResponse(req,rsp,this); + new DirectoryBrowserSupport(this, new FilePath(dir()), getTitle(), "help.png", false).generateResponse(req, rsp, this); } protected abstract String getTitle(); @@ -162,6 +167,7 @@ public class JavadocArchiver extends Recorder { } public static class JavadocAction extends BaseJavadocAction implements ProminentProjectAction { + private final AbstractItem project; public JavadocAction(AbstractItem project) { @@ -178,8 +184,9 @@ public class JavadocArchiver extends Recorder { if (run != null) { File javadocDir = getJavadocDir(run); - if (javadocDir.exists()) + if (javadocDir.exists()) { return javadocDir; + } } } @@ -187,19 +194,20 @@ public class JavadocArchiver extends Recorder { } protected String getTitle() { - return project.getDisplayName()+" javadoc"; + return project.getDisplayName() + " javadoc"; } } - + public static class JavadocBuildAction extends BaseJavadocAction { - private final AbstractBuild<?,?> build; - - public JavadocBuildAction(AbstractBuild<?,?> build) { - this.build = build; - } + + private final AbstractBuild<?, ?> build; + + public JavadocBuildAction(AbstractBuild<?, ?> build) { + this.build = build; + } protected String getTitle() { - return build.getDisplayName()+" javadoc"; + return build.getDisplayName() + " javadoc"; } protected File dir() { @@ -209,6 +217,7 @@ public class JavadocArchiver extends Recorder { @Extension public static class DescriptorImpl extends BuildStepDescriptor<Publisher> { + public String getDisplayName() { return Messages.JavadocArchiver_DisplayName(); } diff --git a/hudson-core/src/main/java/hudson/tasks/LogRotator.java b/hudson-core/src/main/java/hudson/tasks/LogRotator.java index efcac5d..75ecff5 100644 --- a/hudson-core/src/main/java/hudson/tasks/LogRotator.java +++ b/hudson-core/src/main/java/hudson/tasks/LogRotator.java @@ -7,10 +7,10 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: -* -* Kohsuke Kawaguchi, Martin Eigenbrodt - * + * Contributors: + * + * Kohsuke Kawaguchi, Martin Eigenbrodt + * * *******************************************************************************/ @@ -34,47 +34,47 @@ import static java.util.logging.Level.FINER; /** * Deletes old log files. * - * TODO: is there any other task that follows the same pattern? - * try to generalize this just like {@link SCM} or {@link BuildStep}. + * TODO: is there any other task that follows the same pattern? try to + * generalize this just like {@link SCM} or {@link BuildStep}. * * @author Kohsuke Kawaguchi */ public class LogRotator implements Describable<LogRotator> { private static final Logger LOGGER = Logger.getLogger(LogRotator.class.getName()); - /** * If not -1, history is only kept up to this days. */ private final int daysToKeep; - /** * If not -1, only this number of build logs are kept. */ private final int numToKeep; - /** - * If not -1 nor null, artifacts are only kept up to this days. - * Null handling is necessary to remain data compatible with old versions. + * If not -1 nor null, artifacts are only kept up to this days. Null + * handling is necessary to remain data compatible with old versions. + * * @since 1.350 */ private final Integer artifactDaysToKeep; - /** * If not -1 nor null, only this number of builds have their artifacts kept. * Null handling is necessary to remain data compatible with old versions. + * * @since 1.350 */ private final Integer artifactNumToKeep; @DataBoundConstructor - public LogRotator (String logrotate_days, String logrotate_nums, String logrotate_artifact_days, String logrotate_artifact_nums) { - this (parse(logrotate_days),parse(logrotate_nums), - parse(logrotate_artifact_days),parse(logrotate_artifact_nums)); + public LogRotator(String logrotate_days, String logrotate_nums, String logrotate_artifact_days, String logrotate_artifact_nums) { + this(parse(logrotate_days), parse(logrotate_nums), + parse(logrotate_artifact_days), parse(logrotate_artifact_nums)); } public static int parse(String p) { - if(p==null) return -1; + if (p == null) { + return -1; + } try { return Integer.parseInt(p); } catch (NumberFormatException e) { @@ -83,8 +83,7 @@ public class LogRotator implements Describable<LogRotator> { } /** - * @deprecated since 1.350. - * Use {@link #LogRotator(int, int, int, int)} + * @deprecated since 1.350. Use {@link #LogRotator(int, int, int, int)} */ public LogRotator(int daysToKeep, int numToKeep) { this(daysToKeep, numToKeep, -1, -1); @@ -146,7 +145,7 @@ public class LogRotator implements Describable<LogRotator> { * @throws IOException if configured */ private void deleteBuilds(List<? extends Run<?, ?>> builds, Run lastSuccessBuild, Run lastStableBuild, Calendar cal) - throws IOException { + throws IOException { for (Run currentBuild : builds) { if (allowDeleteBuild(lastSuccessBuild, lastStableBuild, currentBuild, cal)) { LOGGER.log(FINER, currentBuild.getFullDisplayName() + " is to be removed"); @@ -156,9 +155,10 @@ public class LogRotator implements Describable<LogRotator> { } /** - * Checks whether current build could be deleted. - * If current build equals to last Success Build or last Stable Build or currentBuild is configured to keep logs or - * currentBuild timestamp is before configured calendar value - return false, otherwise return true. + * Checks whether current build could be deleted. If current build equals to + * last Success Build or last Stable Build or currentBuild is configured to + * keep logs or currentBuild timestamp is before configured calendar value - + * return false, otherwise return true. * * @param lastSuccessBuild {@link Run} * @param lastStableBuild {@link Run} @@ -173,7 +173,7 @@ public class LogRotator implements Describable<LogRotator> { } if (currentBuild == lastSuccessBuild) { LOGGER.log(FINER, - currentBuild.getFullDisplayName() + " is not GC-ed because it's the last successful build"); + currentBuild.getFullDisplayName() + " is not GC-ed because it's the last successful build"); return false; } if (currentBuild == lastStableBuild) { @@ -197,7 +197,7 @@ public class LogRotator implements Describable<LogRotator> { * @throws IOException if configured */ private void deleteBuildArtifacts(List<? extends Run<?, ?>> builds, Run lastSuccessBuild, Run lastStableBuild, - Calendar cal) throws IOException { + Calendar cal) throws IOException { for (Run currentBuild : builds) { if (allowDeleteArtifact(lastSuccessBuild, lastStableBuild, currentBuild, cal)) { currentBuild.deleteArtifacts(); @@ -206,9 +206,10 @@ public class LogRotator implements Describable<LogRotator> { } /** - * Checks whether artifacts from build could be deleted. - * If current build equals to last Success Build or last Stable Build or currentBuild is configured to keep logs or - * currentBuild timestamp is before configured calendar value - return false, otherwise return true. + * Checks whether artifacts from build could be deleted. If current build + * equals to last Success Build or last Stable Build or currentBuild is + * configured to keep logs or currentBuild timestamp is before configured + * calendar value - return false, otherwise return true. * * @param lastSuccessBuild {@link Run} * @param lastStableBuild {@link Run} @@ -219,17 +220,17 @@ public class LogRotator implements Describable<LogRotator> { private boolean allowDeleteArtifact(Run lastSuccessBuild, Run lastStableBuild, Run currentBuild, Calendar cal) { if (currentBuild.isKeepLog()) { LOGGER.log(FINER, - currentBuild.getFullDisplayName() + " is not purged of artifacts because it's marked as a keeper"); + currentBuild.getFullDisplayName() + " is not purged of artifacts because it's marked as a keeper"); return false; } if (currentBuild == lastSuccessBuild) { LOGGER.log(FINER, currentBuild.getFullDisplayName() - + " is not purged of artifacts because it's the last successful build"); + + " is not purged of artifacts because it's the last successful build"); return false; } if (currentBuild == lastStableBuild) { LOGGER.log(FINER, - currentBuild.getFullDisplayName() + " is not purged of artifacts because it's the last stable build"); + currentBuild.getFullDisplayName() + " is not purged of artifacts because it's the last stable build"); return false; } if (null != cal && !currentBuild.getTimestamp().before(cal)) { @@ -272,22 +273,23 @@ public class LogRotator implements Describable<LogRotator> { } private int unbox(Integer i) { - return i==null ? -1: i; + return i == null ? -1 : i; } private String toString(Integer i) { - if (i==null || i==-1) return ""; + if (i == null || i == -1) { + return ""; + } return String.valueOf(i); } - public LRDescriptor getDescriptor() { return DESCRIPTOR; } - public static final LRDescriptor DESCRIPTOR = new LRDescriptor(); public static final class LRDescriptor extends Descriptor<LogRotator> { + public String getDisplayName() { return "Log Rotation"; } @@ -311,11 +313,11 @@ public class LogRotator implements Describable<LogRotator> { return false; } if (artifactDaysToKeep != null ? !artifactDaysToKeep.equals(that.artifactDaysToKeep) - : that.artifactDaysToKeep != null) { + : that.artifactDaysToKeep != null) { return false; } if (artifactNumToKeep != null ? !artifactNumToKeep.equals(that.artifactNumToKeep) - : that.artifactNumToKeep != null) { + : that.artifactNumToKeep != null) { return false; } diff --git a/hudson-core/src/main/java/hudson/tasks/MailAddressResolver.java b/hudson-core/src/main/java/hudson/tasks/MailAddressResolver.java index 9701061..1792e09 100644 --- a/hudson-core/src/main/java/hudson/tasks/MailAddressResolver.java +++ b/hudson-core/src/main/java/hudson/tasks/MailAddressResolver.java @@ -7,10 +7,10 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: -* -* Kohsuke Kawaguchi, Luca Domenico Milanesio - * + * Contributors: + * + * Kohsuke Kawaguchi, Luca Domenico Milanesio + * * *******************************************************************************/ @@ -33,9 +33,9 @@ import java.util.regex.Pattern; /** * Infers e-mail addresses for the user when none is specified. * - * <p> - * This is an extension point of Hudson. Plugins tha contribute new implementation - * of this class should put {@link Extension} on your implementation class, like this: + * <p> This is an extension point of Hudson. Plugins tha contribute new + * implementation of this class should put {@link Extension} on your + * implementation class, like this: * * <pre> * @Extension @@ -44,76 +44,77 @@ import java.util.regex.Pattern; * } * </pre> * - * <h2>Techniques</h2> - * <p> - * User identity in Hudson is global, and not specific to a particular job. As a result, mail address resolution - * only receives {@link User}, which by itself doesn't really have that much information in it. + * <h2>Techniques</h2> <p> User identity in Hudson is global, and not specific + * to a particular job. As a result, mail address resolution only receives + * {@link User}, which by itself doesn't really have that much information in + * it. * - * <p> - * So the common technique for a mail address resolution is to define your own {@link UserProperty} types and - * add it to {@link User} objects where more context is available. For example, an {@link SCM} implementation - * can have a lot more information about a particular user during a check out, so that would be a good place - * to capture information as {@link UserProperty}, which then later used by a {@link MailAddressResolver}. + * <p> So the common technique for a mail address resolution is to define your + * own {@link UserProperty} types and add it to {@link User} objects where more + * context is available. For example, an {@link SCM} implementation can have a + * lot more information about a particular user during a check out, so that + * would be a good place to capture information as {@link UserProperty}, which + * then later used by a {@link MailAddressResolver}. * * @author Kohsuke Kawaguchi * @since 1.192 */ public abstract class MailAddressResolver implements ExtensionPoint { + /** * Infers e-mail address of the given user. * - * <p> - * This method is called when a {@link User} without explicitly configured e-mail - * address is used, as an attempt to infer e-mail address. + * <p> This method is called when a {@link User} without explicitly + * configured e-mail address is used, as an attempt to infer e-mail address. * - * <p> - * The normal strategy is to look at {@link User#getProjects() the projects that the user - * is participating}, then use the repository information to infer the e-mail address. + * <p> The normal strategy is to look at {@link User#getProjects() the projects that the user + * is participating}, then use the repository information to infer the + * e-mail address. * - * <p> - * When multiple resolvers are installed, they are consulted in order and - * the search will be over when an address is inferred by someone. + * <p> When multiple resolvers are installed, they are consulted in order + * and the search will be over when an address is inferred by someone. * - * <p> - * Since {@link MailAddressResolver} is singleton, this method can be invoked concurrently - * from multiple threads. + * <p> Since {@link MailAddressResolver} is singleton, this method can be + * invoked concurrently from multiple threads. * - * @return - * null if the inference failed. + * @return null if the inference failed. */ public abstract String findMailAddressFor(User u); - + public static String resolve(User u) { - LOGGER.fine("Resolving e-mail address for \""+u+"\" ID="+u.getId()); + LOGGER.fine("Resolving e-mail address for \"" + u + "\" ID=" + u.getId()); for (MailAddressResolver r : all()) { String email = r.findMailAddressFor(u); - if(email!=null) { - LOGGER.fine(r+" resolved "+u.getId()+" to "+email); + if (email != null) { + LOGGER.fine(r + " resolved " + u.getId() + " to " + email); return email; } } // fall back logic String extractedAddress = extractAddressFromId(u.getFullName()); - if (extractedAddress != null) + if (extractedAddress != null) { return extractedAddress; + } - if(u.getFullName().contains("@")) - // this already looks like an e-mail ID + if (u.getFullName().contains("@")) // this already looks like an e-mail ID + { return u.getFullName(); + } String ds = Mailer.descriptor().getDefaultSuffix(); - if(ds!=null) { + if (ds != null) { // another common pattern is "DOMAIN\person" in Windows. Only // do this when this full name is not manually set. see HUDSON-5164 Matcher m = WINDOWS_DOMAIN_REGEXP.matcher(u.getFullName()); - if (m.matches() && u.getFullName().replace('\\','_').equals(u.getId())) - return m.group(1)+ds; // user+defaultSuffix - - return u.getId()+ds; - } else + if (m.matches() && u.getFullName().replace('\\', '_').equals(u.getId())) { + return m.group(1) + ds; // user+defaultSuffix + } + return u.getId() + ds; + } else { return null; + } } /** @@ -121,27 +122,25 @@ public abstract class MailAddressResolver implements ExtensionPoint { */ private static String extractAddressFromId(String id) { Matcher m = EMAIL_ADDRESS_REGEXP.matcher(id); - if(m.matches()) - return m.group(1); - return null; + if (m.matches()) { + return m.group(1); + } + return null; } - /** * Matches strings like "Kohsuke Kawaguchi <kohsuke.kawaguchi@sun.com>" * @see #extractAddressFromId(String) */ private static final Pattern EMAIL_ADDRESS_REGEXP = Pattern.compile("^.*<([^>]+)>.*$"); - /** * Matches something like "DOMAIN\person" */ private static final Pattern WINDOWS_DOMAIN_REGEXP = Pattern.compile("[^\\\\ ]+\\\\([^\\\\ ]+)"); - /** * All registered {@link MailAddressResolver} implementations. * - * @deprecated as of 1.286 - * Use {@link #all()} for read access and {@link Extension} for registration. + * @deprecated as of 1.286 Use {@link #all()} for read access and + * {@link Extension} for registration. */ public static final List<MailAddressResolver> LIST = ExtensionListView.createList(MailAddressResolver.class); @@ -151,6 +150,5 @@ public abstract class MailAddressResolver implements ExtensionPoint { public static ExtensionList<MailAddressResolver> all() { return Hudson.getInstance().getExtensionList(MailAddressResolver.class); } - private static final Logger LOGGER = Logger.getLogger(MailAddressResolver.class.getName()); } diff --git a/hudson-core/src/main/java/hudson/tasks/MailMessageIdAction.java b/hudson-core/src/main/java/hudson/tasks/MailMessageIdAction.java index b21e164..1c590c7 100644 --- a/hudson-core/src/main/java/hudson/tasks/MailMessageIdAction.java +++ b/hudson-core/src/main/java/hudson/tasks/MailMessageIdAction.java @@ -7,10 +7,10 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: -* -* Kohsuke Kawaguchi - * + * Contributors: + * + * Kohsuke Kawaguchi + * * *******************************************************************************/ @@ -21,12 +21,12 @@ import hudson.model.Action; /** * Remembers the message ID of the e-mail that was sent for the build. * - * <p> - * This allows us to send further updates as replies. + * <p> This allows us to send further updates as replies. * * @author Kohsuke Kawaguchi */ public class MailMessageIdAction implements Action { + /** * Message ID of the e-mail sent for the build. */ diff --git a/hudson-core/src/main/java/hudson/tasks/MailSender.java b/hudson-core/src/main/java/hudson/tasks/MailSender.java index 3458df1..c7c00a1 100644 --- a/hudson-core/src/main/java/hudson/tasks/MailSender.java +++ b/hudson-core/src/main/java/hudson/tasks/MailSender.java @@ -7,10 +7,10 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: + * Contributors: * * Kohsuke Kawaguchi, Bruce Chapman, Daniel Dyer, Jean-Baptiste Quenot, Anton Kozak - * + * * *******************************************************************************/ @@ -42,30 +42,27 @@ import javax.mail.internet.MimeMessage; public class MailSender extends BaseMailSender { private List<AbstractProject> upstreamProjects = new ArrayList<AbstractProject>(); - /** * If true, only the first unstable build will be reported. */ private boolean dontNotifyEveryUnstableBuild; - /** * If true, individuals will receive e-mails regarding who broke the build. */ private boolean sendToIndividuals; - public MailSender(String recipients, boolean dontNotifyEveryUnstableBuild, boolean sendToIndividuals) { - this(recipients, dontNotifyEveryUnstableBuild, sendToIndividuals, DEFAULT_CHARSET); + this(recipients, dontNotifyEveryUnstableBuild, sendToIndividuals, DEFAULT_CHARSET); } public MailSender(String recipients, boolean dontNotifyEveryUnstableBuild, boolean sendToIndividuals, - String charset) { + String charset) { this(recipients, dontNotifyEveryUnstableBuild, sendToIndividuals, charset, - Collections.<AbstractProject>emptyList()); + Collections.<AbstractProject>emptyList()); } public MailSender(String recipients, boolean dontNotifyEveryUnstableBuild, boolean sendToIndividuals, - String charset, Collection<AbstractProject> includeUpstreamCommitters) { + String charset, Collection<AbstractProject> includeUpstreamCommitters) { super(recipients, charset); this.dontNotifyEveryUnstableBuild = dontNotifyEveryUnstableBuild; this.sendToIndividuals = sendToIndividuals; @@ -79,7 +76,7 @@ public class MailSender extends BaseMailSender { // if the previous e-mail was sent for a success, this new e-mail // is not a follow up AbstractBuild<?, ?> pb = build.getPreviousBuild(); - if(pb!=null && pb.getResult()==Result.SUCCESS) { + if (pb != null && pb.getResult() == Result.SUCCESS) { mail.removeHeader("In-Reply-To"); mail.removeHeader("References"); } @@ -87,8 +84,9 @@ public class MailSender extends BaseMailSender { Address[] allRecipients = mail.getAllRecipients(); if (allRecipients != null) { StringBuilder buf = new StringBuilder("Sending e-mails to:"); - for (Address a : allRecipients) + for (Address a : allRecipients) { buf.append(' ').append(a); + } listener.getLogger().println(buf); Mailer.descriptor().send((HudsonMimeMessage) mail); @@ -107,47 +105,52 @@ public class MailSender extends BaseMailSender { } /** - * To correctly compute the state change from the previous build to this build, - * we need to ignore aborted builds. - * See http://www.nabble.com/Losing-build-state-after-aborts--td24335949.html + * To correctly compute the state change from the previous build to this + * build, we need to ignore aborted builds. See + * http://www.nabble.com/Losing-build-state-after-aborts--td24335949.html * - * <p> - * And since we are consulting the earlier result, we need to wait for the previous build - * to pass the check point. + * <p> And since we are consulting the earlier result, we need to wait for + * the previous build to pass the check point. */ - private Result findPreviousBuildResult(AbstractBuild<?,?> b) throws InterruptedException { + private Result findPreviousBuildResult(AbstractBuild<?, ?> b) throws InterruptedException { CHECKPOINT.block(); do { - b=b.getPreviousBuild(); - if(b==null) return null; - } while(b.getResult()==Result.ABORTED); + b = b.getPreviousBuild(); + if (b == null) { + return null; + } + } while (b.getResult() == Result.ABORTED); return b.getResult(); } protected MimeMessage getMail(AbstractBuild<?, ?> build, BuildListener listener) throws MessagingException, InterruptedException { if (build.getResult() == Result.FAILURE) { return new FailureBuildMail(getRecipients(), sendToIndividuals, upstreamProjects, getCharset()). - getMail(build, listener); + getMail(build, listener); } if (build.getResult() == Result.UNSTABLE) { - if (!dontNotifyEveryUnstableBuild) + if (!dontNotifyEveryUnstableBuild) { return new UnstableBuildMail(getRecipients(), sendToIndividuals, upstreamProjects, getCharset()). - getMail(build, listener); + getMail(build, listener); + } Result prev = findPreviousBuildResult(build); - if (prev == Result.SUCCESS) + if (prev == Result.SUCCESS) { return new UnstableBuildMail(getRecipients(), sendToIndividuals, upstreamProjects, getCharset()). - getMail(build, listener); + getMail(build, listener); + } } if (build.getResult() == Result.SUCCESS) { Result prev = findPreviousBuildResult(build); - if (prev == Result.FAILURE) + if (prev == Result.FAILURE) { return new BackToNormalBuildMail(getRecipients(), sendToIndividuals, upstreamProjects, getCharset(), - Messages.MailSender_BackToNormal_Normal()).getMail(build, listener); - if (prev == Result.UNSTABLE) + Messages.MailSender_BackToNormal_Normal()).getMail(build, listener); + } + if (prev == Result.UNSTABLE) { return new BackToNormalBuildMail(getRecipients(), sendToIndividuals, upstreamProjects, getCharset(), - Messages.MailSender_BackToNormal_Stable()).getMail(build, listener); + Messages.MailSender_BackToNormal_Stable()).getMail(build, listener); + } } return null; @@ -160,9 +163,9 @@ public class MailSender extends BaseMailSender { protected boolean artifactMatches(String path, AbstractBuild<?, ?> build) { return false; } - /** - * Sometimes the outcome of the previous build affects the e-mail we send, hence this checkpoint. + * Sometimes the outcome of the previous build affects the e-mail we send, + * hence this checkpoint. */ private static final CheckPoint CHECKPOINT = new CheckPoint("mail sent"); } diff --git a/hudson-core/src/main/java/hudson/tasks/Mailer.java b/hudson-core/src/main/java/hudson/tasks/Mailer.java index 4dc420c..4659a0b 100644 --- a/hudson-core/src/main/java/hudson/tasks/Mailer.java +++ b/hudson-core/src/main/java/hudson/tasks/Mailer.java @@ -7,10 +7,10 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: + * Contributors: * * Kohsuke Kawaguchi, Bruce Chapman, Erik Ramfelt, Jean-Baptiste Quenot, Luca Domenico Milanesio, Anton Kozak - * + * * *******************************************************************************/ @@ -63,20 +63,18 @@ import static hudson.Util.fixEmptyAndTrim; * @author Kohsuke Kawaguchi */ public class Mailer extends Notifier { - protected static final Logger LOGGER = Logger.getLogger(Mailer.class.getName()); + protected static final Logger LOGGER = Logger.getLogger(Mailer.class.getName()); /** * Whitespace-separated list of e-mail addresses that represent recipients. */ //TODO: review and check whether we can do it private public String recipients; - /** * If true, only the first unstable build will be reported. */ //TODO: review and check whether we can do it private public boolean dontNotifyEveryUnstableBuild; - /** * If true, individuals will receive e-mails regarding who broke the build. */ @@ -94,7 +92,6 @@ public class Mailer extends Notifier { public boolean isSendToIndividuals() { return sendToIndividuals; } - // TODO: left so that XStream won't get angry. figure out how to set the error handling behavior // in XStream. Deprecated since 2005-04-23. private transient String from; @@ -104,7 +101,7 @@ public class Mailer extends Notifier { @Override public boolean perform(AbstractBuild<?, ?> build, Launcher launcher, BuildListener listener) - throws IOException, InterruptedException { + throws IOException, InterruptedException { if (debug) { listener.getLogger().println("Running mailer"); } @@ -113,7 +110,7 @@ public class Mailer extends Notifier { String recip = env.expand(recipients); return new MailSender(recip, dontNotifyEveryUnstableBuild, sendToIndividuals, - descriptor().getCharset()).execute(build, listener); + descriptor().getCharset()).execute(build, listener); } /** @@ -122,10 +119,9 @@ public class Mailer extends Notifier { public BuildStepMonitor getRequiredMonitorService() { return BuildStepMonitor.NONE; } - /** - * @deprecated as of 1.286 - * Use {@link #descriptor()} to obtain the current instance. + * @deprecated as of 1.286 Use {@link #descriptor()} to obtain the current + * instance. */ @Deprecated @RestrictedSince("1.355") @@ -137,58 +133,50 @@ public class Mailer extends Notifier { @Extension public static final class DescriptorImpl extends BuildStepDescriptor<Publisher> { + /** - * The default e-mail address suffix appended to the user name found from changelog, - * to send e-mails. Null if not configured. + * The default e-mail address suffix appended to the user name found + * from changelog, to send e-mails. Null if not configured. */ private String defaultSuffix; - /** * Hudson's own URL, to put into the e-mail. */ private String hudsonUrl = "http://localhost:8080/"; - /** * If non-null, use SMTP-AUTH with these information. */ private String smtpAuthUsername; - private Secret smtpAuthPassword; - /** - * The e-mail address that Hudson puts to "From:" field in outgoing e-mails. - * Null if not configured. + * The e-mail address that Hudson puts to "From:" field in outgoing + * e-mails. Null if not configured. */ private String adminAddress; - /** - * The SMTP server to use for sending e-mail. Null for default to the environment, - * which is usually <tt>localhost</tt>. + * The SMTP server to use for sending e-mail. Null for default to the + * environment, which is usually <tt>localhost</tt>. */ private String smtpHost; - /** - * If true use SSL on port 465 (standard SMTPS) unless <code>smtpPort</code> is set. + * If true use SSL on port 465 (standard SMTPS) unless + * <code>smtpPort</code> is set. */ private boolean useSsl; - /** - * The SMTP port to use for sending e-mail. Null for default to the environment, - * which is usually <tt>25</tt>. + * The SMTP port to use for sending e-mail. Null for default to the + * environment, which is usually <tt>25</tt>. */ private String smtpPort; - /** * The charset to use for the text and subject. */ private String charset; - /** * Used to keep track of number test e-mails. */ private static transient int testEmailCount = 0; - public DescriptorImpl() { load(); DESCRIPTOR = this; @@ -207,54 +195,61 @@ public class Mailer extends Notifier { return defaultSuffix; } - /** JavaMail session. */ + /** + * JavaMail session. + */ public Session createSession() { - return createSession(smtpHost,smtpPort,useSsl,smtpAuthUsername,smtpAuthPassword); + return createSession(smtpHost, smtpPort, useSsl, smtpAuthUsername, smtpAuthPassword); } + private static Session createSession(String smtpHost, String smtpPort, boolean useSsl, String smtpAuthUserName, Secret smtpAuthPassword) { smtpPort = fixEmptyAndTrim(smtpPort); smtpAuthUserName = fixEmptyAndTrim(smtpAuthUserName); Properties props = new Properties(System.getProperties()); props.put("mail.transport.protocol", "smtp"); - if(fixEmptyAndTrim(smtpHost)!=null) - props.put("mail.smtp.host",smtpHost); - if (smtpPort!=null) { + if (fixEmptyAndTrim(smtpHost) != null) { + props.put("mail.smtp.host", smtpHost); + } + if (smtpPort != null) { props.put("mail.smtp.port", smtpPort); } if (useSsl) { - /* This allows the user to override settings by setting system properties but - * also allows us to use the default SMTPs port of 465 if no port is already set. - * It would be cleaner to use smtps, but that's done by calling session.getTransport()... - * and thats done in mail sender, and it would be a bit of a work around to get it all to - * coordinate, and we can make it work through setting mail.smtp properties. - */ - if (props.getProperty("mail.smtp.socketFactory.port") == null) { - String port = smtpPort==null?"465":smtpPort; + /* This allows the user to override settings by setting system properties but + * also allows us to use the default SMTPs port of 465 if no port is already set. + * It would be cleaner to use smtps, but that's done by calling session.getTransport()... + * and thats done in mail sender, and it would be a bit of a work around to get it all to + * coordinate, and we can make it work through setting mail.smtp properties. + */ + if (props.getProperty("mail.smtp.socketFactory.port") == null) { + String port = smtpPort == null ? "465" : smtpPort; props.put("mail.smtp.port", port); props.put("mail.smtp.socketFactory.port", port); - } - if (props.getProperty("mail.smtp.socketFactory.class") == null) { - props.put("mail.smtp.socketFactory.class","javax.net.ssl.SSLSocketFactory"); - } - props.put("mail.smtp.socketFactory.fallback", "false"); - } - if(smtpAuthUserName!=null) - props.put("mail.smtp.auth","true"); + } + if (props.getProperty("mail.smtp.socketFactory.class") == null) { + props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory"); + } + props.put("mail.smtp.socketFactory.fallback", "false"); + } + if (smtpAuthUserName != null) { + props.put("mail.smtp.auth", "true"); + } // avoid hang by setting some timeout. - props.put("mail.smtp.timeout","60000"); - props.put("mail.smtp.connectiontimeout","60000"); + props.put("mail.smtp.timeout", "60000"); + props.put("mail.smtp.connectiontimeout", "60000"); - return Session.getInstance(props,getAuthenticator(smtpAuthUserName,Secret.toString(smtpAuthPassword))); + return Session.getInstance(props, getAuthenticator(smtpAuthUserName, Secret.toString(smtpAuthPassword))); } private static Authenticator getAuthenticator(final String smtpAuthUserName, final String smtpAuthPassword) { - if(smtpAuthUserName==null) return null; + if (smtpAuthUserName == null) { + return null; + } return new Authenticator() { @Override protected PasswordAuthentication getPasswordAuthentication() { - return new PasswordAuthentication(smtpAuthUserName,smtpAuthPassword); + return new PasswordAuthentication(smtpAuthUserName, smtpAuthPassword); } }; } @@ -267,11 +262,12 @@ public class Mailer extends Notifier { defaultSuffix = nullify(json.getString("defaultSuffix")); String url = nullify(json.getString("url")); - if(url!=null && !url.endsWith("/")) + if (url != null && !url.endsWith("/")) { url += '/'; + } hudsonUrl = url; - if(json.has("useSMTPAuth")) { + if (json.has("useSMTPAuth")) { JSONObject auth = json.getJSONObject("useSMTPAuth"); smtpAuthUsername = nullify(auth.getString("smtpAuthUserName")); smtpAuthPassword = Secret.fromString(nullify(auth.getString("smtpAuthPassword"))); @@ -282,15 +278,18 @@ public class Mailer extends Notifier { smtpPort = nullify(json.getString("smtpPort")); useSsl = json.getBoolean("useSsl"); charset = json.getString("charset"); - if (charset == null || charset.length() == 0) - charset = "UTF-8"; + if (charset == null || charset.length() == 0) { + charset = "UTF-8"; + } save(); return true; } private String nullify(String v) { - if(v!=null && v.length()==0) v=null; + if (v != null && v.length() == 0) { + v = null; + } return v; } @@ -300,7 +299,9 @@ public class Mailer extends Notifier { public String getAdminAddress() { String v = adminAddress; - if(v==null) v = Messages.Mailer_Address_Not_Configured(); + if (v == null) { + v = Messages.Mailer_Address_Not_Configured(); + } return v; } @@ -313,22 +314,26 @@ public class Mailer extends Notifier { } public String getSmtpAuthPassword() { - if (smtpAuthPassword==null) return null; + if (smtpAuthPassword == null) { + return null; + } return Secret.toString(smtpAuthPassword); } public boolean getUseSsl() { - return useSsl; + return useSsl; } public String getSmtpPort() { - return smtpPort; + return smtpPort; } public String getCharset() { - String c = charset; - if (c == null || c.length() == 0) c = "UTF-8"; - return c; + String c = charset; + if (c == null || c.length() == 0) { + c = "UTF-8"; + } + return c; } public void setDefaultSuffix(String defaultSuffix) { @@ -340,10 +345,10 @@ public class Mailer extends Notifier { } public void setAdminAddress(String adminAddress) { - if(adminAddress.startsWith("\"") && adminAddress.endsWith("\"")) { + if (adminAddress.startsWith("\"") && adminAddress.endsWith("\"")) { // some users apparently quote the whole thing. Don't konw why // anyone does this, but it's a machine's job to forgive human mistake - adminAddress = adminAddress.substring(1,adminAddress.length()-1); + adminAddress = adminAddress.substring(1, adminAddress.length() - 1); } this.adminAddress = adminAddress; } @@ -372,10 +377,10 @@ public class Mailer extends Notifier { @Override public Publisher newInstance(StaplerRequest req, JSONObject formData) { Mailer m = new Mailer(); - req.bindParameters(m,"mailer_"); - m.dontNotifyEveryUnstableBuild = req.getParameter("mailer_notifyEveryUnstableBuild")==null; + req.bindParameters(m, "mailer_"); + m.dontNotifyEveryUnstableBuild = req.getParameter("mailer_notifyEveryUnstableBuild") == null; - if(hudsonUrl==null) { + if (hudsonUrl == null) { // if Hudson URL is not configured yet, infer some default hudsonUrl = Functions.inferHudsonURL(req); save(); @@ -388,8 +393,9 @@ public class Mailer extends Notifier { * Checks the URL in <tt>global.jelly</tt> */ public FormValidation doCheckUrl(@QueryParameter String value) { - if(value.startsWith("http://localhost")) + if (value.startsWith("http://localhost")) { return FormValidation.warning(Messages.Mailer_Localhost_Error()); + } return FormValidation.ok(); } @@ -404,11 +410,12 @@ public class Mailer extends Notifier { public FormValidation doCheckSmtpServer(@QueryParameter String value) { try { - if (fixEmptyAndTrim(value)!=null) + if (fixEmptyAndTrim(value) != null) { InetAddress.getByName(value); + } return FormValidation.ok(); } catch (UnknownHostException e) { - return FormValidation.error(Messages.Mailer_Unknown_Host_Name()+value); + return FormValidation.error(Messages.Mailer_Unknown_Host_Name() + value); } } @@ -417,14 +424,16 @@ public class Mailer extends Notifier { } public FormValidation doCheckDefaultSuffix(@QueryParameter String value) { - if (value.matches("@[A-Za-z0-9.\\-]+") || fixEmptyAndTrim(value)==null) + if (value.matches("@[A-Za-z0-9.\\-]+") || fixEmptyAndTrim(value) == null) { return FormValidation.ok(); - else + } else { return FormValidation.error(Messages.Mailer_Suffix_Error()); + } } /** * Send an email to the admin address + * * @throws IOException * @throws ServletException * @throws InterruptedException @@ -434,10 +443,12 @@ public class Mailer extends Notifier { @QueryParameter String smtpAuthUserName, @QueryParameter String smtpAuthPassword, @QueryParameter boolean useSsl, @QueryParameter String smtpPort) throws IOException, ServletException, InterruptedException { try { - if (!useSMTPAuth) smtpAuthUserName = smtpAuthPassword = null; + if (!useSMTPAuth) { + smtpAuthUserName = smtpAuthPassword = null; + } Session session = createSession(smtpServer, smtpPort, useSsl, smtpAuthUserName, - Secret.fromString(smtpAuthPassword)); + Secret.fromString(smtpAuthPassword)); MimeMessage msg = new HudsonMimeMessage(session); msg.setSubject("Test email #" + ++testEmailCount); msg.setContent("This is test email #" + testEmailCount + " sent from Hudson Continuous Integration server.", "text/plain"); @@ -451,12 +462,13 @@ public class Mailer extends Notifier { return FormValidation.ok("Email was successfully sent"); } catch (MessagingException e) { - return FormValidation.errorWithMarkup("<p>Failed to send out e-mail</p><pre>"+Util.escape(Functions.printThrowable(e))+"</pre>"); + return FormValidation.errorWithMarkup("<p>Failed to send out e-mail</p><pre>" + Util.escape(Functions.printThrowable(e)) + "</pre>"); } } /** * Sends message + * * @param msg {@link MimeMessage} * @throws MessagingException if any. */ @@ -465,9 +477,10 @@ public class Mailer extends Notifier { } /** - * Wrap {@link Transport#send(javax.mail.Message)} method. Based on - * <a href="http://www.oracle.com/technetwork/java/faq-135477.html#smtpauth">javax.mail recommendations</a> - * and fix <a href="http://issues.hudson-ci.org/browse/HUDSON-7426">HUDSON-7426</a> + * Wrap {@link Transport#send(javax.mail.Message)} method. Based on <a + * href="http://www.oracle.com/technetwork/java/faq-135477.html#smtpauth">javax.mail + * recommendations</a> and fix <a + * href="http://issues.hudson-ci.org/browse/HUDSON-7426">HUDSON-7426</a> * * @param smtpServer smtp server * @param smtpAuthUserName username @@ -475,14 +488,15 @@ public class Mailer extends Notifier { * @param smtpPort port. * @param msg {@link MimeMessage} * @throws MessagingException if any. - * @see {@link #createSession(String, String, boolean, String, hudson.util.Secret)} + * @see + * {@link #createSession(String, String, boolean, String, hudson.util.Secret)} */ public static void send(String smtpServer, String smtpAuthUserName, String smtpAuthPassword, String smtpPort, - HudsonMimeMessage msg) throws MessagingException { - if (null != msg && null !=msg.getSession()) { + HudsonMimeMessage msg) throws MessagingException { + if (null != msg && null != msg.getSession()) { Session session = msg.getSession(); - Transport t = null != session.getProperty("mail.transport.protocol") ? - session.getTransport() : session.getTransport("smtp"); + Transport t = null != session.getProperty("mail.transport.protocol") + ? session.getTransport() : session.getTransport("smtp"); smtpPort = fixEmptyAndTrim(smtpPort); int port = -1; if (StringUtils.isNumeric(smtpPort)) { @@ -504,9 +518,9 @@ public class Mailer extends Notifier { * Per user property that is e-mail address. */ public static class UserProperty extends hudson.model.UserProperty { + /** - * The user's e-mail address. - * Null to leave it to default. + * The user's e-mail address. Null to leave it to default. */ private final String emailAddress; @@ -516,8 +530,9 @@ public class Mailer extends Notifier { @Exported public String getAddress() { - if(emailAddress!=null) + if (emailAddress != null) { return emailAddress; + } // try the inference logic return MailAddressResolver.resolve(user); @@ -525,6 +540,7 @@ public class Mailer extends Notifier { @Extension public static final class DescriptorImpl extends UserPropertyDescriptor { + public String getDisplayName() { return Messages.Mailer_UserProperty_DisplayName(); } @@ -539,17 +555,22 @@ public class Mailer extends Notifier { } } } - /** * Debug probe point to be activated by the scripting console. */ public static boolean debug = false; public static class ConverterImpl extends XStream2.PassthruConverter<Mailer> { - public ConverterImpl(XStream2 xstream) { super(xstream); } - @Override protected void callback(Mailer m, UnmarshallingContext context) { - if (m.from != null || m.subject != null || m.failureOnly || m.charset != null) + + public ConverterImpl(XStream2 xstream) { + super(xstream); + } + + @Override + protected void callback(Mailer m, UnmarshallingContext context) { + if (m.from != null || m.subject != null || m.failureOnly || m.charset != null) { OldDataMonitor.report(context, "1.10"); + } } } } diff --git a/hudson-core/src/main/java/hudson/tasks/Maven.java b/hudson-core/src/main/java/hudson/tasks/Maven.java index 9cf462b..573127a 100644 --- a/hudson-core/src/main/java/hudson/tasks/Maven.java +++ b/hudson-core/src/main/java/hudson/tasks/Maven.java @@ -7,10 +7,10 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: + * Contributors: * * Kohsuke Kawaguchi, Jene Jasper, Stephen Connolly, Tom Huybrechts, Yahoo! Inc., Nikita Levyankov - * + * * *******************************************************************************/ @@ -69,60 +69,55 @@ import java.util.Set; * @author Kohsuke Kawaguchi */ public class Maven extends Builder { + /** - * The targets and other maven options. - * Can be separated by SP or NL. + * The targets and other maven options. Can be separated by SP or NL. */ public final String targets; - /** * Identifies {@link MavenInstallation} to be used. */ public final String mavenName; - /** * MAVEN_OPTS if not null. */ public final String jvmOptions; - /** - * Optional POM file path relative to the workspace. - * Used for the Maven '-f' option. + * Optional POM file path relative to the workspace. Used for the Maven '-f' + * option. */ public final String pom; - /** - * Optional properties to be passed to Maven. Follows {@link Properties} syntax. + * Optional properties to be passed to Maven. Follows {@link Properties} + * syntax. */ public final String properties; - /** - * If true, the build will use its own local Maven repository - * via "-Dmaven.repo.local=...". - * <p> - * This would consume additional disk space, but provides isolation with other builds on the same machine, - * such as mixing SNAPSHOTS. Maven also doesn't try to coordinate the concurrent access to Maven repositories - * from multiple Maven process, so this helps there too. + * If true, the build will use its own local Maven repository via + * "-Dmaven.repo.local=...". <p> This would consume additional disk space, + * but provides isolation with other builds on the same machine, such as + * mixing SNAPSHOTS. Maven also doesn't try to coordinate the concurrent + * access to Maven repositories from multiple Maven process, so this helps + * there too. * * Identical to logic used in maven-plugin. * * @since 1.322 */ public boolean usePrivateRepository = false; - private final static String MAVEN_1_INSTALLATION_COMMON_FILE = "bin/maven"; private final static String MAVEN_2_INSTALLATION_COMMON_FILE = "bin/mvn"; - public Maven(String targets,String name) { - this(targets,name,null,null,null,false); + public Maven(String targets, String name) { + this(targets, name, null, null, null, false); } public Maven(String targets, String name, String pom, String properties, String jvmOptions) { - this(targets, name, pom, properties, jvmOptions, false); + this(targets, name, pom, properties, jvmOptions, false); } - + @DataBoundConstructor - public Maven(String targets,String name, String pom, String properties, String jvmOptions, boolean usePrivateRepository) { + public Maven(String targets, String name, String pom, String properties, String jvmOptions, boolean usePrivateRepository) { this.targets = targets; this.mavenName = name; this.pom = StringUtils.trimToNull(pom); @@ -144,23 +139,24 @@ public class Maven extends Builder { } /** - * Gets the Maven to invoke, - * or null to invoke the default one. + * Gets the Maven to invoke, or null to invoke the default one. */ public MavenInstallation getMaven() { - for( MavenInstallation i : getDescriptor().getInstallations() ) { - if(mavenName !=null && mavenName.equals(i.getName())) + for (MavenInstallation i : getDescriptor().getInstallations()) { + if (mavenName != null && mavenName.equals(i.getName())) { return i; + } } return null; } /** - * Looks for <tt>pom.xlm</tt> or <tt>project.xml</tt> to determine the maven executable - * name. + * Looks for <tt>pom.xlm</tt> or <tt>project.xml</tt> to determine the maven + * executable name. */ private static final class DecideDefaultMavenCommand implements FileCallable<String> { // command line arguments. + private final String arguments; public DecideDefaultMavenCommand(String arguments) { @@ -168,42 +164,44 @@ public class Maven extends Builder { } public String invoke(File ws, VirtualChannel channel) throws IOException { - String seed=null; + String seed = null; // check for the -f option StringTokenizer tokens = new StringTokenizer(arguments); - while(tokens.hasMoreTokens()) { + while (tokens.hasMoreTokens()) { String t = tokens.nextToken(); - if(t.equals("-f") && tokens.hasMoreTokens()) { - File file = new File(ws,tokens.nextToken()); - if(!file.exists()) + if (t.equals("-f") && tokens.hasMoreTokens()) { + File file = new File(ws, tokens.nextToken()); + if (!file.exists()) { continue; // looks like an error, but let the execution fail later - seed = file.isDirectory() ? - /* in M1, you specify a directory in -f */ "maven" - /* in M2, you specify a POM file name. */ : "mvn"; + } + seed = file.isDirectory() + ? /* in M1, you specify a directory in -f */ "maven" + /* in M2, you specify a POM file name. */ : "mvn"; break; } } - if(seed==null) { + if (seed == null) { // as of 1.212 (2008 April), I think Maven2 mostly replaced Maven1, so // switching to err on M2 side. - seed = new File(ws,"project.xml").exists() ? "maven" : "mvn"; + seed = new File(ws, "project.xml").exists() ? "maven" : "mvn"; } - if(Functions.isWindows()) + if (Functions.isWindows()) { seed += ".bat"; + } return seed; } } @Override - public boolean perform(AbstractBuild<?,?> build, Launcher launcher, BuildListener listener) throws IOException, InterruptedException { + public boolean perform(AbstractBuild<?, ?> build, Launcher launcher, BuildListener listener) throws IOException, InterruptedException { VariableResolver<String> vr = build.getBuildVariableResolver(); EnvVars env = build.getEnvironment(listener); - String targets = Util.replaceMacro(this.targets,vr); + String targets = Util.replaceMacro(this.targets, vr); targets = env.expand(targets); String pom = env.expand(this.pom); String properties = env.expand(this.properties); @@ -219,46 +217,48 @@ public class Maven extends Builder { String normalizedTarget = targets .substring(startIndex, endIndex) - .replaceAll("[\t\r\n]+"," "); + .replaceAll("[\t\r\n]+", " "); ArgumentListBuilder args = new ArgumentListBuilder(); MavenInstallation mi = getMaven(); - if(mi==null) { + if (mi == null) { String execName = build.getWorkspace().act(new DecideDefaultMavenCommand(normalizedTarget)); args.add(execName); } else { mi = mi.forNode(Computer.currentComputer().getNode(), listener); - mi = mi.forEnvironment(env); + mi = mi.forEnvironment(env); String exec = mi.getExecutable(launcher); - if(exec==null) { + if (exec == null) { listener.fatalError(Messages.Maven_NoExecutable(mi.getHome())); return false; } args.add(exec); } - if(pom!=null) - args.add("-f",pom); + if (pom != null) { + args.add("-f", pom); + } Set<String> sensitiveVars = build.getSensitiveBuildVariables(); - args.addKeyValuePairs("-D",build.getBuildVariables(),sensitiveVars); - args.addKeyValuePairsFromPropertyString("-D",properties,vr,sensitiveVars); - if (usesPrivateRepository()) + args.addKeyValuePairs("-D", build.getBuildVariables(), sensitiveVars); + args.addKeyValuePairsFromPropertyString("-D", properties, vr, sensitiveVars); + if (usesPrivateRepository()) { args.add("-Dmaven.repo.local=" + build.getWorkspace().child(".repository")); + } args.addTokenized(normalizedTarget); - wrapUpArguments(args,normalizedTarget,build,launcher,listener); + wrapUpArguments(args, normalizedTarget, build, launcher, listener); buildEnvVars(env, mi); try { - MavenConsoleAnnotator mca = new MavenConsoleAnnotator(listener.getLogger(),build.getCharset()); + MavenConsoleAnnotator mca = new MavenConsoleAnnotator(listener.getLogger(), build.getCharset()); int r = launcher.launch().cmds(args).envs(env).stdout(mca).pwd(build.getModuleRoot()).join(); if (0 != r) { return false; } } catch (IOException e) { - Util.displayIOException(e,listener); - e.printStackTrace( listener.fatalError(Messages.Maven_ExecFailed()) ); + Util.displayIOException(e, listener); + e.printStackTrace(listener.fatalError(Messages.Maven_ExecFailed())); return false; } startIndex = endIndex + 1; @@ -267,18 +267,19 @@ public class Maven extends Builder { } /** - * Allows the derived type to make additional modifications to the arguments list. + * Allows the derived type to make additional modifications to the arguments + * list. * * @since 1.344 */ - protected void wrapUpArguments(ArgumentListBuilder args, String normalizedTarget, AbstractBuild<?,?> build, Launcher launcher, BuildListener listener) throws IOException, InterruptedException { + protected void wrapUpArguments(ArgumentListBuilder args, String normalizedTarget, AbstractBuild<?, ?> build, Launcher launcher, BuildListener listener) throws IOException, InterruptedException { } /** * Build up the environment variables toward the Maven launch. */ protected void buildEnvVars(EnvVars env, MavenInstallation mi) throws IOException, InterruptedException { - if(mi!=null) { + if (mi != null) { // if somebody has use M2_HOME they will get a classloading error // when M2_HOME points to a different version of Maven2 from // MAVEN_HOME (as Maven 2 gives M2_HOME priority.) @@ -286,33 +287,34 @@ public class Maven extends Builder { // The other solution would be to set M2_HOME if we are calling Maven2 // and MAVEN_HOME for Maven1 (only of use for strange people that // are calling Maven2 from Maven1) - env.put("M2_HOME",mi.getHome()); - env.put("MAVEN_HOME",mi.getHome()); + env.put("M2_HOME", mi.getHome()); + env.put("MAVEN_HOME", mi.getHome()); } // just as a precaution // see http://maven.apache.org/continuum/faqs.html#how-does-continuum-detect-a-successful-build - env.put("MAVEN_TERMINATE_CMD","on"); + env.put("MAVEN_TERMINATE_CMD", "on"); String jvmOptions = env.expand(this.jvmOptions); - if(jvmOptions!=null) - env.put("MAVEN_OPTS",jvmOptions.replaceAll("[\t\r\n]+"," ")); + if (jvmOptions != null) { + env.put("MAVEN_OPTS", jvmOptions.replaceAll("[\t\r\n]+", " ")); + } } @Override public DescriptorImpl getDescriptor() { - return (DescriptorImpl)super.getDescriptor(); + return (DescriptorImpl) super.getDescriptor(); } - /** - * @deprecated as of 1.286 - * Use {@link Hudson#getDescriptorByType(Class)} to obtain the current instance. - * For compatibility, this field retains the last created {@link DescriptorImpl}. - * TODO: fix sonar plugin that depends on this. That's the only plugin that depends on this field. + * @deprecated as of 1.286 Use {@link Hudson#getDescriptorByType(Class)} to + * obtain the current instance. For compatibility, this field retains the + * last created {@link DescriptorImpl}. TODO: fix sonar plugin that depends + * on this. That's the only plugin that depends on this field. */ public static DescriptorImpl DESCRIPTOR; @Extension public static final class DescriptorImpl extends BuildStepDescriptor<Builder> { + @CopyOnWrite private volatile MavenInstallation[] installations = new MavenInstallation[0]; public static boolean isEnabled = true; @@ -346,7 +348,7 @@ public class Maven extends Builder { @Override public Builder newInstance(StaplerRequest req, JSONObject formData) throws FormException { - return req.bindJSON(Maven.class,formData); + return req.bindJSON(Maven.class, formData); } } @@ -354,14 +356,13 @@ public class Maven extends Builder { * Represents a Maven installation in a system. */ public static final class MavenInstallation extends ToolInstallation implements EnvironmentSpecific<MavenInstallation>, NodeSpecific<MavenInstallation> { + /** * Constants for describing Maven versions for comparison. */ public static final int MAVEN_20 = 0; public static final int MAVEN_21 = 1; public static final int MAVEN_30 = 2; - - /** * @deprecated since 2009-02-25. */ @@ -369,8 +370,8 @@ public class Maven extends Builder { private transient String mavenHome; /** - * @deprecated as of 1.308. - * Use {@link #MavenInstallation(String, String, List)} + * @deprecated as of 1.308. Use + * {@link #MavenInstallation(String, String, List)} */ public MavenInstallation(String name, String home) { super(name, home); @@ -395,91 +396,94 @@ public class Maven extends Builder { } /** - * Compares the version of this Maven installation to the minimum required version specified. + * Compares the version of this Maven installation to the minimum + * required version specified. * - * @param launcher - * Represents the node on which we evaluate the path. - * @param mavenReqVersion - * Represents the minimum required Maven version - constants defined above. + * @param launcher Represents the node on which we evaluate the path. + * @param mavenReqVersion Represents the minimum required Maven version + * - constants defined above. */ public boolean meetsMavenReqVersion(Launcher launcher, int mavenReqVersion) throws IOException, InterruptedException { // FIXME using similar stuff as in the maven plugin could be better // olamy : but will add a dependency on maven in core -> so not so good - String mavenVersion = launcher.getChannel().call(new Callable<String,IOException>() { - public String call() throws IOException { - File[] jars = new File(getHomeDir(),"lib").listFiles(); - if(jars!=null) { // be defensive - for (File jar : jars) { - if (jar.getName().endsWith("-uber.jar") && jar.getName().startsWith("maven-")) { - return jar.getName(); - } + String mavenVersion = launcher.getChannel().call(new Callable<String, IOException>() { + public String call() throws IOException { + File[] jars = new File(getHomeDir(), "lib").listFiles(); + if (jars != null) { // be defensive + for (File jar : jars) { + if (jar.getName().endsWith("-uber.jar") && jar.getName().startsWith("maven-")) { + return jar.getName(); } } - return ""; } - }); + return ""; + } + }); if (!mavenVersion.equals("")) { if (mavenReqVersion == MAVEN_20) { - if(mavenVersion.startsWith("maven-2.") || mavenVersion.startsWith("maven-core-2")) + if (mavenVersion.startsWith("maven-2.") || mavenVersion.startsWith("maven-core-2")) { return true; - } - else if (mavenReqVersion == MAVEN_21) { - if(mavenVersion.startsWith("maven-2.") && !mavenVersion.startsWith("maven-2.0")) + } + } else if (mavenReqVersion == MAVEN_21) { + if (mavenVersion.startsWith("maven-2.") && !mavenVersion.startsWith("maven-2.0")) { return true; - } - else if (mavenReqVersion == MAVEN_30) { - if(mavenVersion.startsWith("maven-3.") && !mavenVersion.startsWith("maven-2.0")) + } + } else if (mavenReqVersion == MAVEN_30) { + if (mavenVersion.startsWith("maven-3.") && !mavenVersion.startsWith("maven-2.0")) { return true; - } + } + } } return false; - + } - + /** * Is this Maven 2.1.x or later? * - * @param launcher - * Represents the node on which we evaluate the path. + * @param launcher Represents the node on which we evaluate the path. */ public boolean isMaven2_1(Launcher launcher) throws IOException, InterruptedException { return meetsMavenReqVersion(launcher, MAVEN_21); } - /* return launcher.getChannel().call(new Callable<Boolean,IOException>() { - public Boolean call() throws IOException { - File[] jars = new File(getHomeDir(),"lib").listFiles(); - if(jars!=null) // be defensive - for (File jar : jars) - if(jar.getName().startsWith("maven-2.") && !jar.getName().startsWith("maven-2.0") && jar.getName().endsWith("-uber.jar")) - return true; - return false; - } - }); - } */ + /* return launcher.getChannel().call(new Callable<Boolean,IOException>() { + public Boolean call() throws IOException { + File[] jars = new File(getHomeDir(),"lib").listFiles(); + if(jars!=null) // be defensive + for (File jar : jars) + if(jar.getName().startsWith("maven-2.") && !jar.getName().startsWith("maven-2.0") && jar.getName().endsWith("-uber.jar")) + return true; + return false; + } + }); + } */ /** * Gets the executable path of this maven on the given target system. */ public String getExecutable(Launcher launcher) throws IOException, InterruptedException { - return launcher.getChannel().call(new Callable<String,IOException>() { + return launcher.getChannel().call(new Callable<String, IOException>() { public String call() throws IOException { File exe = getExeFile("maven"); - if(exe.exists()) + if (exe.exists()) { return exe.getPath(); + } exe = getExeFile("mvn"); - if(exe.exists()) + if (exe.exists()) { return exe.getPath(); + } return null; } }); } private File getExeFile(String execName) { - if(File.separatorChar=='\\') + if (File.separatorChar == '\\') { execName += ".bat"; + } - String m2Home = Util.replaceMacro(getHome(),EnvVars.masterEnvVars); + String m2Home = Util.replaceMacro(getHome(), EnvVars.masterEnvVars); return new File(m2Home, "bin/" + execName); } @@ -489,14 +493,13 @@ public class Maven extends Builder { */ public boolean getExists() { try { - return getExecutable(new LocalLauncher(new StreamTaskListener(new NullStream())))!=null; + return getExecutable(new LocalLauncher(new StreamTaskListener(new NullStream()))) != null; } catch (IOException e) { return false; } catch (InterruptedException e) { return false; } } - private static final long serialVersionUID = 1L; public MavenInstallation forEnvironment(EnvVars environment) { @@ -509,6 +512,7 @@ public class Maven extends Builder { @Extension public static class DescriptorImpl extends ToolDescriptor<MavenInstallation> { + @Override public String getDisplayName() { return "Maven"; @@ -534,20 +538,24 @@ public class Maven extends Builder { */ public FormValidation doCheckMavenHome(@QueryParameter File value) { // this can be used to check the existence of a file on the server, so needs to be protected - if(!Hudson.getInstance().hasPermission(Hudson.ADMINISTER)) + if (!Hudson.getInstance().hasPermission(Hudson.ADMINISTER)) { return FormValidation.ok(); + } - if(value.getPath().equals("")) + if (value.getPath().equals("")) { return FormValidation.ok(); + } - if(!value.isDirectory()) + if (!value.isDirectory()) { return FormValidation.error(Messages.Maven_NotADirectory(value)); + } - File maven1File = new File(value,MAVEN_1_INSTALLATION_COMMON_FILE); - File maven2File = new File(value,MAVEN_2_INSTALLATION_COMMON_FILE); + File maven1File = new File(value, MAVEN_1_INSTALLATION_COMMON_FILE); + File maven2File = new File(value, MAVEN_2_INSTALLATION_COMMON_FILE); - if(!maven1File.exists() && !maven2File.exists()) + if (!maven1File.exists() && !maven2File.exists()) { return FormValidation.error(Messages.Maven_NotMavenDirectory(value)); + } return FormValidation.ok(); } @@ -558,9 +566,14 @@ public class Maven extends Builder { } public static class ConverterImpl extends ToolConverter { - public ConverterImpl(XStream2 xstream) { super(xstream); } - @Override protected String oldHomeField(ToolInstallation obj) { - return ((MavenInstallation)obj).mavenHome; + + public ConverterImpl(XStream2 xstream) { + super(xstream); + } + + @Override + protected String oldHomeField(ToolInstallation obj) { + return ((MavenInstallation) obj).mavenHome; } } } @@ -569,6 +582,7 @@ public class Maven extends Builder { * Automatic Maven installer from apache.org. */ public static class MavenInstaller extends DownloadFromUrlInstaller { + @DataBoundConstructor public MavenInstaller(String id) { super(id); @@ -576,13 +590,14 @@ public class Maven extends Builder { @Extension public static final class DescriptorImpl extends DownloadFromUrlInstaller.DescriptorImpl<MavenInstaller> { + public String getDisplayName() { return Messages.InstallFromApache(); } @Override public boolean isApplicable(Class<? extends ToolInstallation> toolType) { - return toolType==MavenInstallation.class; + return toolType == MavenInstallation.class; } } } @@ -591,22 +606,21 @@ public class Maven extends Builder { * Optional interface that can be implemented by {@link AbstractProject} * that has "contextual" {@link MavenInstallation} associated with it. * - * <p> - * Code like RedeployPublisher uses this interface in an attempt - * to use the consistent Maven installation attached to the project. + * <p> Code like RedeployPublisher uses this interface in an attempt to use + * the consistent Maven installation attached to the project. * * @since 1.235 */ public interface ProjectWithMaven { + /** - * Gets the {@link MavenInstallation} associated with the project. - * Can be null. + * Gets the {@link MavenInstallation} associated with the project. Can + * be null. * - * <p> - * If the Maven installation can not be uniquely determined, - * it's often better to return just one of them, rather than returning - * null, since this method is currently ultimately only used to - * decide where to parse <tt>conf/settings.xml</tt> from. + * <p> If the Maven installation can not be uniquely determined, it's + * often better to return just one of them, rather than returning null, + * since this method is currently ultimately only used to decide where + * to parse <tt>conf/settings.xml</tt> from. */ MavenInstallation inferMavenInstallation(); } @@ -622,24 +636,24 @@ public class Maven extends Builder { Maven that = (Maven) o; return new EqualsBuilder() - .append(usePrivateRepository, that.usePrivateRepository) - .append(jvmOptions, that.jvmOptions) - .append(mavenName, that.mavenName) - .append(pom, that.pom) - .append(properties, that.properties) - .append(targets, that.targets) - .isEquals(); + .append(usePrivateRepository, that.usePrivateRepository) + .append(jvmOptions, that.jvmOptions) + .append(mavenName, that.mavenName) + .append(pom, that.pom) + .append(properties, that.properties) + .append(targets, that.targets) + .isEquals(); } @Override public int hashCode() { return new HashCodeBuilder() - .append(targets) - .append(mavenName) - .append(jvmOptions) - .append(pom) - .append(properties) - .append(usePrivateRepository) - .toHashCode(); + .append(targets) + .append(mavenName) + .append(jvmOptions) + .append(pom) + .append(properties) + .append(usePrivateRepository) + .toHashCode(); } } diff --git a/hudson-core/src/main/java/hudson/tasks/Notifier.java b/hudson-core/src/main/java/hudson/tasks/Notifier.java index a0ca750..581f660 100644 --- a/hudson-core/src/main/java/hudson/tasks/Notifier.java +++ b/hudson-core/src/main/java/hudson/tasks/Notifier.java @@ -7,10 +7,10 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: + * Contributors: + * + * * - * - * * *******************************************************************************/ @@ -22,15 +22,14 @@ import hudson.ExtensionPoint; /** * {@link BuildStep}s that run after the build is completed. * - * <p> - * {@link Notifier} is a kind of {@link Publisher} that sends out the outcome of the builds to - * other systems and humans. This marking ensures that notifiers are run after the build result - * is set to its final value by other {@link Recorder}s. To run even after the build is marked - * as complete, override {@link #needsToRunAfterFinalized} to return true. + * <p> {@link Notifier} is a kind of {@link Publisher} that sends out the + * outcome of the builds to other systems and humans. This marking ensures that + * notifiers are run after the build result is set to its final value by other + * {@link Recorder}s. To run even after the build is marked as complete, + * override {@link #needsToRunAfterFinalized} to return true. * - * <p> - * To register a custom {@link Publisher} from a plugin, - * put {@link Extension} on your descriptor. + * <p> To register a custom {@link Publisher} from a plugin, put + * {@link Extension} on your descriptor. * * * @author Kohsuke Kawaguchi @@ -38,9 +37,12 @@ import hudson.ExtensionPoint; * @see Recorder */ public abstract class Notifier extends Publisher implements ExtensionPoint { + @SuppressWarnings("deprecation") // super only @Deprecated to discourage other subclasses - protected Notifier() {} + protected Notifier() { + } + public BuildStepDescriptor getDescriptor() { - return (BuildStepDescriptor)super.getDescriptor(); + return (BuildStepDescriptor) super.getDescriptor(); } } diff --git a/hudson-core/src/main/java/hudson/tasks/Publisher.java b/hudson-core/src/main/java/hudson/tasks/Publisher.java index c8a7507..528e3c5 100644 --- a/hudson-core/src/main/java/hudson/tasks/Publisher.java +++ b/hudson-core/src/main/java/hudson/tasks/Publisher.java @@ -7,10 +7,10 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: + * Contributors: * * Kohsuke Kawaguchi - * + * * *******************************************************************************/ package hudson.tasks; @@ -34,29 +34,27 @@ import java.util.List; /** * {@link BuildStep}s that run after the build is completed. * - * <p> - * To register a custom {@link Publisher} from a plugin, - * put {@link Extension} on your descriptor implementation. + * <p> To register a custom {@link Publisher} from a plugin, put + * {@link Extension} on your descriptor implementation. * - * <p> - * Starting 1.178, publishers are exposed to all kinds of different - * project type, not just the freestyle project type (in particular, - * the native maven2 job type.) This is convenient default for - * {@link Publisher}s in particular initially, but we encourage advanced - * plugins to consider writing MavenReporter, as it offers the - * potential of reducing the amount of configuration needed to run the plugin. + * <p> Starting 1.178, publishers are exposed to all kinds of different project + * type, not just the freestyle project type (in particular, the native maven2 + * job type.) This is convenient default for {@link Publisher}s in particular + * initially, but we encourage advanced plugins to consider writing + * MavenReporter, as it offers the potential of reducing the amount of + * configuration needed to run the plugin. * - * For those plugins that don't want {@link Publisher} to show up in - * different job type, use {@link BuildStepDescriptor} for the base type - * of your descriptor to control which job type it supports. + * For those plugins that don't want {@link Publisher} to show up in different + * job type, use {@link BuildStepDescriptor} for the base type of your + * descriptor to control which job type it supports. * * @author Kohsuke Kawaguchi, Anton Kozak */ public abstract class Publisher extends BuildStepCompatibilityLayer implements BuildStep, Describable<Publisher> { + /** - * @deprecated - * Don't extend from {@link Publisher} directly. Instead, choose {@link Recorder} or {@link Notifier} - * as your base class. + * @deprecated Don't extend from {@link Publisher} directly. Instead, choose + * {@link Recorder} or {@link Notifier} as your base class. */ @Deprecated protected Publisher() { @@ -67,41 +65,43 @@ public abstract class Publisher extends BuildStepCompatibilityLayer implements B // /** * Default implementation that does nothing. + * * @deprecated since 1.150 */ - @Deprecated @Override + @Deprecated + @Override public boolean prebuild(Build build, BuildListener listener) { return true; } /** * Default implementation that does nothing. + * * @deprecated since 1.150 */ - @Deprecated @Override + @Deprecated + @Override public Action getProjectAction(Project project) { return null; } /** - * Return true if this {@link Publisher} needs to run after the build result is - * fully finalized. + * Return true if this {@link Publisher} needs to run after the build result + * is fully finalized. * - * <p> - * The execution of normal {@link Publisher}s are considered within a part - * of the build. This allows publishers to mark the build as a failure, or - * to include their execution time in the total build time. + * <p> The execution of normal {@link Publisher}s are considered within a + * part of the build. This allows publishers to mark the build as a failure, + * or to include their execution time in the total build time. * - * <p> - * So normally, that is the preferrable behavior, but in a few cases + * <p> So normally, that is the preferrable behavior, but in a few cases * this is problematic. One of such cases is when a publisher needs to - * trigger other builds, which in turn need to see this build as a - * completed build. Those plugins that need to do this can return true - * from this method, so that the {@link #perform(AbstractBuild, Launcher, BuildListener)} - * method is called after the build is marked as completed. + * trigger other builds, which in turn need to see this build as a completed + * build. Those plugins that need to do this can return true from this + * method, so that the + * {@link #perform(AbstractBuild, Launcher, BuildListener)} method is called + * after the build is marked as completed. * - * <p> - * When {@link Publisher} behaves this way, note that they can no longer + * <p> When {@link Publisher} behaves this way, note that they can no longer * change the build status anymore. * * @author Kohsuke Kawaguchi @@ -112,10 +112,11 @@ public abstract class Publisher extends BuildStepCompatibilityLayer implements B } /** - * Returns true if this {@link Publisher} needs to run depends on Build {@link Result}. + * Returns true if this {@link Publisher} needs to run depends on Build + * {@link Result}. * <p/> - * Can be used if execution of {@link Publisher} is not required for some Build {@link Result}, - * i.e. ABORTED, FAILED, etc. + * Can be used if execution of {@link Publisher} is not required for some + * Build {@link Result}, i.e. ABORTED, FAILED, etc. * <p/> * * @since 2.1.1 @@ -131,24 +132,27 @@ public abstract class Publisher extends BuildStepCompatibilityLayer implements B /** * {@link Publisher} has a special sort semantics that requires a subtype. * - * @see DescriptorExtensionList#createDescriptorList(Hudson, Class) + * @see DescriptorExtensionList#createDescriptorList(Hudson, Class) */ - public static final class DescriptorExtensionListImpl extends DescriptorExtensionList<Publisher,Descriptor<Publisher>> + public static final class DescriptorExtensionListImpl extends DescriptorExtensionList<Publisher, Descriptor<Publisher>> implements Comparator<ExtensionComponent<Descriptor<Publisher>>> { + public DescriptorExtensionListImpl(Hudson hudson) { - super(hudson,Publisher.class); + super(hudson, Publisher.class); } @Override protected List<ExtensionComponent<Descriptor<Publisher>>> sort(List<ExtensionComponent<Descriptor<Publisher>>> r) { List<ExtensionComponent<Descriptor<Publisher>>> copy = new ArrayList<ExtensionComponent<Descriptor<Publisher>>>(r); - Collections.sort(copy,this); + Collections.sort(copy, this); return copy; } public int compare(ExtensionComponent<Descriptor<Publisher>> lhs, ExtensionComponent<Descriptor<Publisher>> rhs) { - int r = classify(lhs.getInstance())-classify(rhs.getInstance()); - if (r!=0) return r; + int r = classify(lhs.getInstance()) - classify(rhs.getInstance()); + if (r != 0) { + return r; + } return lhs.compareTo(rhs); } @@ -157,13 +161,21 @@ public abstract class Publisher extends BuildStepCompatibilityLayer implements B * This is used as a sort key. */ private int classify(Descriptor<Publisher> d) { - if(d.isSubTypeOf(Recorder.class)) return 0; - if(d.isSubTypeOf(Notifier.class)) return 2; + if (d.isSubTypeOf(Recorder.class)) { + return 0; + } + if (d.isSubTypeOf(Notifier.class)) { + return 2; + } // for compatibility, if the descriptor is manually registered in a specific way, detect that. Class<? extends Publisher> kind = PublisherList.KIND.get(d); - if(kind==Recorder.class) return 0; - if(kind==Notifier.class) return 2; + if (kind == Recorder.class) { + return 0; + } + if (kind == Notifier.class) { + return 2; + } return 1; } @@ -173,7 +185,7 @@ public abstract class Publisher extends BuildStepCompatibilityLayer implements B * Returns all the registered {@link Publisher} descriptors. */ // for backward compatibility, the signature is not BuildStepDescriptor - public static DescriptorExtensionList<Publisher,Descriptor<Publisher>> all() { - return Hudson.getInstance().<Publisher,Descriptor<Publisher>>getDescriptorList(Publisher.class); + public static DescriptorExtensionList<Publisher, Descriptor<Publisher>> all() { + return Hudson.getInstance().<Publisher, Descriptor<Publisher>>getDescriptorList(Publisher.class); } } diff --git a/hudson-core/src/main/java/hudson/tasks/Recorder.java b/hudson-core/src/main/java/hudson/tasks/Recorder.java index 74f6a15..768bd4d 100644 --- a/hudson-core/src/main/java/hudson/tasks/Recorder.java +++ b/hudson-core/src/main/java/hudson/tasks/Recorder.java @@ -7,10 +7,10 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: + * Contributors: + * + * * - * - * * *******************************************************************************/ @@ -22,15 +22,14 @@ import hudson.ExtensionPoint; /** * {@link BuildStep}s that run after the build is completed. * - * <p> - * {@link Recorder} is a kind of {@link Publisher} that collects statistics from the build, - * and can mark builds as unstable/failure. This marking ensures that builds are marked accordingly - * before notifications are sent via {@link Notifier}s. Otherwise, if the build is marked failed - * after some notifications are sent, inconsistency ensues. + * <p> {@link Recorder} is a kind of {@link Publisher} that collects statistics + * from the build, and can mark builds as unstable/failure. This marking ensures + * that builds are marked accordingly before notifications are sent via + * {@link Notifier}s. Otherwise, if the build is marked failed after some + * notifications are sent, inconsistency ensues. * - * <p> - * To register a custom {@link Publisher} from a plugin, - * put {@link Extension} on your descriptor. + * <p> To register a custom {@link Publisher} from a plugin, put + * {@link Extension} on your descriptor. * * * @author Kohsuke Kawaguchi @@ -38,9 +37,12 @@ import hudson.ExtensionPoint; * @see Notifier */ public abstract class Recorder extends Publisher implements ExtensionPoint { + @SuppressWarnings("deprecation") // super only @Deprecated to discourage other subclasses - protected Recorder() {} + protected Recorder() { + } + public BuildStepDescriptor getDescriptor() { - return (BuildStepDescriptor)super.getDescriptor(); + return (BuildStepDescriptor) super.getDescriptor(); } } diff --git a/hudson-core/src/main/java/hudson/tasks/Shell.java b/hudson-core/src/main/java/hudson/tasks/Shell.java index 553f32c..8b7bee1 100644 --- a/hudson-core/src/main/java/hudson/tasks/Shell.java +++ b/hudson-core/src/main/java/hudson/tasks/Shell.java @@ -7,10 +7,10 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: + * Contributors: * * Kohsuke Kawaguchi, Jene Jasper, Yahoo! Inc., Nikita Levyankov - * + * * *******************************************************************************/ @@ -37,6 +37,7 @@ import java.util.Arrays; * @author Kohsuke Kawaguchi */ public class Shell extends CommandInterpreter { + @DataBoundConstructor public Shell(String command) { super(fixCrLf(command)); @@ -57,13 +58,13 @@ public class Shell extends CommandInterpreter { } /** - * Older versions of bash have a bug where non-ASCII on the first line - * makes the shell think the file is a binary file and not a script. Adding - * a leading line feed works around this problem. + * Older versions of bash have a bug where non-ASCII on the first line makes + * the shell think the file is a binary file and not a script. Adding a + * leading line feed works around this problem. */ private static String addCrForNonASCII(String s) { - if(!s.startsWith("#!")) { - if (s.indexOf('\n')!=0) { + if (!s.startsWith("#!")) { + if (s.indexOf('\n') != 0) { return "\n" + s; } } @@ -72,17 +73,20 @@ public class Shell extends CommandInterpreter { } public String[] buildCommandLine(FilePath script) { - if(command.startsWith("#!")) { + if (command.startsWith("#!")) { // interpreter override int end = command.indexOf('\n'); - if(end<0) end=command.length(); + if (end < 0) { + end = command.length(); + } List<String> args = new ArrayList<String>(); - args.addAll(Arrays.asList(Util.tokenize(command.substring(0,end).trim()))); + args.addAll(Arrays.asList(Util.tokenize(command.substring(0, end).trim()))); args.add(script.getRemote()); - args.set(0,args.get(0).substring(2)); // trim off "#!" + args.set(0, args.get(0).substring(2)); // trim off "#!" return args.toArray(new String[args.size()]); - } else - return new String[] { getDescriptor().getShellOrDefault(),"-xe",script.getRemote()}; + } else { + return new String[]{getDescriptor().getShellOrDefault(), "-xe", script.getRemote()}; + } } protected String getContents() { @@ -95,11 +99,12 @@ public class Shell extends CommandInterpreter { @Override public DescriptorImpl getDescriptor() { - return (DescriptorImpl)super.getDescriptor(); + return (DescriptorImpl) super.getDescriptor(); } @Extension public static final class DescriptorImpl extends BuildStepDescriptor<Builder> { + /** * Shell executable, or null to default. */ @@ -118,8 +123,9 @@ public class Shell extends CommandInterpreter { } public String getShellOrDefault() { - if(shell==null) - return Functions.isWindows() ?"sh":"/bin/sh"; + if (shell == null) { + return Functions.isWindows() ? "sh" : "/bin/sh"; + } return shell; } @@ -148,7 +154,7 @@ public class Shell extends CommandInterpreter { */ public FormValidation doCheck(@QueryParameter String value) { // Executable requires admin permission - return FormValidation.validateExecutable(value); + return FormValidation.validateExecutable(value); } } } diff --git a/hudson-core/src/main/java/hudson/tasks/UserNameResolver.java b/hudson-core/src/main/java/hudson/tasks/UserNameResolver.java index 7298166..ff3bd79 100644 --- a/hudson-core/src/main/java/hudson/tasks/UserNameResolver.java +++ b/hudson-core/src/main/java/hudson/tasks/UserNameResolver.java @@ -7,10 +7,10 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: -* -* Kohsuke Kawaguchi, Tom Huybrechts - * + * Contributors: + * + * Kohsuke Kawaguchi, Tom Huybrechts + * * *******************************************************************************/ @@ -28,9 +28,9 @@ import java.util.List; /** * Finds full name off the user when none is specified. * - * <p> - * This is an extension point of Hudson. Plugins tha contribute new implementation - * of this class should use {@link Extension} to register the instance into Hudson, like this: + * <p> This is an extension point of Hudson. Plugins tha contribute new + * implementation of this class should use {@link Extension} to register the + * instance into Hudson, like this: * * <pre> * @Extension @@ -47,26 +47,25 @@ public abstract class UserNameResolver implements ExtensionPoint { /** * Finds full name of the given user. * - * <p> - * This method is called when a {@link User} without explicitly name is used. + * <p> This method is called when a {@link User} without explicitly name is + * used. * - * <p> - * When multiple resolvers are installed, they are consulted in order and - * the search will be over when a name is found by someoene. + * <p> When multiple resolvers are installed, they are consulted in order + * and the search will be over when a name is found by someoene. * - * <p> - * Since {@link UserNameResolver} is singleton, this method can be invoked concurrently - * from multiple threads. + * <p> Since {@link UserNameResolver} is singleton, this method can be + * invoked concurrently from multiple threads. * - * @return - * null if the inference failed. + * @return null if the inference failed. */ public abstract String findNameFor(User u); - + public static String resolve(User u) { for (UserNameResolver r : all()) { String name = r.findNameFor(u); - if(name!=null) return name; + if (name != null) { + return name; + } } return null; @@ -78,12 +77,11 @@ public abstract class UserNameResolver implements ExtensionPoint { public static ExtensionList<UserNameResolver> all() { return Hudson.getInstance().getExtensionList(UserNameResolver.class); } - /** * All registered {@link UserNameResolver} implementations. * - * @deprecated since 2009-02-24. - * Use {@link #all()} for read access, and use {@link Extension} for registration. + * @deprecated since 2009-02-24. Use {@link #all()} for read access, and use + * {@link Extension} for registration. */ public static final List<UserNameResolver> LIST = ExtensionListView.createList(UserNameResolver.class); } diff --git a/hudson-core/src/main/java/hudson/tasks/_ant/AntConsoleAnnotator.java b/hudson-core/src/main/java/hudson/tasks/_ant/AntConsoleAnnotator.java index 167f8c4..4fc2c7e 100644 --- a/hudson-core/src/main/java/hudson/tasks/_ant/AntConsoleAnnotator.java +++ b/hudson-core/src/main/java/hudson/tasks/_ant/AntConsoleAnnotator.java @@ -7,10 +7,10 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: + * Contributors: + * + * * - * - * * *******************************************************************************/ @@ -24,15 +24,16 @@ import java.nio.ByteBuffer; import java.nio.charset.Charset; /** - * Filter {@link OutputStream} that places an annotation that marks Ant target execution. - * + * Filter {@link OutputStream} that places an annotation that marks Ant target + * execution. + * * @author Kohsuke Kawaguchi * @sine 1.349 */ public class AntConsoleAnnotator extends LineTransformationOutputStream { + private final OutputStream out; private final Charset charset; - private boolean seenEmptyLine; public AntConsoleAnnotator(OutputStream out, Charset charset) { @@ -47,20 +48,22 @@ public class AntConsoleAnnotator extends LineTransformationOutputStream { // trim off CR/LF from the end line = trimEOL(line); - if (seenEmptyLine && endsWith(line,':') && line.indexOf(' ')<0) - // put the annotation + if (seenEmptyLine && endsWith(line, ':') && line.indexOf(' ') < 0) // put the annotation + { new AntTargetNote().encodeTo(out); + } - if (line.equals("BUILD SUCCESSFUL") || line.equals("BUILD FAILED")) + if (line.equals("BUILD SUCCESSFUL") || line.equals("BUILD FAILED")) { new AntOutcomeNote().encodeTo(out); + } - seenEmptyLine = line.length()==0; - out.write(b,0,len); + seenEmptyLine = line.length() == 0; + out.write(b, 0, len); } private boolean endsWith(String line, char c) { int len = line.length(); - return len>0 && line.charAt(len-1)==c; + return len > 0 && line.charAt(len - 1) == c; } @Override @@ -68,5 +71,4 @@ public class AntConsoleAnnotator extends LineTransformationOutputStream { super.close(); out.close(); } - } diff --git a/hudson-core/src/main/java/hudson/tasks/_ant/AntOutcomeNote.java b/hudson-core/src/main/java/hudson/tasks/_ant/AntOutcomeNote.java index ea72dd3..eca3bfa 100644 --- a/hudson-core/src/main/java/hudson/tasks/_ant/AntOutcomeNote.java +++ b/hudson-core/src/main/java/hudson/tasks/_ant/AntOutcomeNote.java @@ -7,10 +7,10 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: + * Contributors: + * + * * - * - * * *******************************************************************************/ @@ -28,20 +28,24 @@ import hudson.console.ConsoleNote; * @author Kohsuke Kawaguchi */ public class AntOutcomeNote extends ConsoleNote { + public AntOutcomeNote() { } @Override public ConsoleAnnotator annotate(Object context, MarkupText text, int charPos) { - if (text.getText().contains("FAIL")) - text.addMarkup(0,text.length(),"<span class=ant-outcome-failure>","</span>"); - if (text.getText().contains("SUCCESS")) - text.addMarkup(0,text.length(),"<span class=ant-outcome-success>","</span>"); + if (text.getText().contains("FAIL")) { + text.addMarkup(0, text.length(), "<span class=ant-outcome-failure>", "</span>"); + } + if (text.getText().contains("SUCCESS")) { + text.addMarkup(0, text.length(), "<span class=ant-outcome-success>", "</span>"); + } return null; } @Extension public static final class DescriptorImpl extends ConsoleAnnotationDescriptor { + public String getDisplayName() { return "Ant build outcome"; } diff --git a/hudson-core/src/main/java/hudson/tasks/_ant/AntTargetNote.java b/hudson-core/src/main/java/hudson/tasks/_ant/AntTargetNote.java index 96132bd..be6c680 100644 --- a/hudson-core/src/main/java/hudson/tasks/_ant/AntTargetNote.java +++ b/hudson-core/src/main/java/hudson/tasks/_ant/AntTargetNote.java @@ -7,10 +7,10 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: + * Contributors: + * + * * - * - * * *******************************************************************************/ @@ -25,30 +25,36 @@ import hudson.console.ConsoleAnnotator; import java.util.regex.Pattern; /** - * Marks the log line "TARGET:" that Ant uses to mark the beginning of the new target. + * Marks the log line "TARGET:" that Ant uses to mark the beginning of the new + * target. + * * @sine 1.349 */ public final class AntTargetNote extends ConsoleNote { + public AntTargetNote() { } @Override public ConsoleAnnotator annotate(Object context, MarkupText text, int charPos) { // still under development. too early to put into production - if (!ENABLED) return null; + if (!ENABLED) { + return null; + } MarkupText.SubText t = text.findToken(Pattern.compile(".*(?=:)")); - if (t!=null) - t.addMarkup(0,t.length(),"<b class=ant-target>","</b>"); + if (t != null) { + t.addMarkup(0, t.length(), "<b class=ant-target>", "</b>"); + } return null; } @Extension public static final class DescriptorImpl extends ConsoleAnnotationDescriptor { + public String getDisplayName() { return "Ant targets"; } } - - public static boolean ENABLED = !Boolean.getBoolean(AntTargetNote.class.getName()+".disabled"); + public static boolean ENABLED = !Boolean.getBoolean(AntTargetNote.class.getName() + ".disabled"); } diff --git a/hudson-core/src/main/java/hudson/tasks/_maven/MavenConsoleAnnotator.java b/hudson-core/src/main/java/hudson/tasks/_maven/MavenConsoleAnnotator.java index cf7a878..99639fa 100644 --- a/hudson-core/src/main/java/hudson/tasks/_maven/MavenConsoleAnnotator.java +++ b/hudson-core/src/main/java/hudson/tasks/_maven/MavenConsoleAnnotator.java @@ -7,10 +7,10 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: + * Contributors: + * + * * - * - * * *******************************************************************************/ @@ -25,11 +25,13 @@ import java.nio.charset.Charset; import java.util.regex.Matcher; /** - * Filter {@link OutputStream} that places annotations that marks various Maven outputs. + * Filter {@link OutputStream} that places annotations that marks various Maven + * outputs. * * @author Kohsuke Kawaguchi */ public class MavenConsoleAnnotator extends LineTransformationOutputStream { + private final OutputStream out; private final Charset charset; @@ -50,18 +52,21 @@ public class MavenConsoleAnnotator extends LineTransformationOutputStream { // we also need the ability for an extension point to have notes hook into the processing Matcher m = MavenMojoNote.PATTERN.matcher(line); - if (m.matches()) + if (m.matches()) { new MavenMojoNote().encodeTo(out); + } m = MavenWarningNote.PATTERN.matcher(line); - if (m.find()) + if (m.find()) { new MavenWarningNote().encodeTo(out); + } m = MavenErrorNote.PATTERN.matcher(line); - if (m.find()) + if (m.find()) { new MavenErrorNote().encodeTo(out); + } - out.write(b,0,len); + out.write(b, 0, len); } @Override diff --git a/hudson-core/src/main/java/hudson/tasks/_maven/MavenErrorNote.java b/hudson-core/src/main/java/hudson/tasks/_maven/MavenErrorNote.java index f914177..ee48315 100644 --- a/hudson-core/src/main/java/hudson/tasks/_maven/MavenErrorNote.java +++ b/hudson-core/src/main/java/hudson/tasks/_maven/MavenErrorNote.java @@ -7,10 +7,10 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: + * Contributors: + * + * * - * - * * *******************************************************************************/ @@ -28,22 +28,22 @@ import java.util.regex.Pattern; * @author Kohsuke Kawaguchi */ public class MavenErrorNote extends ConsoleNote { + public MavenErrorNote() { } @Override public ConsoleAnnotator annotate(Object context, MarkupText text, int charPos) { - text.addMarkup(0,text.length(),"<span class=error-inline>","</span>"); + text.addMarkup(0, text.length(), "<span class=error-inline>", "</span>"); return null; } @Extension public static final class DescriptorImpl extends ConsoleAnnotationDescriptor { + public String getDisplayName() { return "Maven Errors"; } } - public static Pattern PATTERN = Pattern.compile("^\\[ERROR\\]"); } - diff --git a/hudson-core/src/main/java/hudson/tasks/_maven/MavenMojoNote.java b/hudson-core/src/main/java/hudson/tasks/_maven/MavenMojoNote.java index c64317a..3b3e335 100644 --- a/hudson-core/src/main/java/hudson/tasks/_maven/MavenMojoNote.java +++ b/hudson-core/src/main/java/hudson/tasks/_maven/MavenMojoNote.java @@ -7,10 +7,10 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: + * Contributors: + * + * * - * - * * *******************************************************************************/ @@ -25,29 +25,30 @@ import hudson.console.ConsoleNote; import java.util.regex.Pattern; /** - * Marks the log line that reports that Maven is executing a mojo. - * It'll look something like this: + * Marks the log line that reports that Maven is executing a mojo. It'll look + * something like this: * * <pre>[INFO] [pmd:pmd {execution: default}]</pre> * * @author Kohsuke Kawaguchi */ public class MavenMojoNote extends ConsoleNote { + public MavenMojoNote() { } @Override public ConsoleAnnotator annotate(Object context, MarkupText text, int charPos) { - text.addMarkup(7,text.length(),"<b class=maven-mojo>","</b>"); + text.addMarkup(7, text.length(), "<b class=maven-mojo>", "</b>"); return null; } @Extension public static final class DescriptorImpl extends ConsoleAnnotationDescriptor { + public String getDisplayName() { return "Maven Mojos"; } } - public static Pattern PATTERN = Pattern.compile("\\[INFO\\] \\[[A-Za-z0-9-_]+:[A-Za-z0-9-_]+ \\{execution: [A-Za-z0-9-_]+\\}\\]"); } diff --git a/hudson-core/src/main/java/hudson/tasks/_maven/MavenWarningNote.java b/hudson-core/src/main/java/hudson/tasks/_maven/MavenWarningNote.java index 4a6c7e9..1298b63 100644 --- a/hudson-core/src/main/java/hudson/tasks/_maven/MavenWarningNote.java +++ b/hudson-core/src/main/java/hudson/tasks/_maven/MavenWarningNote.java @@ -7,10 +7,10 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: + * Contributors: + * + * * - * - * * *******************************************************************************/ @@ -30,21 +30,22 @@ import java.util.regex.Pattern; * @author Kohsuke Kawaguchi */ public class MavenWarningNote extends ConsoleNote { + public MavenWarningNote() { } @Override public ConsoleAnnotator annotate(Object context, MarkupText text, int charPos) { - text.addMarkup(0,text.length(),"<span class=warning-inline>","</span>"); + text.addMarkup(0, text.length(), "<span class=warning-inline>", "</span>"); return null; } @Extension public static final class DescriptorImpl extends ConsoleAnnotationDescriptor { + public String getDisplayName() { return "Maven Warnings"; } } - public static Pattern PATTERN = Pattern.compile("^\\[WARNING\\]"); } diff --git a/hudson-core/src/main/java/hudson/tasks/junit/CaseResult.java b/hudson-core/src/main/java/hudson/tasks/junit/CaseResult.java index 4d67e15..fdede21 100644 --- a/hudson-core/src/main/java/hudson/tasks/junit/CaseResult.java +++ b/hudson-core/src/main/java/hudson/tasks/junit/CaseResult.java @@ -7,10 +7,10 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: -* -* Kohsuke Kawaguchi, Daniel Dyer, Seiji Sogabe, Tom Huybrechts, Yahoo!, Inc. - * + * Contributors: + * + * Kohsuke Kawaguchi, Daniel Dyer, Seiji Sogabe, Tom Huybrechts, Yahoo!, Inc. + * * *******************************************************************************/ @@ -36,11 +36,12 @@ import static java.util.Collections.emptyList; * @author Kohsuke Kawaguchi */ public final class CaseResult extends TestResult implements Comparable<CaseResult> { + private static final Logger LOGGER = Logger.getLogger(CaseResult.class.getName()); private final float duration; /** - * In JUnit, a test is a method of a class. This field holds the fully qualified class name - * that the test was in. + * In JUnit, a test is a method of a class. This field holds the fully + * qualified class name that the test was in. */ private final String className; /** @@ -51,18 +52,16 @@ public final class CaseResult extends TestResult implements Comparable<CaseResul private final String errorStackTrace; private final String errorDetails; private transient SuiteResult parent; - private transient ClassResult classResult; - /** - * Some tools report stdout and stderr at testcase level (such as Maven surefire plugin), others do so at - * the suite level (such as Ant JUnit task.) + * Some tools report stdout and stderr at testcase level (such as Maven + * surefire plugin), others do so at the suite level (such as Ant JUnit + * task.) * - * If these information are reported at the test case level, these fields are set, - * otherwise null, in which case {@link SuiteResult#stdout}. + * If these information are reported at the test case level, these fields + * are set, otherwise null, in which case {@link SuiteResult#stdout}. */ - private final String stdout,stderr; - + private final String stdout, stderr; /** * This test has been failing since this build number (not id.) * @@ -72,8 +71,8 @@ public final class CaseResult extends TestResult implements Comparable<CaseResul private static float parseTime(Element testCase) { String time = testCase.attributeValue("time"); - if(time!=null) { - time = time.replace(",",""); + if (time != null) { + time = time.replace(",", ""); try { return Float.parseFloat(time); } catch (NumberFormatException e) { @@ -100,14 +99,14 @@ public final class CaseResult extends TestResult implements Comparable<CaseResul /* - According to http://www.nabble.com/NPE-(Fatal%3A-Null)-in-recording-junit-test-results-td23562964.html - there's some odd-ball cases where testClassName is null but - @name contains fully qualified name. + According to http://www.nabble.com/NPE-(Fatal%3A-Null)-in-recording-junit-test-results-td23562964.html + there's some odd-ball cases where testClassName is null but + @name contains fully qualified name. */ String nameAttr = testCase.attributeValue("name"); - if(testClassName==null && nameAttr.contains(".")) { - testClassName = nameAttr.substring(0,nameAttr.lastIndexOf('.')); - nameAttr = nameAttr.substring(nameAttr.lastIndexOf('.')+1); + if (testClassName == null && nameAttr.contains(".")) { + testClassName = nameAttr.substring(0, nameAttr.lastIndexOf('.')); + nameAttr = nameAttr.substring(nameAttr.lastIndexOf('.') + 1); } className = testClassName; @@ -122,8 +121,8 @@ public final class CaseResult extends TestResult implements Comparable<CaseResul stdout = possiblyTrimStdio(_this, keepLongStdio, testCase.elementText("system-out")); stderr = possiblyTrimStdio(_this, keepLongStdio, testCase.elementText("system-err")); } - private static final int HALF_MAX_SIZE = 500; + static String possiblyTrimStdio(Collection<CaseResult> results, boolean keepLongStdio, String stdio) { // HUDSON-6516 if (stdio == null) { return null; @@ -145,7 +144,8 @@ public final class CaseResult extends TestResult implements Comparable<CaseResul } /** - * Used to create a fake failure, when Hudson fails to load data from XML files. + * Used to create a fake failure, when Hudson fails to load data from XML + * files. */ CaseResult(SuiteResult parent, String testName, String errorStackTrace) { this.className = parent == null ? "unnamed" : parent.getName(); @@ -158,15 +158,16 @@ public final class CaseResult extends TestResult implements Comparable<CaseResul this.duration = 0.0f; this.skipped = false; } - + public ClassResult getParent() { - return classResult; + return classResult; } private static String getError(Element testCase) { String msg = testCase.elementText("error"); - if(msg!=null) + if (msg != null) { return msg; + } return testCase.elementText("failure"); } @@ -184,8 +185,8 @@ public final class CaseResult extends TestResult implements Comparable<CaseResul } /** - * If the testCase element includes the skipped element (as output by TestNG), then - * the test has neither passed nor failed, it was never run. + * If the testCase element includes the skipped element (as output by + * TestNG), then the test has neither passed nor failed, it was never run. */ private static boolean isMarkedAsSkipped(Element testCase) { return testCase.element("skipped") != null; @@ -196,13 +197,14 @@ public final class CaseResult extends TestResult implements Comparable<CaseResul } /** - * Gets the name of the test, which is returned from {@code TestCase.getName()} + * Gets the name of the test, which is returned from + * {@code TestCase.getName()} * - * <p> - * Note that this may contain any URL-unfriendly character. + * <p> Note that this may contain any URL-unfriendly character. */ - @Exported(visibility=999) - public @Override String getName() { + @Exported(visibility = 999) + public @Override + String getName() { return testName; } @@ -217,7 +219,7 @@ public final class CaseResult extends TestResult implements Comparable<CaseResul /** * Gets the duration of the test, in seconds */ - @Exported(visibility=9) + @Exported(visibility = 9) public float getDuration() { return duration; } @@ -225,21 +227,23 @@ public final class CaseResult extends TestResult implements Comparable<CaseResul /** * Gets the version of {@link #getName()} that's URL-safe. */ - public @Override String getSafeName() { + public @Override + String getSafeName() { StringBuilder buf = new StringBuilder(testName); - for( int i=0; i<buf.length(); i++ ) { + for (int i = 0; i < buf.length(); i++) { char ch = buf.charAt(i); - if(!Character.isJavaIdentifierPart(ch)) - buf.setCharAt(i,'_'); + if (!Character.isJavaIdentifierPart(ch)) { + buf.setCharAt(i, '_'); + } } - Collection<CaseResult> siblings = (classResult ==null ? Collections.<CaseResult>emptyList(): classResult.getChildren()); + Collection<CaseResult> siblings = (classResult == null ? Collections.<CaseResult>emptyList() : classResult.getChildren()); return uniquifyName(siblings, buf.toString()); } /** * Gets the class name of a test class. */ - @Exported(visibility=9) + @Exported(visibility = 9) public String getClassName() { return className; } @@ -249,7 +253,7 @@ public final class CaseResult extends TestResult implements Comparable<CaseResul */ public String getSimpleName() { int idx = className.lastIndexOf('.'); - return className.substring(idx+1); + return className.substring(idx + 1); } /** @@ -257,23 +261,33 @@ public final class CaseResult extends TestResult implements Comparable<CaseResul */ public String getPackageName() { int idx = className.lastIndexOf('.'); - if(idx<0) return "(root)"; - else return className.substring(0,idx); + if (idx < 0) { + return "(root)"; + } else { + return className.substring(0, idx); + } } public String getFullName() { - return className+'.'+getName(); + return className + '.' + getName(); } - @Override public int getFailCount() { - if (!isPassed() && !isSkipped()) return 1; else return 0; + if (!isPassed() && !isSkipped()) { + return 1; + } else { + return 0; + } } @Override public int getSkipCount() { - if (isSkipped()) return 1; else return 0; + if (isSkipped()) { + return 1; + } else { + return 0; + } } @Override @@ -282,18 +296,18 @@ public final class CaseResult extends TestResult implements Comparable<CaseResul } /** - * If this test failed, then return the build number - * when this test started failing. + * If this test failed, then return the build number when this test started + * failing. */ - @Exported(visibility=9) + @Exported(visibility = 9) public int getFailedSince() { // If we haven't calculated failedSince yet, and we should, // do it now. - if (failedSince==0 && getFailCount()==1) { + if (failedSince == 0 && getFailCount() == 1) { CaseResult prev = getPreviousResult(); - if(prev!=null && !prev.isPassed()) + if (prev != null && !prev.isPassed()) { this.failedSince = prev.failedSince; - else if (getOwner() != null) { + } else if (getOwner() != null) { this.failedSince = getOwner().getNumber(); } else { LOGGER.warning("trouble calculating getFailedSince. We've got prev, but no owner."); @@ -302,45 +316,50 @@ public final class CaseResult extends TestResult implements Comparable<CaseResul } return failedSince; } - - public Run<?,?> getFailedSinceRun() { - return getOwner().getParent().getBuildByNumber(getFailedSince()); + + public Run<?, ?> getFailedSinceRun() { + return getOwner().getParent().getBuildByNumber(getFailedSince()); } /** - * Gets the number of consecutive builds (including this) - * that this test case has been failing. + * Gets the number of consecutive builds (including this) that this test + * case has been failing. */ - @Exported(visibility=9) + @Exported(visibility = 9) public int getAge() { - if(isPassed()) + if (isPassed()) { return 0; - else if (getOwner() != null) { - return getOwner().getNumber()-getFailedSince()+1; + } else if (getOwner() != null) { + return getOwner().getNumber() - getFailedSince() + 1; } else { LOGGER.fine("Trying to get age of a CaseResult without an owner"); - return 0; - } + return 0; + } } /** * The stdout of this test. * - * <p> - * Depending on the tool that produced the XML report, this method works somewhat inconsistently. - * With some tools (such as Maven surefire plugin), you get the accurate information, that is - * the stdout from this test case. With some other tools (such as the JUnit task in Ant), this - * method returns the stdout produced by the entire test suite. + * <p> Depending on the tool that produced the XML report, this method works + * somewhat inconsistently. With some tools (such as Maven surefire plugin), + * you get the accurate information, that is the stdout from this test case. + * With some other tools (such as the JUnit task in Ant), this method + * returns the stdout produced by the entire test suite. + * + * <p> If you need to know which is the case, compare this output from + * {@link SuiteResult#getStdout()}. * - * <p> - * If you need to know which is the case, compare this output from {@link SuiteResult#getStdout()}. * @since 1.294 */ @Exported public String getStdout() { - if(stdout!=null) return stdout; + if (stdout != null) { + return stdout; + } SuiteResult sr = getSuiteResult(); - if (sr==null) return ""; + if (sr == null) { + return ""; + } return getSuiteResult().getStdout(); } @@ -352,29 +371,38 @@ public final class CaseResult extends TestResult implements Comparable<CaseResul */ @Exported public String getStderr() { - if(stderr!=null) return stderr; + if (stderr != null) { + return stderr; + } SuiteResult sr = getSuiteResult(); - if (sr==null) return ""; + if (sr == null) { + return ""; + } return getSuiteResult().getStderr(); } @Override public CaseResult getPreviousResult() { - if (parent == null) return null; + if (parent == null) { + return null; + } SuiteResult pr = parent.getPreviousResult(); - if(pr==null) return null; + if (pr == null) { + return null; + } return pr.getCase(getName()); } - + /** * Case results have no children + * * @return null */ @Override public TestResult findCorrespondingResult(String id) { if (id.equals(safe(getName()))) { return this; - } + } return null; } @@ -409,14 +437,16 @@ public final class CaseResult extends TestResult implements Comparable<CaseResul } private Collection<? extends hudson.tasks.test.TestResult> singletonListOrEmpty(boolean f) { - if (f) + if (f) { return Collections.singletonList(this); - else + } else { return emptyList(); + } } /** - * If there was an error or a failure, this is the stack trace, or otherwise null. + * If there was an error or a failure, this is the stack trace, or otherwise + * null. */ @Exported public String getErrorStackTrace() { @@ -432,19 +462,21 @@ public final class CaseResult extends TestResult implements Comparable<CaseResul } /** - * @return true if the test was not skipped and did not fail, false otherwise. + * @return true if the test was not skipped and did not fail, false + * otherwise. */ public boolean isPassed() { - return !skipped && errorStackTrace==null; + return !skipped && errorStackTrace == null; } /** - * Tests whether the test was skipped or not. TestNG allows tests to be + * Tests whether the test was skipped or not. TestNG allows tests to be * skipped if their dependencies fail or they are part of a group that has * been configured to be skipped. + * * @return true if the test was not executed, false otherwise. */ - @Exported(visibility=9) + @Exported(visibility = 9) public boolean isSkipped() { return skipped; } @@ -452,31 +484,36 @@ public final class CaseResult extends TestResult implements Comparable<CaseResul public SuiteResult getSuiteResult() { return parent; } - + @Override - public AbstractBuild<?,?> getOwner() { + public AbstractBuild<?, ?> getOwner() { SuiteResult sr = getSuiteResult(); - if (sr==null) { - LOGGER.warning("In getOwner(), getSuiteResult is null"); return null; } + if (sr == null) { + LOGGER.warning("In getOwner(), getSuiteResult is null"); + return null; + } hudson.tasks.junit.TestResult tr = sr.getParent(); - if (tr==null) { - LOGGER.warning("In getOwner(), suiteResult.getParent() is null."); return null; } - return tr.getOwner(); + if (tr == null) { + LOGGER.warning("In getOwner(), suiteResult.getParent() is null."); + return null; + } + return tr.getOwner(); } public void setParentSuiteResult(SuiteResult parent) { this.parent = parent; - } + } public void freeze(SuiteResult parent) { this.parent = parent; // some old test data doesn't have failedSince value set, so for those compute them. - if(!isPassed() && failedSince==0) { + if (!isPassed() && failedSince == 0) { CaseResult prev = getPreviousResult(); - if(prev!=null && !prev.isPassed()) + if (prev != null && !prev.isPassed()) { this.failedSince = prev.failedSince; - else + } else { this.failedSince = getOwner().getNumber(); + } } } @@ -484,17 +521,17 @@ public final class CaseResult extends TestResult implements Comparable<CaseResul return this.getFullName().compareTo(that.getFullName()); } - @Exported(name="status",visibility=9) // because stapler notices suffix 's' and remove it + @Exported(name = "status", visibility = 9) // because stapler notices suffix 's' and remove it public Status getStatus() { if (skipped) { return Status.SKIPPED; } CaseResult pr = getPreviousResult(); - if(pr==null) { + if (pr == null) { return isPassed() ? Status.PASSED : Status.FAILED; } - if(pr.isPassed()) { + if (pr.isPassed()) { return isPassed() ? Status.PASSED : Status.REGRESSION; } else { return isPassed() ? Status.FIXED : Status.FAILED; @@ -509,37 +546,37 @@ public final class CaseResult extends TestResult implements Comparable<CaseResul * Constants that represent the status of this test. */ public enum Status { + /** * This test runs OK, just like its previous run. */ - PASSED("result-passed",Messages._CaseResult_Status_Passed(),true), + PASSED("result-passed", Messages._CaseResult_Status_Passed(), true), /** - * This test was skipped due to configuration or the - * failure or skipping of a method that it depends on. + * This test was skipped due to configuration or the failure or skipping + * of a method that it depends on. */ - SKIPPED("result-skipped",Messages._CaseResult_Status_Skipped(),false), + SKIPPED("result-skipped", Messages._CaseResult_Status_Skipped(), false), /** * This test failed, just like its previous run. */ - FAILED("result-failed",Messages._CaseResult_Status_Failed(),false), + FAILED("result-failed", Messages._CaseResult_Status_Failed(), false), /** * This test has been failing, but now it runs OK. */ - FIXED("result-fixed",Messages._CaseResult_Status_Fixed(),true), + FIXED("result-fixed", Messages._CaseResult_Status_Fixed(), true), /** * This test has been running OK, but now it failed. */ - REGRESSION("result-regression",Messages._CaseResult_Status_Regression(),false); - + REGRESSION("result-regression", Messages._CaseResult_Status_Regression(), false); private final String cssClass; private final Localizable message; public final boolean isOK; Status(String cssClass, Localizable message, boolean OK) { - this.cssClass = cssClass; - this.message = message; - isOK = OK; - } + this.cssClass = cssClass; + this.message = message; + isOK = OK; + } public String getCssClass() { return cssClass; @@ -550,18 +587,16 @@ public final class CaseResult extends TestResult implements Comparable<CaseResul } public boolean isRegression() { - return this==REGRESSION; + return this == REGRESSION; } } - /** * For sorting errors by age. */ /*package*/ static final Comparator<CaseResult> BY_AGE = new Comparator<CaseResult>() { public int compare(CaseResult lhs, CaseResult rhs) { - return lhs.getAge()-rhs.getAge(); + return lhs.getAge() - rhs.getAge(); } }; - private static final long serialVersionUID = 1L; } diff --git a/hudson-core/src/main/java/hudson/tasks/junit/ClassResult.java b/hudson-core/src/main/java/hudson/tasks/junit/ClassResult.java index 8580547..5da6757 100644 --- a/hudson-core/src/main/java/hudson/tasks/junit/ClassResult.java +++ b/hudson-core/src/main/java/hudson/tasks/junit/ClassResult.java @@ -7,10 +7,10 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: -* -* Kohsuke Kawaguchi, Daniel Dyer, id:cactusman, Tom Huybrechts, Yahoo!, Inc. - * + * Contributors: + * + * Kohsuke Kawaguchi, Daniel Dyer, id:cactusman, Tom Huybrechts, Yahoo!, Inc. + * * *******************************************************************************/ @@ -34,14 +34,11 @@ import java.util.List; * @author Kohsuke Kawaguchi */ public final class ClassResult extends TabulatedResult implements Comparable<ClassResult> { - private final String className; // simple name + private final String className; // simple name private final List<CaseResult> cases = new ArrayList<CaseResult>(); - - private int passCount,failCount,skipCount; - - private float duration; - + private int passCount, failCount, skipCount; + private float duration; private final PackageResult parent; ClassResult(PackageResult parent, String className) { @@ -51,7 +48,7 @@ public final class ClassResult extends TabulatedResult implements Comparable<Cla @Override public AbstractBuild<?, ?> getOwner() { - return (parent==null ? null: parent.getOwner()); + return (parent == null ? null : parent.getOwner()); } public PackageResult getParent() { @@ -60,12 +57,16 @@ public final class ClassResult extends TabulatedResult implements Comparable<Cla @Override public ClassResult getPreviousResult() { - if(parent==null) return null; + if (parent == null) { + return null; + } TestResult pr = parent.getPreviousResult(); - if(pr==null) return null; - if(pr instanceof PackageResult) { - return ((PackageResult)pr).getClassResult(getName()); - } + if (pr == null) { + return null; + } + if (pr instanceof PackageResult) { + return ((PackageResult) pr).getClassResult(getName()); + } return null; } @@ -79,7 +80,7 @@ public final class ClassResult extends TabulatedResult implements Comparable<Cla caseName = id.substring(caseNameStart); } else { caseName = id; - } + } CaseResult child = getCaseResult(caseName); if (child != null) { @@ -95,40 +96,44 @@ public final class ClassResult extends TabulatedResult implements Comparable<Cla @Override public String getChildTitle() { - return "Class Reults"; + return "Class Reults"; } - @Exported(visibility=999) + @Exported(visibility = 999) public String getName() { int idx = className.lastIndexOf('.'); - if(idx<0) return className; - else return className.substring(idx+1); + if (idx < 0) { + return className; + } else { + return className.substring(idx + 1); + } } - public @Override String getSafeName() { + public @Override + String getSafeName() { return uniquifyName(parent.getChildren(), safe(getName())); } - + public CaseResult getCaseResult(String name) { for (CaseResult c : cases) { - if(c.getSafeName().equals(name)) + if (c.getSafeName().equals(name)) { return c; + } } return null; } @Override public Object getDynamic(String name, StaplerRequest req, StaplerResponse rsp) { - CaseResult c = getCaseResult(name); - if (c != null) { + CaseResult c = getCaseResult(name); + if (c != null) { return c; - } else { + } else { return super.getDynamic(name, req, rsp); - } + } } - - @Exported(name="child") + @Exported(name = "child") public List<CaseResult> getChildren() { return cases; } @@ -139,9 +144,9 @@ public final class ClassResult extends TabulatedResult implements Comparable<Cla // TODO: wait for stapler 1.60 @Exported public float getDuration() { - return duration; + return duration; } - + @Exported public int getPassCount() { return passCount; @@ -166,36 +171,31 @@ public final class ClassResult extends TabulatedResult implements Comparable<Cla */ @Override public void tally() { - passCount=failCount=skipCount=0; - duration=0; + passCount = failCount = skipCount = 0; + duration = 0; for (CaseResult r : cases) { r.setClass(this); if (r.isSkipped()) { skipCount++; - } - else if(r.isPassed()) { + } else if (r.isPassed()) { passCount++; - } - else { + } else { failCount++; } duration += r.getDuration(); } } - void freeze() { - passCount=failCount=skipCount=0; - duration=0; + passCount = failCount = skipCount = 0; + duration = 0; for (CaseResult r : cases) { r.setClass(this); if (r.isSkipped()) { skipCount++; - } - else if(r.isPassed()) { + } else if (r.isPassed()) { passCount++; - } - else { + } else { failCount++; } duration += r.getDuration(); @@ -204,7 +204,7 @@ public final class ClassResult extends TabulatedResult implements Comparable<Cla } public String getClassName() { - return className; + return className; } public int compareTo(ClassResult that) { @@ -214,9 +214,9 @@ public final class ClassResult extends TabulatedResult implements Comparable<Cla public String getDisplayName() { return getName(); } - + public String getFullName() { - return getParent().getDisplayName() + "." + className; + return getParent().getDisplayName() + "." + className; } /** @@ -224,8 +224,8 @@ public final class ClassResult extends TabulatedResult implements Comparable<Cla */ @Override public String getRelativePathFrom(TestObject it) { - if(it instanceof CaseResult) { - return ".."; + if (it instanceof CaseResult) { + return ".."; } else { return super.getRelativePathFrom(it); } diff --git a/hudson-core/src/main/java/hudson/tasks/junit/History.java b/hudson-core/src/main/java/hudson/tasks/junit/History.java index 1771144..2e54e07 100644 --- a/hudson-core/src/main/java/hudson/tasks/junit/History.java +++ b/hudson-core/src/main/java/hudson/tasks/junit/History.java @@ -7,10 +7,10 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: + * Contributors: * * Tom Huybrechts, Yahoo!, Inc., Seiji Sogabe, Winston Prakash - * + * * *******************************************************************************/ package hudson.tasks.junit; @@ -113,7 +113,7 @@ public class History { for (hudson.tasks.test.TestResult o : list) { xSeries.add(o.getOwner().getDisplayName()); - + double duration = o.getDuration() / 60; if (o.getFailCount() > 0) { ySeriesFailed.add(duration); @@ -131,7 +131,6 @@ public class History { // For backward compatibility with JFreechart data.add(duration, "", new HistoryChartLabel(o) { - @Override public Color getColor(int row, int column) { if (o.getFailCount() > 0) { @@ -159,18 +158,18 @@ public class History { private DataSet<String, HistoryChartLabel> getCountGraphDataSet() { DataSet<String, HistoryChartLabel> data = new DataSet<String, HistoryChartLabel>(); - + GraphSeries<String> xSeries = new GraphSeries<String>("Build No."); data.setXSeries(xSeries); - + GraphSeries<Number> ySeriesFailed = new GraphSeries<Number>(GraphSeries.TYPE_BAR, "Failed", ColorPalette.RED); //ySeriesFailed.setBaseURL(getRelPath(req)); data.addYSeries(ySeriesFailed); - + GraphSeries<Number> ySeriesSkipped = new GraphSeries<Number>(GraphSeries.TYPE_BAR, "Skipped", ColorPalette.YELLOW); //ySeriesSkipped.setBaseURL(getRelPath(req)); data.addYSeries(ySeriesSkipped); - + GraphSeries<Number> ySeriesPassed = new GraphSeries<Number>(GraphSeries.TYPE_BAR, "Passed", ColorPalette.BLUE); //ySeriesPassed.setBaseURL(getRelPath(req)); data.addYSeries(ySeriesPassed); @@ -186,10 +185,10 @@ public class History { for (TestResult o : list) { xSeries.add(o.getOwner().getDisplayName()); - ySeriesFailed.add((double)o.getFailCount()); - ySeriesSkipped.add((double)o.getSkipCount()); - ySeriesPassed.add((double)(o.getTotalCount() - o.getFailCount() - o.getSkipCount())); - + ySeriesFailed.add((double) o.getFailCount()); + ySeriesSkipped.add((double) o.getSkipCount()); + ySeriesPassed.add((double) (o.getTotalCount() - o.getFailCount() - o.getSkipCount())); + // For backward compatibility with JFreechart data.add(o.getPassCount(), "2Passed", new HistoryChartLabel(o)); data.add(o.getFailCount(), "1Failed", new HistoryChartLabel(o)); @@ -247,7 +246,7 @@ public class History { @Override public Color getColor(int row, int column) { - return ColorPalette.BLUE; + return ColorPalette.BLUE; } @Override diff --git a/hudson-core/src/main/java/hudson/tasks/junit/JUnitParser.java b/hudson-core/src/main/java/hudson/tasks/junit/JUnitParser.java index 8be714e..bc24896 100644 --- a/hudson-core/src/main/java/hudson/tasks/junit/JUnitParser.java +++ b/hudson-core/src/main/java/hudson/tasks/junit/JUnitParser.java @@ -7,10 +7,10 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: + * Contributors: + * + * * - * - * * *******************************************************************************/ @@ -30,21 +30,25 @@ import org.apache.tools.ant.DirectoryScanner; /** * Parse some JUnit xml files and generate a TestResult containing all the - * results parsed. + * results parsed. */ @Extension public class JUnitParser extends TestResultParser { private final boolean keepLongStdio; - /** XXX TestResultParser.all does not seem to ever be called so why must this be an Extension? */ + /** + * XXX TestResultParser.all does not seem to ever be called so why must this + * be an Extension? + */ @Deprecated public JUnitParser() { this(false); } /** - * @param keepLongStdio if true, retain a suite's complete stdout/stderr even if this is huge and the suite passed + * @param keepLongStdio if true, retain a suite's complete stdout/stderr + * even if this is huge and the suite passed * @since 1.358 */ public JUnitParser(boolean keepLongStdio) { @@ -63,22 +67,22 @@ public class JUnitParser extends TestResultParser { @Override public TestResult parse(String testResultLocations, - AbstractBuild build, Launcher launcher, - TaskListener listener) - throws InterruptedException, IOException - { + AbstractBuild build, Launcher launcher, + TaskListener listener) + throws InterruptedException, IOException { final long buildTime = build.getTimestamp().getTimeInMillis(); final long timeOnMaster = System.currentTimeMillis(); // [BUG 3123310] TODO - Test Result Refactor: review and fix TestDataPublisher/TestAction subsystem] // also get code that deals with testDataPublishers from JUnitResultArchiver.perform - - TestResult testResult = build.getWorkspace().act( new ParseResultCallable(testResultLocations, buildTime, timeOnMaster, keepLongStdio)); - return testResult; + + TestResult testResult = build.getWorkspace().act(new ParseResultCallable(testResultLocations, buildTime, timeOnMaster, keepLongStdio)); + return testResult; } private static final class ParseResultCallable implements FilePath.FileCallable<TestResult> { + private final long buildTime; private final String testResults; private final long nowMaster; @@ -106,8 +110,7 @@ public class JUnitParser extends TestResultParser { TestResult result = new TestResult(buildTime + (nowSlave - nowMaster), ds, keepLongStdio); result.tally(); - return result; + return result; } } - } diff --git a/hudson-core/src/main/java/hudson/tasks/junit/JUnitResultArchiver.java b/hudson-core/src/main/java/hudson/tasks/junit/JUnitResultArchiver.java index ae3da41..eb6eef7 100644 --- a/hudson-core/src/main/java/hudson/tasks/junit/JUnitResultArchiver.java +++ b/hudson-core/src/main/java/hudson/tasks/junit/JUnitResultArchiver.java @@ -7,10 +7,10 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: -* -* Kohsuke Kawaguchi, Martin Eigenbrodt, Tom Huybrechts, Yahoo!, Inc., Richard Hierlmeier - * + * Contributors: + * + * Kohsuke Kawaguchi, Martin Eigenbrodt, Tom Huybrechts, Yahoo!, Inc., Richard Hierlmeier + * * *******************************************************************************/ @@ -57,54 +57,56 @@ import java.util.List; /** * Generates HTML report from JUnit test result XML files. - * + * * @author Kohsuke Kawaguchi */ public class JUnitResultArchiver extends Recorder implements Serializable, - MatrixAggregatable { + MatrixAggregatable { /** * {@link FileSet} "includes" string, like "foo/bar/*.xml" */ private final String testResults; - /** - * If true, retain a suite's complete stdout/stderr even if this is huge and the suite passed. + * If true, retain a suite's complete stdout/stderr even if this is huge and + * the suite passed. + * * @since 1.358 */ private final boolean keepLongStdio; - /** - * {@link TestDataPublisher}s configured for this archiver, to process the recorded data. - * For compatibility reasons, can be null. + * {@link TestDataPublisher}s configured for this archiver, to process the + * recorded data. For compatibility reasons, can be null. + * * @since 1.320 */ private final DescribableList<TestDataPublisher, Descriptor<TestDataPublisher>> testDataPublishers; - /** - * left for backwards compatibility - * @deprecated since 2009-08-09. - */ - @Deprecated - public JUnitResultArchiver(String testResults) { - this(testResults, false, null); - } + /** + * left for backwards compatibility + * + * @deprecated since 2009-08-09. + */ + @Deprecated + public JUnitResultArchiver(String testResults) { + this(testResults, false, null); + } @Deprecated public JUnitResultArchiver(String testResults, DescribableList<TestDataPublisher, Descriptor<TestDataPublisher>> testDataPublishers) { this(testResults, false, testDataPublishers); } - - @DataBoundConstructor - public JUnitResultArchiver( - String testResults, + + @DataBoundConstructor + public JUnitResultArchiver( + String testResults, boolean keepLongStdio, - DescribableList<TestDataPublisher, Descriptor<TestDataPublisher>> testDataPublishers) { - this.testResults = testResults; + DescribableList<TestDataPublisher, Descriptor<TestDataPublisher>> testDataPublishers) { + this.testResults = testResults; this.keepLongStdio = keepLongStdio; - this.testDataPublishers = testDataPublishers; - } + this.testDataPublishers = testDataPublishers; + } /** * @inheritDoc @@ -119,157 +121,158 @@ public class JUnitResultArchiver extends Recorder implements Serializable, * In progress. Working on delegating the actual parsing to the JUnitParser. */ protected TestResult parse(String expandedTestResults, AbstractBuild build, Launcher launcher, BuildListener listener) - throws IOException, InterruptedException - { + throws IOException, InterruptedException { return new JUnitParser(isKeepLongStdio()).parse(expandedTestResults, build, launcher, listener); } @Override - public boolean perform(AbstractBuild build, Launcher launcher, - BuildListener listener) throws InterruptedException, IOException { - listener.getLogger().println(Messages.JUnitResultArchiver_Recording()); - TestResultAction action; - - final String testResults = build.getEnvironment(listener).expand(this.testResults); - - try { - TestResult result = parse(testResults, build, launcher, listener); - - try { - action = new TestResultAction(build, result, listener); - } catch (NullPointerException npe) { - throw new AbortException(Messages.JUnitResultArchiver_BadXML(testResults)); - } + public boolean perform(AbstractBuild build, Launcher launcher, + BuildListener listener) throws InterruptedException, IOException { + listener.getLogger().println(Messages.JUnitResultArchiver_Recording()); + TestResultAction action; + + final String testResults = build.getEnvironment(listener).expand(this.testResults); + + try { + TestResult result = parse(testResults, build, launcher, listener); + + try { + action = new TestResultAction(build, result, listener); + } catch (NullPointerException npe) { + throw new AbortException(Messages.JUnitResultArchiver_BadXML(testResults)); + } result.freeze(action); - if (result.getPassCount() == 0 && result.getFailCount() == 0) - throw new AbortException(Messages.JUnitResultArchiver_ResultIsEmpty()); + if (result.getPassCount() == 0 && result.getFailCount() == 0) { + throw new AbortException(Messages.JUnitResultArchiver_ResultIsEmpty()); + } // TODO: Move into JUnitParser [BUG 3123310] - List<Data> data = new ArrayList<Data>(); - if (testDataPublishers != null) { - for (TestDataPublisher tdp : testDataPublishers) { - Data d = tdp.getTestData(build, launcher, listener, result); - if (d != null) { - data.add(d); - } - } - } - - action.setData(data); - - CHECKPOINT.block(); - - } catch (AbortException e) { - if (build.getResult() == Result.FAILURE) - // most likely a build failed before it gets to the test phase. - // don't report confusing error message. - return true; - - listener.getLogger().println(e.getMessage()); - build.setResult(Result.FAILURE); - return true; - } catch (IOException e) { - e.printStackTrace(listener.error("Failed to archive test reports")); - build.setResult(Result.FAILURE); - return true; - } - - build.getActions().add(action); - CHECKPOINT.report(); - - if (action.getResult().getFailCount() > 0) - build.setResult(Result.UNSTABLE); - - return true; - } - - /** - * Not actually used, but left for backward compatibility - * - * @deprecated since 2009-08-10. - */ - protected TestResult parseResult(DirectoryScanner ds, long buildTime) - throws IOException { - return new TestResult(buildTime, ds); - } - - /** - * This class does explicit checkpointing. - */ - public BuildStepMonitor getRequiredMonitorService() { - return BuildStepMonitor.NONE; - } - - public String getTestResults() { - return testResults; - } - - public DescribableList<TestDataPublisher, Descriptor<TestDataPublisher>> getTestDataPublishers() { - return testDataPublishers; - } - - @Override - public Collection<Action> getProjectActions(AbstractProject<?, ?> project) { - return Collections.<Action>singleton(new TestResultProjectAction(project)); - } - - public MatrixAggregator createAggregator(MatrixBuild build, - Launcher launcher, BuildListener listener) { - return new TestResultAggregator(build, launcher, listener); - } - - /** - * @return the keepLongStdio - */ - public boolean isKeepLongStdio() { - return keepLongStdio; - } - - /** - * Test result tracks the diff from the previous run, hence the checkpoint. - */ - private static final CheckPoint CHECKPOINT = new CheckPoint( - "JUnit result archiving"); - - private static final long serialVersionUID = 1L; + List<Data> data = new ArrayList<Data>(); + if (testDataPublishers != null) { + for (TestDataPublisher tdp : testDataPublishers) { + Data d = tdp.getTestData(build, launcher, listener, result); + if (d != null) { + data.add(d); + } + } + } + + action.setData(data); + + CHECKPOINT.block(); + + } catch (AbortException e) { + if (build.getResult() == Result.FAILURE) // most likely a build failed before it gets to the test phase. + // don't report confusing error message. + { + return true; + } + + listener.getLogger().println(e.getMessage()); + build.setResult(Result.FAILURE); + return true; + } catch (IOException e) { + e.printStackTrace(listener.error("Failed to archive test reports")); + build.setResult(Result.FAILURE); + return true; + } + + build.getActions().add(action); + CHECKPOINT.report(); + + if (action.getResult().getFailCount() > 0) { + build.setResult(Result.UNSTABLE); + } + + return true; + } + + /** + * Not actually used, but left for backward compatibility + * + * @deprecated since 2009-08-10. + */ + protected TestResult parseResult(DirectoryScanner ds, long buildTime) + throws IOException { + return new TestResult(buildTime, ds); + } + + /** + * This class does explicit checkpointing. + */ + public BuildStepMonitor getRequiredMonitorService() { + return BuildStepMonitor.NONE; + } + + public String getTestResults() { + return testResults; + } + + public DescribableList<TestDataPublisher, Descriptor<TestDataPublisher>> getTestDataPublishers() { + return testDataPublishers; + } + + @Override + public Collection<Action> getProjectActions(AbstractProject<?, ?> project) { + return Collections.<Action>singleton(new TestResultProjectAction(project)); + } + + public MatrixAggregator createAggregator(MatrixBuild build, + Launcher launcher, BuildListener listener) { + return new TestResultAggregator(build, launcher, listener); + } + + /** + * @return the keepLongStdio + */ + public boolean isKeepLongStdio() { + return keepLongStdio; + } + /** + * Test result tracks the diff from the previous run, hence the checkpoint. + */ + private static final CheckPoint CHECKPOINT = new CheckPoint( + "JUnit result archiving"); + private static final long serialVersionUID = 1L; @Extension public static class DescriptorImpl extends BuildStepDescriptor<Publisher> { - public String getDisplayName() { - return Messages.JUnitResultArchiver_DisplayName(); - } + + public String getDisplayName() { + return Messages.JUnitResultArchiver_DisplayName(); + } @Override public String getHelpFile() { return "/help/tasks/junit/report.html"; } - @Override - public Publisher newInstance(StaplerRequest req, JSONObject formData) - throws hudson.model.Descriptor.FormException { - String testResults = formData.getString("testResults"); + @Override + public Publisher newInstance(StaplerRequest req, JSONObject formData) + throws hudson.model.Descriptor.FormException { + String testResults = formData.getString("testResults"); boolean keepLongStdio = formData.getBoolean("keepLongStdio"); - DescribableList<TestDataPublisher, Descriptor<TestDataPublisher>> testDataPublishers = new DescribableList<TestDataPublisher, Descriptor<TestDataPublisher>>(Saveable.NOOP); + DescribableList<TestDataPublisher, Descriptor<TestDataPublisher>> testDataPublishers = new DescribableList<TestDataPublisher, Descriptor<TestDataPublisher>>(Saveable.NOOP); try { testDataPublishers.rebuild(req, formData, TestDataPublisher.all()); } catch (IOException e) { - throw new FormException(e,null); + throw new FormException(e, null); } return new JUnitResultArchiver(testResults, keepLongStdio, testDataPublishers); - } - - /** - * Performs on-the-fly validation on the file mask wildcard. - */ - public FormValidation doCheckTestResults( - @AncestorInPath AbstractProject project, - @QueryParameter String value) throws IOException { - return FilePath.validateFileMask(project.getSomeWorkspace(), value); - } - - public boolean isApplicable(Class<? extends AbstractProject> jobType) { - return true; - } + } + + /** + * Performs on-the-fly validation on the file mask wildcard. + */ + public FormValidation doCheckTestResults( + @AncestorInPath AbstractProject project, + @QueryParameter String value) throws IOException { + return FilePath.validateFileMask(project.getSomeWorkspace(), value); + } + + public boolean isApplicable(Class<? extends AbstractProject> jobType) { + return true; + } } } diff --git a/hudson-core/src/main/java/hudson/tasks/junit/PackageResult.java b/hudson-core/src/main/java/hudson/tasks/junit/PackageResult.java index 4ca3cf3..918a865 100644 --- a/hudson-core/src/main/java/hudson/tasks/junit/PackageResult.java +++ b/hudson-core/src/main/java/hudson/tasks/junit/PackageResult.java @@ -7,10 +7,10 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: -* -* Kohsuke Kawaguchi, Daniel Dyer, id:cactusman, Tom Huybrechts, Yahoo!, Inc. - * + * Contributors: + * + * Kohsuke Kawaguchi, Daniel Dyer, id:cactusman, Tom Huybrechts, Yahoo!, Inc. + * * *******************************************************************************/ @@ -36,26 +36,26 @@ public final class PackageResult extends MetaTabulatedResult implements Comparab /** * All {@link ClassResult}s keyed by their short name. */ - private final Map<String,ClassResult> classes = new TreeMap<String,ClassResult>(); - private int passCount,failCount,skipCount; + private final Map<String, ClassResult> classes = new TreeMap<String, ClassResult>(); + private int passCount, failCount, skipCount; private final hudson.tasks.junit.TestResult parent; - private float duration; + private float duration; PackageResult(hudson.tasks.junit.TestResult parent, String packageName) { this.packageName = packageName; this.parent = parent; } - + @Override public AbstractBuild<?, ?> getOwner() { return (parent == null ? null : parent.getOwner()); } public hudson.tasks.junit.TestResult getParent() { - return parent; + return parent; } - @Exported(visibility=999) + @Exported(visibility = 999) public String getName() { return packageName; } @@ -79,7 +79,7 @@ public final class PackageResult extends MetaTabulatedResult implements Comparab className = id.substring(classNameStart); } else { className = id; - } + } int classNameEnd = className.indexOf('/'); if (classNameEnd > 0) { subId = className.substring(classNameEnd + 1); @@ -95,7 +95,7 @@ public final class PackageResult extends MetaTabulatedResult implements Comparab return child.findCorrespondingResult(subId); } else { return child; - } + } } return null; @@ -114,9 +114,9 @@ public final class PackageResult extends MetaTabulatedResult implements Comparab // TODO: wait until stapler 1.60 to do this @Exported @Override public float getDuration() { - return duration; + return duration; } - + @Exported @Override public int getPassCount() { @@ -139,17 +139,17 @@ public final class PackageResult extends MetaTabulatedResult implements Comparab public Object getDynamic(String name, StaplerRequest req, StaplerResponse rsp) { ClassResult result = getClassResult(name); if (result != null) { - return result; + return result; } else { - return super.getDynamic(name, req, rsp); + return super.getDynamic(name, req, rsp); } } - public ClassResult getClassResult(String name) { - return classes.get(name); - } + public ClassResult getClassResult(String name) { + return classes.get(name); + } - @Exported(name="child") + @Exported(name = "child") public Collection<ClassResult> getChildren() { return classes.values(); } @@ -164,8 +164,8 @@ public final class PackageResult extends MetaTabulatedResult implements Comparab } /** - * Returns a list of the failed cases, in no particular - * sort order + * Returns a list of the failed cases, in no particular sort order + * * @return */ public List<CaseResult> getFailedTests() { @@ -174,14 +174,15 @@ public final class PackageResult extends MetaTabulatedResult implements Comparab for (CaseResult cr : clr.getChildren()) { if (!cr.isPassed() && !cr.isSkipped()) { r.add(cr); + } } } - } return r; } /** * Returns a list of the failed cases, sorted by age. + * * @return */ public List<CaseResult> getFailedTestsSortedByAge() { @@ -205,7 +206,7 @@ public final class PackageResult extends MetaTabulatedResult implements Comparab } } } - Collections.sort(r,CaseResult.BY_AGE); + Collections.sort(r, CaseResult.BY_AGE); return r; } @@ -245,7 +246,8 @@ public final class PackageResult extends MetaTabulatedResult implements Comparab // return null; // (FIXME: generated) // } /** - * @return true if every test was not skipped and every test did not fail, false otherwise. + * @return true if every test was not skipped and every test did not fail, + * false otherwise. */ @Override public boolean isPassed() { @@ -256,10 +258,10 @@ public final class PackageResult extends MetaTabulatedResult implements Comparab String n = r.getSimpleName(), sn = safe(n); ClassResult c = getClassResult(sn); if (c == null) { - classes.put(sn,c=new ClassResult(this,n)); + classes.put(sn, c = new ClassResult(this, n)); } c.add(r); - duration += r.getDuration(); + duration += r.getDuration(); } /** diff --git a/hudson-core/src/main/java/hudson/tasks/junit/SuiteResult.java b/hudson-core/src/main/java/hudson/tasks/junit/SuiteResult.java index 83f1a55..3b95522 100644 --- a/hudson-core/src/main/java/hudson/tasks/junit/SuiteResult.java +++ b/hudson-core/src/main/java/hudson/tasks/junit/SuiteResult.java @@ -7,10 +7,10 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: -* -* Kohsuke Kawaguchi, Erik Ramfelt, Xavier Le Vourch, Tom Huybrechts, Yahoo!, Inc. - * + * Contributors: + * + * Kohsuke Kawaguchi, Erik Ramfelt, Xavier Le Vourch, Tom Huybrechts, Yahoo!, Inc. + * * *******************************************************************************/ @@ -39,29 +39,26 @@ import java.util.regex.Pattern; /** * Result of one test suite. * - * <p> - * The notion of "test suite" is rather arbitrary in JUnit ant task. - * It's basically one invocation of junit. + * <p> The notion of "test suite" is rather arbitrary in JUnit ant task. It's + * basically one invocation of junit. * - * <p> - * This object is really only used as a part of the persisted - * object tree. + * <p> This object is really only used as a part of the persisted object tree. * * @author Kohsuke Kawaguchi */ @ExportedBean public final class SuiteResult implements Serializable { + private final String file; private final String name; private final String stdout; private final String stderr; private float duration; /** - * The 'timestamp' attribute of the test suite. - * AFAICT, this is not a required attribute in XML, so the value may be null. + * The 'timestamp' attribute of the test suite. AFAICT, this is not a + * required attribute in XML, so the value may be null. */ private String timestamp; - /** * All test cases. */ @@ -76,9 +73,9 @@ public final class SuiteResult implements Serializable { } /** - * Parses the JUnit XML file into {@link SuiteResult}s. - * This method returns a collection, as a single XML may have multiple <testsuite> - * elements wrapped into the top-level <testsuites>. + * Parses the JUnit XML file into {@link SuiteResult}s. This method returns + * a collection, as a single XML may have multiple <testsuite> elements + * wrapped into the top-level <testsuites>. */ static List<SuiteResult> parse(File xmlReport, boolean keepLongStdio) throws DocumentException, IOException { List<SuiteResult> r = new ArrayList<SuiteResult>(); @@ -97,52 +94,54 @@ public final class SuiteResult implements Serializable { } /** - * Gets the "testsuite" elements that contain at least one "testcase" element. - * Finds all the elements recursively in order to find nested "testsuite" elements. - * Bug 6546 + * Gets the "testsuite" elements that contain at least one "testcase" + * element. Finds all the elements recursively in order to find nested + * "testsuite" elements. Bug 6546 + * * @see http://issues.hudson-ci.org/browse/HUDSON-6545 * @param element XML element to examine * @param r List of SuiteResult * @param xmlReport A Junit XML report file - * @param keepLongStdio if true, retain a suite's complete stdout/stderr even if this is huge and the suite passed + * @param keepLongStdio if true, retain a suite's complete stdout/stderr + * even if this is huge and the suite passed */ static private void getTestSuites(Element element, List<SuiteResult> r, File xmlReport, boolean keepLongStdio) throws DocumentException, IOException { - if(element.elements("testcase").size() != 0) { + if (element.elements("testcase").size() != 0) { r.add(new SuiteResult(xmlReport, element, keepLongStdio)); } - for (Element suite : (List<Element>)element.elements("testsuite")) { + for (Element suite : (List<Element>) element.elements("testsuite")) { getTestSuites(suite, r, xmlReport, keepLongStdio); } } - /** - * @param xmlReport - * A JUnit XML report file whose top level element is 'testsuite'. - * @param suite - * The parsed result of {@code xmlReport} + * @param xmlReport A JUnit XML report file whose top level element is + * 'testsuite'. + * @param suite The parsed result of {@code xmlReport} */ private SuiteResult(File xmlReport, Element suite, boolean keepLongStdio) throws DocumentException, IOException { - this.file = xmlReport.getAbsolutePath(); + this.file = xmlReport.getAbsolutePath(); String name = suite.attributeValue("name"); - if(name==null) - // some user reported that name is null in their environment. - // see http://www.nabble.com/Unexpected-Null-Pointer-Exception-in-Hudson-1.131-tf4314802.html - name = '('+xmlReport.getName()+')'; - else { + if (name == null) // some user reported that name is null in their environment. + // see http://www.nabble.com/Unexpected-Null-Pointer-Exception-in-Hudson-1.131-tf4314802.html + { + name = '(' + xmlReport.getName() + ')'; + } else { String pkg = suite.attributeValue("package"); - if(pkg!=null&& pkg.length()>0) name=pkg+'.'+name; + if (pkg != null && pkg.length() > 0) { + name = pkg + '.' + name; + } } this.name = TestObject.safe(name); this.timestamp = suite.attributeValue("timestamp"); Element ex = suite.element("error"); - if(ex!=null) { + if (ex != null) { // according to junit-noframes.xsl l.229, this happens when the test class failed to load addCase(new CaseResult(this, suite, "<init>", keepLongStdio)); } - for (Element e : (List<Element>)suite.elements("testcase")) { + for (Element e : (List<Element>) suite.elements("testcase")) { // http://issues.hudson-ci.org/browse/HUDSON-1233 indicates that // when <testsuites> is present, we are better off using @classname on the // individual testcase class. @@ -167,17 +166,17 @@ public final class SuiteResult implements Serializable { String stdout = suite.elementText("system-out"); String stderr = suite.elementText("system-err"); - if (stdout==null && stderr==null) { + if (stdout == null && stderr == null) { // Surefire never puts stdout/stderr in the XML. Instead, it goes to a separate file Matcher m = SUREFIRE_FILENAME.matcher(xmlReport.getName()); if (m.matches()) { // look for ***-output.txt from TEST-***.xml - File mavenOutputFile = new File(xmlReport.getParentFile(),m.group(1)+"-output.txt"); + File mavenOutputFile = new File(xmlReport.getParentFile(), m.group(1) + "-output.txt"); if (mavenOutputFile.exists()) { try { stdout = FileUtils.readFileToString(mavenOutputFile); } catch (IOException e) { - throw new IOException2("Failed to read "+mavenOutputFile,e); + throw new IOException2("Failed to read " + mavenOutputFile, e); } } } @@ -189,17 +188,17 @@ public final class SuiteResult implements Serializable { /*package*/ void addCase(CaseResult cr) { cases.add(cr); - duration += cr.getDuration(); + duration += cr.getDuration(); } - @Exported(visibility=9) + @Exported(visibility = 9) public String getName() { return name; } - @Exported(visibility=9) + @Exported(visibility = 9) public float getDuration() { - return duration; + return duration; } /** @@ -215,7 +214,7 @@ public final class SuiteResult implements Serializable { /** * The stderr of this test. - * + * * @since 1.281 * @see CaseResult#getStderr() */ @@ -223,63 +222,67 @@ public final class SuiteResult implements Serializable { public String getStderr() { return stderr; } - + /** * The absolute path to the original test report. OS-dependent. */ public String getFile() { - return file; - } + return file; + } - public hudson.tasks.junit.TestResult getParent() { + public hudson.tasks.junit.TestResult getParent() { return parent; } - @Exported(visibility=9) + @Exported(visibility = 9) public String getTimestamp() { return timestamp; } - @Exported(inline=true,visibility=9) + @Exported(inline = true, visibility = 9) public List<CaseResult> getCases() { return cases; } public SuiteResult getPreviousResult() { hudson.tasks.test.TestResult pr = parent.getPreviousResult(); - if(pr==null) return null; - if(pr instanceof hudson.tasks.junit.TestResult) - return ((hudson.tasks.junit.TestResult)pr).getSuite(name); + if (pr == null) { + return null; + } + if (pr instanceof hudson.tasks.junit.TestResult) { + return ((hudson.tasks.junit.TestResult) pr).getSuite(name); + } return null; } /** - * Returns the {@link CaseResult} whose {@link CaseResult#getName()} - * is the same as the given string. + * Returns the {@link CaseResult} whose {@link CaseResult#getName()} is the + * same as the given string. * - * <p> - * Note that test name needs not be unique. + * <p> Note that test name needs not be unique. */ public CaseResult getCase(String name) { for (CaseResult c : cases) { - if(c.getName().equals(name)) + if (c.getName().equals(name)) { return c; + } } return null; } - - public Set<String> getClassNames() { - Set<String> result = new HashSet<String>(); - for (CaseResult c : cases) { - result.add(c.getClassName()); - } - return result; - } - - /** KLUGE. We have to call this to prevent freeze() - * from calling c.freeze() on all its children, - * because that in turn calls c.getOwner(), - * which requires a non-null parent. + + public Set<String> getClassNames() { + Set<String> result = new HashSet<String>(); + for (CaseResult c : cases) { + result.add(c.getClassName()); + } + return result; + } + + /** + * KLUGE. We have to call this to prevent freeze() from calling c.freeze() + * on all its children, because that in turn calls c.getOwner(), which + * requires a non-null parent. + * * @param parent */ void setParent(hudson.tasks.junit.TestResult parent) { @@ -287,16 +290,15 @@ public final class SuiteResult implements Serializable { } /*package*/ boolean freeze(hudson.tasks.junit.TestResult owner) { - if(this.parent!=null) + if (this.parent != null) { return false; // already frozen - + } this.parent = owner; - for (CaseResult c : cases) + for (CaseResult c : cases) { c.freeze(this); + } return true; } - private static final long serialVersionUID = 1L; - private static final Pattern SUREFIRE_FILENAME = Pattern.compile("TEST-(.+)\\.xml"); } diff --git a/hudson-core/src/main/java/hudson/tasks/junit/TestAction.java b/hudson-core/src/main/java/hudson/tasks/junit/TestAction.java index 8e5e1e1..5b181fb 100644 --- a/hudson-core/src/main/java/hudson/tasks/junit/TestAction.java +++ b/hudson-core/src/main/java/hudson/tasks/junit/TestAction.java @@ -7,10 +7,10 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: -* -* Tom Huybrechts - * + * Contributors: + * + * Tom Huybrechts + * * *******************************************************************************/ @@ -19,25 +19,22 @@ package hudson.tasks.junit; import hudson.model.Action; /** - * - * Jelly (all optional): - * <ul> - * <li>index.jelly: included at the top of the test page</li> - * <li>summary.jelly: included in a collapsed panel on the test parent page</li> - * <li>badge.jelly: shown after the test link on the test parent page</li> - * </ul> - * + * + * Jelly (all optional): <ul> <li>index.jelly: included at the top of the test + * page</li> <li>summary.jelly: included in a collapsed panel on the test parent + * page</li> <li>badge.jelly: shown after the test link on the test parent + * page</li> </ul> + * * @author tom * @since 1.320 * @see TestDataPublisher */ public abstract class TestAction implements Action { - /** - * Returns text with annotations. - */ - public String annotate(String text) { - return text; - } - + /** + * Returns text with annotations. + */ + public String annotate(String text) { + return text; + } } diff --git a/hudson-core/src/main/java/hudson/tasks/junit/TestDataPublisher.java b/hudson-core/src/main/java/hudson/tasks/junit/TestDataPublisher.java index 8853022..08a6df2 100644 --- a/hudson-core/src/main/java/hudson/tasks/junit/TestDataPublisher.java +++ b/hudson-core/src/main/java/hudson/tasks/junit/TestDataPublisher.java @@ -7,10 +7,10 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: -* -* Tom Huybrechts, Yahoo!, Inc. - * + * Contributors: + * + * Tom Huybrechts, Yahoo!, Inc. + * * *******************************************************************************/ @@ -27,28 +27,29 @@ import java.io.IOException; /** * Contributes {@link TestAction}s to test results. * - * This enables plugins to annotate test results and provide richer UI, such as letting users - * claim test failures, allowing people to file bugs, or more generally, additional actions, views, etc. + * This enables plugins to annotate test results and provide richer UI, such as + * letting users claim test failures, allowing people to file bugs, or more + * generally, additional actions, views, etc. * - * <p> - * To register your implementation, put {@link Extension} on your descriptor implementation. + * <p> To register your implementation, put {@link Extension} on your descriptor + * implementation. * * @since 1.320 */ public abstract class TestDataPublisher extends AbstractDescribableImpl<TestDataPublisher> implements ExtensionPoint { /** - * Called after test results are collected by Hudson, to create a resolver for {@link TestAction}s. + * Called after test results are collected by Hudson, to create a resolver + * for {@link TestAction}s. * - * @return - * can be null to indicate that there's nothing to contribute for this test result. + * @return can be null to indicate that there's nothing to contribute for + * this test result. */ - public abstract TestResultAction.Data getTestData( - AbstractBuild<?, ?> build, Launcher launcher, - BuildListener listener, TestResult testResult) throws IOException, InterruptedException; - - public static DescriptorExtensionList<TestDataPublisher, Descriptor<TestDataPublisher>> all() { - return Hudson.getInstance().<TestDataPublisher, Descriptor<TestDataPublisher>>getDescriptorList(TestDataPublisher.class); - } + public abstract TestResultAction.Data getTestData( + AbstractBuild<?, ?> build, Launcher launcher, + BuildListener listener, TestResult testResult) throws IOException, InterruptedException; + public static DescriptorExtensionList<TestDataPublisher, Descriptor<TestDataPublisher>> all() { + return Hudson.getInstance().<TestDataPublisher, Descriptor<TestDataPublisher>>getDescriptorList(TestDataPublisher.class); + } } diff --git a/hudson-core/src/main/java/hudson/tasks/junit/TestObject.java b/hudson-core/src/main/java/hudson/tasks/junit/TestObject.java index b2e4416..bab0c50 100644 --- a/hudson-core/src/main/java/hudson/tasks/junit/TestObject.java +++ b/hudson-core/src/main/java/hudson/tasks/junit/TestObject.java @@ -7,10 +7,10 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: -* -* Kohsuke Kawaguchi, Tom Huybrechts, Yahoo! Inc., InfraDNA, Inc. - * + * Contributors: + * + * Kohsuke Kawaguchi, Tom Huybrechts, Yahoo! Inc., InfraDNA, Inc. + * * *******************************************************************************/ @@ -27,73 +27,73 @@ import java.util.List; /** * Stub of base class for all test result objects. The real implementation of - * the TestObject is in hudson.tasks.test.TestObject. This class simply - * defines abstract methods so that legacy code will continue to compile. + * the TestObject is in hudson.tasks.test.TestObject. This class simply defines + * abstract methods so that legacy code will continue to compile. + * + * @deprecated Use {@link hudson.tasks.test.TestObject} instead. * - * @deprecated - * Use {@link hudson.tasks.test.TestObject} instead. - * * @author Kohsuke Kawaguchi */ @ExportedBean public abstract class TestObject extends AbstractModelObject implements Serializable { - public abstract AbstractBuild<?,?> getOwner() ; - + public abstract AbstractBuild<?, ?> getOwner(); + public abstract TestObject getParent(); - public abstract String getId(); - /** - * Returns url relative to TestResult - */ - public abstract String getUrl(); + public abstract String getId(); - public abstract TestResult getTestResult(); + /** + * Returns url relative to TestResult + */ + public abstract String getUrl(); + + public abstract TestResult getTestResult(); - public abstract AbstractTestResultAction getTestResultAction(); + public abstract AbstractTestResultAction getTestResultAction(); - public abstract List<TestAction> getTestActions(); + public abstract List<TestAction> getTestActions(); public abstract <T> T getTestAction(Class<T> klazz); /** - * Gets the counter part of this {@link TestObject} in the previous run. - * - * @return null if no such counter part exists. - */ - public abstract TestObject getPreviousResult(); - - public abstract TestObject getResultInBuild(AbstractBuild<?,?> build); - - /** - * Time took to run this test. In seconds. - */ - public abstract float getDuration(); - - /** - * Returns the string representation of the {@link #getDuration()}, in a - * human readable format. - */ - public abstract String getDurationString(); + * Gets the counter part of this {@link TestObject} in the previous run. + * + * @return null if no such counter part exists. + */ + public abstract TestObject getPreviousResult(); + + public abstract TestObject getResultInBuild(AbstractBuild<?, ?> build); + + /** + * Time took to run this test. In seconds. + */ + public abstract float getDuration(); + + /** + * Returns the string representation of the {@link #getDuration()}, in a + * human readable format. + */ + public abstract String getDurationString(); public abstract String getDescription(); public abstract void setDescription(String description); /** - * Exposes this object through the remote API. - */ - public abstract Api getApi(); + * Exposes this object through the remote API. + */ + public abstract Api getApi(); /** - * Gets the name of this object. - */ - public abstract String getName(); + * Gets the name of this object. + */ + public abstract String getName(); /** - * Gets the version of {@link #getName()} that's URL-safe. - */ - public abstract String getSafeName(); + * Gets the version of {@link #getName()} that's URL-safe. + */ + public abstract String getSafeName(); public abstract String getSearchUrl(); @@ -118,12 +118,10 @@ public abstract class TestObject extends AbstractModelObject implements Serializ public abstract int getTotalCount(); public abstract History getHistory(); - // public abstract Object getDynamic(String token, StaplerRequest req, // StaplerResponse rsp); // // public abstract HttpResponse doSubmitDescription( // @QueryParameter String description) throws IOException, // ServletException; - } diff --git a/hudson-core/src/main/java/hudson/tasks/junit/TestResult.java b/hudson-core/src/main/java/hudson/tasks/junit/TestResult.java index 9b8f221..ec8bed7 100644 --- a/hudson-core/src/main/java/hudson/tasks/junit/TestResult.java +++ b/hudson-core/src/main/java/hudson/tasks/junit/TestResult.java @@ -7,10 +7,10 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: -* -* Kohsuke Kawaguchi, Daniel Dyer, id:cactusman, Tom Huybrechts, Yahoo!, Inc. - * + * Contributors: + * + * Kohsuke Kawaguchi, Daniel Dyer, id:cactusman, Tom Huybrechts, Yahoo!, Inc. + * * *******************************************************************************/ @@ -49,45 +49,36 @@ import java.util.logging.Logger; * @author Kohsuke Kawaguchi */ public final class TestResult extends MetaTabulatedResult { - private static final Logger LOGGER = Logger.getLogger(TestResult.class.getName()); + private static final Logger LOGGER = Logger.getLogger(TestResult.class.getName()); /** - * List of all {@link SuiteResult}s in this test. - * This is the core data structure to be persisted in the disk. + * List of all {@link SuiteResult}s in this test. This is the core data + * structure to be persisted in the disk. */ private final List<SuiteResult> suites = new ArrayList<SuiteResult>(); - /** * {@link #suites} keyed by their names for faster lookup. */ - private transient Map<String,SuiteResult> suitesByName; - + private transient Map<String, SuiteResult> suitesByName; /** * Results tabulated by package. */ - private transient Map<String,PackageResult> byPackages; - + private transient Map<String, PackageResult> byPackages; // set during the freeze phase private transient AbstractTestResultAction parentAction; - private transient TestObject parent; - /** * Number of all tests. */ private transient int totalTests; - private transient int skippedTests; - private float duration; - /** * Number of failed/error tests. */ private transient List<CaseResult> failedTests; - private final boolean keepLongStdio; - + /** * Creates an empty result. */ @@ -101,48 +92,50 @@ public final class TestResult extends MetaTabulatedResult { } /** - * Collect reports from the given {@link DirectoryScanner}, while - * filtering out all files that were created before the given time. - * @param keepLongStdio if true, retain a suite's complete stdout/stderr even if this is huge and the suite passed + * Collect reports from the given {@link DirectoryScanner}, while filtering + * out all files that were created before the given time. + * + * @param keepLongStdio if true, retain a suite's complete stdout/stderr + * even if this is huge and the suite passed * @since 1.358 */ public TestResult(long buildTime, DirectoryScanner results, boolean keepLongStdio) throws IOException { this.keepLongStdio = keepLongStdio; parse(buildTime, results); } - + public TestObject getParent() { - return parent; + return parent; } - + @Override public void setParent(TestObject parent) { this.parent = parent; } - + @Override public TestResult getTestResult() { - return this; + return this; } /** - * Collect reports from the given {@link DirectoryScanner}, while - * filtering out all files that were created before the given time. + * Collect reports from the given {@link DirectoryScanner}, while filtering + * out all files that were created before the given time. */ public void parse(long buildTime, DirectoryScanner results) throws IOException { String[] includedFiles = results.getIncludedFiles(); File baseDir = results.getBasedir(); - boolean parsed=false; + boolean parsed = false; for (String value : includedFiles) { File reportFile = new File(baseDir, value); // only count files that were actually updated during this build - if ( (buildTime-3000/*error margin*/ <= reportFile.lastModified()) || !checkTimestamps) { - if(reportFile.length()==0) { + if ((buildTime - 3000/*error margin*/ <= reportFile.lastModified()) || !checkTimestamps) { + if (reportFile.length() == 0) { // this is a typical problem when JVM quits abnormally, like OutOfMemoryError during a test. SuiteResult sr = new SuiteResult(reportFile.getName(), "", ""); - sr.addCase(new CaseResult(sr,"<init>","Test report file "+reportFile.getAbsolutePath()+" was length 0")); + sr.addCase(new CaseResult(sr, "<init>", "Test report file " + reportFile.getAbsolutePath() + " was length 0")); add(sr); } else { parse(reportFile); @@ -151,21 +144,22 @@ public final class TestResult extends MetaTabulatedResult { } } - if(!parsed) { + if (!parsed) { long localTime = System.currentTimeMillis(); - if(localTime < buildTime-1000) /*margin*/ - // build time is in the the future. clock on this slave must be running behind + if (localTime < buildTime - 1000) /*margin*/ // build time is in the the future. clock on this slave must be running behind + { throw new AbortException( - "Clock on this slave is out of sync with the master, and therefore \n" + - "I can't figure out what test results are new and what are old.\n" + - "Please keep the slave clock in sync with the master."); + "Clock on this slave is out of sync with the master, and therefore \n" + + "I can't figure out what test results are new and what are old.\n" + + "Please keep the slave clock in sync with the master."); + } - File f = new File(baseDir,includedFiles[0]); + File f = new File(baseDir, includedFiles[0]); throw new AbortException( - String.format( - "Test reports were found but none of them are new. Did tests run? \n"+ - "For example, %s is %s old\n", f, - Util.getTimeSpanString(buildTime-f.lastModified()))); + String.format( + "Test reports were found but none of them are new. Did tests run? \n" + + "For example, %s is %s old\n", f, + Util.getTimeSpanString(buildTime - f.lastModified()))); } } @@ -173,8 +167,9 @@ public final class TestResult extends MetaTabulatedResult { for (SuiteResult s : suites) { // a common problem is that people parse TEST-*.xml as well as TESTS-TestSuite.xml // see http://www.nabble.com/Problem-with-duplicate-build-execution-td17549182.html for discussion - if(s.getName().equals(sr.getName()) && eq(s.getTimestamp(),sr.getTimestamp())) + if (s.getName().equals(sr.getName()) && eq(s.getTimestamp(), sr.getTimestamp())) { return; // duplicate + } } suites.add(sr); duration += sr.getDuration(); @@ -189,22 +184,23 @@ public final class TestResult extends MetaTabulatedResult { */ public void parse(File reportFile) throws IOException { try { - for (SuiteResult suiteResult : SuiteResult.parse(reportFile, keepLongStdio)) + for (SuiteResult suiteResult : SuiteResult.parse(reportFile, keepLongStdio)) { add(suiteResult); + } } catch (RuntimeException e) { - throw new IOException2("Failed to read "+reportFile,e); + throw new IOException2("Failed to read " + reportFile, e); } catch (DocumentException e) { if (!reportFile.getPath().endsWith(".xml")) { - throw new IOException2("Failed to read "+reportFile+"\n"+ - "Is this really a JUnit report file? Your configuration must be matching too many files",e); + throw new IOException2("Failed to read " + reportFile + "\n" + + "Is this really a JUnit report file? Your configuration must be matching too many files", e); } else { SuiteResult sr = new SuiteResult(reportFile.getName(), "", ""); StringWriter writer = new StringWriter(); e.printStackTrace(new PrintWriter(writer)); - String error = "Failed to read test report file "+reportFile.getAbsolutePath()+"\n"+writer.toString(); - sr.addCase(new CaseResult(sr,"<init>",error)); + String error = "Failed to read test report file " + reportFile.getAbsolutePath() + "\n" + writer.toString(); + sr.addCase(new CaseResult(sr, "<init>", error)); add(sr); - throw new IOException2("Failed to read "+reportFile,e); + throw new IOException2("Failed to read " + reportFile, e); } } } @@ -214,8 +210,8 @@ public final class TestResult extends MetaTabulatedResult { } @Override - public AbstractBuild<?,?> getOwner() { - return (parentAction == null? null: parentAction.owner); + public AbstractBuild<?, ?> getOwner() { + return (parentAction == null ? null : parentAction.owner); } @Override @@ -223,7 +219,7 @@ public final class TestResult extends MetaTabulatedResult { if (getId().equals(id) || (id == null)) { return this; } - + String firstElement = null; String subId = null; int sepIndex = id.indexOf('/'); @@ -243,14 +239,14 @@ public final class TestResult extends MetaTabulatedResult { sepIndex = subId.indexOf('/'); if (sepIndex < 0) { packageName = subId; - subId = null; + subId = null; } else { packageName = subId.substring(0, sepIndex); subId = subId.substring(sepIndex + 1); } } else { packageName = firstElement; - subId = null; + subId = null; } PackageResult child = byPackage(packageName); if (child != null) { @@ -261,7 +257,7 @@ public final class TestResult extends MetaTabulatedResult { } } else { return null; - } + } } @Override @@ -274,28 +270,29 @@ public final class TestResult extends MetaTabulatedResult { return Messages.TestResult_getChildTitle(); } - @Exported(visibility=999) + @Exported(visibility = 999) @Override public float getDuration() { - return duration; + return duration; } - - @Exported(visibility=999) + + @Exported(visibility = 999) @Override public int getPassCount() { - return totalTests-getFailCount()-getSkipCount(); + return totalTests - getFailCount() - getSkipCount(); } - @Exported(visibility=999) + @Exported(visibility = 999) @Override public int getFailCount() { - if(failedTests==null) + if (failedTests == null) { return 0; - else - return failedTests.size(); + } else { + return failedTests.size(); + } } - @Exported(visibility=999) + @Exported(visibility = 999) @Override public int getSkipCount() { return skippedTests; @@ -327,8 +324,8 @@ public final class TestResult extends MetaTabulatedResult { } /** - * If this test failed, then return the build number - * when this test started failing. + * If this test failed, then return the build number when this test started + * failing. */ @Override public int getFailedSince() { @@ -336,8 +333,7 @@ public final class TestResult extends MetaTabulatedResult { } /** - * If this test failed, then return the run - * when this test started failing. + * If this test failed, then return the run when this test started failing. */ @Override public Run<?, ?> getFailedSinceRun() { @@ -347,21 +343,25 @@ public final class TestResult extends MetaTabulatedResult { /** * The stdout of this test. * <p/> + * < + * p/> + * Depending on the tool that produced the XML report, this method works + * somewhat inconsistently. With some tools (such as Maven surefire plugin), + * you get the accurate information, that is the stdout from this test case. + * With some other tools (such as the JUnit task in Ant), this method + * returns the stdout produced by the entire test suite. * <p/> - * Depending on the tool that produced the XML report, this method works somewhat inconsistently. - * With some tools (such as Maven surefire plugin), you get the accurate information, that is - * the stdout from this test case. With some other tools (such as the JUnit task in Ant), this - * method returns the stdout produced by the entire test suite. - * <p/> - * <p/> - * If you need to know which is the case, compare this output from {@link SuiteResult#getStdout()}. + * < + * p/> + * If you need to know which is the case, compare this output from + * {@link SuiteResult#getStdout()}. * * @since 1.294 */ @Override public String getStdout() { StringBuilder sb = new StringBuilder(); - for (SuiteResult suite: suites) { + for (SuiteResult suite : suites) { sb.append("Standard Out (stdout) for Suite: " + suite.getName()); sb.append(suite.getStdout()); } @@ -377,7 +377,7 @@ public final class TestResult extends MetaTabulatedResult { @Override public String getStderr() { StringBuilder sb = new StringBuilder(); - for (SuiteResult suite: suites) { + for (SuiteResult suite : suites) { sb.append("Standard Error (stderr) for Suite: " + suite.getName()); sb.append(suite.getStderr()); } @@ -385,11 +385,12 @@ public final class TestResult extends MetaTabulatedResult { } /** - * If there was an error or a failure, this is the stack trace, or otherwise null. + * If there was an error or a failure, this is the stack trace, or otherwise + * null. */ @Override public String getErrorStackTrace() { - return "No error stack traces available at this level. Drill down to individual tests to find stack traces."; + return "No error stack traces available at this level. Drill down to individual tests to find stack traces."; } /** @@ -401,11 +402,12 @@ public final class TestResult extends MetaTabulatedResult { } /** - * @return true if the test was not skipped and did not fail, false otherwise. + * @return true if the test was not skipped and did not fail, false + * otherwise. */ @Override public boolean isPassed() { - return (getFailCount() == 0); + return (getFailCount() == 0); } @Override @@ -418,15 +420,14 @@ public final class TestResult extends MetaTabulatedResult { */ @Override public boolean hasChildren() { - return !suites.isEmpty(); + return !suites.isEmpty(); } - @Exported(inline=true,visibility=9) + @Exported(inline = true, visibility = 9) public Collection<SuiteResult> getSuites() { return suites; } - @Override public String getName() { return "junit"; @@ -437,12 +438,12 @@ public final class TestResult extends MetaTabulatedResult { if (token.equals(getId())) { return this; } - + PackageResult result = byPackage(token); if (result != null) { - return result; + return result; } else { - return super.getDynamic(token, req, rsp); + return super.getDynamic(token, req, rsp); } } @@ -453,18 +454,18 @@ public final class TestResult extends MetaTabulatedResult { public SuiteResult getSuite(String name) { return suitesByName.get(name); } - - @Override - public void setParentAction(AbstractTestResultAction action) { + + @Override + public void setParentAction(AbstractTestResultAction action) { this.parentAction = action; tally(); // I want to be sure to inform our children when we get an action. - } + } + + @Override + public AbstractTestResultAction getParentAction() { + return this.parentAction; + } - @Override - public AbstractTestResultAction getParentAction() { - return this.parentAction; - } - /** * Recount my children. */ @@ -472,9 +473,9 @@ public final class TestResult extends MetaTabulatedResult { public void tally() { /// Empty out data structures // TODO: free children? memmory leak? - suitesByName = new HashMap<String,SuiteResult>(); + suitesByName = new HashMap<String, SuiteResult>(); failedTests = new ArrayList<CaseResult>(); - byPackages = new TreeMap<String,PackageResult>(); + byPackages = new TreeMap<String, PackageResult>(); totalTests = 0; skippedTests = 0; @@ -482,17 +483,18 @@ public final class TestResult extends MetaTabulatedResult { // Ask all of our children to tally themselves for (SuiteResult s : suites) { s.setParent(this); // kluge to prevent double-counting the results - suitesByName.put(s.getName(),s); + suitesByName.put(s.getName(), s); List<CaseResult> cases = s.getCases(); - for (CaseResult cr: cases) { + for (CaseResult cr : cases) { cr.setParentAction(this.parentAction); cr.setParentSuiteResult(s); cr.tally(); String pkg = cr.getPackageName(), spkg = safe(pkg); PackageResult pr = byPackage(spkg); - if(pr==null) - byPackages.put(spkg,pr=new PackageResult(this,pkg)); + if (pr == null) { + byPackages.put(spkg, pr = new PackageResult(this, pkg)); + } pr.add(cr); } } @@ -506,51 +508,53 @@ public final class TestResult extends MetaTabulatedResult { } /** - * Builds up the transient part of the data structure - * from results {@link #parse(File) parsed} so far. + * Builds up the transient part of the data structure from results + * {@link #parse(File) parsed} so far. * - * <p> - * After the data is frozen, more files can be parsed - * and then freeze can be called again. + * <p> After the data is frozen, more files can be parsed and then freeze + * can be called again. */ public void freeze(TestResultAction parent) { this.parentAction = parent; - if(suitesByName==null) { + if (suitesByName == null) { // freeze for the first time - suitesByName = new HashMap<String,SuiteResult>(); + suitesByName = new HashMap<String, SuiteResult>(); totalTests = 0; failedTests = new ArrayList<CaseResult>(); - byPackages = new TreeMap<String,PackageResult>(); + byPackages = new TreeMap<String, PackageResult>(); } for (SuiteResult s : suites) { - if(!s.freeze(this)) // this is disturbing: has-a-parent is conflated with has-been-counted + if (!s.freeze(this)) // this is disturbing: has-a-parent is conflated with has-been-counted + { continue; + } - suitesByName.put(s.getName(),s); + suitesByName.put(s.getName(), s); totalTests += s.getCases().size(); - for(CaseResult cr : s.getCases()) { - if(cr.isSkipped()) + for (CaseResult cr : s.getCases()) { + if (cr.isSkipped()) { skippedTests++; - else if(!cr.isPassed()) + } else if (!cr.isPassed()) { failedTests.add(cr); + } String pkg = cr.getPackageName(), spkg = safe(pkg); PackageResult pr = byPackage(spkg); - if(pr==null) - byPackages.put(spkg,pr=new PackageResult(this,pkg)); + if (pr == null) { + byPackages.put(spkg, pr = new PackageResult(this, pkg)); + } pr.add(cr); } } - Collections.sort(failedTests,CaseResult.BY_AGE); + Collections.sort(failedTests, CaseResult.BY_AGE); - for (PackageResult pr : byPackages.values()) + for (PackageResult pr : byPackages.values()) { pr.freeze(); + } } - private static final long serialVersionUID = 1L; private static final boolean checkTimestamps = true; // TODO: change to System.getProperty - } diff --git a/hudson-core/src/main/java/hudson/tasks/junit/TestResultAction.java b/hudson-core/src/main/java/hudson/tasks/junit/TestResultAction.java index a1b9b7f..a81464d 100644 --- a/hudson-core/src/main/java/hudson/tasks/junit/TestResultAction.java +++ b/hudson-core/src/main/java/hudson/tasks/junit/TestResultAction.java @@ -7,10 +7,10 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: -* -* Kohsuke Kawaguchi, Daniel Dyer, Red Hat, Inc., Tom Huybrechts, Yahoo!, Inc. - * + * Contributors: + * + * Kohsuke Kawaguchi, Daniel Dyer, Red Hat, Inc., Tom Huybrechts, Yahoo!, Inc. + * * *******************************************************************************/ @@ -38,20 +38,16 @@ import java.util.logging.Logger; /** * {@link Action} that displays the JUnit test result. * - * <p> - * The actual test reports are isolated by {@link WeakReference} - * so that it doesn't eat up too much memory. + * <p> The actual test reports are isolated by {@link WeakReference} so that it + * doesn't eat up too much memory. * * @author Kohsuke Kawaguchi */ public class TestResultAction extends AbstractTestResultAction<TestResultAction> implements StaplerProxy { - - private static final Logger LOGGER = Logger.getLogger(TestResultAction.class.getName()); - private static final XStream XSTREAM = new XStream2(); - + private static final Logger LOGGER = Logger.getLogger(TestResultAction.class.getName()); + private static final XStream XSTREAM = new XStream2(); private transient WeakReference<TestResult> result; - // Hudson < 1.25 didn't set these fields, so use Integer // so that we can distinguish between 0 tests vs not-computed-yet. private int failCount; @@ -111,29 +107,32 @@ public class TestResultAction extends AbstractTestResultAction<TestResultAction> @Override public synchronized int getFailCount() { - if (totalCount == null) + if (totalCount == null) { getResult(); // this will compute the result + } return failCount; } @Override public synchronized int getSkipCount() { - if (totalCount == null) + if (totalCount == null) { getResult(); // this will compute the result + } return skipCount; } @Override public synchronized int getTotalCount() { - if (totalCount == null) + if (totalCount == null) { getResult(); // this will compute the result + } return totalCount; } - @Override - public List<CaseResult> getFailedTests() { - return getResult().getFailedTests(); - } + @Override + public List<CaseResult> getFailedTests() { + return getResult().getFailedTests(); + } /** * Loads a {@link TestResult} from disk. @@ -149,59 +148,60 @@ public class TestResultAction extends AbstractTestResultAction<TestResultAction> r.freeze(this); return r; } - + @Override public Object getTarget() { return getResult(); } - + public List<TestAction> getActions(TestObject object) { - List<TestAction> result = new ArrayList<TestAction>(); - // Added check for null testData to avoid NPE from issue 4257. - if (testData != null) { - for (Data data : testData) { - result.addAll(data.getTestAction(object)); + List<TestAction> result = new ArrayList<TestAction>(); + // Added check for null testData to avoid NPE from issue 4257. + if (testData != null) { + for (Data data : testData) { + result.addAll(data.getTestAction(object)); + } } + return Collections.unmodifiableList(result); + } - return Collections.unmodifiableList(result); - - } + public void setData(List<Data> testData) { - this.testData = testData; + this.testData = testData; } /** * Resolves {@link TestAction}s for the given {@link TestObject}. * - * <p> - * This object itself is persisted as a part of {@link AbstractBuild}, so it needs to be XStream-serializable. + * <p> This object itself is persisted as a part of {@link AbstractBuild}, + * so it needs to be XStream-serializable. * * @see TestDataPublisher */ public static abstract class Data { - /** - * Returns all TestActions for the testObject. - * - * @return - * Can be empty but never null. The caller must assume that the returned list is read-only. - */ - public abstract List<? extends TestAction> getTestAction(hudson.tasks.junit.TestObject testObject); + + /** + * Returns all TestActions for the testObject. + * + * @return Can be empty but never null. The caller must assume that the + * returned list is read-only. + */ + public abstract List<? extends TestAction> getTestAction(hudson.tasks.junit.TestObject testObject); } public Object readResolve() { super.readResolve(); // let it do the post-deserialization work - if (testData == null) { - testData = new ArrayList<Data>(); - } - - return this; + if (testData == null) { + testData = new ArrayList<Data>(); + } + + return this; } - + static { XSTREAM.alias("result", TestResult.class); XSTREAM.alias("suite", SuiteResult.class); XSTREAM.alias("case", CaseResult.class); XSTREAM.registerConverter(new HeapSpaceStringConverter(), 100); } - } diff --git a/hudson-core/src/main/java/hudson/tasks/junit/XMLEntityResolver.java b/hudson-core/src/main/java/hudson/tasks/junit/XMLEntityResolver.java index 50c100c..c039c96 100644 --- a/hudson-core/src/main/java/hudson/tasks/junit/XMLEntityResolver.java +++ b/hudson-core/src/main/java/hudson/tasks/junit/XMLEntityResolver.java @@ -7,10 +7,10 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: -* -* Kohsuke Kawaguchi, Jorg Heymans - * + * Contributors: + * + * Kohsuke Kawaguchi, Jorg Heymans + * * *******************************************************************************/ @@ -27,8 +27,7 @@ import java.util.logging.Logger; /** * As the name suggest: a resolver for XML entities. * - * <p> - * Basically, it provides the possibility to intercept online DTD lookups + * <p> Basically, it provides the possibility to intercept online DTD lookups * and instead do offline lookup by redirecting to a local directory where * .dtd's are stored * @@ -52,13 +51,13 @@ class XMLEntityResolver implements EntityResolver { String dtdFileName = systemId.substring(TESTNG_NAMESPACE.length()); URL url = getClass().getClassLoader().getResource(dtdFileName); - if (url != null) + if (url != null) { return new InputSource(url.toString()); + } } } // Default fallback return null; } - private static final Logger LOGGER = Logger.getLogger(XMLEntityResolver.class.getName()); } diff --git a/hudson-core/src/main/java/hudson/tasks/junit/package.html b/hudson-core/src/main/java/hudson/tasks/junit/package.html index cdddd82..ab5f93d 100644 --- a/hudson-core/src/main/java/hudson/tasks/junit/package.html +++ b/hudson-core/src/main/java/hudson/tasks/junit/package.html @@ -16,5 +16,5 @@ --> <html><head/><body> -Model objects that represent JUnit test reports. -</body></html>
\ No newline at end of file + Model objects that represent JUnit test reports. + </body></html>
\ No newline at end of file diff --git a/hudson-core/src/main/java/hudson/tasks/mail/BuildResultMail.java b/hudson-core/src/main/java/hudson/tasks/mail/BuildResultMail.java index b0cbfd0..5a7380f 100644 --- a/hudson-core/src/main/java/hudson/tasks/mail/BuildResultMail.java +++ b/hudson-core/src/main/java/hudson/tasks/mail/BuildResultMail.java @@ -35,6 +35,5 @@ public interface BuildResultMail { * @throws InterruptedException exception if any. */ MimeMessage getMail(AbstractBuild<?, ?> build, BuildListener listener) - throws MessagingException, InterruptedException; - + throws MessagingException, InterruptedException; }
\ No newline at end of file diff --git a/hudson-core/src/main/java/hudson/tasks/mail/impl/BackToNormalBuildMail.java b/hudson-core/src/main/java/hudson/tasks/mail/impl/BackToNormalBuildMail.java index bd15df3..39a8a41 100644 --- a/hudson-core/src/main/java/hudson/tasks/mail/impl/BackToNormalBuildMail.java +++ b/hudson-core/src/main/java/hudson/tasks/mail/impl/BackToNormalBuildMail.java @@ -33,7 +33,7 @@ public class BackToNormalBuildMail extends BaseBuildResultMail { private String currentState; public BackToNormalBuildMail(String recipients, boolean sendToIndividuals, - List<AbstractProject> upstreamProjects, String charset, String currentState) { + List<AbstractProject> upstreamProjects, String charset, String currentState) { super(recipients, sendToIndividuals, upstreamProjects, charset); this.currentState = currentState; } @@ -42,7 +42,7 @@ public class BackToNormalBuildMail extends BaseBuildResultMail { * @inheritDoc */ public MimeMessage getMail(AbstractBuild<?, ?> build, BuildListener listener) - throws MessagingException, InterruptedException { + throws MessagingException, InterruptedException { MimeMessage msg = createEmptyMail(build, listener); msg.setSubject(getSubject(build, Messages.MailSender_BackToNormalMail_Subject(currentState)), getCharset()); StringBuilder buf = new StringBuilder(); diff --git a/hudson-core/src/main/java/hudson/tasks/mail/impl/BaseBuildResultMail.java b/hudson-core/src/main/java/hudson/tasks/mail/impl/BaseBuildResultMail.java index c3a5127..b5b2c2d 100644 --- a/hudson-core/src/main/java/hudson/tasks/mail/impl/BaseBuildResultMail.java +++ b/hudson-core/src/main/java/hudson/tasks/mail/impl/BaseBuildResultMail.java @@ -44,34 +44,28 @@ import org.apache.commons.collections.CollectionUtils; */ public abstract class BaseBuildResultMail implements BuildResultMail { - protected static final int MAX_LOG_LINES = Integer.getInteger(MailSender.class.getName()+".maxLogLines",250); - + protected static final int MAX_LOG_LINES = Integer.getInteger(MailSender.class.getName() + ".maxLogLines", 250); //TODO where it's used? public static boolean debug = false; - /** * Whitespace-separated list of e-mail addresses that represent recipients. */ private String recipients; - /** * The charset to use for the text and subject. */ private String charset; - /** * The list of upstream projects. */ private List<AbstractProject> upstreamProjects; - /** * If true, individuals will receive e-mails regarding who broke the build. */ private boolean sendToIndividuals; - public BaseBuildResultMail(String recipients, boolean sendToIndividuals, List<AbstractProject> upstreamProjects, - String charset) { + String charset) { this.recipients = recipients; this.sendToIndividuals = sendToIndividuals; this.upstreamProjects = upstreamProjects; @@ -104,6 +98,7 @@ public abstract class BaseBuildResultMail implements BuildResultMail { protected String getSubjectPrefix() { return hudson.mail.Messages.hudson_email_subject_prefix(); } + /** * Creates empty mail. * @@ -124,12 +119,12 @@ public abstract class BaseBuildResultMail implements BuildResultMail { StringTokenizer tokens = new StringTokenizer(getRecipients()); while (tokens.hasMoreTokens()) { String address = tokens.nextToken(); - if(address.startsWith("upstream-individuals:")) { + if (address.startsWith("upstream-individuals:")) { // people who made a change in the upstream String projectName = address.substring("upstream-individuals:".length()); - AbstractProject up = Hudson.getInstance().getItemByFullName(projectName,AbstractProject.class); - if(up==null) { - listener.getLogger().println("No such project exist: "+projectName); + AbstractProject up = Hudson.getInstance().getItemByFullName(projectName, AbstractProject.class); + if (up == null) { + listener.getLogger().println("No such project exist: " + projectName); continue; } includeCulpritsOf(up, build, listener, rcp); @@ -153,19 +148,20 @@ public abstract class BaseBuildResultMail implements BuildResultMail { if (sendToIndividuals) { Set<User> culprits = build.getCulprits(); - if(debug) - listener.getLogger().println("Trying to send e-mails to individuals who broke the build. sizeof(culprits)=="+culprits.size()); + if (debug) { + listener.getLogger().println("Trying to send e-mails to individuals who broke the build. sizeof(culprits)==" + culprits.size()); + } - rcp.addAll(buildCulpritList(listener,culprits)); + rcp.addAll(buildCulpritList(listener, culprits)); } msg.setRecipients(Message.RecipientType.TO, rcp.toArray(new InternetAddress[rcp.size()])); AbstractBuild<?, ?> pb = build.getPreviousBuild(); - if(pb!=null) { + if (pb != null) { MailMessageIdAction b = pb.getAction(MailMessageIdAction.class); - if(b!=null) { - msg.setHeader("In-Reply-To",b.messageId); - msg.setHeader("References",b.messageId); + if (b != null) { + msg.setHeader("In-Reply-To", b.messageId); + msg.setHeader("References", b.messageId); } } @@ -180,7 +176,7 @@ public abstract class BaseBuildResultMail implements BuildResultMail { */ protected void appendBuildUrl(AbstractBuild<?, ?> build, StringBuilder buf) { appendUrl(Util.encode(build.getUrl()) - + (build.getChangeSet().isEmptySet() ? "" : "changes"), buf); + + (build.getChangeSet().isEmptySet() ? "" : "changes"), buf); } /** @@ -191,8 +187,9 @@ public abstract class BaseBuildResultMail implements BuildResultMail { */ protected void appendUrl(String url, StringBuilder buf) { String baseUrl = Mailer.descriptor().getUrl(); - if (baseUrl != null) + if (baseUrl != null) { buf.append(Messages.MailSender_Link(baseUrl, url)).append("\n\n"); + } } /** @@ -207,7 +204,6 @@ public abstract class BaseBuildResultMail implements BuildResultMail { } } - /** * Returns the subject of the mail. * @@ -217,42 +213,42 @@ public abstract class BaseBuildResultMail implements BuildResultMail { */ protected String getSubject(AbstractBuild<?, ?> build, String caption) { return new StringBuilder().append(getSubjectPrefix()) - .append(" ") - .append(caption) - .append(" ") - .append(build.getFullDisplayName()) - .toString(); + .append(" ") + .append(caption) + .append(" ") + .append(build.getFullDisplayName()) + .toString(); } private void includeCulpritsOf(AbstractProject upstreamProject, AbstractBuild<?, ?> currentBuild, BuildListener listener, Set<InternetAddress> recipientList) throws AddressException { - AbstractBuild<?,?> upstreamBuild = currentBuild.getUpstreamRelationshipBuild(upstreamProject); - AbstractBuild<?,?> previousBuild = currentBuild.getPreviousBuild(); - AbstractBuild<?,?> previousBuildUpstreamBuild = previousBuild!=null ? previousBuild.getUpstreamRelationshipBuild(upstreamProject) : null; - if(previousBuild==null && upstreamBuild==null && previousBuildUpstreamBuild==null) { - listener.getLogger().println("Unable to compute the changesets in "+ upstreamProject +". Is the fingerprint configured?"); + AbstractBuild<?, ?> upstreamBuild = currentBuild.getUpstreamRelationshipBuild(upstreamProject); + AbstractBuild<?, ?> previousBuild = currentBuild.getPreviousBuild(); + AbstractBuild<?, ?> previousBuildUpstreamBuild = previousBuild != null ? previousBuild.getUpstreamRelationshipBuild(upstreamProject) : null; + if (previousBuild == null && upstreamBuild == null && previousBuildUpstreamBuild == null) { + listener.getLogger().println("Unable to compute the changesets in " + upstreamProject + ". Is the fingerprint configured?"); return; } - if(previousBuild==null || upstreamBuild==null || previousBuildUpstreamBuild==null) { - listener.getLogger().println("Unable to compute the changesets in "+ upstreamProject); + if (previousBuild == null || upstreamBuild == null || previousBuildUpstreamBuild == null) { + listener.getLogger().println("Unable to compute the changesets in " + upstreamProject); return; } - AbstractBuild<?,?> b=previousBuildUpstreamBuild; + AbstractBuild<?, ?> b = previousBuildUpstreamBuild; do { - recipientList.addAll(buildCulpritList(listener,b.getCulprits())); + recipientList.addAll(buildCulpritList(listener, b.getCulprits())); b = b.getNextBuild(); - } while ( b != upstreamBuild && b != null ); + } while (b != upstreamBuild && b != null); } - private Set<InternetAddress> buildCulpritList(BuildListener listener, Set<User> culprits) throws AddressException { Set<InternetAddress> r = new HashSet<InternetAddress>(); for (User a : culprits) { String adrs = Util.fixEmpty(a.getProperty(Mailer.UserProperty.class).getAddress()); - if(debug) - listener.getLogger().println(" User "+a.getId()+" -> "+adrs); - if (adrs != null) + if (debug) { + listener.getLogger().println(" User " + a.getId() + " -> " + adrs); + } + if (adrs != null) { r.add(new InternetAddress(adrs)); - else { + } else { listener.getLogger().println(Messages.MailSender_NoAddress(a.getFullName())); } } @@ -267,5 +263,4 @@ public abstract class BaseBuildResultMail implements BuildResultMail { private String getTextFooter() { return hudson.mail.Messages.hudson_email_footer(); } - } diff --git a/hudson-core/src/main/java/hudson/tasks/mail/impl/FailureBuildMail.java b/hudson-core/src/main/java/hudson/tasks/mail/impl/FailureBuildMail.java index c830a81..93e3772 100644 --- a/hudson-core/src/main/java/hudson/tasks/mail/impl/FailureBuildMail.java +++ b/hudson-core/src/main/java/hudson/tasks/mail/impl/FailureBuildMail.java @@ -39,7 +39,7 @@ import org.apache.tools.ant.types.selectors.SelectorUtils; public class FailureBuildMail extends BaseBuildResultMail { public FailureBuildMail(String recipients, boolean sendToIndividuals, - List<AbstractProject> upstreamProjects, String charset) { + List<AbstractProject> upstreamProjects, String charset) { super(recipients, sendToIndividuals, upstreamProjects, charset); } @@ -47,7 +47,7 @@ public class FailureBuildMail extends BaseBuildResultMail { * @inheritDoc */ public MimeMessage getMail(AbstractBuild<?, ?> build, BuildListener listener) - throws MessagingException, InterruptedException { + throws MessagingException, InterruptedException { MimeMessage msg = createEmptyMail(build, listener); msg.setSubject(getSubject(build, Messages.MailSender_FailureMail_Subject()), getCharset()); @@ -100,13 +100,13 @@ public class FailureBuildMail extends BaseBuildResultMail { // Careful with path separator between $1 and $2: // workspaceDir will not normally end with one; // workspaceDir.toURI() will end with '/' if and only if workspaceDir.exists() at time of call - wsPattern = Pattern.compile("(" + - Pattern.quote(ws.getRemote()) + "|" + Pattern.quote(ws.toURI().toString()) - + ")[/\\\\]?([^:#\\s]*)"); + wsPattern = Pattern.compile("(" + + Pattern.quote(ws.getRemote()) + "|" + Pattern.quote(ws.toURI().toString()) + + ")[/\\\\]?([^:#\\s]*)"); } for (String line : lines) { line = line.replace('\0', - ' '); // shall we replace other control code? This one is motivated by http://www.nabble.com/Problems-with-NULL-characters-in-generated-output-td25005177.html + ' '); // shall we replace other control code? This one is motivated by http://www.nabble.com/Problems-with-NULL-characters-in-generated-output-td25005177.html if (wsPattern != null) { // Perl: $line =~ s{$rx}{$path = $2; $path =~ s!\\\\!/!g; $workspaceUrl . $path}eg; Matcher m = wsPattern.matcher(line); @@ -127,7 +127,7 @@ public class FailureBuildMail extends BaseBuildResultMail { } catch (IOException e) { // somehow failed to read the contents of the log buf.append(Messages.MailSender_FailureMail_FailedToAccessBuildLog()).append("\n\n").append( - Functions.printThrowable(e)); + Functions.printThrowable(e)); } appendFooter(buf); msg.setText(buf.toString(), getCharset()); @@ -160,5 +160,4 @@ public class FailureBuildMail extends BaseBuildResultMail { // new Object[]{path, artifacts}); return false; } - } diff --git a/hudson-core/src/main/java/hudson/tasks/mail/impl/UnstableBuildMail.java b/hudson-core/src/main/java/hudson/tasks/mail/impl/UnstableBuildMail.java index c1516bf..5f9d875 100644 --- a/hudson-core/src/main/java/hudson/tasks/mail/impl/UnstableBuildMail.java +++ b/hudson-core/src/main/java/hudson/tasks/mail/impl/UnstableBuildMail.java @@ -30,7 +30,7 @@ import javax.mail.internet.MimeMessage; public class UnstableBuildMail extends BaseBuildResultMail { public UnstableBuildMail(String recipients, boolean sendToIndividuals, - List<AbstractProject> upstreamProjects, String charset) { + List<AbstractProject> upstreamProjects, String charset) { super(recipients, sendToIndividuals, upstreamProjects, charset); } @@ -38,7 +38,7 @@ public class UnstableBuildMail extends BaseBuildResultMail { * @inheritDoc */ public MimeMessage getMail(AbstractBuild<?, ?> build, BuildListener listener) - throws MessagingException, InterruptedException { + throws MessagingException, InterruptedException { MimeMessage msg = createEmptyMail(build, listener); String subject = Messages.MailSender_UnstableMail_Subject(); diff --git a/hudson-core/src/main/java/hudson/tasks/package.html b/hudson-core/src/main/java/hudson/tasks/package.html index a511e66..26d10a8 100644 --- a/hudson-core/src/main/java/hudson/tasks/package.html +++ b/hudson-core/src/main/java/hudson/tasks/package.html @@ -16,6 +16,6 @@ --> <html><head/><body> -Built-in <a href="Builder.html"><tt>Builder</tt></a>s and <a href="Publisher.html"><tt>Publisher</tt></a>s -that perform the actual heavy-lifting of a build. -</body></html>
\ No newline at end of file + Built-in <a href="Builder.html"><tt>Builder</tt></a>s and <a href="Publisher.html"><tt>Publisher</tt></a>s + that perform the actual heavy-lifting of a build. + </body></html>
\ No newline at end of file diff --git a/hudson-core/src/main/java/hudson/tasks/test/AbstractTestResultAction.java b/hudson-core/src/main/java/hudson/tasks/test/AbstractTestResultAction.java index 22700fd..1dfaff1 100644 --- a/hudson-core/src/main/java/hudson/tasks/test/AbstractTestResultAction.java +++ b/hudson-core/src/main/java/hudson/tasks/test/AbstractTestResultAction.java @@ -7,10 +7,10 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: + * Contributors: * * Inc., Kohsuke Kawaguchi, Daniel Dyer, Red Hat, Inc., Stephen Connolly, id:cactusman, Yahoo!, Inc, Winston Prakash - * + * * *******************************************************************************/ @@ -43,18 +43,18 @@ import org.eclipse.hudson.graph.GraphSeries; /** * Common base class for recording test result. * - * <p> - * {@link Project} and {@link Build} recognizes {@link Action}s that derive from this, - * and displays it nicely (regardless of the underlying implementation.) + * <p> {@link Project} and {@link Build} recognizes {@link Action}s that derive + * from this, and displays it nicely (regardless of the underlying + * implementation.) * * @author Kohsuke Kawaguchi */ @ExportedBean public abstract class AbstractTestResultAction<T extends AbstractTestResultAction> implements HealthReportingAction { //TODO: review and check whether we can do it private - public final AbstractBuild<?,?> owner; - private Map<String,String> descriptions = new ConcurrentHashMap<String, String>(); + public final AbstractBuild<?, ?> owner; + private Map<String, String> descriptions = new ConcurrentHashMap<String, String>(); protected AbstractTestResultAction(AbstractBuild owner) { this.owner = owner; @@ -63,13 +63,13 @@ public abstract class AbstractTestResultAction<T extends AbstractTestResultActio /** * Gets the number of failed tests. */ - @Exported(visibility=2) + @Exported(visibility = 2) public abstract int getFailCount(); /** * Gets the number of skipped tests. */ - @Exported(visibility=2) + @Exported(visibility = 2) public int getSkipCount() { // Not all sub-classes will understand the concept of skipped tests. // This default implementation is for them, so that they don't have @@ -82,7 +82,7 @@ public abstract class AbstractTestResultAction<T extends AbstractTestResultActio /** * Gets the total number of tests. */ - @Exported(visibility=2) + @Exported(visibility = 2) public abstract int getTotalCount(); /** @@ -90,16 +90,17 @@ public abstract class AbstractTestResultAction<T extends AbstractTestResultActio */ public final String getFailureDiffString() { T prev = getPreviousResult(); - if(prev==null) return ""; // no record - - return " / "+Functions.getDiffString(this.getFailCount()-prev.getFailCount()); + if (prev == null) { + return ""; // no record + } + return " / " + Functions.getDiffString(this.getFailCount() - prev.getFailCount()); } public String getDisplayName() { return Messages.AbstractTestResultAction_getDisplayName(); } - @Exported(visibility=2) + @Exported(visibility = 2) public String getUrlName() { return "testReport"; } @@ -115,12 +116,12 @@ public abstract class AbstractTestResultAction<T extends AbstractTestResultActio public HealthReport getBuildHealth() { final int totalCount = getTotalCount(); final int failCount = getFailCount(); - int score = (totalCount == 0) ? 100 : (int) (100.0 * (1.0 - ((double)failCount) / totalCount)); + int score = (totalCount == 0) ? 100 : (int) (100.0 * (1.0 - ((double) failCount) / totalCount)); Localizable description, displayName = Messages._AbstractTestResultAction_getDisplayName(); if (totalCount == 0) { - description = Messages._AbstractTestResultAction_zeroTestDescription(displayName); + description = Messages._AbstractTestResultAction_zeroTestDescription(displayName); } else { - description = Messages._AbstractTestResultAction_TestsDescription(displayName, failCount, totalCount); + description = Messages._AbstractTestResultAction_TestsDescription(displayName, failCount, totalCount); } return new HealthReport(score, description); } @@ -133,14 +134,13 @@ public abstract class AbstractTestResultAction<T extends AbstractTestResultActio } /** - * Returns the object that represents the actual test result. - * This method is used by the remote API so that the XML/JSON - * that we are sending won't contain unnecessary indirection - * (that is, {@link AbstractTestResultAction} in between. + * Returns the object that represents the actual test result. This method is + * used by the remote API so that the XML/JSON that we are sending won't + * contain unnecessary indirection (that is, + * {@link AbstractTestResultAction} in between. * - * <p> - * If such a concept doesn't make sense for a particular subtype, - * return <tt>this</tt>. + * <p> If such a concept doesn't make sense for a particular subtype, return + * <tt>this</tt>. */ public abstract Object getResult(); @@ -148,25 +148,27 @@ public abstract class AbstractTestResultAction<T extends AbstractTestResultActio * Gets the test result of the previous build, if it's recorded, or null. */ public T getPreviousResult() { - return (T)getPreviousResult(getClass()); + return (T) getPreviousResult(getClass()); } private <U extends AbstractTestResultAction> U getPreviousResult(Class<U> type) { - AbstractBuild<?,?> b = owner; - while(true) { + AbstractBuild<?, ?> b = owner; + while (true) { b = b.getPreviousBuild(); - if(b==null) + if (b == null) { return null; + } U r = b.getAction(type); - if(r!=null) + if (r != null) { return r; + } } } - + public TestResult findPreviousCorresponding(TestResult test) { T previousResult = getPreviousResult(); if (previousResult != null) { - TestResult testResult = (TestResult)getResult(); + TestResult testResult = (TestResult) getResult(); return testResult.findCorrespondingResult(test.getId()); } @@ -174,45 +176,45 @@ public abstract class AbstractTestResultAction<T extends AbstractTestResultActio } public TestResult findCorrespondingResult(String id) { - return ((TestResult)getResult()).findCorrespondingResult(id); + return ((TestResult) getResult()).findCorrespondingResult(id); } - + /** * A shortcut for summary.jelly - * + * * @return List of failed tests from associated test result. */ public List<CaseResult> getFailedTests() { return Collections.emptyList(); } - + /** - * {@link TestObject}s do not have their own persistence mechanism, so updatable data of {@link TestObject}s - * need to be persisted by the owning {@link AbstractTestResultAction}, and this method and + * {@link TestObject}s do not have their own persistence mechanism, so + * updatable data of {@link TestObject}s need to be persisted by the owning + * {@link AbstractTestResultAction}, and this method and * {@link #setDescription(TestObject, String)} provides that logic. * - * <p> - * The default implementation stores information in the 'this' object. + * <p> The default implementation stores information in the 'this' object. * - * @see TestObject#getDescription() + * @see TestObject#getDescription() */ protected String getDescription(TestObject object) { - return descriptions.get(object.getId()); + return descriptions.get(object.getId()); } protected void setDescription(TestObject object, String description) { - descriptions.put(object.getId(), description); + descriptions.put(object.getId(), description); } public Object readResolve() { - if (descriptions == null) { - descriptions = new ConcurrentHashMap<String, String>(); - } - - return this; + if (descriptions == null) { + descriptions = new ConcurrentHashMap<String, String>(); + } + + return this; } - - /** + + /** * Returns a full path down to a test result */ public String getTestResultPath(TestResult it) { @@ -222,93 +224,98 @@ public abstract class AbstractTestResultAction<T extends AbstractTestResultActio /** * Generates a PNG image for the test result trend. */ - public void doGraph( StaplerRequest req, StaplerResponse rsp) throws IOException { - if(ChartUtil.awtProblemCause!=null) { + public void doGraph(StaplerRequest req, StaplerResponse rsp) throws IOException { + if (ChartUtil.awtProblemCause != null) { // not available. send out error message - rsp.sendRedirect2(req.getContextPath()+"/images/headless.png"); + rsp.sendRedirect2(req.getContextPath() + "/images/headless.png"); return; } - if(req.checkIfModified(owner.getTimestamp(),rsp)) + if (req.checkIfModified(owner.getTimestamp(), rsp)) { return; - + } + Area defSize = calcDefaultSize(); Graph graph = new Graph(-1, defSize.width, defSize.height); graph.setYAxisLabel("count"); graph.setData(getGraphDataSet(req)); - graph.doPng(req,rsp); - + graph.doPng(req, rsp); + //ChartUtil.generateGraph(req,rsp,createChart(req,buildDataSet(req)),calcDefaultSize()); } /** - * Generates a clickable map HTML for {@link #doGraph(StaplerRequest, StaplerResponse)}. + * Generates a clickable map HTML for + * {@link #doGraph(StaplerRequest, StaplerResponse)}. */ - public void doGraphMap( StaplerRequest req, StaplerResponse rsp) throws IOException { - if(req.checkIfModified(owner.getTimestamp(),rsp)) + public void doGraphMap(StaplerRequest req, StaplerResponse rsp) throws IOException { + if (req.checkIfModified(owner.getTimestamp(), rsp)) { return; - + } + Area defSize = calcDefaultSize(); Graph graph = new Graph(-1, defSize.width, defSize.height); graph.setYAxisLabel("count"); graph.setData(getGraphDataSet(req)); - graph.doMap(req,rsp); + graph.doMap(req, rsp); } - + private DataSet getGraphDataSet(StaplerRequest req) { boolean failureOnly = Boolean.valueOf(req.getParameter("failureOnly")); DataSet<String, ChartLabel> dsb = new DataSet<String, ChartLabel>(); - - + + GraphSeries<String> xSeries = new GraphSeries<String>("Build No."); dsb.setXSeries(xSeries); - + GraphSeries<Number> ySeriesFailed = new GraphSeries<Number>(GraphSeries.TYPE_BAR, "Failed", ColorPalette.RED); - ySeriesFailed.setBaseURL(getRelPath(req)); - + ySeriesFailed.setBaseURL(getRelPath(req)); + GraphSeries<Number> ySeriesSkipped = new GraphSeries<Number>(GraphSeries.TYPE_BAR, "Skipped", ColorPalette.YELLOW); ySeriesSkipped.setBaseURL(getRelPath(req)); - + GraphSeries<Number> ySeriesPassed = new GraphSeries<Number>(GraphSeries.TYPE_BAR, "Passed", ColorPalette.BLUE); ySeriesPassed.setBaseURL(getRelPath(req)); - - if(!failureOnly) { + + if (!failureOnly) { dsb.addYSeries(ySeriesFailed); dsb.addYSeries(ySeriesSkipped); dsb.addYSeries(ySeriesPassed); - }else{ + } else { dsb.addYSeries(ySeriesFailed); } - for( AbstractTestResultAction<?> a=this; a!=null; a=a.getPreviousResult(AbstractTestResultAction.class) ) { + for (AbstractTestResultAction<?> a = this; a != null; a = a.getPreviousResult(AbstractTestResultAction.class)) { xSeries.add(a.owner.getDisplayName()); - ySeriesFailed.add((double)a.getFailCount()); - + ySeriesFailed.add((double) a.getFailCount()); + // For backward compatibility with JFreechart - dsb.add((double)a.getFailCount(), "failed", new TestResultChartLabel(req, a.owner)); - - if(!failureOnly) { - ySeriesSkipped.add((double)a.getSkipCount()); - ySeriesPassed.add((double)(a.getTotalCount() - a.getFailCount() - a.getSkipCount())); - + dsb.add((double) a.getFailCount(), "failed", new TestResultChartLabel(req, a.owner)); + + if (!failureOnly) { + ySeriesSkipped.add((double) a.getSkipCount()); + ySeriesPassed.add((double) (a.getTotalCount() - a.getFailCount() - a.getSkipCount())); + // For backward compatibility with JFreechart - dsb.add((double)a.getSkipCount(), "skipped", new TestResultChartLabel(req, a.owner)); - dsb.add((double)a.getTotalCount()-a.getFailCount()-a.getSkipCount(),"total", new TestResultChartLabel(req, a.owner)); - } + dsb.add((double) a.getSkipCount(), "skipped", new TestResultChartLabel(req, a.owner)); + dsb.add((double) a.getTotalCount() - a.getFailCount() - a.getSkipCount(), "total", new TestResultChartLabel(req, a.owner)); + } } - + return dsb; } - + // For backward compatibility with JFreechart - private class TestResultChartLabel extends NumberOnlyBuildLabel{ + private class TestResultChartLabel extends NumberOnlyBuildLabel { + final String relPath; - - public TestResultChartLabel(StaplerRequest req, AbstractBuild build){ + + public TestResultChartLabel(StaplerRequest req, AbstractBuild build) { super(build); relPath = getRelPath(req); } + @Override public Color getColor(int row, int column) { return ColorPalette.BLUE; @@ -316,45 +323,48 @@ public abstract class AbstractTestResultAction<T extends AbstractTestResultActio @Override public String getLink(int row, int column) { - return relPath + build.getNumber()+"/testReport/"; + return relPath + build.getNumber() + "/testReport/"; } @Override public String getToolTip(int row, int column) { - - AbstractTestResultAction a = build.getAction(AbstractTestResultAction.class); - switch (row) { - case 0: - return String.valueOf(Messages.AbstractTestResultAction_fail(build.getDisplayName(), a.getFailCount())); - case 1: - return String.valueOf(Messages.AbstractTestResultAction_skip(build.getDisplayName(), a.getSkipCount())); - default: - return String.valueOf(Messages.AbstractTestResultAction_test(build.getDisplayName(), a.getTotalCount())); - } + + AbstractTestResultAction a = build.getAction(AbstractTestResultAction.class); + switch (row) { + case 0: + return String.valueOf(Messages.AbstractTestResultAction_fail(build.getDisplayName(), a.getFailCount())); + case 1: + return String.valueOf(Messages.AbstractTestResultAction_skip(build.getDisplayName(), a.getSkipCount())); + default: + return String.valueOf(Messages.AbstractTestResultAction_test(build.getDisplayName(), a.getTotalCount())); + } } public int compareTo(ChartLabel that) { - return this.build.number-((TestResultChartLabel)that).build.number; + return this.build.number - ((TestResultChartLabel) that).build.number; } } /** * Determines the default size of the trend graph. * - * This is default because the query parameter can choose arbitrary size. - * If the screen resolution is too low, use a smaller size. + * This is default because the query parameter can choose arbitrary size. If + * the screen resolution is too low, use a smaller size. */ private Area calcDefaultSize() { Area res = Functions.getScreenResolution(); - if(res!=null && res.width<=800) - return new Area(250,100); - else - return new Area(500,200); + if (res != null && res.width <= 800) { + return new Area(250, 100); + } else { + return new Area(500, 200); + } } private String getRelPath(StaplerRequest req) { String relPath = req.getParameter("rel"); - if(relPath==null) return ""; + if (relPath == null) { + return ""; + } return relPath; } } diff --git a/hudson-core/src/main/java/hudson/tasks/test/AggregatedTestResultAction.java b/hudson-core/src/main/java/hudson/tasks/test/AggregatedTestResultAction.java index cd79e31..55edf6f 100644 --- a/hudson-core/src/main/java/hudson/tasks/test/AggregatedTestResultAction.java +++ b/hudson-core/src/main/java/hudson/tasks/test/AggregatedTestResultAction.java @@ -7,10 +7,10 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: -* -* Kohsuke Kawaguchi, Daniel Dyer, Red Hat, Inc., Yahoo!, Inc. - * + * Contributors: + * + * Kohsuke Kawaguchi, Daniel Dyer, Red Hat, Inc., Yahoo!, Inc. + * * *******************************************************************************/ @@ -27,24 +27,26 @@ import java.util.ArrayList; import java.util.List; /** - * {@link AbstractTestResultAction} that aggregates all the test results - * from the corresponding {@link AbstractBuild}s. + * {@link AbstractTestResultAction} that aggregates all the test results from + * the corresponding {@link AbstractBuild}s. * - * <p> - * (This has nothing to do with {@link AggregatedTestResultPublisher}, unfortunately) + * <p> (This has nothing to do with {@link AggregatedTestResultPublisher}, + * unfortunately) * * @author Kohsuke Kawaguchi */ @ExportedBean public abstract class AggregatedTestResultAction extends AbstractTestResultAction { - private int failCount,skipCount,totalCount; + + private int failCount, skipCount, totalCount; public static final class Child { + /** - * Name of the module. Could be relative to something. - * The interpretation of this is done by - * {@link AggregatedTestResultAction#getChildName(AbstractTestResultAction)} and - * {@link AggregatedTestResultAction#resolveChild(Child)} and + * Name of the module. Could be relative to something. The + * interpretation of this is done by + * {@link AggregatedTestResultAction#getChildName(AbstractTestResultAction)} + * and {@link AggregatedTestResultAction#resolveChild(Child)} and */ public final String name; public final int build; @@ -54,7 +56,6 @@ public abstract class AggregatedTestResultAction extends AbstractTestResultActio this.build = build; } } - /** * child builds whose test results are used for aggregation. */ @@ -72,15 +73,16 @@ public abstract class AggregatedTestResultAction extends AbstractTestResultActio protected void update(List<? extends AbstractTestResultAction> children) { failCount = skipCount = totalCount = 0; this.children.clear(); - for (AbstractTestResultAction tr : children) + for (AbstractTestResultAction tr : children) { add(tr); + } } protected void add(AbstractTestResultAction child) { failCount += child.getFailCount(); skipCount += child.getSkipCount(); totalCount += child.getTotalCount(); - this.children.add(new Child(getChildName(child),child.owner.number)); + this.children.add(new Child(getChildName(child), child.owner.number)); } public int getFailCount() { @@ -95,7 +97,7 @@ public abstract class AggregatedTestResultAction extends AbstractTestResultActio public int getTotalCount() { return totalCount; } - + public List<ChildReport> getResult() { // I think this is a reasonable default. return getChildReports(); @@ -115,11 +117,12 @@ public abstract class AggregatedTestResultAction extends AbstractTestResultActio /** * Data-binding bean for the remote API. */ - @ExportedBean(defaultVisibility=2) + @ExportedBean(defaultVisibility = 2) public static final class ChildReport { //TODO: review and check whether we can do it private + @Exported - public final AbstractBuild<?,?> child; + public final AbstractBuild<?, ?> child; //TODO: review and check whether we can do it private @Exported public final Object result; @@ -141,7 +144,7 @@ public abstract class AggregatedTestResultAction extends AbstractTestResultActio /** * Mainly for the remote API. Expose results from children. */ - @Exported(inline=true) + @Exported(inline = true) public List<ChildReport> getChildReports() { return new AbstractList<ChildReport>() { public ChildReport get(int index) { @@ -157,25 +160,27 @@ public abstract class AggregatedTestResultAction extends AbstractTestResultActio } protected abstract String getChildName(AbstractTestResultAction tr); - public abstract AbstractBuild<?,?> resolveChild(Child child); + + public abstract AbstractBuild<?, ?> resolveChild(Child child); /** * Uses {@link #resolveChild(Child)} and obtain the * {@link AbstractTestResultAction} object for the given child. */ protected AbstractTestResultAction getChildReport(Child child) { - AbstractBuild<?,?> b = resolveChild(child); - if(b==null) return null; + AbstractBuild<?, ?> b = resolveChild(child); + if (b == null) { + return null; + } return b.getAction(AbstractTestResultAction.class); } /** * Since there's no TestObject that points this action as the owner - * (aggregated {@link TestObject}s point to their respective real owners, not 'this'), - * so this method should be never invoked. + * (aggregated {@link TestObject}s point to their respective real owners, + * not 'this'), so this method should be never invoked. * - * @deprecated - * so that IDE warns you if you accidentally try to call it. + * @deprecated so that IDE warns you if you accidentally try to call it. */ @Override protected final String getDescription(TestObject object) { @@ -185,8 +190,7 @@ public abstract class AggregatedTestResultAction extends AbstractTestResultActio /** * See {@link #getDescription(TestObject)} * - * @deprecated - * so that IDE warns you if you accidentally try to call it. + * @deprecated so that IDE warns you if you accidentally try to call it. */ @Override protected final void setDescription(TestObject object, String description) { diff --git a/hudson-core/src/main/java/hudson/tasks/test/AggregatedTestResultPublisher.java b/hudson-core/src/main/java/hudson/tasks/test/AggregatedTestResultPublisher.java index a559423..24959a1 100644 --- a/hudson-core/src/main/java/hudson/tasks/test/AggregatedTestResultPublisher.java +++ b/hudson-core/src/main/java/hudson/tasks/test/AggregatedTestResultPublisher.java @@ -7,10 +7,10 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: -* -* Kohsuke Kawaguchi, Michael B. Donohue, Yahoo!, Inc. - * + * Contributors: + * + * Kohsuke Kawaguchi, Michael B. Donohue, Yahoo!, Inc. + * * *******************************************************************************/ @@ -48,16 +48,16 @@ import java.util.Collections; import java.util.List; /** - * Aggregates downstream test reports into a single consolidated report, - * so that people can see the overall test results in one page - * when tests are scattered across many different jobs. + * Aggregates downstream test reports into a single consolidated report, so that + * people can see the overall test results in one page when tests are scattered + * across many different jobs. * * @author Kohsuke Kawaguchi */ public class AggregatedTestResultPublisher extends Recorder { + /** - * Jobs to aggregate. Comma separated. - * Null if triggering downstreams. + * Jobs to aggregate. Comma separated. Null if triggering downstreams. */ public final String jobs; @@ -65,9 +65,9 @@ public class AggregatedTestResultPublisher extends Recorder { this.jobs = Util.fixEmptyAndTrim(jobs); } - public boolean perform(AbstractBuild<?,?> build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException { + public boolean perform(AbstractBuild<?, ?> build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException { // add a TestResult just so that it can show up later. - build.addAction(new TestResultAction(jobs,build)); + build.addAction(new TestResultAction(jobs, build)); return true; } @@ -82,12 +82,11 @@ public class AggregatedTestResultPublisher extends Recorder { * are gone, we can still retain some useful information. */ public static final class TestResultAction extends AbstractTestResultAction { + /** - * Jobs to aggregate. Comma separated. - * Never null. + * Jobs to aggregate. Comma separated. Never null. */ private final String jobs; - /** * The last time the fields of this object is computed from the rest. */ @@ -96,7 +95,6 @@ public class AggregatedTestResultPublisher extends Recorder { * When was the last time any build completed? */ private static long lastChanged = 0; - private transient int failCount; private transient int totalCount; private transient List<AbstractTestResultAction> individuals; @@ -106,13 +104,15 @@ public class AggregatedTestResultPublisher extends Recorder { private transient List<AbstractProject> didntRun; private transient List<AbstractProject> noFingerprints; - public TestResultAction(String jobs, AbstractBuild<?,?> owner) { + public TestResultAction(String jobs, AbstractBuild<?, ?> owner) { super(owner); - if(jobs==null) { + if (jobs == null) { // resolve null as the transitive downstream jobs StringBuilder buf = new StringBuilder(); for (AbstractProject p : getProject().getTransitiveDownstreamProjects()) { - if(buf.length()>0) buf.append(','); + if (buf.length() > 0) { + buf.append(','); + } buf.append(p.getFullName()); } jobs = buf.toString(); @@ -125,15 +125,16 @@ public class AggregatedTestResultPublisher extends Recorder { */ public Collection<AbstractProject> getJobs() { List<AbstractProject> r = new ArrayList<AbstractProject>(); - for (String job : Util.tokenize(jobs,",")) { + for (String job : Util.tokenize(jobs, ",")) { AbstractProject j = Hudson.getInstance().getItemByFullName(job.trim(), AbstractProject.class); - if(j!=null) + if (j != null) { r.add(j); + } } return r; } - private AbstractProject<?,?> getProject() { + private AbstractProject<?, ?> getProject() { return owner.getProject(); } @@ -154,11 +155,10 @@ public class AggregatedTestResultPublisher extends Recorder { /** * Since there's no TestObject that points this action as the owner - * (aggregated {@link TestObject}s point to their respective real owners, not 'this'), - * so this method should be never invoked. + * (aggregated {@link TestObject}s point to their respective real + * owners, not 'this'), so this method should be never invoked. * - * @deprecated - * so that IDE warns you if you accidentally try to call it. + * @deprecated so that IDE warns you if you accidentally try to call it. */ @Override protected String getDescription(TestObject object) { @@ -168,8 +168,7 @@ public class AggregatedTestResultPublisher extends Recorder { /** * See {@link #getDescription(TestObject)} * - * @deprecated - * so that IDE warns you if you accidentally try to call it. + * @deprecated so that IDE warns you if you accidentally try to call it. */ @Override protected void setDescription(TestObject object, String description) { @@ -185,16 +184,16 @@ public class AggregatedTestResultPublisher extends Recorder { } /** - * Gets the downstream projects that haven't run yet, but - * expected to produce test results. + * Gets the downstream projects that haven't run yet, but expected to + * produce test results. */ public List<AbstractProject> getDidntRun() { return Collections.unmodifiableList(didntRun); } - /** - * Gets the downstream projects that have available test results, but - * do not appear to have fingerprinting enabled. + /** + * Gets the downstream projects that have available test results, but do + * not appear to have fingerprinting enabled. */ public List<AbstractProject> getNoFingerprints() { return Collections.unmodifiableList(noFingerprints); @@ -205,8 +204,10 @@ public class AggregatedTestResultPublisher extends Recorder { */ private synchronized void upToDateCheck() { // up to date check - if(lastUpdated>lastChanged) return; - lastUpdated = lastChanged+1; + if (lastUpdated > lastChanged) { + return; + } + lastUpdated = lastChanged + 1; int failCount = 0; int totalCount = 0; @@ -215,11 +216,11 @@ public class AggregatedTestResultPublisher extends Recorder { List<AbstractProject> noFingerprints = new ArrayList<AbstractProject>(); for (AbstractProject job : getJobs()) { RangeSet rs = owner.getDownstreamRelationship(job); - if(rs.isEmpty()) { + if (rs.isEmpty()) { // is this job expected to produce a test result? Run b = job.getLastSuccessfulBuild(); - if(b!=null && b.getAction(AbstractTestResultAction.class)!=null) { - if(b.getAction(FingerprintAction.class)!=null) { + if (b != null && b.getAction(AbstractTestResultAction.class) != null) { + if (b.getAction(FingerprintAction.class) != null) { didntRun.add(job); } else { noFingerprints.add(job); @@ -228,11 +229,13 @@ public class AggregatedTestResultPublisher extends Recorder { } else { for (int n : rs.listNumbersReverse()) { Run b = job.getBuildByNumber(n); - if(b==null) continue; - if(b.isBuilding() || b.getResult().isWorseThan(Result.UNSTABLE)) + if (b == null) { + continue; + } + if (b.isBuilding() || b.getResult().isWorseThan(Result.UNSTABLE)) { continue; // don't count them - - for( AbstractTestResultAction ta : b.getActions(AbstractTestResultAction.class)) { + } + for (AbstractTestResultAction ta : b.getActions(AbstractTestResultAction.class)) { failCount += ta.getFailCount(); totalCount += ta.getTotalCount(); individuals.add(ta); @@ -250,7 +253,7 @@ public class AggregatedTestResultPublisher extends Recorder { } public boolean getHasFingerprintAction() { - return this.owner.getAction(FingerprintAction.class)!=null; + return this.owner.getAction(FingerprintAction.class) != null; } @Override @@ -265,6 +268,7 @@ public class AggregatedTestResultPublisher extends Recorder { @Extension public static class RunListenerImpl extends RunListener<Run> { + @Override public void onCompleted(Run run, TaskListener listener) { lastChanged = System.currentTimeMillis(); @@ -274,6 +278,7 @@ public class AggregatedTestResultPublisher extends Recorder { @Extension public static final class DescriptorImpl extends BuildStepDescriptor<Publisher> { + public boolean isApplicable(Class<? extends AbstractProject> jobType) { return true; // for all types } @@ -289,25 +294,28 @@ public class AggregatedTestResultPublisher extends Recorder { public FormValidation doCheck(@AncestorInPath AbstractProject project, @QueryParameter String value) { // Require CONFIGURE permission on this project - if(!project.hasPermission(Item.CONFIGURE)) return FormValidation.ok(); + if (!project.hasPermission(Item.CONFIGURE)) { + return FormValidation.ok(); + } for (String name : Util.tokenize(fixNull(value), ",")) { name = name.trim(); - if(Hudson.getInstance().getItemByFullName(name)==null) - return FormValidation.error(hudson.tasks.Messages.BuildTrigger_NoSuchProject(name,AbstractProject.findNearest(name).getName())); + if (Hudson.getInstance().getItemByFullName(name) == null) { + return FormValidation.error(hudson.tasks.Messages.BuildTrigger_NoSuchProject(name, AbstractProject.findNearest(name).getName())); + } } - + return FormValidation.ok(); } @Override public AggregatedTestResultPublisher newInstance(StaplerRequest req, JSONObject formData) throws FormException { JSONObject s = formData.getJSONObject("specify"); - if(s.isNullObject()) + if (s.isNullObject()) { return new AggregatedTestResultPublisher(null); - else + } else { return new AggregatedTestResultPublisher(s.getString("jobs")); + } } } - } diff --git a/hudson-core/src/main/java/hudson/tasks/test/DefaultTestResultParserImpl.java b/hudson-core/src/main/java/hudson/tasks/test/DefaultTestResultParserImpl.java index cf24213..ea39047 100644 --- a/hudson-core/src/main/java/hudson/tasks/test/DefaultTestResultParserImpl.java +++ b/hudson-core/src/main/java/hudson/tasks/test/DefaultTestResultParserImpl.java @@ -7,10 +7,10 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: + * Contributors: + * + * * - * - * * *******************************************************************************/ @@ -32,36 +32,36 @@ import java.util.ArrayList; import java.util.List; /** - * Default partial implementation of {@link TestResultParser} that handles GLOB dereferencing - * and other checks for user errors, such as misconfigured GLOBs, up-to-date checks on test reports. + * Default partial implementation of {@link TestResultParser} that handles GLOB + * dereferencing and other checks for user errors, such as misconfigured GLOBs, + * up-to-date checks on test reports. * - * <p> - * The instance of the parser will be serialized to the node that performed the build and the parsing will be done - * remotely on that slave. + * <p> The instance of the parser will be serialized to the node that performed + * the build and the parsing will be done remotely on that slave. * * @since 1.343 * @author Kohsuke Kawaguchi */ public abstract class DefaultTestResultParserImpl extends TestResultParser implements Serializable { + /** - * This method is executed on the slave that has the report files to parse test reports and builds {@link TestResult}. + * This method is executed on the slave that has the report files to parse + * test reports and builds {@link TestResult}. * - * @param reportFiles - * List of files to be parsed. Never be empty nor null. - * @param launcher - * Can be used to fork processes on the machine where the build is running. Never null. - * @param listener - * Use this to report progress and other problems. Never null. + * @param reportFiles List of files to be parsed. Never be empty nor null. + * @param launcher Can be used to fork processes on the machine where the + * build is running. Never null. + * @param listener Use this to report progress and other problems. Never + * null. * - * @throws InterruptedException - * If the user cancels the build, it will be received as a thread interruption. Do not catch - * it, and instead just forward that through the call stack. - * @throws IOException - * If you don't care about handling exceptions gracefully, you can just throw IOException - * and let the default exception handling in Hudson takes care of it. - * @throws AbortException - * If you encounter an error that you handled gracefully, throw this exception and Hudson - * will not show a stack trace. + * @throws InterruptedException If the user cancels the build, it will be + * received as a thread interruption. Do not catch it, and instead just + * forward that through the call stack. + * @throws IOException If you don't care about handling exceptions + * gracefully, you can just throw IOException and let the default exception + * handling in Hudson takes care of it. + * @throws AbortException If you encounter an error that you handled + * gracefully, throw this exception and Hudson will not show a stack trace. */ protected abstract TestResult parse(List<File> reportFiles, Launcher launcher, TaskListener listener) throws InterruptedException, IOException; @@ -79,8 +79,9 @@ public abstract class DefaultTestResultParserImpl extends TestResultParser imple long localBuildTime = buildTime + (nowSlave - nowMaster); FilePath[] paths = new FilePath(dir).list(testResultLocations); - if (paths.length==0) - throw new AbortException("No test reports that matches "+testResultLocations+" found. Configuration error?"); + if (paths.length == 0) { + throw new AbortException("No test reports that matches " + testResultLocations + " found. Configuration error?"); + } // since dir is local, paths all point to the local files List<File> files = new ArrayList<File>(paths.length); @@ -95,18 +96,16 @@ public abstract class DefaultTestResultParserImpl extends TestResultParser imple if (files.isEmpty()) { // none of the files were new throw new AbortException( - String.format( - "Test reports were found but none of them are new. Did tests run? \n"+ - "For example, %s is %s old\n", paths[0].getRemote(), - Util.getTimeSpanString(localBuildTime-paths[0].lastModified()))); + String.format( + "Test reports were found but none of them are new. Did tests run? \n" + + "For example, %s is %s old\n", paths[0].getRemote(), + Util.getTimeSpanString(localBuildTime - paths[0].lastModified()))); } - return parse(files,launcher,listener); + return parse(files, launcher, listener); } }); } - private static final long serialVersionUID = 1L; - - public static final boolean IGNORE_TIMESTAMP_CHECK = Boolean.getBoolean(TestResultParser.class.getName()+".ignoreTimestampCheck"); + public static final boolean IGNORE_TIMESTAMP_CHECK = Boolean.getBoolean(TestResultParser.class.getName() + ".ignoreTimestampCheck"); } diff --git a/hudson-core/src/main/java/hudson/tasks/test/MatrixTestResult.java b/hudson-core/src/main/java/hudson/tasks/test/MatrixTestResult.java index 361ae11..0466517 100644 --- a/hudson-core/src/main/java/hudson/tasks/test/MatrixTestResult.java +++ b/hudson-core/src/main/java/hudson/tasks/test/MatrixTestResult.java @@ -7,10 +7,10 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: -* -* Kohsuke Kawaguchi, Yahoo!, Inc. - * + * Contributors: + * + * Kohsuke Kawaguchi, Yahoo!, Inc. + * * *******************************************************************************/ @@ -25,12 +25,12 @@ import hudson.model.Action; /** * {@link Action} that aggregates all the test results from {@link MatrixRun}s. * - * <p> - * This object is attached to {@link MatrixBuild}. + * <p> This object is attached to {@link MatrixBuild}. * * @author Kohsuke Kawaguchi */ public class MatrixTestResult extends AggregatedTestResultAction { + public MatrixTestResult(MatrixBuild owner) { super(owner); } @@ -44,8 +44,8 @@ public class MatrixTestResult extends AggregatedTestResultAction { } @Override - public AbstractBuild<?,?> resolveChild(Child child) { - MatrixBuild b = (MatrixBuild)owner; + public AbstractBuild<?, ?> resolveChild(Child child) { + MatrixBuild b = (MatrixBuild) owner; return b.getRun(Combination.fromString(child.name)); } diff --git a/hudson-core/src/main/java/hudson/tasks/test/MetaTabulatedResult.java b/hudson-core/src/main/java/hudson/tasks/test/MetaTabulatedResult.java index a480354..fc29f77 100644 --- a/hudson-core/src/main/java/hudson/tasks/test/MetaTabulatedResult.java +++ b/hudson-core/src/main/java/hudson/tasks/test/MetaTabulatedResult.java @@ -7,23 +7,21 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: -* -* Kohsuke Kawaguchi, Yahoo!, Inc. - * + * Contributors: + * + * Kohsuke Kawaguchi, Yahoo!, Inc. + * * *******************************************************************************/ package hudson.tasks.test; - import java.util.Collection; /** - * The purpose of this class is to provide a good place for the - * jelly to bind to. - * {@link TabulatedResult} whose immediate children - * are other {@link TabulatedResult}s. + * The purpose of this class is to provide a good place for the jelly to bind + * to. {@link TabulatedResult} whose immediate children are other + * {@link TabulatedResult}s. * * @author Kohsuke Kawaguchi */ @@ -33,5 +31,4 @@ public abstract class MetaTabulatedResult extends TabulatedResult { * All failed tests. */ public abstract Collection<? extends TestResult> getFailedTests(); - } diff --git a/hudson-core/src/main/java/hudson/tasks/test/SimpleCaseResult.java b/hudson-core/src/main/java/hudson/tasks/test/SimpleCaseResult.java index 926b309..1bc4454 100644 --- a/hudson-core/src/main/java/hudson/tasks/test/SimpleCaseResult.java +++ b/hudson-core/src/main/java/hudson/tasks/test/SimpleCaseResult.java @@ -7,10 +7,10 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: + * Contributors: + * + * * - * - * * *******************************************************************************/ @@ -28,26 +28,28 @@ import java.util.logging.Logger; import static java.util.Collections.emptyList; /** - * The simplest possible case result, with no language ties. - * Acts as if it passed, has no children, and has no failed or skipped tests. + * The simplest possible case result, with no language ties. Acts as if it + * passed, has no children, and has no failed or skipped tests. */ public class SimpleCaseResult extends TestResult { + protected AbstractTestResultAction parentAction; protected final List<SimpleCaseResult> listOnlyContainingThisObject = new ArrayList<SimpleCaseResult>(1); protected float duration = 1.0f; private static final Logger LOGGER = Logger.getLogger(SimpleCaseResult.class.getName()); public SimpleCaseResult(float duration) { - listOnlyContainingThisObject.add(this); + listOnlyContainingThisObject.add(this); } - + public SimpleCaseResult() { this(1.0f); } /** - * Sets the parent action, which means the action that binds - * this particular case result to a build. Should not be null. + * Sets the parent action, which means the action that binds this particular + * case result to a build. Should not be null. + * * @param parentAction */ @Override @@ -64,7 +66,7 @@ public class SimpleCaseResult extends TestResult { public TestObject getParent() { return null; } - + @Override public TestResult findCorrespondingResult(String id) { if (id.equals(getId())) { @@ -73,7 +75,7 @@ public class SimpleCaseResult extends TestResult { return null; } - + /** * Gets the "children" of this test result that failed * @@ -106,6 +108,7 @@ public class SimpleCaseResult extends TestResult { /** * Let's pretend that our trivial test result always passes. + * * @return always true */ @Override @@ -126,11 +129,11 @@ public class SimpleCaseResult extends TestResult { * Returns true iff this test failed. */ public boolean isFailed() { - return false; + return false; } /** - * Time took to run this test. In seconds. + * Time took to run this test. In seconds. */ @Override public float getDuration() { @@ -182,10 +185,10 @@ public class SimpleCaseResult extends TestResult { } @Override - public AbstractBuild<?,?> getOwner() { + public AbstractBuild<?, ?> getOwner() { if (parentAction == null) { LOGGER.warning("in Trivial Test Result, parentAction is null, but getOwner() called"); - return null; + return null; } return parentAction.owner; } @@ -194,14 +197,8 @@ public class SimpleCaseResult extends TestResult { public List<TestAction> getTestActions() { return SimpleCaseResult.EMPTY_ACTION_LIST; } - - /** * An empty list of actions, useful for tests */ public static final List<TestAction> EMPTY_ACTION_LIST = Collections.unmodifiableList(new ArrayList<TestAction>()); - - - - } diff --git a/hudson-core/src/main/java/hudson/tasks/test/TabulatedResult.java b/hudson-core/src/main/java/hudson/tasks/test/TabulatedResult.java index ddf7399..8937b4e 100644 --- a/hudson-core/src/main/java/hudson/tasks/test/TabulatedResult.java +++ b/hudson-core/src/main/java/hudson/tasks/test/TabulatedResult.java @@ -7,10 +7,10 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: -* -* Kohsuke Kawaguchi, Daniel Dyer, Tom Huybrechts, Yahoo!, Inc. - * + * Contributors: + * + * Kohsuke Kawaguchi, Daniel Dyer, Tom Huybrechts, Yahoo!, Inc. + * * *******************************************************************************/ @@ -21,9 +21,8 @@ import java.util.Collection; /** * Cumulated result of multiple tests. * - * <p> - * On top of {@link TestResult}, this class introduces a tree structure - * of {@link TestResult}s. + * <p> On top of {@link TestResult}, this class introduces a tree structure of + * {@link TestResult}s. * * @author Kohsuke Kawaguchi */ diff --git a/hudson-core/src/main/java/hudson/tasks/test/TestObject.java b/hudson-core/src/main/java/hudson/tasks/test/TestObject.java index b026e3f..a9469c3 100644 --- a/hudson-core/src/main/java/hudson/tasks/test/TestObject.java +++ b/hudson-core/src/main/java/hudson/tasks/test/TestObject.java @@ -7,10 +7,10 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: + * Contributors: * * Kohsuke Kawaguchi, Tom Huybrechts, Yahoo!, Inc. - * + * * *******************************************************************************/ @@ -33,11 +33,11 @@ import java.util.*; import java.util.logging.Logger; /** - * Base class for all test result objects. - * For compatibility with code that expects this class to be in hudson.tasks.junit, - * we've created a pure-abstract class, hudson.tasks.junit.TestObject. That - * stub class is deprecated; instead, people should use this class. - * + * Base class for all test result objects. For compatibility with code that + * expects this class to be in hudson.tasks.junit, we've created a pure-abstract + * class, hudson.tasks.junit.TestObject. That stub class is deprecated; instead, + * people should use this class. + * * @author Kohsuke Kawaguchi */ @ExportedBean @@ -96,17 +96,18 @@ public abstract class TestObject extends hudson.tasks.junit.TestObject { /** * Returns the top level test result data. - * + * * @return - */ + */ public TestResult getTopLevelTestResult() { TestObject parent = getParent(); return (parent == null ? null : getParent().getTopLevelTestResult()); } - + /** - * Computes the relative path to get to this test object from <code>it</code>. If + * Computes the relative path to get to this test object from + * <code>it</code>. If * <code>it</code> does not appear in the parent chain for this object, a * relative path from the server root will be returned. * @@ -121,47 +122,47 @@ public abstract class TestObject extends hudson.tasks.junit.TestObject { // } else { // return a complete path starting with "/" // } - if (it==this) { + if (it == this) { return "."; } StringBuilder buf = new StringBuilder(); TestObject next = this; - TestObject cur = this; + TestObject cur = this; // Walk up my ancesotors from leaf to root, looking for "it" // and accumulating a relative url as I go - while (next!=null && it!=next) { + while (next != null && it != next) { cur = next; - buf.insert(0,'/'); - buf.insert(0,cur.getSafeName()); + buf.insert(0, '/'); + buf.insert(0, cur.getSafeName()); next = cur.getParent(); } - if (it==next) { + if (it == next) { return buf.toString(); } else { // Keep adding on to the string we've built so far // Start with the test result action AbstractTestResultAction action = getTestResultAction(); - if (action==null) { + if (action == null) { LOGGER.warning("trying to get relative path, but we can't determine the action that owns this result."); return ""; // this won't take us to the right place, but it also won't 404. } - buf.insert(0,'/'); - buf.insert(0,action.getUrlName()); + buf.insert(0, '/'); + buf.insert(0, action.getUrlName()); // Now the build - AbstractBuild<?,?> myBuild = cur.getOwner(); - if (myBuild ==null) { + AbstractBuild<?, ?> myBuild = cur.getOwner(); + if (myBuild == null) { LOGGER.warning("trying to get relative path, but we can't determine the build that owns this result."); return ""; // this won't take us to the right place, but it also won't 404. } - buf.insert(0,'/'); - buf.insert(0,myBuild.getUrl()); + buf.insert(0, '/'); + buf.insert(0, myBuild.getUrl()); // If we're inside a stapler request, just delegate to Hudson.Functions to get the relative path! StaplerRequest req = Stapler.getCurrentRequest(); - if (req!=null && myBuild instanceof Item) { + if (req != null && myBuild instanceof Item) { buf.insert(0, '/'); // Ugly but I don't see how else to convince the compiler that myBuild is an Item Item myBuildAsItem = (Item) myBuild; @@ -170,8 +171,8 @@ public abstract class TestObject extends hudson.tasks.junit.TestObject { // We're not in a stapler request. Okay, give up. LOGGER.info("trying to get relative path, but it is not my ancestor, and we're not in a stapler request. Trying absolute hudson url..."); String hudsonRootUrl = Hudson.getInstance().getRootUrl(); - if (hudsonRootUrl==null||hudsonRootUrl.length()==0) { - LOGGER.warning("Can't find anything like a decent hudson url. Punting, returning empty string."); + if (hudsonRootUrl == null || hudsonRootUrl.length() == 0) { + LOGGER.warning("Can't find anything like a decent hudson url. Punting, returning empty string."); return ""; } @@ -179,18 +180,18 @@ public abstract class TestObject extends hudson.tasks.junit.TestObject { buf.insert(0, hudsonRootUrl); } - LOGGER.info("Here's our relative path: " + buf.toString()); - return buf.toString(); + LOGGER.info("Here's our relative path: " + buf.toString()); + return buf.toString(); } } /** - * Subclasses may override this method if they are - * associated with a particular subclass of - * AbstractTestResultAction. + * Subclasses may override this method if they are associated with a + * particular subclass of AbstractTestResultAction. * - * @return the test result action that connects this test result to a particular build + * @return the test result action that connects this test result to a + * particular build */ @Override public AbstractTestResultAction getTestResultAction() { @@ -204,7 +205,8 @@ public abstract class TestObject extends hudson.tasks.junit.TestObject { } /** - * Get a list of all TestActions associated with this TestObject. + * Get a list of all TestActions associated with this TestObject. + * * @return */ @Override @@ -219,7 +221,8 @@ public abstract class TestObject extends hudson.tasks.junit.TestObject { } /** - * Gets a test action of the class passed in. + * Gets a test action of the class passed in. + * * @param klazz * @param <T> an instance of the class passed in * @return @@ -249,8 +252,8 @@ public abstract class TestObject extends hudson.tasks.junit.TestObject { public abstract TestResult getResultInBuild(AbstractBuild<?, ?> build); /** - * Find the test result corresponding to the one identified by <code>id></code> - * withint this test result. + * Find the test result corresponding to the one identified by + * <code>id></code> withint this test result. * * @param id The path to the original test result * @return A corresponding test result, or null if there is no corresponding diff --git a/hudson-core/src/main/java/hudson/tasks/test/TestResult.java b/hudson-core/src/main/java/hudson/tasks/test/TestResult.java index 42eafaf..dc65582 100644 --- a/hudson-core/src/main/java/hudson/tasks/test/TestResult.java +++ b/hudson-core/src/main/java/hudson/tasks/test/TestResult.java @@ -7,10 +7,10 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: + * Contributors: + * + * * - * - * * *******************************************************************************/ @@ -25,44 +25,46 @@ import java.util.Collection; import static java.util.Collections.emptyList; - /** * A class that represents a general concept of a test result, without any - * language or implementation specifics. - * Subclasses must add @Exported annotation to the fields they want to export. + * language or implementation specifics. Subclasses must add + * + * @Exported annotation to the fields they want to export. * * @sine 1.343 */ public abstract class TestResult extends TestObject { /** - * If the concept of a parent action is important to a subclass, then it should - * provide a non-noop implementation of this method. + * If the concept of a parent action is important to a subclass, then it + * should provide a non-noop implementation of this method. + * * @param action */ public void setParentAction(AbstractTestResultAction action) { } /** - * Returns the action that points to the top level test result includes - * this test result. - * + * Returns the action that points to the top level test result includes this + * test result. + * * @return */ public AbstractTestResultAction getParentAction() { return getOwner().getTestResultAction(); } - + /** * Request that the result update its counts of its children. Does not - * require a parent action or owner or siblings. Subclasses should - * implement this, unless they are *always* in a tallied state. + * require a parent action or owner or siblings. Subclasses should implement + * this, unless they are *always* in a tallied state. */ public void tally() { } - + /** * Sets the parent test result + * * @param parent */ public void setParent(TestObject parent) { @@ -71,7 +73,7 @@ public abstract class TestResult extends TestObject { /** * Gets the human readable title of this result object. */ - public /* abstract */ String getTitle(){ + public /* abstract */ String getTitle() { return ""; } @@ -79,7 +81,8 @@ public abstract class TestResult extends TestObject { * Mark a build as unstable if there are failures. Otherwise, leave the * build result unchanged. * - * @return {@link Result#UNSTABLE} if there are test failures, null otherwise. + * @return {@link Result#UNSTABLE} if there are test failures, null + * otherwise. * */ public Result getBuildResult() { @@ -111,33 +114,34 @@ public abstract class TestResult extends TestObject { return 0; } - /** * Gets the total number of skipped tests. */ public /* abstract */ int getSkipCount() { return 0; } - + /** * Gets the counter part of this {@link TestResult} in the previous run. * * @return null if no such counter part exists. */ public TestResult getPreviousResult() { - AbstractBuild<?,?> b = getOwner(); + AbstractBuild<?, ?> b = getOwner(); if (b == null) { return null; } - while(true) { + while (true) { b = b.getPreviousBuild(); - if(b==null) + if (b == null) { return null; + } AbstractTestResultAction r = b.getAction(getParentAction().getClass()); - if(r!=null) { + if (r != null) { TestResult result = r.findCorrespondingResult(this.getId()); - if (result!=null) + if (result != null) { return result; + } } } } @@ -147,7 +151,7 @@ public abstract class TestResult extends TestObject { * * @return null if no such counter part exists. */ - public TestResult getResultInBuild(AbstractBuild<?,?> build) { + public TestResult getResultInBuild(AbstractBuild<?, ?> build) { AbstractTestResultAction tra = build.getAction(getParentAction().getClass()); if (tra == null) { tra = build.getAction(AbstractTestResultAction.class); @@ -157,15 +161,16 @@ public abstract class TestResult extends TestObject { /** * Gets the "children" of this test result that failed + * * @return the children of this test result, if any, or an empty collection */ public Collection<? extends TestResult> getFailedTests() { return emptyList(); } - /** * Gets the "children" of this test result that passed + * * @return the children of this test result, if any, or an empty collection */ public Collection<? extends TestResult> getPassedTests() { @@ -174,6 +179,7 @@ public abstract class TestResult extends TestObject { /** * Gets the "children" of this test result that were skipped + * * @return the children of this test result, if any, or an empty list */ public Collection<? extends TestResult> getSkippedTests() { @@ -181,18 +187,17 @@ public abstract class TestResult extends TestObject { } /** - * If this test failed, then return the build number - * when this test started failing. + * If this test failed, then return the build number when this test started + * failing. */ public int getFailedSince() { return 0; } /** - * If this test failed, then return the run - * when this test started failing. + * If this test failed, then return the run when this test started failing. */ - public Run<?,?> getFailedSinceRun() { + public Run<?, ?> getFailedSinceRun() { return null; } @@ -211,7 +216,8 @@ public abstract class TestResult extends TestObject { } /** - * If there was an error or a failure, this is the stack trace, or otherwise null. + * If there was an error or a failure, this is the stack trace, or otherwise + * null. */ public String getErrorStackTrace() { return ""; @@ -221,11 +227,12 @@ public abstract class TestResult extends TestObject { * If there was an error or a failure, this is the text from the message. */ public String getErrorDetails() { - return ""; + return ""; } /** - * @return true if the test was not skipped and did not fail, false otherwise. + * @return true if the test was not skipped and did not fail, false + * otherwise. */ public boolean isPassed() { return ((getSkipCount() == 0) && (getFailCount() == 0)); @@ -240,23 +247,25 @@ public abstract class TestResult extends TestObject { sb.append("Fail: ").append(this.getFailCount()).append(", "); sb.append("Skipt: ").append(this.getSkipCount()).append(", "); sb.append("Pass: ").append(this.getSkipCount()).append(",\n"); - sb.append("Test Result Class: " ).append(this.getClass().getName()).append(" }\n"); - return sb.toString(); + sb.append("Test Result Class: ").append(this.getClass().getName()).append(" }\n"); + return sb.toString(); } /** - * Annotate some text -- what does this do? + * Annotate some text -- what does this do? + * * @param text * @return */ public String annotate(String text) { - if (text == null) - return null; + if (text == null) { + return null; + } text = text.replace("&", "&").replace("<", "<").replaceAll( - "\\b(https?://[^\\s)>]+)", "<a href=\"$1\">$1</a>"); + "\\b(https?://[^\\s)>]+)", "<a href=\"$1\">$1</a>"); - for (TestAction action: getTestActions()) { - text = action.annotate(text); + for (TestAction action : getTestActions()) { + text = action.annotate(text); } return text; } diff --git a/hudson-core/src/main/java/hudson/tasks/test/TestResultAggregator.java b/hudson-core/src/main/java/hudson/tasks/test/TestResultAggregator.java index 9896414..0f09527 100644 --- a/hudson-core/src/main/java/hudson/tasks/test/TestResultAggregator.java +++ b/hudson-core/src/main/java/hudson/tasks/test/TestResultAggregator.java @@ -7,10 +7,10 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: -* -* Kohsuke Kawaguchi, Yahoo!, Inc. - * + * Contributors: + * + * Kohsuke Kawaguchi, Yahoo!, Inc. + * * *******************************************************************************/ @@ -25,12 +25,13 @@ import hudson.model.BuildListener; import java.io.IOException; /** - * Aggregates {@link AbstractTestResultAction}s of {@link MatrixRun}s - * into {@link MatrixBuild}. - * + * Aggregates {@link AbstractTestResultAction}s of {@link MatrixRun}s into + * {@link MatrixBuild}. + * * @author Kohsuke Kawaguchi */ public class TestResultAggregator extends MatrixAggregator { + private MatrixTestResult result; public TestResultAggregator(MatrixBuild build, Launcher launcher, BuildListener listener) { @@ -47,7 +48,9 @@ public class TestResultAggregator extends MatrixAggregator { @Override public boolean endRun(MatrixRun run) throws InterruptedException, IOException { AbstractTestResultAction atr = run.getAction(AbstractTestResultAction.class); - if(atr!=null) result.add(atr); + if (atr != null) { + result.add(atr); + } return true; } } diff --git a/hudson-core/src/main/java/hudson/tasks/test/TestResultParser.java b/hudson-core/src/main/java/hudson/tasks/test/TestResultParser.java index 1c48efd..555d1ad 100644 --- a/hudson-core/src/main/java/hudson/tasks/test/TestResultParser.java +++ b/hudson-core/src/main/java/hudson/tasks/test/TestResultParser.java @@ -7,10 +7,10 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: + * Contributors: + * + * * - * - * * *******************************************************************************/ @@ -26,36 +26,39 @@ import hudson.model.TaskListener; import java.io.IOException; /** - * Parses test result files and builds in-memory representation of it as {@link TestResult}. + * Parses test result files and builds in-memory representation of it as + * {@link TestResult}. * - * <p> - * This extension point encapsulates the knowledge of a particular test report format and its parsing process, - * thereby improving the pluggability of test result parsing; integration with a new test tool can be done - * by just writing a parser, without writing a custom {@link hudson.tasks.Publisher}, and the test reports are displayed - * with the default UI and recognized by the rest of Hudson as test reports. + * <p> This extension point encapsulates the knowledge of a particular test + * report format and its parsing process, thereby improving the pluggability of + * test result parsing; integration with a new test tool can be done by just + * writing a parser, without writing a custom {@link hudson.tasks.Publisher}, + * and the test reports are displayed with the default UI and recognized by the + * rest of Hudson as test reports. * - * <p> - * Most typical implementations of this class should extend from {@link DefaultTestResultParserImpl}, - * which handles a set of default error checks on user inputs. + * <p> Most typical implementations of this class should extend from + * {@link DefaultTestResultParserImpl}, which handles a set of default error + * checks on user inputs. * - * <p> - * Parsers are stateless, and the {@link #parse(String, hudson.model.AbstractBuild, hudson.Launcher, hudson.model.TaskListener)} method - * can be concurrently invoked by multiple threads for different builds. + * <p> Parsers are stateless, and the + * {@link #parse(String, hudson.model.AbstractBuild, hudson.Launcher, hudson.model.TaskListener)} + * method can be concurrently invoked by multiple threads for different builds. * * @since 1.343 * @see DefaultTestResultParserImpl */ public abstract class TestResultParser implements ExtensionPoint { + /** * Returns a human readable name of the parser, like "JUnit Parser". */ public String getDisplayName() { - return "Unknown Parser"; + return "Unknown Parser"; } /** - * This text is used in the UI prompt for the GLOB that specifies files to be parsed by this parser. - * For example, "JUnit XML reports:" + * This text is used in the UI prompt for the GLOB that specifies files to + * be parsed by this parser. For example, "JUnit XML reports:" */ public String getTestResultLocationMessage() { return "Paths to results files to parse:"; @@ -69,45 +72,41 @@ public abstract class TestResultParser implements ExtensionPoint { } /** - * Parses the specified set of files and builds a {@link TestResult} object that represents them. + * Parses the specified set of files and builds a {@link TestResult} object + * that represents them. * - * <p> - * The implementation is encouraged to do the following: + * <p> The implementation is encouraged to do the following: * - * <ul> - * <li> - * If the build is successful but GLOB didn't match anything, report that as an error. This is - * to detect the error in GLOB. But don't do this if the build has already failed (for example, - * think of a failure in SCM checkout.) + * <ul> <li> If the build is successful but GLOB didn't match anything, + * report that as an error. This is to detect the error in GLOB. But don't + * do this if the build has already failed (for example, think of a failure + * in SCM checkout.) * - * <li> - * Examine time stamp of test report files and if those are younger than the build, ignore them. - * This is to ignore test reports created by earlier executions. Take the possible timestamp - * difference in the master/slave into account. - * </ul> + * <li> Examine time stamp of test report files and if those are younger + * than the build, ignore them. This is to ignore test reports created by + * earlier executions. Take the possible timestamp difference in the + * master/slave into account. </ul> * - * @param testResultLocations - * GLOB pattern relative to the {@linkplain AbstractBuild#getWorkspace() workspace} that - * specifies the locations of the test result files. Never null. - * @param build - * Build for which these tests are parsed. Never null. - * @param launcher - * Can be used to fork processes on the machine where the build is running. Never null. - * @param listener - * Use this to report progress and other problems. Never null. + * @param testResultLocations GLOB pattern relative to the + * {@linkplain AbstractBuild#getWorkspace() workspace} that specifies the + * locations of the test result files. Never null. + * @param build Build for which these tests are parsed. Never null. + * @param launcher Can be used to fork processes on the machine where the + * build is running. Never null. + * @param listener Use this to report progress and other problems. Never + * null. * - * @throws InterruptedException - * If the user cancels the build, it will be received as a thread interruption. Do not catch - * it, and instead just forward that through the call stack. - * @throws IOException - * If you don't care about handling exceptions gracefully, you can just throw IOException - * and let the default exception handling in Hudson takes care of it. - * @throws AbortException - * If you encounter an error that you handled gracefully, throw this exception and Hudson - * will not show a stack trace. + * @throws InterruptedException If the user cancels the build, it will be + * received as a thread interruption. Do not catch it, and instead just + * forward that through the call stack. + * @throws IOException If you don't care about handling exceptions + * gracefully, you can just throw IOException and let the default exception + * handling in Hudson takes care of it. + * @throws AbortException If you encounter an error that you handled + * gracefully, throw this exception and Hudson will not show a stack trace. */ public abstract TestResult parse(String testResultLocations, - AbstractBuild build, Launcher launcher, - TaskListener listener) + AbstractBuild build, Launcher launcher, + TaskListener listener) throws InterruptedException, IOException; } diff --git a/hudson-core/src/main/java/hudson/tasks/test/TestResultProjectAction.java b/hudson-core/src/main/java/hudson/tasks/test/TestResultProjectAction.java index c97a076..320ca8f 100644 --- a/hudson-core/src/main/java/hudson/tasks/test/TestResultProjectAction.java +++ b/hudson-core/src/main/java/hudson/tasks/test/TestResultProjectAction.java @@ -7,10 +7,10 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: -* -* Kohsuke Kawaguchi - * + * Contributors: + * + * Kohsuke Kawaguchi + * * *******************************************************************************/ @@ -31,22 +31,23 @@ import java.io.IOException; import java.util.List; /** - * Project action object from test reporter, such as {@link JUnitResultArchiver}, - * which displays the trend report on the project top page. + * Project action object from test reporter, such as + * {@link JUnitResultArchiver}, which displays the trend report on the project + * top page. * - * <p> - * This works with any {@link AbstractTestResultAction} implementation. + * <p> This works with any {@link AbstractTestResultAction} implementation. * * @author Kohsuke Kawaguchi */ public class TestResultProjectAction implements Action { + /** * Project that owns this action. */ //TODO: review and check whether we can do it private - public final AbstractProject<?,?> project; + public final AbstractProject<?, ?> project; - public TestResultProjectAction(AbstractProject<?,?> project) { + public TestResultProjectAction(AbstractProject<?, ?> project) { this.project = project; } @@ -70,16 +71,19 @@ public class TestResultProjectAction implements Action { } public AbstractTestResultAction getLastTestResultAction() { - final AbstractBuild<?,?> tb = project.getLastSuccessfulBuild(); + final AbstractBuild<?, ?> tb = project.getLastSuccessfulBuild(); - AbstractBuild<?,?> b=project.getLastBuild(); - while(b!=null) { + AbstractBuild<?, ?> b = project.getLastBuild(); + while (b != null) { AbstractTestResultAction a = b.getTestResultAction(); - if(a!=null) return a; - if(b==tb) - // if even the last successful build didn't produce the test result, - // that means we just don't have any tests configured. + if (a != null) { + return a; + } + if (b == tb) // if even the last successful build didn't produce the test result, + // that means we just don't have any tests configured. + { return null; + } b = b.getPreviousBuild(); } @@ -89,37 +93,41 @@ public class TestResultProjectAction implements Action { /** * Display the test result trend. */ - public void doTrend( StaplerRequest req, StaplerResponse rsp ) throws IOException, ServletException { + public void doTrend(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { AbstractTestResultAction a = getLastTestResultAction(); - if(a!=null) - a.doGraph(req,rsp); - else + if (a != null) { + a.doGraph(req, rsp); + } else { rsp.setStatus(HttpServletResponse.SC_NOT_FOUND); + } } /** - * Generates the clickable map HTML fragment for {@link #doTrend(StaplerRequest, StaplerResponse)}. + * Generates the clickable map HTML fragment for + * {@link #doTrend(StaplerRequest, StaplerResponse)}. */ - public void doTrendMap( StaplerRequest req, StaplerResponse rsp ) throws IOException, ServletException { + public void doTrendMap(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { AbstractTestResultAction a = getLastTestResultAction(); - if(a!=null) - a.doGraphMap(req,rsp); - else + if (a != null) { + a.doGraphMap(req, rsp); + } else { rsp.setStatus(HttpServletResponse.SC_NOT_FOUND); + } } /** * Changes the test result report display mode. */ - public void doFlipTrend( StaplerRequest req, StaplerResponse rsp ) throws IOException, ServletException { + public void doFlipTrend(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { boolean failureOnly = false; // check the current preference value Cookie[] cookies = req.getCookies(); - if(cookies!=null) { + if (cookies != null) { for (Cookie cookie : cookies) { - if(cookie.getName().equals(FAILURE_ONLY_COOKIE)) + if (cookie.getName().equals(FAILURE_ONLY_COOKIE)) { failureOnly = Boolean.parseBoolean(cookie.getValue()); + } } } @@ -127,16 +135,15 @@ public class TestResultProjectAction implements Action { failureOnly = !failureOnly; // set the updated value - Cookie cookie = new Cookie(FAILURE_ONLY_COOKIE,String.valueOf(failureOnly)); + Cookie cookie = new Cookie(FAILURE_ONLY_COOKIE, String.valueOf(failureOnly)); List anc = req.getAncestors(); - Ancestor a = (Ancestor) anc.get(anc.size()-2); + Ancestor a = (Ancestor) anc.get(anc.size() - 2); cookie.setPath(a.getUrl()); // just for this project - cookie.setMaxAge(60*60*24*365); // 1 year + cookie.setMaxAge(60 * 60 * 24 * 365); // 1 year rsp.addCookie(cookie); // back to the project page rsp.sendRedirect(".."); } - private static final String FAILURE_ONLY_COOKIE = "TestResultAction_failureOnly"; } diff --git a/hudson-core/src/main/java/hudson/tasks/test/package.html b/hudson-core/src/main/java/hudson/tasks/test/package.html index b103e9e..98c8c9f 100644 --- a/hudson-core/src/main/java/hudson/tasks/test/package.html +++ b/hudson-core/src/main/java/hudson/tasks/test/package.html @@ -16,7 +16,7 @@ --> <html><head/><body> -Defines contracts that need to be implemented by a test reporting -action (such as the built-in JUnit one). This contract allows <tt>Project</tt> -to display a test result trend history. + Defines contracts that need to be implemented by a test reporting + action (such as the built-in JUnit one). This contract allows <tt>Project</tt> + to display a test result trend history. </body></html>
\ No newline at end of file |

