| author | Henrik Lynggaard Hansen | 2012-07-16 15:39:55 (EDT) |
|---|---|---|
| committer | Henrik Lynggaard Hansen | 2012-07-16 15:39:55 (EDT) |
| commit | 63947f0d5d47f9a82ccde0cee2893a63f67951b7 (patch) (side-by-side diff) | |
| tree | 25adda3e6a68982832b267b0063d5b02caef1e54 | |
| parent | 825e47b2ae6a94d7be58a9f180e10928c8d62613 (diff) | |
| download | org.eclipse.hudson.core-63947f0d5d47f9a82ccde0cee2893a63f67951b7.zip org.eclipse.hudson.core-63947f0d5d47f9a82ccde0cee2893a63f67951b7.tar.gz org.eclipse.hudson.core-63947f0d5d47f9a82ccde0cee2893a63f67951b7.tar.bz2 | |
Reformat hudson.util and subpackagesrefs/changes/04/6804/1
Change-Id: I3fea6f6b5e3da90753dbc0ff910aea3b916a2a03
Signed-off-by: Henrik Lynggaard Hansen <henrik@hlyh.dk>
124 files changed, 3839 insertions, 3294 deletions
diff --git a/hudson-core/src/main/java/hudson/util/AWTProblem.java b/hudson-core/src/main/java/hudson/util/AWTProblem.java index 20bcc77..5eddadb 100644 --- a/hudson-core/src/main/java/hudson/util/AWTProblem.java +++ b/hudson-core/src/main/java/hudson/util/AWTProblem.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,6 +21,7 @@ package hudson.util; */ public class AWTProblem extends ErrorObject { //TODO: review and check whether we can do it private + public final Throwable cause; public Throwable getCause() { @@ -31,4 +32,3 @@ public class AWTProblem extends ErrorObject { this.cause = cause; } } - diff --git a/hudson-core/src/main/java/hudson/util/AbstractTaskListener.java b/hudson-core/src/main/java/hudson/util/AbstractTaskListener.java index 33e16b3..67687a2 100644 --- a/hudson-core/src/main/java/hudson/util/AbstractTaskListener.java +++ b/hudson-core/src/main/java/hudson/util/AbstractTaskListener.java @@ -8,7 +8,7 @@ * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * + * * *******************************************************************************/ @@ -21,11 +21,13 @@ import java.io.IOException; /** * Partial default implementation of {@link TaskListener} + * * @author Kohsuke Kawaguchi */ public abstract class AbstractTaskListener implements TaskListener { + public void hyperlink(String url, String text) throws IOException { - annotate(new HyperlinkNote(url,text.length())); + annotate(new HyperlinkNote(url, text.length())); getLogger().print(text); } } diff --git a/hudson-core/src/main/java/hudson/util/AdaptedIterator.java b/hudson-core/src/main/java/hudson/util/AdaptedIterator.java index aff1cf2..2cd3358 100644 --- a/hudson-core/src/main/java/hudson/util/AdaptedIterator.java +++ b/hudson-core/src/main/java/hudson/util/AdaptedIterator.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,14 +21,15 @@ import java.util.Iterator; /** * {@link Iterator} that adapts the values returned from another iterator. * - * <p> - * This class should be really in {@link Iterators} but for historical reasons it's here. + * <p> This class should be really in {@link Iterators} but for historical + * reasons it's here. * * @author Kohsuke Kawaguchi * @since 1.121 * @see Iterators */ -public abstract class AdaptedIterator<T,U> implements Iterator<U> { +public abstract class AdaptedIterator<T, U> implements Iterator<U> { + private final Iterator<? extends T> core; protected AdaptedIterator(Iterator<? extends T> core) { diff --git a/hudson-core/src/main/java/hudson/util/AdministrativeError.java b/hudson-core/src/main/java/hudson/util/AdministrativeError.java index cc6a7e2..0350a0f 100644 --- a/hudson-core/src/main/java/hudson/util/AdministrativeError.java +++ b/hudson-core/src/main/java/hudson/util/AdministrativeError.java @@ -8,7 +8,7 @@ * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * + * * *******************************************************************************/ @@ -18,30 +18,32 @@ import hudson.model.AdministrativeMonitor; import hudson.Extension; /** - * A convenient {@link AdministrativeMonitor} implementations that show an error message - * and optional stack trace. This is useful for notifying a non-fatal error to the administrator. + * A convenient {@link AdministrativeMonitor} implementations that show an error + * message and optional stack trace. This is useful for notifying a non-fatal + * error to the administrator. * - * <p> - * These errors are registered when instances are created. No need to use {@link Extension}. + * <p> These errors are registered when instances are created. No need to use + * {@link Extension}. * * @author Kohsuke Kawaguchi */ public class AdministrativeError extends AdministrativeMonitor { + public final String message; public final String title; public final Throwable details; /** - * @param id - * Unique ID that distinguishes this error from other errors. - * Must remain the same across Hudson executions. Use a caller class name, or something like that. - * @param title - * A title of the problem. This is used as the HTML title - * of the details page. Should be just one sentence, like "ZFS migration error." - * @param message - * A short description of the problem. This is used in the "/manage" page, and can include HTML, but it should be still short. - * @param details - * An exception indicating the problem. The administrator can see this once they click "more details". + * @param id Unique ID that distinguishes this error from other errors. Must + * remain the same across Hudson executions. Use a caller class name, or + * something like that. + * @param title A title of the problem. This is used as the HTML title of + * the details page. Should be just one sentence, like "ZFS migration + * error." + * @param message A short description of the problem. This is used in the + * "/manage" page, and can include HTML, but it should be still short. + * @param details An exception indicating the problem. The administrator can + * see this once they click "more details". */ public AdministrativeError(String id, String title, String message, Throwable details) { super(id); diff --git a/hudson-core/src/main/java/hudson/util/Area.java b/hudson-core/src/main/java/hudson/util/Area.java index e806d56..72e2707 100644 --- a/hudson-core/src/main/java/hudson/util/Area.java +++ b/hudson-core/src/main/java/hudson/util/Area.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 + * * *******************************************************************************/ @@ -26,6 +26,7 @@ import java.util.regex.Pattern; * @since 1.213 */ public final class Area { + public final int width; public final int height; @@ -39,19 +40,19 @@ public final class Area { */ public static Area parse(String s) { Matcher m = PATTERN.matcher(s); - if(m.matches()) - return new Area(Integer.parseInt(m.group(1)),Integer.parseInt(m.group(2))); + if (m.matches()) { + return new Area(Integer.parseInt(m.group(1)), Integer.parseInt(m.group(2))); + } return null; } public int area() { - return width*height; + return width * height; } @Override public String toString() { - return width+"x"+height; + return width + "x" + height; } - private static final Pattern PATTERN = Pattern.compile("(\\d+)x(\\d+)"); } diff --git a/hudson-core/src/main/java/hudson/util/ArgumentListBuilder.java b/hudson-core/src/main/java/hudson/util/ArgumentListBuilder.java index c48c801..1b14cca 100644 --- a/hudson-core/src/main/java/hudson/util/ArgumentListBuilder.java +++ b/hudson-core/src/main/java/hudson/util/ArgumentListBuilder.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, Alan Harder, Yahoo! Inc. - * + * * *******************************************************************************/ @@ -36,9 +36,11 @@ import java.util.Set; * @author Kohsuke Kawaguchi */ public class ArgumentListBuilder implements Serializable { + private final List<String> args = new ArrayList<String>(); /** - * Bit mask indicating arguments that shouldn't be echoed-back (e.g., password) + * Bit mask indicating arguments that shouldn't be echoed-back (e.g., + * password) */ private BitSet mask = new BitSet(); @@ -65,27 +67,28 @@ public class ArgumentListBuilder implements Serializable { } public ArgumentListBuilder add(String a) { - return add(a,false); + return add(a, false); } /** * @since 1.378 */ public ArgumentListBuilder add(String a, boolean mask) { - if(a!=null) { - if(mask) { + if (a != null) { + if (mask) { this.mask.set(args.size()); } args.add(a); } return this; } - + public ArgumentListBuilder prepend(String... args) { // left-shift the mask - BitSet nm = new BitSet(this.args.size()+args.length); - for(int i=0; i<this.args.size(); i++) - nm.set(i+args.length, mask.get(i)); + BitSet nm = new BitSet(this.args.size() + args.length); + for (int i = 0; i < this.args.size(); i++) { + nm.set(i + args.length, mask.get(i)); + } mask = nm; this.args.addAll(0, Arrays.asList(args)); @@ -93,22 +96,21 @@ public class ArgumentListBuilder implements Serializable { } /** - * Adds an argument by quoting it. - * This is necessary only in a rare circumstance, - * such as when adding argument for ssh and rsh. + * Adds an argument by quoting it. This is necessary only in a rare + * circumstance, such as when adding argument for ssh and rsh. * - * Normal process invocations don't need it, because each - * argument is treated as its own string and never merged into one. + * Normal process invocations don't need it, because each argument is + * treated as its own string and never merged into one. */ public ArgumentListBuilder addQuoted(String a) { - return add('"'+a+'"', false); + return add('"' + a + '"', false); } /** * @since 1.378 */ public ArgumentListBuilder addQuoted(String a, boolean mask) { - return add('"'+a+'"', mask); + return add('"' + a + '"', mask); } public ArgumentListBuilder add(String... args) { @@ -119,10 +121,13 @@ public class ArgumentListBuilder implements Serializable { } /** - * Decomposes the given token into multiple arguments by splitting via whitespace. + * Decomposes the given token into multiple arguments by splitting via + * whitespace. */ public ArgumentListBuilder addTokenized(String s) { - if(s==null) return this; + if (s == null) { + return this; + } add(Util.tokenize(s)); return this; } @@ -131,8 +136,10 @@ public class ArgumentListBuilder implements Serializable { * @since 1.378 */ public ArgumentListBuilder addKeyValuePair(String prefix, String key, String value, boolean mask) { - if(key==null) return this; - add(((prefix==null)?"-D":prefix)+key+'='+value, mask); + if (key == null) { + return this; + } + add(((prefix == null) ? "-D" : prefix) + key + '=' + value, mask); return this; } @@ -140,74 +147,75 @@ public class ArgumentListBuilder implements Serializable { * Adds key value pairs as "-Dkey=value -Dkey=value ..." * * <tt>-D</tt> portion is configurable as the 'prefix' parameter. + * * @since 1.114 */ - public ArgumentListBuilder addKeyValuePairs(String prefix, Map<String,String> props) { - for (Entry<String,String> e : props.entrySet()) + public ArgumentListBuilder addKeyValuePairs(String prefix, Map<String, String> props) { + for (Entry<String, String> e : props.entrySet()) { addKeyValuePair(prefix, e.getKey(), e.getValue(), false); + } return this; } /** * Adds key value pairs as "-Dkey=value -Dkey=value ..." with masking. * - * @param prefix - * Configures the -D portion of the example. Defaults to -D if null. - * @param props - * The map of key/value pairs to add - * @param propsToMask - * Set containing key names to mark as masked in the argument list. Key - * names that do not exist in the set will be added unmasked. + * @param prefix Configures the -D portion of the example. Defaults to -D if + * null. + * @param props The map of key/value pairs to add + * @param propsToMask Set containing key names to mark as masked in the + * argument list. Key names that do not exist in the set will be added + * unmasked. * @since 1.378 */ - public ArgumentListBuilder addKeyValuePairs(String prefix, Map<String,String> props, Set<String> propsToMask) { - for (Entry<String,String> e : props.entrySet()) { + public ArgumentListBuilder addKeyValuePairs(String prefix, Map<String, String> props, Set<String> propsToMask) { + for (Entry<String, String> e : props.entrySet()) { addKeyValuePair(prefix, e.getKey(), e.getValue(), (propsToMask == null) ? false : propsToMask.contains(e.getKey())); } return this; } /** - * Adds key value pairs as "-Dkey=value -Dkey=value ..." by parsing a given string using {@link Properties}. + * Adds key value pairs as "-Dkey=value -Dkey=value ..." by parsing a given + * string using {@link Properties}. * - * @param prefix - * The '-D' portion of the example. Defaults to -D if null. - * @param properties - * The persisted form of {@link Properties}. For example, "abc=def\nghi=jkl". Can be null, in which - * case this method becomes no-op. - * @param vr - * {@link VariableResolver} to be performed on the values. + * @param prefix The '-D' portion of the example. Defaults to -D if null. + * @param properties The persisted form of {@link Properties}. For example, + * "abc=def\nghi=jkl". Can be null, in which case this method becomes no-op. + * @param vr {@link VariableResolver} to be performed on the values. * @since 1.262 */ public ArgumentListBuilder addKeyValuePairsFromPropertyString(String prefix, String properties, VariableResolver vr) throws IOException { - if(properties==null) return this; + if (properties == null) { + return this; + } - for (Entry<Object,Object> entry : Util.loadProperties(properties).entrySet()) { - addKeyValuePair(prefix, (String)entry.getKey(), Util.replaceMacro(entry.getValue().toString(),vr), false); + for (Entry<Object, Object> entry : Util.loadProperties(properties).entrySet()) { + addKeyValuePair(prefix, (String) entry.getKey(), Util.replaceMacro(entry.getValue().toString(), vr), false); } return this; } /** - * Adds key value pairs as "-Dkey=value -Dkey=value ..." by parsing a given string using {@link Properties} with masking. + * Adds key value pairs as "-Dkey=value -Dkey=value ..." by parsing a given + * string using {@link Properties} with masking. * - * @param prefix - * The '-D' portion of the example. Defaults to -D if null. - * @param properties - * The persisted form of {@link Properties}. For example, "abc=def\nghi=jkl". Can be null, in which - * case this method becomes no-op. - * @param vr - * {@link VariableResolver} to be performed on the values. - * @param propsToMask - * Set containing key names to mark as masked in the argument list. Key - * names that do not exist in the set will be added unmasked. + * @param prefix The '-D' portion of the example. Defaults to -D if null. + * @param properties The persisted form of {@link Properties}. For example, + * "abc=def\nghi=jkl". Can be null, in which case this method becomes no-op. + * @param vr {@link VariableResolver} to be performed on the values. + * @param propsToMask Set containing key names to mark as masked in the + * argument list. Key names that do not exist in the set will be added + * unmasked. * @since 1.378 */ public ArgumentListBuilder addKeyValuePairsFromPropertyString(String prefix, String properties, VariableResolver vr, Set<String> propsToMask) throws IOException { - if(properties==null) return this; + if (properties == null) { + return this; + } - for (Entry<Object,Object> entry : Util.loadProperties(properties).entrySet()) { - addKeyValuePair(prefix, (String)entry.getKey(), Util.replaceMacro(entry.getValue().toString(),vr), (propsToMask == null) ? false : propsToMask.contains((String)entry.getKey())); + for (Entry<Object, Object> entry : Util.loadProperties(properties).entrySet()) { + addKeyValuePair(prefix, (String) entry.getKey(), Util.replaceMacro(entry.getValue().toString(), vr), (propsToMask == null) ? false : propsToMask.contains((String) entry.getKey())); } return this; } @@ -220,7 +228,7 @@ public class ArgumentListBuilder implements Serializable { public String[] toCommandArray() { return args.toArray(new String[args.size()]); } - + @Override public ArgumentListBuilder clone() { ArgumentListBuilder r = new ArgumentListBuilder(); @@ -242,41 +250,45 @@ public class ArgumentListBuilder implements Serializable { } /** - * Just adds quotes around args containing spaces, but no other special characters, - * so this method should generally be used only for informational/logging purposes. + * Just adds quotes around args containing spaces, but no other special + * characters, so this method should generally be used only for + * informational/logging purposes. */ public String toStringWithQuote() { StringBuilder buf = new StringBuilder(); for (String arg : args) { - if(buf.length()>0) buf.append(' '); + if (buf.length() > 0) { + buf.append(' '); + } - if(arg.indexOf(' ')>=0 || arg.length()==0) + if (arg.indexOf(' ') >= 0 || arg.length() == 0) { buf.append('"').append(arg).append('"'); - else + } else { buf.append(arg); + } } return buf.toString(); } /** - * Wrap command in a CMD.EXE call so we can return the exit code (ERRORLEVEL). - * This method takes care of escaping special characters in the command, which - * is needed since the command is now passed as a string to the CMD.EXE shell. - * This is done as follows: - * Wrap arguments in double quotes if they contain any of: - * space *?,;^&<>|" or % followed by a letter. - * <br/> When testing from command prompt, these characters also need to be - * prepended with a ^ character: ^&<>| -- however, invoking cmd.exe from - * Hudson does not seem to require this extra escaping so it is not added by - * this method. - * <br/> A " is prepended with another " character. Note: Windows has issues - * escaping some combinations of quotes and spaces. Quotes should be avoided. - * <br/> A % followed by a letter has that letter wrapped in double quotes, - * to avoid possible variable expansion. ie, %foo% becomes "%"f"oo%". - * The second % does not need special handling because it is not followed - * by a letter. <br/> - * Example: "-Dfoo=*abc?def;ghi^jkl&mno<pqr>stu|vwx""yz%"e"nd" - * @return new ArgumentListBuilder that runs given command through cmd.exe /C + * Wrap command in a CMD.EXE call so we can return the exit code + * (ERRORLEVEL). This method takes care of escaping special characters in + * the command, which is needed since the command is now passed as a string + * to the CMD.EXE shell. This is done as follows: Wrap arguments in double + * quotes if they contain any of: space *?,;^&<>|" or % followed by a + * letter. <br/> When testing from command prompt, these characters also + * need to be prepended with a ^ character: ^&<>| -- however, invoking + * cmd.exe from Hudson does not seem to require this extra escaping so it is + * not added by this method. <br/> A " is prepended with another " + * character. Note: Windows has issues escaping some combinations of quotes + * and spaces. Quotes should be avoided. <br/> A % followed by a letter has + * that letter wrapped in double quotes, to avoid possible variable + * expansion. ie, %foo% becomes "%"f"oo%". The second % does not need + * special handling because it is not followed by a letter. <br/> Example: + * "-Dfoo=*abc?def;ghi^jkl&mno<pqr>stu|vwx""yz%"e"nd" + * + * @return new ArgumentListBuilder that runs given command through cmd.exe + * /C * @since 1.386 */ public ArgumentListBuilder toWindowsCommand() { @@ -288,24 +300,33 @@ public class ArgumentListBuilder implements Serializable { char c = arg.charAt(i); if (!quoted && (c == ' ' || c == '*' || c == '?' || c == ',' || c == ';')) { quoted = startQuoting(quotedArgs, arg, i); - } - else if (c == '^' || c == '&' || c == '<' || c == '>' || c == '|') { - if (!quoted) quoted = startQuoting(quotedArgs, arg, i); + } else if (c == '^' || c == '&' || c == '<' || c == '>' || c == '|') { + if (!quoted) { + quoted = startQuoting(quotedArgs, arg, i); + } // quotedArgs.append('^'); See note in javadoc above - } - else if (c == '"') { - if (!quoted) quoted = startQuoting(quotedArgs, arg, i); + } else if (c == '"') { + if (!quoted) { + quoted = startQuoting(quotedArgs, arg, i); + } quotedArgs.append('"'); - } - else if (percent && ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'))) { - if (!quoted) quoted = startQuoting(quotedArgs, arg, i); + } else if (percent && ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'))) { + if (!quoted) { + quoted = startQuoting(quotedArgs, arg, i); + } quotedArgs.append('"').append(c); c = '"'; } percent = (c == '%'); - if (quoted) quotedArgs.append(c); + if (quoted) { + quotedArgs.append(c); + } + } + if (quoted) { + quotedArgs.append('"'); + } else { + quotedArgs.append(arg); } - if (quoted) quotedArgs.append('"'); else quotedArgs.append(arg); quotedArgs.append(' '); } // (comment copied from old code in hudson.tasks.Ant) @@ -324,30 +345,34 @@ public class ArgumentListBuilder implements Serializable { /** * Returns true if there are any masked arguments. + * * @return true if there are any masked arguments; false otherwise */ public boolean hasMaskedArguments() { - return mask.length()>0; + return mask.length() > 0; } /** - * Returns an array of booleans where the masked arguments are marked as true + * Returns an array of booleans where the masked arguments are marked as + * true + * * @return an array of booleans. */ public boolean[] toMaskArray() { boolean[] mask = new boolean[args.size()]; - for( int i=0; i<mask.length; i++) + for (int i = 0; i < mask.length; i++) { mask[i] = this.mask.get(i); + } return mask; } /** * Add a masked argument + * * @param string the argument */ public void addMasked(String string) { add(string, true); } - private static final long serialVersionUID = 1L; } diff --git a/hudson-core/src/main/java/hudson/util/AtomicFileWriter.java b/hudson-core/src/main/java/hudson/util/AtomicFileWriter.java index d6e27ac..774701c 100644 --- a/hudson-core/src/main/java/hudson/util/AtomicFileWriter.java +++ b/hudson-core/src/main/java/hudson/util/AtomicFileWriter.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,9 +28,8 @@ import java.nio.charset.Charset; /** * Buffered {@link FileWriter} that uses UTF-8. * - * <p> - * The write operation is atomic when used for overwriting; - * it either leaves the original file intact, or it completely rewrites it with new contents. + * <p> The write operation is atomic when used for overwriting; it either leaves + * the original file intact, or it completely rewrites it with new contents. * * @author Kohsuke Kawaguchi */ @@ -44,25 +43,26 @@ public class AtomicFileWriter extends Writer { * Writes with UTF-8 encoding. */ public AtomicFileWriter(File f) throws IOException { - this(f,"UTF-8"); + this(f, "UTF-8"); } /** - * @param encoding - * File encoding to write. If null, platform default encoding is chosen. + * @param encoding File encoding to write. If null, platform default + * encoding is chosen. */ public AtomicFileWriter(File f, String encoding) throws IOException { File dir = f.getParentFile(); try { dir.mkdirs(); - tmpFile = File.createTempFile("atomic",null, dir); + tmpFile = File.createTempFile("atomic", null, dir); } catch (IOException e) { - throw new IOException2("Failed to create a temporary file in "+ dir,e); + throw new IOException2("Failed to create a temporary file in " + dir, e); } destFile = f; - if (encoding==null) + if (encoding == null) { encoding = Charset.defaultCharset().name(); - core = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(tmpFile),encoding)); + } + core = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(tmpFile), encoding)); } @Override @@ -72,11 +72,11 @@ public class AtomicFileWriter extends Writer { @Override public void write(String str, int off, int len) throws IOException { - core.write(str,off,len); + core.write(str, off, len); } public void write(char cbuf[], int off, int len) throws IOException { - core.write(cbuf,off,len); + core.write(cbuf, off, len); } public void flush() throws IOException { @@ -88,10 +88,10 @@ public class AtomicFileWriter extends Writer { } /** - * When the write operation failed, call this method to - * leave the original file intact and remove the temporary file. - * This method can be safely invoked from the "finally" block, even after - * the {@link #commit()} is called, to simplify coding. + * When the write operation failed, call this method to leave the original + * file intact and remove the temporary file. This method can be safely + * invoked from the "finally" block, even after the {@link #commit()} is + * called, to simplify coding. */ public void abort() throws IOException { close(); @@ -100,9 +100,9 @@ public class AtomicFileWriter extends Writer { public void commit() throws IOException { close(); - if(destFile.exists() && !destFile.delete()) { + if (destFile.exists() && !destFile.delete()) { tmpFile.delete(); - throw new IOException("Unable to delete "+destFile); + throw new IOException("Unable to delete " + destFile); } tmpFile.renameTo(destFile); } @@ -114,8 +114,7 @@ public class AtomicFileWriter extends Writer { } /** - * Until the data is committed, this file captures - * the written content. + * Until the data is committed, this file captures the written content. */ public File getTemporaryFile() { return tmpFile; diff --git a/hudson-core/src/main/java/hudson/util/AutoCompleteSeeder.java b/hudson-core/src/main/java/hudson/util/AutoCompleteSeeder.java index 67093d8..4bcfc99 100644 --- a/hudson-core/src/main/java/hudson/util/AutoCompleteSeeder.java +++ b/hudson-core/src/main/java/hudson/util/AutoCompleteSeeder.java @@ -4,10 +4,11 @@ import java.util.ArrayList; import java.util.List; /** - * Utility class for taking the current input value and computing a list - * of potential terms to match against the list of defined labels. + * Utility class for taking the current input value and computing a list of + * potential terms to match against the list of defined labels. */ public class AutoCompleteSeeder { + private String source; public AutoCompleteSeeder(String source) { diff --git a/hudson-core/src/main/java/hudson/util/ByteArrayOutputStream2.java b/hudson-core/src/main/java/hudson/util/ByteArrayOutputStream2.java index 31bf5d7..f204d37 100644 --- a/hudson-core/src/main/java/hudson/util/ByteArrayOutputStream2.java +++ b/hudson-core/src/main/java/hudson/util/ByteArrayOutputStream2.java @@ -8,7 +8,7 @@ * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * + * * *******************************************************************************/ @@ -20,9 +20,11 @@ import java.io.InputStream; /** * {@link ByteArrayOutputStream} with access to its raw buffer. + * * @since 1.349 */ public class ByteArrayOutputStream2 extends ByteArrayOutputStream { + public ByteArrayOutputStream2() { } @@ -38,16 +40,18 @@ public class ByteArrayOutputStream2 extends ByteArrayOutputStream { * Reads the given {@link InputStream} completely into the buffer. */ public void readFrom(InputStream is) throws IOException { - while(true) { - if(count==buf.length) { + while (true) { + if (count == buf.length) { // realllocate - byte[] data = new byte[buf.length*2]; - System.arraycopy(buf,0,data,0,buf.length); + byte[] data = new byte[buf.length * 2]; + System.arraycopy(buf, 0, data, 0, buf.length); buf = data; } - int sz = is.read(buf,count,buf.length-count); - if(sz<0) return; + int sz = is.read(buf, count, buf.length - count); + if (sz < 0) { + return; + } count += sz; } } diff --git a/hudson-core/src/main/java/hudson/util/ByteBuffer.java b/hudson-core/src/main/java/hudson/util/ByteBuffer.java index e863def..1d727a1 100644 --- a/hudson-core/src/main/java/hudson/util/ByteBuffer.java +++ b/hudson-core/src/main/java/hudson/util/ByteBuffer.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 + * * *******************************************************************************/ @@ -24,29 +24,28 @@ import java.io.InputStream; /** * {@link ByteArrayOutputStream} re-implementation. * - * <p> - * This version allows one to read while writing is in progress. + * <p> This version allows one to read while writing is in progress. * * @author Kohsuke Kawaguchi * @deprecated since 2008-05-28. Moved to stapler */ public class ByteBuffer extends OutputStream { + private byte[] buf = new byte[8192]; /** * Size of the data. */ private int size = 0; - public synchronized void write(byte b[], int off, int len) throws IOException { ensureCapacity(len); - System.arraycopy(b,off,buf,size,len); - size+=len; + System.arraycopy(b, off, buf, size, len); + size += len; } public synchronized void write(int b) throws IOException { ensureCapacity(1); - buf[size++] = (byte)b; + buf[size++] = (byte) b; } public synchronized long length() { @@ -54,23 +53,24 @@ public class ByteBuffer extends OutputStream { } private void ensureCapacity(int len) { - if(buf.length-size>len) + if (buf.length - size > len) { return; + } - byte[] n = new byte[Math.max(buf.length*2, size+len)]; - System.arraycopy(buf,0,n,0,size); + byte[] n = new byte[Math.max(buf.length * 2, size + len)]; + System.arraycopy(buf, 0, n, 0, size); this.buf = n; } public synchronized String toString() { - return new String(buf,0,size); + return new String(buf, 0, size); } /** * Writes the contents of this buffer to another OutputStream. */ public synchronized void writeTo(OutputStream os) throws IOException { - os.write(buf,0,size); + os.write(buf, 0, size); } /** @@ -79,36 +79,39 @@ public class ByteBuffer extends OutputStream { public InputStream newInputStream() { return new InputStream() { private int pos = 0; + public int read() throws IOException { - synchronized(ByteBuffer.this) { - if(pos>=size) return -1; + synchronized (ByteBuffer.this) { + if (pos >= size) { + return -1; + } return buf[pos++]; } } public int read(byte b[], int off, int len) throws IOException { - synchronized(ByteBuffer.this) { - if(size==pos) + synchronized (ByteBuffer.this) { + if (size == pos) { return -1; + } - int sz = Math.min(len,size-pos); - System.arraycopy(buf,pos,b,off,sz); - pos+=sz; + int sz = Math.min(len, size - pos); + System.arraycopy(buf, pos, b, off, sz); + pos += sz; return sz; } } - public int available() throws IOException { - synchronized(ByteBuffer.this) { - return size-pos; + synchronized (ByteBuffer.this) { + return size - pos; } } public long skip(long n) throws IOException { - synchronized(ByteBuffer.this) { - int diff = (int) Math.min(n,size-pos); - pos+=diff; + synchronized (ByteBuffer.this) { + int diff = (int) Math.min(n, size - pos); + pos += diff; return diff; } } diff --git a/hudson-core/src/main/java/hudson/util/CascadingUtil.java b/hudson-core/src/main/java/hudson/util/CascadingUtil.java index 00abf8b..94229d4 100644 --- a/hudson-core/src/main/java/hudson/util/CascadingUtil.java +++ b/hudson-core/src/main/java/hudson/util/CascadingUtil.java @@ -67,7 +67,8 @@ public class CascadingUtil { * * @param currentJob job that should be analyzed. * @param key key. - * @return {@link import org.eclipse.hudson.api.model.IProjectProperty} instance or null. + * @return {@link import org.eclipse.hudson.api.model.IProjectProperty} + * instance or null. * @throws IllegalArgumentException if currentJob is null. */ public static IProjectProperty getProjectProperty(Job currentJob, String key) { @@ -75,12 +76,14 @@ public class CascadingUtil { } /** - * Returns StringProjectProperty by specified key. If property doesn't exists, it will be initialized and added to - * current job. + * Returns StringProjectProperty by specified key. If property doesn't + * exists, it will be initialized and added to current job. * * @param currentJob job that should be analyzed. * @param key key. - * @return {@link org.eclipse.hudson.model.project.property.StringProjectProperty} instance. + * @return + * {@link org.eclipse.hudson.model.project.property.StringProjectProperty} + * instance. * @throws IllegalArgumentException if currentJob is null. */ public static StringProjectProperty getStringProjectProperty(Job currentJob, String key) { @@ -88,12 +91,14 @@ public class CascadingUtil { } /** - * Returns BaseProjectProperty by specified key. If property doesn't exists, it will be initialized and added to - * current job. + * Returns BaseProjectProperty by specified key. If property doesn't exists, + * it will be initialized and added to current job. * * @param currentJob job that should be analyzed. * @param key key. - * @return {@link org.eclipse.hudson.model.project.property.BaseProjectProperty} instance. + * @return + * {@link org.eclipse.hudson.model.project.property.BaseProjectProperty} + * instance. * @throws IllegalArgumentException if currentJob is null. */ public static BaseProjectProperty getBaseProjectProperty(Job currentJob, String key) { @@ -101,12 +106,14 @@ public class CascadingUtil { } /** - * Returns ExternalProjectProperty by specified key. If property doesn't exists, it will be initialized and added to - * current job. + * Returns ExternalProjectProperty by specified key. If property doesn't + * exists, it will be initialized and added to current job. * * @param currentJob job that should be analyzed. * @param key key. - * @return {@link org.eclipse.hudson.model.project.property.ExternalProjectProperty} instance. + * @return + * {@link org.eclipse.hudson.model.project.property.ExternalProjectProperty} + * instance. * @throws IllegalArgumentException if currentJob is null. */ public static ExternalProjectProperty getExternalProjectProperty(Job currentJob, String key) { @@ -114,12 +121,14 @@ public class CascadingUtil { } /** - * Returns CopyOnWriteListProjectProperty by specified key. If property doesn't exists, - * it will be initialized and added to current job. + * Returns CopyOnWriteListProjectProperty by specified key. If property + * doesn't exists, it will be initialized and added to current job. * * @param currentJob job that should be analyzed. * @param key key. - * @return {@link org.eclipse.hudson.model.project.property.CopyOnWriteListProjectProperty} instance. + * @return + * {@link org.eclipse.hudson.model.project.property.CopyOnWriteListProjectProperty} + * instance. * @throws IllegalArgumentException if currentJob is null. */ public static CopyOnWriteListProjectProperty getCopyOnWriteListProjectProperty(Job currentJob, String key) { @@ -127,12 +136,14 @@ public class CascadingUtil { } /** - * Returns ResultProjectProperty by specified key. If property doesn't exists, it will be initialized and added to - * current job. + * Returns ResultProjectProperty by specified key. If property doesn't + * exists, it will be initialized and added to current job. * * @param currentJob job that should be analyzed. * @param key key. - * @return {@link org.eclipse.hudson.model.project.property.ResultProjectProperty} instance. + * @return + * {@link org.eclipse.hudson.model.project.property.ResultProjectProperty} + * instance. * @throws IllegalArgumentException if currentJob is null. */ public static ResultProjectProperty getResultProjectProperty(Job currentJob, String key) { @@ -140,12 +151,14 @@ public class CascadingUtil { } /** - * Returns BooleanProjectProperty by specified key. If property doesn't exists, it will be initialized and added to - * current job. + * Returns BooleanProjectProperty by specified key. If property doesn't + * exists, it will be initialized and added to current job. * * @param currentJob job that should be analyzed. * @param key key. - * @return {@link org.eclipse.hudson.model.project.property.BooleanProjectProperty} instance. + * @return + * {@link org.eclipse.hudson.model.project.property.BooleanProjectProperty} + * instance. * @throws IllegalArgumentException if currentJob is null. */ public static BooleanProjectProperty getBooleanProjectProperty(Job currentJob, String key) { @@ -153,12 +166,14 @@ public class CascadingUtil { } /** - * Returns IntegerProjectProperty by specified key. If property doesn't exists, it will be initialized and added to - * current job. + * Returns IntegerProjectProperty by specified key. If property doesn't + * exists, it will be initialized and added to current job. * * @param currentJob job that should be analyzed. * @param key key. - * @return {@link org.eclipse.hudson.model.project.property.IntegerProjectProperty} instance. + * @return + * {@link org.eclipse.hudson.model.project.property.IntegerProjectProperty} + * instance. * @throws IllegalArgumentException if currentJob is null. */ public static IntegerProjectProperty getIntegerProjectProperty(Job currentJob, String key) { @@ -166,12 +181,14 @@ public class CascadingUtil { } /** - * Returns LogRotatorProjectProperty by specified key. If property doesn't exists, it will be initialized and added - * to current job. + * Returns LogRotatorProjectProperty by specified key. If property doesn't + * exists, it will be initialized and added to current job. * * @param currentJob job that should be analyzed. * @param key key. - * @return {@link org.eclipse.hudson.model.project.property.LogRotatorProjectProperty} instance. + * @return + * {@link org.eclipse.hudson.model.project.property.LogRotatorProjectProperty} + * instance. * @throws IllegalArgumentException if currentJob is null. */ public static LogRotatorProjectProperty getLogRotatorProjectProperty(Job currentJob, String key) { @@ -179,12 +196,14 @@ public class CascadingUtil { } /** - * Returns DescribableListProjectProperty by specified key. If property doesn't exists, it will be initialized and - * added to current job. + * Returns DescribableListProjectProperty by specified key. If property + * doesn't exists, it will be initialized and added to current job. * * @param currentJob job that should be analyzed. * @param key key. - * @return {@link org.eclipse.hudson.model.project.property.DescribableListProjectProperty} instance. + * @return + * {@link org.eclipse.hudson.model.project.property.DescribableListProjectProperty} + * instance. * @throws IllegalArgumentException if currentJob is null. */ public static DescribableListProjectProperty getDescribableListProjectProperty(Job currentJob, String key) { @@ -192,12 +211,14 @@ public class CascadingUtil { } /** - * Returns AxisListProjectProperty by specified key. If property doesn't exists, it will be initialized and added to - * current job. + * Returns AxisListProjectProperty by specified key. If property doesn't + * exists, it will be initialized and added to current job. * * @param currentJob job that should be analyzed. * @param key key. - * @return {@link org.eclipse.hudson.model.project.property.AxisListProjectProperty} instance. + * @return + * {@link org.eclipse.hudson.model.project.property.AxisListProjectProperty} + * instance. * @throws IllegalArgumentException if currentJob is null. */ public static AxisListProjectProperty getAxesListProjectProperty(Job currentJob, String key) { @@ -205,12 +226,14 @@ public class CascadingUtil { } /** - * Returns SCMProjectProperty by specified key. If property doesn't exists, it will be initialized and added to - * current job. + * Returns SCMProjectProperty by specified key. If property doesn't exists, + * it will be initialized and added to current job. * * @param currentJob job that should be analyzed. * @param key key. - * @return {@link org.eclipse.hudson.model.project.property.SCMProjectProperty} instance. + * @return + * {@link org.eclipse.hudson.model.project.property.SCMProjectProperty} + * instance. * @throws IllegalArgumentException if currentJob is null. */ public static SCMProjectProperty getScmProjectProperty(Job currentJob, String key) { @@ -218,12 +241,14 @@ public class CascadingUtil { } /** - * Returns TriggerProjectProperty by specified key. If property doesn't exists, it will be initialized and added to - * current job. + * Returns TriggerProjectProperty by specified key. If property doesn't + * exists, it will be initialized and added to current job. * * @param currentJob job that should be analyzed. * @param key key. - * @return {@link org.eclipse.hudson.model.project.property.TriggerProjectProperty} instance. + * @return + * {@link org.eclipse.hudson.model.project.property.TriggerProjectProperty} + * instance. * @throws IllegalArgumentException if currentJob is null. */ public static TriggerProjectProperty getTriggerProjectProperty(Job currentJob, String key) { @@ -235,9 +260,10 @@ public class CascadingUtil { * * @param currentJob job that should be analyzed. * @param key key. - * @param clazz required property class. - * If class is not null and property was not found, property of given class will be created. - * @return {@link org.eclipse.hudson.api.model.IProjectProperty} instance or null. + * @param clazz required property class. If class is not null and property + * was not found, property of given class will be created. + * @return {@link org.eclipse.hudson.api.model.IProjectProperty} instance or + * null. * @throws IllegalArgumentException if currentJob is null. */ @SuppressWarnings("unchecked") @@ -265,11 +291,13 @@ public class CascadingUtil { } /** - * Checks whether cascadingCandidate project can produce cycle cascading dependencies. + * Checks whether cascadingCandidate project can produce cycle cascading + * dependencies. * * @param cascadingCandidate candidate. * @param cascadingChildren children of given job. - * @return false - if cyclic cascading dependency is not possible, true - otherwise. + * @return false - if cyclic cascading dependency is not possible, true - + * otherwise. */ @SuppressWarnings("unchecked") public static boolean hasCyclicCascadingLink(Job cascadingCandidate, Set<String> cascadingChildren) { @@ -292,11 +320,12 @@ public class CascadingUtil { * * @param cascadingProject cascading project to start from. * @param projectToUnlink project that should be unlinked. - * @return true if project was unlinked, false - if cascadingProject or projectToUnlink is Null + * @return true if project was unlinked, false - if cascadingProject or + * projectToUnlink is Null * @throws java.io.IOException if cascading project couldn't be saved. */ public static boolean unlinkProjectFromCascadingParents(ICascadingJob cascadingProject, String projectToUnlink) - throws IOException { + throws IOException { if (null != cascadingProject && null != projectToUnlink) { Job job = Functions.getItemByName(Hudson.getInstance().getAllItems(Job.class), projectToUnlink); if (null != job) { @@ -317,7 +346,7 @@ public class CascadingUtil { * @throws java.io.IOException if cascading project couldn't be saved. */ private static boolean unlinkProjectFromCascadingParents(ICascadingJob cascadingProject, Set<String> projectsToUnlink) - throws IOException { + throws IOException { if (null != cascadingProject && null != projectsToUnlink) { for (String toUnlink : projectsToUnlink) { cascadingProject.removeCascadingChild(toUnlink); @@ -331,8 +360,8 @@ public class CascadingUtil { } /** - * Links cascading project to children project. Method updates all parent cascading projects starting - * from the specified cascadingProject. + * Links cascading project to children project. Method updates all parent + * cascading projects starting from the specified cascadingProject. * * @param cascadingProject cascadingProject. * @param childProjectName the name of child project name. @@ -348,9 +377,10 @@ public class CascadingUtil { } /** - * Updates the name of the project in all children cascading references. - * If this project uses some cascading parent, the name of this project will be renamed in the cascading children - * collection of the cascading parent project. + * Updates the name of the project in all children cascading references. If + * this project uses some cascading parent, the name of this project will be + * renamed in the cascading children collection of the cascading parent + * project. * * @param cascadingProject cascading project. * @param oldName old project name. @@ -358,7 +388,7 @@ public class CascadingUtil { * @throws java.io.IOException if cascading project couldn't be saved. */ public static void renameCascadingChildLinks(ICascadingJob cascadingProject, String oldName, String newName) - throws IOException { + throws IOException { if (cascadingProject != null) { cascadingProject.renameCascadingChildName(oldName, newName); if (cascadingProject.hasCascadingProject()) { @@ -368,8 +398,9 @@ public class CascadingUtil { } /** - * Updates the name of the project in all parent cascading references. - * If this project is used as cascading parent, it's name will be renamed in all children projects. + * Updates the name of the project in all parent cascading references. If + * this project is used as cascading parent, it's name will be renamed in + * all children projects. * * @param oldName old project name. * @param newName new project name. @@ -386,8 +417,8 @@ public class CascadingUtil { } /** - * Returns possible cascading parents for current job, which are filtered by type and checked for avoidness cyclic - * dependency + * Returns possible cascading parents for current job, which are filtered by + * type and checked for avoidness cyclic dependency * * @param type project type. * @param currentJob current job instance @@ -405,7 +436,7 @@ public class CascadingUtil { for (T item : allItems) { Job job = (Job) item; if (!StringUtils.equals(currentJob.getName(), job.getName()) - && !hasCyclicCascadingLink(job, currentJob.getCascadingChildrenNames())) { + && !hasCyclicCascadingLink(job, currentJob.getCascadingChildrenNames())) { result.add(job); } } @@ -413,7 +444,9 @@ public class CascadingUtil { } /** - * Creates {@link org.eclipse.hudson.model.project.property.ExternalProjectProperty} based on Descriptors collection, StaplerRequest and JSON resonse. + * Creates + * {@link org.eclipse.hudson.model.project.property.ExternalProjectProperty} + * based on Descriptors collection, StaplerRequest and JSON resonse. * * @param req StaplerRequest * @param json JSONObject @@ -424,8 +457,8 @@ public class CascadingUtil { */ @SuppressWarnings("unchecked") public static <T extends Describable<T>> void buildExternalProperties(StaplerRequest req, JSONObject json, - List<Descriptor<T>> descriptors, Job owner) - throws Descriptor.FormException { + List<Descriptor<T>> descriptors, Job owner) + throws Descriptor.FormException { for (Descriptor d : descriptors) { String name = d.getJsonSafeClassName(); ExternalProjectProperty<Describable> baseProperty = getExternalProjectProperty(owner, name); @@ -445,12 +478,11 @@ public class CascadingUtil { * @param key trigger property key * @param req stapler request * @param json submited json - * @throws hudson.model.Descriptor.FormException - * if incorrect parameters + * @throws hudson.model.Descriptor.FormException if incorrect parameters */ @SuppressWarnings("unchecked") public static void setChildrenTrigger(Job job, TriggerDescriptor descriptor, String key, StaplerRequest req, - JSONObject json) throws Descriptor.FormException { + JSONObject json) throws Descriptor.FormException { TriggerProjectProperty property = CascadingUtil.getTriggerProjectProperty(job, key); if (property.getValue() != null) { property.getValue().stop(); @@ -476,9 +508,11 @@ public class CascadingUtil { } } } + /** - * Sets parameterDefinitionProperties for current job. This method is recursively executed for cascading children - * for setting valid {@link ParametersDefinitionProperty#owner} value. + * Sets parameterDefinitionProperties for current job. This method is + * recursively executed for cascading children for setting valid + * {@link ParametersDefinitionProperty#owner} value. * * @param job job. * @param key parameter key, @@ -486,15 +520,14 @@ public class CascadingUtil { */ @SuppressWarnings("unchecked") public static void setParameterDefinitionProperties(Job job, - String key, - CopyOnWriteList<ParametersDefinitionProperty> parameterDefinitionProperties) { + String key, + CopyOnWriteList<ParametersDefinitionProperty> parameterDefinitionProperties) { CopyOnWriteListProjectProperty projectProperty = getCopyOnWriteListProjectProperty(job, key); - CopyOnWriteList<ParametersDefinitionProperty> pdProperties - = new CopyOnWriteList<ParametersDefinitionProperty>(); + CopyOnWriteList<ParametersDefinitionProperty> pdProperties = new CopyOnWriteList<ParametersDefinitionProperty>(); //Create new instance for each parameter in order to set owner and use in cascading children. for (ParametersDefinitionProperty pdp : parameterDefinitionProperties) { ParametersDefinitionProperty copiedDefinitionProperty = new ParametersDefinitionProperty( - new ArrayList<ParameterDefinition>(pdp.getParameterDefinitions())); + new ArrayList<ParameterDefinition>(pdp.getParameterDefinitions())); copiedDefinitionProperty.setOwner((AbstractProject) job); pdProperties.add(copiedDefinitionProperty); } @@ -520,19 +553,24 @@ public class CascadingUtil { } /** - * Checks whether JobProperty supports cascading. - * Method skips {@link AuthorizationMatrixProperty} and {@link ParametersDefinitionProperty} classes. - * {@link AuthorizationMatrixProperty} doesn't support cascading for now. - * As for {@link ParametersDefinitionProperty} single instance doesn't support cascading, so, classes are - * grouped into list of {@link ParametersDefinitionProperty} and whole list could be inherited or overridden. - + * Checks whether JobProperty supports cascading. Method skips + * {@link AuthorizationMatrixProperty} and + * {@link ParametersDefinitionProperty} classes. + * {@link AuthorizationMatrixProperty} doesn't support cascading for now. As + * for {@link ParametersDefinitionProperty} single instance doesn't support + * cascading, so, classes are grouped into list of + * {@link ParametersDefinitionProperty} and whole list could be inherited or + * overridden. + * * @param d property descriptor. - * @return true - if JobProperty could be used for cascading, false - otherwise. - * @see #setParameterDefinitionProperties(hudson.model.Job, String, CopyOnWriteList) + * @return true - if JobProperty could be used for cascading, false - + * otherwise. + * @see #setParameterDefinitionProperties(hudson.model.Job, String, + * CopyOnWriteList) * @see hudson.model.Job#getParameterDefinitionProperties() */ public static boolean isCascadableJobProperty(JobPropertyDescriptor d) { return !(d instanceof AuthorizationMatrixProperty.DescriptorImpl - || d instanceof ParametersDefinitionProperty.DescriptorImpl); + || d instanceof ParametersDefinitionProperty.DescriptorImpl); } } diff --git a/hudson-core/src/main/java/hudson/util/CaseInsensitiveComparator.java b/hudson-core/src/main/java/hudson/util/CaseInsensitiveComparator.java index 01f2c47..2694b97 100644 --- a/hudson-core/src/main/java/hudson/util/CaseInsensitiveComparator.java +++ b/hudson-core/src/main/java/hudson/util/CaseInsensitiveComparator.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 + * * *******************************************************************************/ @@ -25,13 +25,14 @@ import java.io.Serializable; * @author Kohsuke Kawaguchi */ public final class CaseInsensitiveComparator implements Comparator<String>, Serializable { + public static final Comparator<String> INSTANCE = new CaseInsensitiveComparator(); - private CaseInsensitiveComparator() {} + private CaseInsensitiveComparator() { + } public int compare(String lhs, String rhs) { return lhs.compareToIgnoreCase(rhs); } - private static final long serialVersionUID = 1L; } diff --git a/hudson-core/src/main/java/hudson/util/CertificateUtil.java b/hudson-core/src/main/java/hudson/util/CertificateUtil.java index b4ae316..562e4a1 100644 --- a/hudson-core/src/main/java/hudson/util/CertificateUtil.java +++ b/hudson-core/src/main/java/hudson/util/CertificateUtil.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.util; @@ -39,6 +39,7 @@ import java.util.Set; * @author Kohsuke Kawaguchi */ public class CertificateUtil { + /** * Obtains the list of default root CAs installed in the JRE. */ @@ -47,7 +48,7 @@ public class CertificateUtil { Set<TrustAnchor> rootCAs = new HashSet<TrustAnchor>(); for (X509Certificate c : x509tm.getAcceptedIssuers()) { - rootCAs.add(new TrustAnchor(c,null)); + rootCAs.add(new TrustAnchor(c, null)); } return rootCAs; } @@ -57,7 +58,7 @@ public class CertificateUtil { */ public static X509TrustManager getDefaultX509TrustManager() throws NoSuchAlgorithmException, KeyStoreException { TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); - tmf.init((KeyStore)null); + tmf.init((KeyStore) null); for (TrustManager tm : tmf.getTrustManagers()) { if (tm instanceof X509TrustManager) { @@ -68,10 +69,11 @@ public class CertificateUtil { } /** - * Validate a certificate chain. Normal return indicates a successful validation. + * Validate a certificate chain. Normal return indicates a successful + * validation. */ public static PKIXCertPathValidatorResult validatePath(List<X509Certificate> certs) throws GeneralSecurityException { - return validatePath(certs,getDefaultRootCAs()); + return validatePath(certs, getDefaultRootCAs()); } public static PKIXCertPathValidatorResult validatePath(List<X509Certificate> certs, Set<TrustAnchor> trustAnchors) throws GeneralSecurityException { diff --git a/hudson-core/src/main/java/hudson/util/CharSpool.java b/hudson-core/src/main/java/hudson/util/CharSpool.java index 906c47e..46760f6 100644 --- a/hudson-core/src/main/java/hudson/util/CharSpool.java +++ b/hudson-core/src/main/java/hudson/util/CharSpool.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 + * * *******************************************************************************/ @@ -22,21 +22,22 @@ import java.util.LinkedList; import java.util.List; /** - * {@link Writer} that spools the output and writes to another {@link Writer} later. + * {@link Writer} that spools the output and writes to another {@link Writer} + * later. * * @author Kohsuke Kawaguchi * @deprecated since 2008-05-28. moved to stapler */ public final class CharSpool extends Writer { - private List<char[]> buf; + private List<char[]> buf; private char[] last = new char[1024]; private int pos; public void write(char cbuf[], int off, int len) { - while(len>0) { - int sz = Math.min(last.length-pos,len); - System.arraycopy(cbuf,off,last,pos,sz); + while (len > 0) { + int sz = Math.min(last.length - pos, len); + System.arraycopy(cbuf, off, last, pos, sz); len -= sz; off += sz; pos += sz; @@ -45,11 +46,13 @@ public final class CharSpool extends Writer { } private void renew() { - if(pos<last.length) + if (pos < last.length) { return; + } - if(buf==null) + if (buf == null) { buf = new LinkedList<char[]>(); + } buf.add(last); last = new char[1024]; pos = 0; @@ -57,7 +60,7 @@ public final class CharSpool extends Writer { public void write(int c) { renew(); - last[pos++] = (char)c; + last[pos++] = (char) c; } public void flush() { @@ -69,11 +72,11 @@ public final class CharSpool extends Writer { } public void writeTo(Writer w) throws IOException { - if(buf!=null) { + if (buf != null) { for (char[] cb : buf) { w.write(cb); } } - w.write(last,0,pos); + w.write(last, 0, pos); } } diff --git a/hudson-core/src/main/java/hudson/util/CharacterEncodingFilter.java b/hudson-core/src/main/java/hudson/util/CharacterEncodingFilter.java index 8ae7dee..0336f46 100644 --- a/hudson-core/src/main/java/hudson/util/CharacterEncodingFilter.java +++ b/hudson-core/src/main/java/hudson/util/CharacterEncodingFilter.java @@ -7,10 +7,10 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: + * Contributors: * * Seiji Sogabe - * + * * *******************************************************************************/ @@ -28,8 +28,8 @@ import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; /** - * Filter that sets the character encoding to be used in parsing the request - * to avoid Non-ASCII characters garbled. + * Filter that sets the character encoding to be used in parsing the request to + * avoid Non-ASCII characters garbled. * * @author Seiji Sogabe */ @@ -39,15 +39,11 @@ public class CharacterEncodingFilter implements Filter { * The default character encoding. */ private static final String ENCODING = "UTF-8"; - - private static final Boolean DISABLE_FILTER - = Boolean.getBoolean(CharacterEncodingFilter.class.getName() + ".disableFilter"); - + private static final Boolean DISABLE_FILTER = Boolean.getBoolean(CharacterEncodingFilter.class.getName() + ".disableFilter"); /** * The character encoding sets forcibly? */ - private static final Boolean FORCE_ENCODING - = Boolean.getBoolean(CharacterEncodingFilter.class.getName() + ".forceEncoding"); + private static final Boolean FORCE_ENCODING = Boolean.getBoolean(CharacterEncodingFilter.class.getName() + ".forceEncoding"); public void init(FilterConfig filterConfig) throws ServletException { LOGGER.log(Level.INFO, @@ -95,9 +91,8 @@ public class CharacterEncodingFilter implements Filter { if (FORCE_ENCODING || req.getCharacterEncoding() == null) { return true; } - + return false; } - private static final Logger LOGGER = Logger.getLogger(CharacterEncodingFilter.class.getName()); } diff --git a/hudson-core/src/main/java/hudson/util/ChunkedInputStream.java b/hudson-core/src/main/java/hudson/util/ChunkedInputStream.java index 5691eeb..84ad451 100644 --- a/hudson-core/src/main/java/hudson/util/ChunkedInputStream.java +++ b/hudson-core/src/main/java/hudson/util/ChunkedInputStream.java @@ -27,7 +27,6 @@ * <http://www.apache.org/>. * */ - package hudson.util; import java.io.ByteArrayOutputStream; @@ -35,13 +34,12 @@ import java.io.IOException; import java.io.InputStream; import java.util.logging.Logger; - /** * <p>Transparently coalesces chunks of a HTTP stream that uses * Transfer-Encoding chunked.</p> * * <p>Note that this class NEVER closes the underlying stream, even when close - * gets called. Instead, it will read until the "end" of its chunking on close, + * gets called. Instead, it will read until the "end" of its chunking on close, * which allows for the seamless invocation of subsequent HTTP 1.1 calls, while * not requiring the client to remember to read the entire contents of the * response.</p> @@ -58,25 +56,34 @@ import java.util.logging.Logger; * */ public class ChunkedInputStream extends InputStream { - /** The inputstream that we're wrapping */ - private InputStream in; - /** The chunk size */ + /** + * The inputstream that we're wrapping + */ + private InputStream in; + /** + * The chunk size + */ private int chunkSize; - - /** The current position within the current chunk */ + /** + * The current position within the current chunk + */ private int pos; - - /** True if we'are at the beginning of stream */ + /** + * True if we'are at the beginning of stream + */ private boolean bof = true; - - /** True if we've reached the end of stream */ + /** + * True if we've reached the end of stream + */ private boolean eof = false; - - /** True if this stream is closed */ + /** + * True if this stream is closed + */ private boolean closed = false; - - /** Log object for this class. */ + /** + * Log object for this class. + */ private static final Logger LOGGER = Logger.getLogger(ChunkedInputStream.class.getName()); /** @@ -87,7 +94,7 @@ public class ChunkedInputStream extends InputStream { * @throws IOException If an IO error occurs */ public ChunkedInputStream( - final InputStream in) throws IOException { + final InputStream in) throws IOException { if (in == null) { throw new IllegalArgumentException("InputStream parameter may not be null"); @@ -128,6 +135,7 @@ public class ChunkedInputStream extends InputStream { /** * Read some bytes from the stream. + * * @param b The byte array that will hold the contents from the stream. * @param off The offset into the byte array at which bytes will start to be * placed. @@ -138,7 +146,7 @@ public class ChunkedInputStream extends InputStream { * @throws IOException if an IO problem occurs. */ @Override - public int read (byte[] b, int off, int len) throws IOException { + public int read(byte[] b, int off, int len) throws IOException { if (closed) { throw new IOException("Attempted read from closed stream."); @@ -161,6 +169,7 @@ public class ChunkedInputStream extends InputStream { /** * Read some bytes from the stream. + * * @param b The byte array that will hold the contents from the stream. * @return The number of bytes returned or -1 if the end of stream has been * reached. @@ -168,12 +177,13 @@ public class ChunkedInputStream extends InputStream { * @throws IOException if an IO problem occurs. */ @Override - public int read (byte[] b) throws IOException { + public int read(byte[] b) throws IOException { return read(b, 0, b.length); } /** * Read the CRLF terminator. + * * @throws IOException If an IO error occurs. */ private void readCRLF() throws IOException { @@ -181,13 +191,13 @@ public class ChunkedInputStream extends InputStream { int lf = in.read(); if ((cr != '\r') || (lf != '\n')) { throw new IOException( - "CRLF expected at end of chunk: " + cr + "/" + lf); + "CRLF expected at end of chunk: " + cr + "/" + lf); } } - /** * Read the next chunk. + * * @throws IOException If an IO error occurs. */ private void nextChunk() throws IOException { @@ -214,13 +224,13 @@ public class ChunkedInputStream extends InputStream { * @throws IOException when the chunk size could not be parsed */ private static int getChunkSizeFromInputStream(final InputStream in) - throws IOException { + throws IOException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); // States: 0=normal, 1=\r was scanned, 2=inside quoted string, -1=end int state = 0; while (state != -1) { - int b = in.read(); + int b = in.read(); if (b == -1) { throw new IOException("chunked stream ended unexpectedly"); } @@ -232,7 +242,7 @@ public class ChunkedInputStream extends InputStream { break; case '\"': state = 2; - /* fall through */ + /* fall through */ default: baos.write(b); } @@ -244,7 +254,7 @@ public class ChunkedInputStream extends InputStream { } else { // this was not CRLF throw new IOException("Protocol violation: Unexpected" - + " single newline character in chunk size"); + + " single newline character in chunk size"); } break; @@ -256,33 +266,35 @@ public class ChunkedInputStream extends InputStream { break; case '\"': state = 0; - /* fall through */ + /* fall through */ default: baos.write(b); } break; - default: throw new RuntimeException("assertion failed"); + default: + throw new RuntimeException("assertion failed"); } } //parse data - String dataString = new String(baos.toByteArray(),"US-ASCII"); + String dataString = new String(baos.toByteArray(), "US-ASCII"); int separator = dataString.indexOf(';'); dataString = (separator > 0) - ? dataString.substring(0, separator).trim() - : dataString.trim(); + ? dataString.substring(0, separator).trim() + : dataString.trim(); int result; try { result = Integer.parseInt(dataString.trim(), 16); } catch (NumberFormatException e) { - throw new IOException ("Bad chunk size: " + dataString); + throw new IOException("Bad chunk size: " + dataString); } return result; } /** * Reads and stores the Trailer headers. + * * @throws IOException If an IO problem occurs */ private void parseTrailerHeaders() throws IOException { @@ -310,9 +322,10 @@ public class ChunkedInputStream extends InputStream { } /** - * Upon close, this reads the remainder of the chunked message, - * leaving the underlying socket at a position to start reading the - * next response without scanning. + * Upon close, this reads the remainder of the chunked message, leaving the + * underlying socket at a position to start reading the next response + * without scanning. + * * @throws IOException If an IO problem occurs. */ @Override @@ -332,10 +345,9 @@ public class ChunkedInputStream extends InputStream { /** * Exhaust an input stream, reading until EOF has been encountered. * - * <p>Note that this function is intended as a non-public utility. - * This is a little weird, but it seemed silly to make a utility - * class for this one function, so instead it is just static and - * shared that way.</p> + * <p>Note that this function is intended as a non-public utility. This is a + * little weird, but it seemed silly to make a utility class for this one + * function, so instead it is just static and shared that way.</p> * * @param inStream The {@link InputStream} to exhaust. * @throws IOException If an IO problem occurs diff --git a/hudson-core/src/main/java/hudson/util/ChunkedOutputStream.java b/hudson-core/src/main/java/hudson/util/ChunkedOutputStream.java index dd4e704..cfde940 100644 --- a/hudson-core/src/main/java/hudson/util/ChunkedOutputStream.java +++ b/hudson-core/src/main/java/hudson/util/ChunkedOutputStream.java @@ -27,41 +27,40 @@ * <http://www.apache.org/>. * */ - package hudson.util; import java.io.IOException; import java.io.OutputStream; /** - * Implements HTTP chunking support. Writes are buffered to an internal buffer (2048 default size). - * Chunks are guaranteed to be at least as large as the buffer size (except for the last chunk). + * Implements HTTP chunking support. Writes are buffered to an internal buffer + * (2048 default size). Chunks are guaranteed to be at least as large as the + * buffer size (except for the last chunk). * * @author Mohammad Rezaei, Goldman, Sachs & Co. */ public class ChunkedOutputStream extends OutputStream { // ------------------------------------------------------- Static Variables - private static final byte CRLF[] = new byte[] {(byte) 13, (byte) 10}; - - /** End chunk */ + private static final byte CRLF[] = new byte[]{(byte) 13, (byte) 10}; + /** + * End chunk + */ private static final byte ENDCHUNK[] = CRLF; - - /** 0 */ - private static final byte ZERO[] = new byte[] {(byte) '0'}; - + /** + * 0 + */ + private static final byte ZERO[] = new byte[]{(byte) '0'}; // ----------------------------------------------------- Instance Variables private OutputStream stream = null; - private byte[] cache; - private int cachePosition = 0; - private boolean wroteLastChunk = false; // ----------------------------------------------------------- Constructors /** * Wraps a stream and chunks the output. + * * @param stream to wrap * @param bufferSize minimum chunk size (excluding last chunk) * @throws IOException @@ -74,8 +73,9 @@ public class ChunkedOutputStream extends OutputStream { } /** - * Wraps a stream and chunks the output. The default buffer size of 2048 was chosen because - * the chunk overhead is less than 0.5% + * Wraps a stream and chunks the output. The default buffer size of 2048 was + * chosen because the chunk overhead is less than 0.5% + * * @param stream * @throws IOException */ @@ -86,6 +86,7 @@ public class ChunkedOutputStream extends OutputStream { // ----------------------------------------------------------- Internal methods /** * Writes the cache out onto the underlying stream + * * @throws IOException * * @since 3.0 @@ -101,8 +102,9 @@ public class ChunkedOutputStream extends OutputStream { } /** - * Writes the cache and bufferToAppend to the underlying stream - * as one large chunk + * Writes the cache and bufferToAppend to the underlying stream as one large + * chunk + * * @param bufferToAppend * @param off * @param len @@ -129,7 +131,9 @@ public class ChunkedOutputStream extends OutputStream { // ----------------------------------------------------------- Public Methods /** - * Must be called to ensure the internal cache is flushed and the closing chunk is written. + * Must be called to ensure the internal cache is flushed and the closing + * chunk is written. + * * @throws IOException * * @since 3.0 @@ -146,8 +150,8 @@ public class ChunkedOutputStream extends OutputStream { /** * Write the specified byte to our output stream. * - * Note: Avoid this method as it will cause an inefficient single byte chunk. - * Use write (byte[], int, int) instead. + * Note: Avoid this method as it will cause an inefficient single byte + * chunk. Use write (byte[], int, int) instead. * * @param b The byte to be written * @throws IOException if an input/output error occurs @@ -155,12 +159,15 @@ public class ChunkedOutputStream extends OutputStream { public void write(int b) throws IOException { cache[cachePosition] = (byte) b; cachePosition++; - if (cachePosition == cache.length) flushCache(); + if (cachePosition == cache.length) { + flushCache(); + } } /** - * Writes the array. If the array does not fit within the buffer, it is - * not split, but rather written out as one large chunk. + * Writes the array. If the array does not fit within the buffer, it is not + * split, but rather written out as one large chunk. + * * @param b * @throws IOException * @@ -183,6 +190,7 @@ public class ChunkedOutputStream extends OutputStream { /** * Flushes the underlying stream, but leaves the internal buffer alone. + * * @throws IOException */ @Override @@ -192,7 +200,9 @@ public class ChunkedOutputStream extends OutputStream { } /** - * Finishes writing to the underlying stream, but does NOT close the underlying stream. + * Finishes writing to the underlying stream, but does NOT close the + * underlying stream. + * * @throws IOException */ @Override diff --git a/hudson-core/src/main/java/hudson/util/ClasspathBuilder.java b/hudson-core/src/main/java/hudson/util/ClasspathBuilder.java index 11e85ad..07749a2 100644 --- a/hudson-core/src/main/java/hudson/util/ClasspathBuilder.java +++ b/hudson-core/src/main/java/hudson/util/ClasspathBuilder.java @@ -8,7 +8,7 @@ * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * + * * *******************************************************************************/ @@ -32,6 +32,7 @@ import java.util.ArrayList; * @since 1.300 */ public class ClasspathBuilder implements Serializable, Iterable<String> { + private final List<String> args = new ArrayList<String>(); /** @@ -58,6 +59,7 @@ public class ClasspathBuilder implements Serializable, Iterable<String> { /** * Adds a jar file that contains the given class. + * * @since 1.361 */ public ClasspathBuilder addJarOf(Class c) throws IOException { @@ -67,11 +69,12 @@ public class ClasspathBuilder implements Serializable, Iterable<String> { /** * Adds all the files that matches the given glob in the directory. * - * @see FilePath#list(String) + * @see FilePath#list(String) */ public ClasspathBuilder addAll(FilePath base, String glob) throws IOException, InterruptedException { - for(FilePath item : base.list(glob)) + for (FilePath item : base.list(glob)) { add(item); + } return this; } @@ -94,6 +97,6 @@ public class ClasspathBuilder implements Serializable, Iterable<String> { * @since 2.1.0 */ public String toString(final String sep) { - return Util.join(args,sep); + return Util.join(args, sep); } } diff --git a/hudson-core/src/main/java/hudson/util/ClockDifference.java b/hudson-core/src/main/java/hudson/util/ClockDifference.java index a8ea0b3..fe7b66a 100644 --- a/hudson-core/src/main/java/hudson/util/ClockDifference.java +++ b/hudson-core/src/main/java/hudson/util/ClockDifference.java @@ -7,10 +7,10 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: -* -* Kohsuke Kawaguchi, Seiji Sogabe, Thomas J. Black - * + * Contributors: + * + * Kohsuke Kawaguchi, Seiji Sogabe, Thomas J. Black + * * *******************************************************************************/ @@ -31,11 +31,12 @@ import org.kohsuke.stapler.export.Exported; */ @ExportedBean public final class ClockDifference { + /** * The difference in milliseconds. * - * Positive value means the slave is behind the master, - * negative value means the slave is ahead of the master. + * Positive value means the slave is behind the master, negative value means + * the slave is ahead of the master. */ @Exported public final long diff; @@ -48,7 +49,7 @@ public final class ClockDifference { * Returns true if the difference is big enough to be considered dangerous. */ public boolean isDangerous() { - return Math.abs(diff)>5000; + return Math.abs(diff) > 5000; } /** @@ -63,30 +64,34 @@ public final class ClockDifference { */ @Override public String toString() { - if(-1000<diff && diff <1000) + if (-1000 < diff && diff < 1000) { return Messages.ClockDifference_InSync(); // clock is in sync - + } long abs = Math.abs(diff); String s = Util.getTimeSpanString(abs); - if(diff<0) + if (diff < 0) { s += Messages.ClockDifference_Ahead(); - else + } else { s += Messages.ClockDifference_Behind(); + } return s; } - + public String toHtml() { String s = toString(); - if(isDangerous()) + if (isDangerous()) { s = Util.wrapToErrorSpan(s); + } return s; } public static String toHtml(Node d) { try { - if(d==null) return FAILED_HTML; + if (d == null) { + return FAILED_HTML; + } return d.getClockDifference().toHtml(); } catch (IOException e) { return FAILED_HTML; @@ -96,16 +101,16 @@ public final class ClockDifference { } /** - * Gets the clock difference in HTML string. - * This version handles null {@link ClockDifference}. + * Gets the clock difference in HTML string. This version handles null + * {@link ClockDifference}. */ public static String toHtml(ClockDifference d) { - if(d==null) return FAILED_HTML; + if (d == null) { + return FAILED_HTML; + } return d.toHtml(); } - public static final ClockDifference ZERO = new ClockDifference(0); - private static final String FAILED_HTML = "<span class='error'>" + Messages.ClockDifference_Failed() + "</span>"; } diff --git a/hudson-core/src/main/java/hudson/util/ColorPalette.java b/hudson-core/src/main/java/hudson/util/ColorPalette.java index d46b44e..4f04336 100644 --- a/hudson-core/src/main/java/hudson/util/ColorPalette.java +++ b/hudson-core/src/main/java/hudson/util/ColorPalette.java @@ -7,39 +7,37 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: + * Contributors: * * Inc., Kohsuke Kawaguchi, Winston Prakash - * + * * *******************************************************************************/ package hudson.util; - import java.awt.Color; import java.util.List; import java.util.Collections; import java.util.Arrays; /** - * Color constants consistent with the Hudson color palette. + * Color constants consistent with the Hudson color palette. * * @author Kohsuke Kawaguchi */ public class ColorPalette { - public static final Color RED = new Color(0xEF,0x29,0x29); - public static final Color YELLOW = new Color(0xFC,0xE9,0x4F); - public static final Color BLUE = new Color(0x72,0x9F,0xCF); - public static final Color GREY = new Color(0xAB,0xAB,0xAB); - + + public static final Color RED = new Color(0xEF, 0x29, 0x29); + public static final Color YELLOW = new Color(0xFC, 0xE9, 0x4F); + public static final Color BLUE = new Color(0x72, 0x9F, 0xCF); + public static final Color GREY = new Color(0xAB, 0xAB, 0xAB); /** * Color list usable for generating line charts. */ public static List<Color> LINE_GRAPH = Collections.unmodifiableList(Arrays.asList( - new Color(0xCC0000), - new Color(0x3465a4), - new Color(0x73d216), - new Color(0xedd400) - )); + new Color(0xCC0000), + new Color(0x3465a4), + new Color(0x73d216), + new Color(0xedd400))); } diff --git a/hudson-core/src/main/java/hudson/util/ComboBoxModel.java b/hudson-core/src/main/java/hudson/util/ComboBoxModel.java index a3fe3fc..1583635 100644 --- a/hudson-core/src/main/java/hudson/util/ComboBoxModel.java +++ b/hudson-core/src/main/java/hudson/util/ComboBoxModel.java @@ -7,10 +7,10 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: + * Contributors: * * CollabNet - * + * * *******************************************************************************/ @@ -31,11 +31,13 @@ import java.util.Collection; import static java.util.Arrays.asList; /** - * Model object for dynamically filed combo box, which is really just {@code ArrayList<String>} - * + * Model object for dynamically filed combo box, which is really just + * {@code ArrayList<String>} + * * @author Kohsuke Kawaguchi */ public class ComboBoxModel extends ArrayList<String> implements HttpResponse { + public ComboBoxModel(int initialCapacity) { super(initialCapacity); } diff --git a/hudson-core/src/main/java/hudson/util/CompressedFile.java b/hudson-core/src/main/java/hudson/util/CompressedFile.java index b0aff76..ea771fb 100644 --- a/hudson-core/src/main/java/hudson/util/CompressedFile.java +++ b/hudson-core/src/main/java/hudson/util/CompressedFile.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 + * * *******************************************************************************/ @@ -37,15 +37,13 @@ import java.util.zip.GZIPInputStream; import java.util.zip.GZIPOutputStream; /** - * Represents write-once read-many file that can be optiionally compressed - * to save disk space. This is used for console output and other bulky data. + * Represents write-once read-many file that can be optiionally compressed to + * save disk space. This is used for console output and other bulky data. * - * <p> - * In this class, the data on the disk can be one of two states: - * <ol> - * <li>Uncompressed, in which case the original data is available in the specified file name. - * <li>Compressed, in which case the gzip-compressed data is available in the specifiled file name + ".gz" extension. - * </ol> + * <p> In this class, the data on the disk can be one of two states: <ol> + * <li>Uncompressed, in which case the original data is available in the + * specified file name. <li>Compressed, in which case the gzip-compressed data + * is available in the specifiled file name + ".gz" extension. </ol> * * Once the file is written and completed, it can be compressed asynchronously * by {@link #compress()}. @@ -53,23 +51,19 @@ import java.util.zip.GZIPOutputStream; * @author Kohsuke Kawaguchi */ public class CompressedFile { - + /** - * Executor used for compression. Limited up to one thread since - * this should be a fairly low-priority task. + * Executor used for compression. Limited up to one thread since this should + * be a fairly low-priority task. */ private static final ExecutorService COMPRESSION_THREAD = new ThreadPoolExecutor( - 0, 1, 5L, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(), - new ExceptionCatchingThreadFactory(new DaemonThreadFactory())); - - private static final Logger LOGGER = Logger.getLogger(CompressedFile.class.getName()); - - + 0, 1, 5L, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(), + new ExceptionCatchingThreadFactory(new DaemonThreadFactory())); + private static final Logger LOGGER = Logger.getLogger(CompressedFile.class.getName()); /** * The name of the raw file. */ private final File file; - /** * The name of the compressed file. */ @@ -97,7 +91,7 @@ public class CompressedFile { if (file.exists()) { return new FileInputStream(file); } - + // check if the compressed file exists if (gz.exists()) { return new GZIPInputStream(new FileInputStream(gz)); @@ -118,7 +112,7 @@ public class CompressedFile { } else { return ""; } - + StringBuilder str = new StringBuilder((int) sizeGuess); Reader r = null; @@ -138,9 +132,8 @@ public class CompressedFile { /** * Asynchronously schedules the compression of this file. * - * <p> - * Once the file is compressed, the original will be removed and - * the further reading will be done from the compressed stream. + * <p> Once the file is compressed, the original will be removed and the + * further reading will be done from the compressed stream. */ public void compress() { COMPRESSION_THREAD.submit(new Runnable() { @@ -160,7 +153,7 @@ public class CompressedFile { } catch (IOException e) { LOGGER.log(Level.WARNING, "Failed to compress " + file, e); // in case a processing is left in the middle - gz.delete(); + gz.delete(); } } }); diff --git a/hudson-core/src/main/java/hudson/util/ConcurrentHashMapConverter.java b/hudson-core/src/main/java/hudson/util/ConcurrentHashMapConverter.java index 967b14e..61fc72b 100644 --- a/hudson-core/src/main/java/hudson/util/ConcurrentHashMapConverter.java +++ b/hudson-core/src/main/java/hudson/util/ConcurrentHashMapConverter.java @@ -7,10 +7,10 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: + * Contributors: + * + * * - * - * * *******************************************************************************/ @@ -27,25 +27,27 @@ import com.thoughtworks.xstream.mapper.Mapper; import java.util.concurrent.ConcurrentHashMap; /** - * {@link ConcurrentHashMap} should convert like a map, instead of via serialization. + * {@link ConcurrentHashMap} should convert like a map, instead of via + * serialization. * * @author Kohsuke Kawaguchi */ public class ConcurrentHashMapConverter extends MapConverter { + private final SerializableConverter sc; public ConcurrentHashMapConverter(XStream xs) { - this(xs.getMapper(),xs.getReflectionProvider()); + this(xs.getMapper(), xs.getReflectionProvider()); } public ConcurrentHashMapConverter(Mapper mapper, ReflectionProvider reflectionProvider) { super(mapper); - sc = new SerializableConverter(mapper,reflectionProvider); + sc = new SerializableConverter(mapper, reflectionProvider); } @Override public boolean canConvert(Class type) { - return type==ConcurrentHashMap.class; + return type == ConcurrentHashMap.class; } @Override @@ -53,8 +55,8 @@ public class ConcurrentHashMapConverter extends MapConverter { // ConcurrentHashMap used to serialize as custom serialization, // so read it in a compatible fashion. String s = reader.getAttribute("serialization"); - if(s!=null && s.equals("custom")) { - return sc.unmarshal(reader,context); + if (s != null && s.equals("custom")) { + return sc.unmarshal(reader, context); } else { return super.unmarshal(reader, context); } diff --git a/hudson-core/src/main/java/hudson/util/ConsistentHash.java b/hudson-core/src/main/java/hudson/util/ConsistentHash.java index 0c43699..74bb3f4 100644 --- a/hudson-core/src/main/java/hudson/util/ConsistentHash.java +++ b/hudson-core/src/main/java/hudson/util/ConsistentHash.java @@ -7,7 +7,7 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: + * Contributors: * * Kohsuke Kawaguchi, Winston Prakash * @@ -32,43 +32,43 @@ import org.slf4j.LoggerFactory; /** * Consistent hash. * - * <p> - * This implementation is concurrency safe; additions and removals are serialized, but look up - * can be performed concurrently even when modifications is in progress. + * <p> This implementation is concurrency safe; additions and removals are + * serialized, but look up can be performed concurrently even when modifications + * is in progress. * - * <p> - * Since typical hash functions we use in {@link Object#hashCode()} isn't random enough to - * evenly populate the 2^32 ring space, we only ask the user to give us - * <a href="http://en.wikipedia.org/wiki/Injective_function">an injective function</a> to a string, - * and then we use MD5 to create random enough distribution. + * <p> Since typical hash functions we use in {@link Object#hashCode()} isn't + * random enough to evenly populate the 2^32 ring space, we only ask the user to + * give us <a href="http://en.wikipedia.org/wiki/Injective_function">an + * injective function</a> to a string, and then we use MD5 to create random + * enough distribution. * - * <p> - * This consistent hash implementaiton is consistent both to the addition/removal of Ts, as well - * as increase/decrease of the replicas. + * <p> This consistent hash implementaiton is consistent both to the + * addition/removal of Ts, as well as increase/decrease of the replicas. * - * <p> - * See http://en.wikipedia.org/wiki/Consistent_hashing for references, and - * http://weblogs.java.net/blog/tomwhite/archive/2007/11/consistent_hash.html is probably a reasonable depiction. - * If we trust his experiments, creating 100 replicas will reduce the stddev to 10% of the mean for 10 nodes. + * <p> See http://en.wikipedia.org/wiki/Consistent_hashing for references, and + * http://weblogs.java.net/blog/tomwhite/archive/2007/11/consistent_hash.html is + * probably a reasonable depiction. If we trust his experiments, creating 100 + * replicas will reduce the stddev to 10% of the mean for 10 nodes. * * @author Kohsuke Kawaguchi * @since 1.302 */ public class ConsistentHash<T> { - + private Logger logger = LoggerFactory.getLogger(ConsistentHash.class); /** * All the items in the hash, to their replication factors. */ - private final Map<T,Point[]> items = new HashMap<T,Point[]>(); - + private final Map<T, Point[]> items = new HashMap<T, Point[]>(); private final int defaultReplication; private final Hash<T> hash; /** - * Used for remembering the computed MD5 hash, since it's bit expensive to do it all over again. + * Used for remembering the computed MD5 hash, since it's bit expensive to + * do it all over again. */ private static final class Point implements Comparable<Point> { + final int hash; final Object item; @@ -78,12 +78,15 @@ public class ConsistentHash<T> { } public int compareTo(Point that) { - if(this.hash<that.hash) return -1; - if(this.hash==that.hash) return 0; + if (this.hash < that.hash) { + return -1; + } + if (this.hash == that.hash) { + return 0; + } return 1; } } - /** * Table that gets atomically replaced for concurrency safe operation. */ @@ -93,53 +96,58 @@ public class ConsistentHash<T> { * Immutable consistent hash table. */ private final class Table { + private final int[] hash; private final Object[] owner; // really T[] private Table() { // merge all points from all nodes and sort them into a single array Point[] allPoints = new Point[countAllPoints()]; - int p=0; + int p = 0; for (Point[] v : items.values()) { - System.arraycopy(v,0,allPoints,p,v.length); - p+=v.length; + System.arraycopy(v, 0, allPoints, p, v.length); + p += v.length; } Arrays.sort(allPoints); hash = new int[allPoints.length]; owner = new Object[allPoints.length]; - for (int i=0; i<allPoints.length; i++) { + for (int i = 0; i < allPoints.length; i++) { Point pt = allPoints[i]; - hash[i]=pt.hash; - owner[i]=pt.item; + hash[i] = pt.hash; + owner[i] = pt.item; } } T lookup(int queryPoint) { int i = index(queryPoint); - if(i<0) return null; - return (T)owner[i]; + if (i < 0) { + return null; + } + return (T) owner[i]; } /** * Returns a consistent stream of nodes starting the given query point. * - * <p> - * This is a permutation of all the nodes, where nodes with more replicas - * are more likely to show up early on. + * <p> This is a permutation of all the nodes, where nodes with more + * replicas are more likely to show up early on. */ Iterator<T> list(int queryPoint) { final int start = index(queryPoint); return new DuplicateFilterIterator<T>(new Iterator<T>() { - int pos=0; + int pos = 0; + public boolean hasNext() { - return pos<owner.length; + return pos < owner.length; } public T next() { - if(!hasNext()) throw new NoSuchElementException(); - return (T)owner[(start+(pos++))%owner.length]; + if (!hasNext()) { + throw new NoSuchElementException(); + } + return (T) owner[(start + (pos++)) % owner.length]; } public void remove() { @@ -150,9 +158,11 @@ public class ConsistentHash<T> { private int index(int queryPoint) { int idx = Arrays.binarySearch(hash, queryPoint); - if(idx<0) { - idx = -idx-1; // idx is now 'insertion point' - if(hash.length==0) return -1; + if (idx < 0) { + idx = -idx - 1; // idx is now 'insertion point' + if (hash.length == 0) { + return -1; + } idx %= hash.length; // make it a circle } return idx; @@ -162,27 +172,23 @@ public class ConsistentHash<T> { /** * Hashes an object to some value. * - * <p> - * By default, {@link ConsistentHash} uses {@link Object#toString()} on 'T' to - * obtain the hash, but that behavior can be changed by providing - * a {@link Hash} implementation. + * <p> By default, {@link ConsistentHash} uses {@link Object#toString()} on + * 'T' to obtain the hash, but that behavior can be changed by providing a + * {@link Hash} implementation. * - * <p> - * This hash function need not produce a very uniform distribution, as the - * output is rehashed with MD5. But it does need to make sure it doesn't - * produce the same value for two different 'T's (and that's why this returns - * String, not the usual int.) + * <p> This hash function need not produce a very uniform distribution, as + * the output is rehashed with MD5. But it does need to make sure it doesn't + * produce the same value for two different 'T's (and that's why this + * returns String, not the usual int.) */ public interface Hash<T> { + /** - * @param t - * The object to be hashed. Never null. - * @return - * The hash value. + * @param t The object to be hashed. Never null. + * @return The hash value. */ String hash(T t); } - private static final Hash DEFAULT_HASH = new Hash() { public String hash(Object o) { return o.toString(); @@ -194,11 +200,11 @@ public class ConsistentHash<T> { } public ConsistentHash(int defaultReplication) { - this(DEFAULT_HASH,defaultReplication); + this(DEFAULT_HASH, defaultReplication); } public ConsistentHash(Hash<T> hash) { - this(hash,100); + this(hash, 100); } public ConsistentHash(Hash<T> hash, int defaultReplication) { @@ -208,9 +214,10 @@ public class ConsistentHash<T> { } public int countAllPoints() { - int r=0; - for (Point[] v : items.values()) - r+=v.length; + int r = 0; + for (Point[] v : items.values()) { + r += v.length; + } return r; } @@ -218,47 +225,49 @@ public class ConsistentHash<T> { * Adds a new node with the default number of replica. */ public void add(T node) { - add(node,defaultReplication); + add(node, defaultReplication); } /** * Calls {@link #add(Object)} with all the arguments. */ public void addAll(T... nodes) { - for (T node : nodes) + for (T node : nodes) { add(node); + } } /** * Calls {@link #add(Object)} with all the arguments. */ public void addAll(Collection<? extends T> nodes) { - for (T node : nodes) + for (T node : nodes) { add(node); + } } /** * Removes the node entirely. This is the same as {@code add(node,0)} */ public void remove(T node) { - add(node,0); + add(node, 0); } /** * Adds a new node with the given number of replica. * - * <p> - * This is the only function that manipulates {@link #items}. + * <p> This is the only function that manipulates {@link #items}. */ public synchronized void add(T node, int replica) { - if(replica==0) { + if (replica == 0) { items.remove(node); } else { Point[] points = new Point[replica]; String seed = hash.hash(node); - for (int i=0; i<replica; i++) - points[i] = new Point(md5(seed+':'+i),node); - items.put(node,points); + for (int i = 0; i < replica; i++) { + points[i] = new Point(md5(seed + ':' + i), node); + } + items.put(node, points); } table = new Table(); } @@ -273,11 +282,12 @@ public class ConsistentHash<T> { byte[] digest = md5.digest(); // 16 bytes -> 4 bytes - for (int i=0; i<4; i++) - digest[i] ^= digest[i+4]+digest[i+8]+digest[i+12]; - return (b2i(digest[0])<< 24)|(b2i(digest[1])<<16)|(b2i(digest[2])<< 8)|b2i(digest[3]); + for (int i = 0; i < 4; i++) { + digest[i] ^= digest[i + 4] + digest[i + 8] + digest[i + 12]; + } + return (b2i(digest[0]) << 24) | (b2i(digest[1]) << 16) | (b2i(digest[2]) << 8) | b2i(digest[3]); } catch (Exception ex) { - logger.error("Error finding MD5 for the string " + s, ex); + logger.error("Error finding MD5 for the string " + s, ex); return -1; } } @@ -286,26 +296,24 @@ public class ConsistentHash<T> { * unsigned byte->int. */ private int b2i(byte b) { - return ((int)b)&0xFF; + return ((int) b) & 0xFF; } /** * Looks up a consistent hash with the given data point. * - * <p> - * The whole point of this class is that if the same query point is given, - * it's likely to return the same result even when other nodes are added/removed, - * or the # of replicas for the given node is changed. + * <p> The whole point of this class is that if the same query point is + * given, it's likely to return the same result even when other nodes are + * added/removed, or the # of replicas for the given node is changed. * - * @return - * null if the consistent hash is empty. Otherwise always non-null. + * @return null if the consistent hash is empty. Otherwise always non-null. */ public T lookup(int queryPoint) { return table.lookup(queryPoint); } /** - * Takes a string, hash it with MD5, then calls {@link #lookup(int)}. + * Takes a string, hash it with MD5, then calls {@link #lookup(int)}. */ public T lookup(String queryPoint) { return lookup(md5(queryPoint)); @@ -314,13 +322,11 @@ public class ConsistentHash<T> { /** * Creates a permutation of all the nodes for the given data point. * - * <p> - * The returned pemutation is consistent, in the sense that small change + * <p> The returned pemutation is consistent, in the sense that small change * to the consitent hash (like addition/removal/change of replicas) only * creates a small change in the permutation. * - * <p> - * Nodes with more replicas are more likely to show up early in the list + * <p> Nodes with more replicas are more likely to show up early in the list */ public Iterable<T> list(final int queryPoint) { return new Iterable<T>() { diff --git a/hudson-core/src/main/java/hudson/util/CopyOnWriteList.java b/hudson-core/src/main/java/hudson/util/CopyOnWriteList.java index 84b6660..ae105da 100644 --- a/hudson-core/src/main/java/hudson/util/CopyOnWriteList.java +++ b/hudson-core/src/main/java/hudson/util/CopyOnWriteList.java @@ -7,10 +7,10 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: -* -* Kohsuke Kawaguchi, Nikita Levyankov - * + * Contributors: + * + * Kohsuke Kawaguchi, Nikita Levyankov + * * *******************************************************************************/ @@ -39,17 +39,17 @@ import static java.util.logging.Level.WARNING; /** * {@link List}-like implementation that has copy-on-write semantics. * - * <p> - * This class is suitable where highly concurrent access is needed, yet - * the write operation is relatively uncommon. + * <p> This class is suitable where highly concurrent access is needed, yet the + * write operation is relatively uncommon. * * @author Kohsuke Kawaguchi */ public class CopyOnWriteList<E> implements Iterable<E> { + private volatile List<? extends E> core; public CopyOnWriteList(List<E> core) { - this(core,false); + this(core, false); } private CopyOnWriteList(List<E> core, boolean noCopy) { @@ -75,9 +75,8 @@ public class CopyOnWriteList<E> implements Iterable<E> { /** * Removes an item from the list. * - * @return - * true if the list contained the item. False if it didn't, - * in which case there's no change. + * @return true if the list contained the item. False if it didn't, in which + * case there's no change. */ public synchronized boolean remove(E e) { List<E> n = new ArrayList<E>(core); @@ -93,12 +92,13 @@ public class CopyOnWriteList<E> implements Iterable<E> { final Iterator<? extends E> itr = core.iterator(); return new Iterator<E>() { private E last; + public boolean hasNext() { return itr.hasNext(); } public E next() { - return last=itr.next(); + return last = itr.next(); } public void remove() { @@ -160,17 +160,19 @@ public class CopyOnWriteList<E> implements Iterable<E> { * {@link Converter} implementation for XStream. */ public static final class ConverterImpl extends AbstractCollectionConverter { + public ConverterImpl(Mapper mapper) { super(mapper); } public boolean canConvert(Class type) { - return type==CopyOnWriteList.class; + return type == CopyOnWriteList.class; } public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { - for (Object o : (CopyOnWriteList) source) + for (Object o : (CopyOnWriteList) source) { writeItem(o, context, writer); + } } @SuppressWarnings("unchecked") @@ -183,16 +185,16 @@ public class CopyOnWriteList<E> implements Iterable<E> { Object item = readItem(reader, context, items); items.add(item); } catch (CannotResolveClassException e) { - LOGGER.log(WARNING,"Failed to resolve class",e); + LOGGER.log(WARNING, "Failed to resolve class", e); RobustReflectionConverter.addErrorInContext(context, e); } catch (LinkageError e) { - LOGGER.log(WARNING,"Failed to resolve class",e); + LOGGER.log(WARNING, "Failed to resolve class", e); RobustReflectionConverter.addErrorInContext(context, e); } reader.moveUp(); } - return new CopyOnWriteList(items,true); + return new CopyOnWriteList(items, true); } } @@ -213,6 +215,5 @@ public class CopyOnWriteList<E> implements Iterable<E> { public int hashCode() { return core != null ? core.hashCode() : 0; } - private static final Logger LOGGER = Logger.getLogger(CopyOnWriteList.class.getName()); } diff --git a/hudson-core/src/main/java/hudson/util/CopyOnWriteMap.java b/hudson-core/src/main/java/hudson/util/CopyOnWriteMap.java index 6f33d2a..83ded76 100644 --- a/hudson-core/src/main/java/hudson/util/CopyOnWriteMap.java +++ b/hudson-core/src/main/java/hudson/util/CopyOnWriteMap.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 - * + * * *******************************************************************************/ @@ -36,28 +36,28 @@ import java.util.TreeMap; /** * {@link Map} that has copy-on-write semantics. * - * <p> - * This class is suitable where highly concurrent access is needed, yet - * the write operation is relatively uncommon. + * <p> This class is suitable where highly concurrent access is needed, yet the + * write operation is relatively uncommon. * * @author Kohsuke Kawaguchi */ -public abstract class CopyOnWriteMap<K,V> implements Map<K,V> { - protected volatile Map<K,V> core; +public abstract class CopyOnWriteMap<K, V> implements Map<K, V> { + + protected volatile Map<K, V> core; /** * Read-only view of {@link #core}. */ - private volatile Map<K,V> view; + private volatile Map<K, V> view; - protected CopyOnWriteMap(Map<K,V> core) { + protected CopyOnWriteMap(Map<K, V> core) { update(core); } protected CopyOnWriteMap() { - update(Collections.<K,V>emptyMap()); + update(Collections.<K, V>emptyMap()); } - protected void update(Map<K,V> m) { + protected void update(Map<K, V> m) { core = m; view = Collections.unmodifiableMap(core); } @@ -83,15 +83,15 @@ public abstract class CopyOnWriteMap<K,V> implements Map<K,V> { } public synchronized V put(K key, V value) { - Map<K,V> m = copy(); - V r = m.put(key,value); + Map<K, V> m = copy(); + V r = m.put(key, value); update(m); return r; } public synchronized V remove(Object key) { - Map<K,V> m = copy(); + Map<K, V> m = copy(); V r = m.remove(key); update(m); @@ -99,15 +99,15 @@ public abstract class CopyOnWriteMap<K,V> implements Map<K,V> { } public synchronized void putAll(Map<? extends K, ? extends V> t) { - Map<K,V> m = copy(); + Map<K, V> m = copy(); m.putAll(t); update(m); } - protected abstract Map<K,V> copy(); + protected abstract Map<K, V> copy(); public synchronized void clear() { - update(Collections.<K,V>emptyMap()); + update(Collections.<K, V>emptyMap()); } /** @@ -127,43 +127,45 @@ public abstract class CopyOnWriteMap<K,V> implements Map<K,V> { /** * This method will return a read-only {@link Set}. */ - public Set<Entry<K,V>> entrySet() { + public Set<Entry<K, V>> entrySet() { return view.entrySet(); } /** * {@link CopyOnWriteMap} backed by {@link HashMap}. */ - public static final class Hash<K,V> extends CopyOnWriteMap<K,V> { - public Hash(Map<K,V> core) { - super(new LinkedHashMap<K,V>(core)); + public static final class Hash<K, V> extends CopyOnWriteMap<K, V> { + + public Hash(Map<K, V> core) { + super(new LinkedHashMap<K, V>(core)); } public Hash() { } - protected Map<K,V> copy() { - return new LinkedHashMap<K,V>(core); + protected Map<K, V> copy() { + return new LinkedHashMap<K, V>(core); } public static class ConverterImpl extends MapConverter { + public ConverterImpl(Mapper mapper) { super(mapper); } @Override public boolean canConvert(Class type) { - return type==Hash.class; + return type == Hash.class; } @Override public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { - return new Hash((Map) super.unmarshal(reader,context)); + return new Hash((Map) super.unmarshal(reader, context)); } @Override public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { - super.marshal(((Hash)source).core,writer,context); + super.marshal(((Hash) source).core, writer, context); } } } @@ -171,16 +173,17 @@ public abstract class CopyOnWriteMap<K,V> implements Map<K,V> { /** * {@link CopyOnWriteMap} backed by {@link TreeMap}. */ - public static final class Tree<K,V> extends CopyOnWriteMap<K,V> { + public static final class Tree<K, V> extends CopyOnWriteMap<K, V> { + private final Comparator<K> comparator; - public Tree(Map<K,V> core, Comparator<K> comparator) { + public Tree(Map<K, V> core, Comparator<K> comparator) { this(comparator); putAll(core); } public Tree(Comparator<K> comparator) { - super(new TreeMap<K,V>(comparator)); + super(new TreeMap<K, V>(comparator)); this.comparator = comparator; } @@ -188,36 +191,37 @@ public abstract class CopyOnWriteMap<K,V> implements Map<K,V> { this(null); } - protected Map<K,V> copy() { - TreeMap<K,V> m = new TreeMap<K,V>(comparator); + protected Map<K, V> copy() { + TreeMap<K, V> m = new TreeMap<K, V>(comparator); m.putAll(core); return m; } @Override public synchronized void clear() { - update(new TreeMap<K,V>(comparator)); + update(new TreeMap<K, V>(comparator)); } public static class ConverterImpl extends TreeMapConverter { + public ConverterImpl(Mapper mapper) { super(mapper); } @Override public boolean canConvert(Class type) { - return type==Tree.class; + return type == Tree.class; } @Override public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { - TreeMap tm = (TreeMap) super.unmarshal(reader,context); - return new Tree(tm,tm.comparator()); + TreeMap tm = (TreeMap) super.unmarshal(reader, context); + return new Tree(tm, tm.comparator()); } @Override public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { - super.marshal(((Tree)source).core,writer,context); + super.marshal(((Tree) source).core, writer, context); } } } diff --git a/hudson-core/src/main/java/hudson/util/CyclicGraphDetector.java b/hudson-core/src/main/java/hudson/util/CyclicGraphDetector.java index aeabf70..d0326b9 100644 --- a/hudson-core/src/main/java/hudson/util/CyclicGraphDetector.java +++ b/hudson-core/src/main/java/hudson/util/CyclicGraphDetector.java @@ -8,7 +8,7 @@ * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * + * * *******************************************************************************/ @@ -27,32 +27,39 @@ import java.util.Stack; * @author Kohsuke Kawaguchi */ public abstract class CyclicGraphDetector<N> { + private final Set<N> visited = new HashSet<N>(); private final Set<N> visiting = new HashSet<N>(); private final Stack<N> path = new Stack<N>(); public void run(Iterable<? extends N> allNodes) throws CycleDetectedException { - for (N n : allNodes) + for (N n : allNodes) { visit(n); + } } /** - * List up edges from the given node (by listing nodes that those edges point to.) + * List up edges from the given node (by listing nodes that those edges + * point to.) * - * @return - * Never null. + * @return Never null. */ protected abstract Iterable<? extends N> getEdges(N n); private void visit(N p) throws CycleDetectedException { - if (!visited.add(p)) return; + if (!visited.add(p)) { + return; + } visiting.add(p); path.push(p); for (N q : getEdges(p)) { - if (q==null) continue; // ignore unresolved references - if (visiting.contains(q)) + if (q == null) { + continue; // ignore unresolved references + } + if (visiting.contains(q)) { detectedCycle(q); + } visit(q); } visiting.remove(p); @@ -67,6 +74,7 @@ public abstract class CyclicGraphDetector<N> { public static final class CycleDetectedException extends Exception { //TODO: review and check whether we can do it private + public final List cycle; public List getCycle() { @@ -74,7 +82,7 @@ public abstract class CyclicGraphDetector<N> { } public CycleDetectedException(List cycle) { - super("Cycle detected: "+Util.join(cycle," -> ")); + super("Cycle detected: " + Util.join(cycle, " -> ")); this.cycle = cycle; } } diff --git a/hudson-core/src/main/java/hudson/util/DaemonThreadFactory.java b/hudson-core/src/main/java/hudson/util/DaemonThreadFactory.java index b83f8ef..8c68a6d 100644 --- a/hudson-core/src/main/java/hudson/util/DaemonThreadFactory.java +++ b/hudson-core/src/main/java/hudson/util/DaemonThreadFactory.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 + * * *******************************************************************************/ @@ -25,6 +25,7 @@ import java.util.concurrent.ThreadFactory; * @author Kohsuke Kawaguchi */ public class DaemonThreadFactory implements ThreadFactory { + private final ThreadFactory core; public DaemonThreadFactory() { diff --git a/hudson-core/src/main/java/hudson/util/DecodingStream.java b/hudson-core/src/main/java/hudson/util/DecodingStream.java index 22f0cce..1b9a6fa 100644 --- a/hudson-core/src/main/java/hudson/util/DecodingStream.java +++ b/hudson-core/src/main/java/hudson/util/DecodingStream.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 + * * *******************************************************************************/ @@ -27,6 +27,7 @@ import java.io.OutputStream; * @see EncodingStream */ public class DecodingStream extends FilterOutputStream { + private int last = -1; public DecodingStream(OutputStream out) { @@ -35,12 +36,12 @@ public class DecodingStream extends FilterOutputStream { @Override public void write(int b) throws IOException { - if(last==-1) { + if (last == -1) { last = b; return; } - out.write( Character.getNumericValue(last)*16 + Character.getNumericValue(b) ); + out.write(Character.getNumericValue(last) * 16 + Character.getNumericValue(b)); last = -1; } } diff --git a/hudson-core/src/main/java/hudson/util/DeepEquals.java b/hudson-core/src/main/java/hudson/util/DeepEquals.java index a67330e..9689be1 100644 --- a/hudson-core/src/main/java/hudson/util/DeepEquals.java +++ b/hudson-core/src/main/java/hudson/util/DeepEquals.java @@ -31,60 +31,55 @@ import java.util.SortedSet; import java.util.concurrent.ConcurrentHashMap; /** - * Test two objects for equivalence with a 'deep' comparison. This will traverse + * Test two objects for equivalence with a 'deep' comparison. This will traverse * the Object graph and perform either a field-by-field comparison on each - * object (if no .equals() method has been overridden from Object), or it - * will call the customized .equals() method if it exists. This method will - * allow object graphs loaded at different times (with different object ids) - * to be reliably compared. Object.equals() / Object.hashCode() rely on the - * object's identity, which would not consider two equivalent objects necessarily - * equals. This allows graphs containing instances of Classes that did not - * overide .equals() / .hashCode() to be compared. For example, testing for - * existence in a cache. Relying on an object's identity will not locate an - * equivalent object in a cache.<br/><br/> + * object (if no .equals() method has been overridden from Object), or it will + * call the customized .equals() method if it exists. This method will allow + * object graphs loaded at different times (with different object ids) to be + * reliably compared. Object.equals() / Object.hashCode() rely on the object's + * identity, which would not consider two equivalent objects necessarily equals. + * This allows graphs containing instances of Classes that did not overide + * .equals() / .hashCode() to be compared. For example, testing for existence in + * a cache. Relying on an object's identity will not locate an equivalent object + * in a cache.<br/><br/> * - * This method will handle cycles correctly, for example A->B->C->A. Suppose a and - * a' are two separate instances of A with the same values for all fields on - * A, B, and C. Then a.deepEquals(a') will return true. It uses cycle detection + * This method will handle cycles correctly, for example A->B->C->A. Suppose a + * and a' are two separate instances of A with the same values for all fields on + * A, B, and C. Then a.deepEquals(a') will return true. It uses cycle detection * storing visited objects in a Set to prevent endless loops. - * + * * @author John DeRegnaucourt (jdereg@gmail.com) */ -public class DeepEquals -{ +public class DeepEquals { + private static final Map<Class, Boolean> _customEquals = new ConcurrentHashMap<Class, Boolean>(); private static final Map<Class, Boolean> _customHash = new ConcurrentHashMap<Class, Boolean>(); private static final Map<Class, Collection<Field>> _reflectedFields = new ConcurrentHashMap<Class, Collection<Field>>(); - - private static class DualKey - { + + private static class DualKey { + private final Object _key1; private final Object _key2; - - private DualKey(Object k1, Object k2) - { + + private DualKey(Object k1, Object k2) { _key1 = k1; _key2 = k2; } - - public boolean equals(Object other) - { - if (other == null) - { + + public boolean equals(Object other) { + if (other == null) { return false; } - - if (!(other instanceof DualKey)) - { + + if (!(other instanceof DualKey)) { return false; } - + DualKey that = (DualKey) other; return _key1 == that._key1 && _key2 == that._key2; } - - public int hashCode() - { + + public int hashCode() { int h1 = _key1 != null ? _key1.hashCode() : 0; int h2 = _key2 != null ? _key2.hashCode() : 0; return h1 + h2; @@ -92,146 +87,126 @@ public class DeepEquals } /** - * Compare two objects with a 'deep' comparison. This will traverse the + * Compare two objects with a 'deep' comparison. This will traverse the * Object graph and perform either a field-by-field comparison on each * object (if no .equals() method has been overridden from Object), or it - * will call the customized .equals() method if it exists. This method will + * will call the customized .equals() method if it exists. This method will * allow object graphs loaded at different times (with different object ids) - * to be reliably compared. Object.equals() / Object.hashCode() rely on the - * object's identity, which would not consider to equivalent objects necessarily - * equals. This allows graphs containing instances of Classes that did no - * overide .equals() / .hashCode() to be compared. For example, testing for - * existence in a cache. Relying on an objects identity will not locate an - * object in cache, yet relying on it being equivalent will.<br/><br/> + * to be reliably compared. Object.equals() / Object.hashCode() rely on the + * object's identity, which would not consider to equivalent objects + * necessarily equals. This allows graphs containing instances of Classes + * that did no overide .equals() / .hashCode() to be compared. For example, + * testing for existence in a cache. Relying on an objects identity will not + * locate an object in cache, yet relying on it being equivalent + * will.<br/><br/> + * + * This method will handle cycles correctly, for example A->B->C->A. Suppose + * a and a' are two separate instances of the A with the same values for all + * fields on A, B, and C. Then a.deepEquals(a') will return true. It uses + * cycle detection storing visited objects in a Set to prevent endless + * loops. * - * This method will handle cycles correctly, for example A->B->C->A. Suppose a and - * a' are two separate instances of the A with the same values for all fields on - * A, B, and C. Then a.deepEquals(a') will return true. It uses cycle detection - * storing visited objects in a Set to prevent endless loops. * @param a Object one to compare * @param b Object two to compare - * @return true if a is equivalent to b, false otherwise. Equivalent means that - * all field values of both subgraphs are the same, either at the field level - * or via the respectively encountered overridden .equals() methods during - * traversal. + * @return true if a is equivalent to b, false otherwise. Equivalent means + * that all field values of both subgraphs are the same, either at the field + * level or via the respectively encountered overridden .equals() methods + * during traversal. */ - public static boolean deepEquals(Object a, Object b) - { + public static boolean deepEquals(Object a, Object b) { Set visited = new HashSet<DualKey>(); LinkedList<DualKey> stack = new LinkedList<DualKey>(); stack.addFirst(new DualKey(a, b)); - while (!stack.isEmpty()) - { - DualKey dualKey = stack.removeFirst(); + while (!stack.isEmpty()) { + DualKey dualKey = stack.removeFirst(); visited.add(dualKey); - - if (dualKey._key1 == dualKey._key2) - { // Same instance is always equal to itself. + + if (dualKey._key1 == dualKey._key2) { // Same instance is always equal to itself. continue; } - - if (dualKey._key1 == null || dualKey._key2 == null) - { // If either one is null, not equal (both can't be null, due to above comparison). + + if (dualKey._key1 == null || dualKey._key2 == null) { // If either one is null, not equal (both can't be null, due to above comparison). return false; } - - if (!dualKey._key1.getClass().equals(dualKey._key2.getClass())) - { // Must be same class + + if (!dualKey._key1.getClass().equals(dualKey._key2.getClass())) { // Must be same class return false; } - + // Handle all [] types. In order to be equal, the arrays must be the same // length, be of the same type, be in the same order, and all elements within // the array must be deeply equivalent. - if (dualKey._key1.getClass().isArray()) - { - if (!compareArrays(dualKey._key1, dualKey._key2, stack, visited)) - { + if (dualKey._key1.getClass().isArray()) { + if (!compareArrays(dualKey._key1, dualKey._key2, stack, visited)) { return false; } continue; } - + // Special handle SortedSets because they are fast to compare because their // elements must be in the same order to be equivalent Sets. - if (dualKey._key1 instanceof SortedSet) - { - if (!compareOrderedCollection((Collection) dualKey._key1, (Collection) dualKey._key2, stack, visited)) - { + if (dualKey._key1 instanceof SortedSet) { + if (!compareOrderedCollection((Collection) dualKey._key1, (Collection) dualKey._key2, stack, visited)) { return false; } continue; } - + // Handled unordered Sets. This is a slightly more expensive comparison because order cannot // be assumed, a temporary Map must be created, however the comparison still runs in O(N) time. - if (dualKey._key1 instanceof Set) - { - if (!compareUnorderedCollection((Collection) dualKey._key1, (Collection) dualKey._key2, stack, visited)) - { + if (dualKey._key1 instanceof Set) { + if (!compareUnorderedCollection((Collection) dualKey._key1, (Collection) dualKey._key2, stack, visited)) { return false; } continue; } - + // Check any Collection that is not a Set. In these cases, element order // matters, therefore this comparison is faster than using unordered comparison. - if (dualKey._key1 instanceof Collection) - { - if (!compareOrderedCollection((Collection) dualKey._key1, (Collection) dualKey._key2, stack, visited)) - { + if (dualKey._key1 instanceof Collection) { + if (!compareOrderedCollection((Collection) dualKey._key1, (Collection) dualKey._key2, stack, visited)) { return false; - } + } continue; } - + // Compare two SortedMaps. This takes advantage of the fact that these // Maps can be compared in O(N) time due to their ordering. - if (dualKey._key1 instanceof SortedMap) - { - if (!compareSortedMap((SortedMap) dualKey._key1, (SortedMap) dualKey._key2, stack, visited)) - { + if (dualKey._key1 instanceof SortedMap) { + if (!compareSortedMap((SortedMap) dualKey._key1, (SortedMap) dualKey._key2, stack, visited)) { return false; } continue; } - + // Compare two Unordered Maps. This is a slightly more expensive comparison because // order cannot be assumed, therefore a temporary Map must be created, however the // comparison still runs in O(N) time. - if (dualKey._key1 instanceof Map) - { - if (!compareUnorderedMap((Map) dualKey._key1, (Map) dualKey._key2, stack, visited)) - { + if (dualKey._key1 instanceof Map) { + if (!compareUnorderedMap((Map) dualKey._key1, (Map) dualKey._key2, stack, visited)) { return false; } continue; } - - if (hasCustomEquals(dualKey._key1.getClass())) - { - if (!dualKey._key1.equals(dualKey._key2)) - { + + if (hasCustomEquals(dualKey._key1.getClass())) { + if (!dualKey._key1.equals(dualKey._key2)) { return false; } continue; - } - - Collection<Field> fields = getDeepDeclaredFields(dualKey._key1.getClass()); - - for (Field field : fields) - { - try - { + } + + Collection<Field> fields = getDeepDeclaredFields(dualKey._key1.getClass()); + + for (Field field : fields) { + try { DualKey dk = new DualKey(field.get(dualKey._key1), field.get(dualKey._key2)); - if (!visited.contains(dk)) - { + if (!visited.contains(dk)) { stack.addFirst(dk); } + } catch (Exception ignored) { } - catch (Exception ignored) - { } } } @@ -239,29 +214,28 @@ public class DeepEquals } /** - * Deeply compare to Arrays []. Both arrays must be of the same type, same length, and all - * elements within the arrays must be deeply equal in order to return true. + * Deeply compare to Arrays []. Both arrays must be of the same type, same + * length, and all elements within the arrays must be deeply equal in order + * to return true. + * * @param array1 [] type (Object[], String[], etc.) * @param array2 [] type (Object[], String[], etc.) * @param stack add items to compare to the Stack (Stack versus recursion) * @param visited Set of objects already compared (prevents cycles) - * @return true if the two arrays are the same length and contain deeply equivalent items. + * @return true if the two arrays are the same length and contain deeply + * equivalent items. */ - private static boolean compareArrays(Object array1, Object array2, LinkedList stack, Set visited) - { + private static boolean compareArrays(Object array1, Object array2, LinkedList stack, Set visited) { // Same instance check already performed... int len = Array.getLength(array1); - if (len != Array.getLength(array2)) - { + if (len != Array.getLength(array2)) { return false; } - for (int i = 0; i < len; i++) - { + for (int i = 0; i < len; i++) { DualKey dk = new DualKey(Array.get(array1, i), Array.get(array2, i)); - if (!visited.contains(dk)) - { // push contents for further comparison + if (!visited.contains(dk)) { // push contents for further comparison stack.addFirst(dk); } } @@ -269,79 +243,72 @@ public class DeepEquals } /** - * Deeply compare two Collections that must be same length and in same order. + * Deeply compare two Collections that must be same length and in same + * order. + * * @param col1 First collection of items to compare * @param col2 Second collection of items to compare * @param stack add items to compare to the Stack (Stack versus recursion) - * @param visited Set of objects already compared (prevents cycles) - * value of 'true' indicates that the Collections may be equal, and the sets - * items will be added to the Stack for further comparison. + * @param visited Set of objects already compared (prevents cycles) value of + * 'true' indicates that the Collections may be equal, and the sets items + * will be added to the Stack for further comparison. */ - private static boolean compareOrderedCollection(Collection col1, Collection col2, LinkedList stack, Set visited) - { + private static boolean compareOrderedCollection(Collection col1, Collection col2, LinkedList stack, Set visited) { // Same instance check already performed... - if (col1.size() != col2.size()) - { + if (col1.size() != col2.size()) { return false; } - + Iterator i1 = col1.iterator(); Iterator i2 = col2.iterator(); - - while (i1.hasNext()) - { + + while (i1.hasNext()) { DualKey dk = new DualKey(i1.next(), i2.next()); - if (!visited.contains(dk)) - { // push contents for further comparison + if (!visited.contains(dk)) { // push contents for further comparison stack.addFirst(dk); } } return true; } - + /** - * Deeply compare the two sets referenced by dualKey. This method attempts + * Deeply compare the two sets referenced by dualKey. This method attempts * to quickly determine inequality by length, then if lengths match, it * places one collection into a temporary Map by deepHashCode(), so that it * can walk the other collection and look for each item in the map, which * runs in O(N) time, rather than an O(N^2) lookup that would occur if each * item from collection one was scanned for in collection two. + * * @param col1 First collection of items to compare * @param col2 Second collection of items to compare * @param stack add items to compare to the Stack (Stack versus recursion) - * @param visited Set containing items that have already been compared, - * so as to prevent cycles. + * @param visited Set containing items that have already been compared, so + * as to prevent cycles. * @return boolean false if the Collections are for certain not equals. A * value of 'true' indicates that the Collections may be equal, and the sets * items will be added to the Stack for further comparison. */ - private static boolean compareUnorderedCollection(Collection col1, Collection col2, LinkedList stack, Set visited) - { + private static boolean compareUnorderedCollection(Collection col1, Collection col2, LinkedList stack, Set visited) { // Same instance check already performed... - if (col1.size() != col2.size()) - { + if (col1.size() != col2.size()) { return false; } Map fastLookup = new HashMap(); - for (Object o : col2) - { + for (Object o : col2) { fastLookup.put(deepHashCode(o), o); } - for (Object o : col1) - { + for (Object o : col1) { Object other = fastLookup.get(deepHashCode(o)); - if (other == null) - { // Item not even found in other Collection, no need to continue. + if (other == null) { // Item not even found in other Collection, no need to continue. return false; } DualKey dk = new DualKey(o, other); - if (!visited.contains(dk)) - { // Place items on 'stack' for further comparison. + if (!visited.contains(dk)) { // Place items on 'stack' for further comparison. stack.addFirst(dk); } } @@ -349,42 +316,40 @@ public class DeepEquals } /** - * Deeply compare two SortedMap instances. This method walks the Maps in order, - * taking advantage of the fact that they Maps are SortedMaps. + * Deeply compare two SortedMap instances. This method walks the Maps in + * order, taking advantage of the fact that they Maps are SortedMaps. + * * @param map1 SortedMap one * @param map2 SortedMap two * @param stack add items to compare to the Stack (Stack versus recursion) - * @param visited Set containing items that have already been compared, to prevent cycles. - * @return false if the Maps are for certain not equals. 'true' indicates that 'on the surface' the maps - * are equal, however, it will place the contents of the Maps on the stack for further comparisons. + * @param visited Set containing items that have already been compared, to + * prevent cycles. + * @return false if the Maps are for certain not equals. 'true' indicates + * that 'on the surface' the maps are equal, however, it will place the + * contents of the Maps on the stack for further comparisons. */ - private static boolean compareSortedMap(SortedMap map1, SortedMap map2, LinkedList stack, Set visited) - { + private static boolean compareSortedMap(SortedMap map1, SortedMap map2, LinkedList stack, Set visited) { // Same instance check already performed... - if (map1.size() != map2.size()) - { + if (map1.size() != map2.size()) { return false; } Iterator i1 = map1.entrySet().iterator(); Iterator i2 = map2.entrySet().iterator(); - while (i1.hasNext()) - { - Map.Entry entry1 = (Map.Entry)i1.next(); - Map.Entry entry2 = (Map.Entry)i2.next(); + while (i1.hasNext()) { + Map.Entry entry1 = (Map.Entry) i1.next(); + Map.Entry entry2 = (Map.Entry) i2.next(); // Must split the Key and Value so that Map.Entry's equals() method is not used. DualKey dk = new DualKey(entry1.getKey(), entry2.getKey()); - if (!visited.contains(dk)) - { // Push Keys for further comparison + if (!visited.contains(dk)) { // Push Keys for further comparison stack.addFirst(dk); } dk = new DualKey(entry1.getValue(), entry2.getValue()); - if (!visited.contains(dk)) - { // Push values for further comparison + if (!visited.contains(dk)) { // Push values for further comparison stack.addFirst(dk); } } @@ -392,48 +357,44 @@ public class DeepEquals } /** - * Deeply compare two Map instances. After quick short-circuit tests, this method - * uses a temporary Map so that this method can run in O(N) time. + * Deeply compare two Map instances. After quick short-circuit tests, this + * method uses a temporary Map so that this method can run in O(N) time. + * * @param map1 Map one * @param map2 Map two * @param stack add items to compare to the Stack (Stack versus recursion) - * @param visited Set containing items that have already been compared, to prevent cycles. - * @return false if the Maps are for certain not equals. 'true' indicates that 'on the surface' the maps - * are equal, however, it will place the contents of the Maps on the stack for further comparisons. + * @param visited Set containing items that have already been compared, to + * prevent cycles. + * @return false if the Maps are for certain not equals. 'true' indicates + * that 'on the surface' the maps are equal, however, it will place the + * contents of the Maps on the stack for further comparisons. */ - private static boolean compareUnorderedMap(Map map1, Map map2, LinkedList stack, Set visited) - { + private static boolean compareUnorderedMap(Map map1, Map map2, LinkedList stack, Set visited) { // Same instance check already performed... - if (map1.size() != map2.size()) - { + if (map1.size() != map2.size()) { return false; } Map fastLookup = new HashMap(); - for (Map.Entry entry : (Set<Map.Entry>)map2.entrySet()) - { + for (Map.Entry entry : (Set<Map.Entry>) map2.entrySet()) { fastLookup.put(deepHashCode(entry.getKey()), entry); } - for (Map.Entry entry : (Set<Map.Entry>)map1.entrySet()) - { - Map.Entry other = (Map.Entry)fastLookup.get(deepHashCode(entry.getKey())); - if (other == null) - { + for (Map.Entry entry : (Set<Map.Entry>) map1.entrySet()) { + Map.Entry other = (Map.Entry) fastLookup.get(deepHashCode(entry.getKey())); + if (other == null) { return false; } DualKey dk = new DualKey(entry.getKey(), other.getKey()); - if (!visited.contains(dk)) - { // Push keys for further comparison + if (!visited.contains(dk)) { // Push keys for further comparison stack.addFirst(dk); } dk = new DualKey(entry.getValue(), other.getValue()); - if (!visited.contains(dk)) - { // Push values for further comparison + if (!visited.contains(dk)) { // Push values for further comparison stack.addFirst(dk); } } @@ -442,30 +403,27 @@ public class DeepEquals } /** - * Determine if the passed in class has a non-Object.equals() method. This + * Determine if the passed in class has a non-Object.equals() method. This * method caches its results in static ConcurrentHashMap to benefit * execution performance. + * * @param c Class to check. - * @return true, if the passed in Class has a .equals() method somewhere between - * itself and just below Object in it's inheritance. + * @return true, if the passed in Class has a .equals() method somewhere + * between itself and just below Object in it's inheritance. */ - public static boolean hasCustomEquals(Class c) - { + public static boolean hasCustomEquals(Class c) { Class origClass = c; - if (_customEquals.containsKey(c)) - { + if (_customEquals.containsKey(c)) { return _customEquals.get(c); } - while (!Object.class.equals(c)) - { - try - { + while (!Object.class.equals(c)) { + try { c.getDeclaredMethod("equals", Object.class); _customEquals.put(origClass, true); return true; + } catch (Exception ignored) { } - catch (Exception ignored) { } c = c.getSuperclass(); } _customEquals.put(origClass, false); @@ -474,165 +432,143 @@ public class DeepEquals /** * Get a deterministic hashCode (int) value for an Object, regardless of - * when it was created or where it was loaded into memory. The problem - * with java.lang.Object.hashCode() is that it essentially relies on - * memory location of an object (what identity it was assigned), whereas - * this method will produce the same hashCode for any object graph, regardless - * of how many times it is created.<br/><br/> + * when it was created or where it was loaded into memory. The problem with + * java.lang.Object.hashCode() is that it essentially relies on memory + * location of an object (what identity it was assigned), whereas this + * method will produce the same hashCode for any object graph, regardless of + * how many times it is created.<br/><br/> * - * This method will handle cycles correctly (A->B->C->A). In this case, - * Starting with object A, B, or C would yield the same hashCode. If an + * This method will handle cycles correctly (A->B->C->A). In this case, + * Starting with object A, B, or C would yield the same hashCode. If an * object encountered (root, suboject, etc.) has a hashCode() method on it * (that is not Object.hashCode()), that hashCode() method will be called * and it will stop traversal on that branch. + * * @param obj Object who hashCode is desired. * @return the 'deep' hashCode value for the passed in object. */ - public static int deepHashCode(Object obj) - { + public static int deepHashCode(Object obj) { Set visited = new HashSet(); LinkedList<Object> stack = new LinkedList<Object>(); stack.addFirst(obj); int hash = 0; - while (!stack.isEmpty()) - { + while (!stack.isEmpty()) { obj = stack.removeFirst(); - if (obj == null || visited.contains(obj)) - { + if (obj == null || visited.contains(obj)) { continue; } - + visited.add(obj); - - if (obj.getClass().isArray()) - { + + if (obj.getClass().isArray()) { int len = Array.getLength(obj); - for (int i = 0; i < len; i++) - { + for (int i = 0; i < len; i++) { stack.addFirst(Array.get(obj, i)); } continue; } - - if (obj instanceof Collection) - { - stack.addAll(0, (Collection)obj); + + if (obj instanceof Collection) { + stack.addAll(0, (Collection) obj); continue; } - - if (obj instanceof Map) - { - stack.addAll(0, ((Map)obj).keySet()); - stack.addAll(0, ((Map)obj).values()); - continue; + + if (obj instanceof Map) { + stack.addAll(0, ((Map) obj).keySet()); + stack.addAll(0, ((Map) obj).values()); + continue; } - - if (hasCustomHashCode(obj.getClass())) - { // A real hashCode() method exists, call it. + + if (hasCustomHashCode(obj.getClass())) { // A real hashCode() method exists, call it. hash += obj.hashCode(); continue; } - + Collection<Field> fields = getDeepDeclaredFields(obj.getClass()); - for (Field field : fields) - { - try - { + for (Field field : fields) { + try { stack.addFirst(field.get(obj)); + } catch (Exception ignored) { } - catch (Exception ignored) { } } } - return hash; + return hash; } - + /** - * Determine if the passed in class has a non-Object.hashCode() method. This + * Determine if the passed in class has a non-Object.hashCode() method. This * method caches its results in static ConcurrentHashMap to benefit * execution performance. + * * @param c Class to check. - * @return true, if the passed in Class has a .hashCode() method somewhere between - * itself and just below Object in it's inheritance. + * @return true, if the passed in Class has a .hashCode() method somewhere + * between itself and just below Object in it's inheritance. */ - public static boolean hasCustomHashCode(Class c) - { + public static boolean hasCustomHashCode(Class c) { Class origClass = c; - if (_customHash.containsKey(c)) - { + if (_customHash.containsKey(c)) { return _customHash.get(c); } - - while (!Object.class.equals(c)) - { - try - { + + while (!Object.class.equals(c)) { + try { c.getDeclaredMethod("hashCode"); _customHash.put(origClass, true); return true; + } catch (Exception ignored) { } - catch (Exception ignored) { } c = c.getSuperclass(); } _customHash.put(origClass, false); return false; } - + /** - * Get all non static, non transient, fields of the passed in class. - * The special this$ field is also not returned. The result is cached - * in a static ConcurrentHashMap to benefit execution performance. + * Get all non static, non transient, fields of the passed in class. The + * special this$ field is also not returned. The result is cached in a + * static ConcurrentHashMap to benefit execution performance. + * * @param c Class instance - * @return Collection of only the fields in the passed in class - * that would need further processing (reference fields). This - * makes field traversal on a class faster as it does not need to - * continually process known fields like primitives. + * @return Collection of only the fields in the passed in class that would + * need further processing (reference fields). This makes field traversal on + * a class faster as it does not need to continually process known fields + * like primitives. */ - public static Collection<Field> getDeepDeclaredFields(Class c) - { - if (_reflectedFields.containsKey(c)) - { + public static Collection<Field> getDeepDeclaredFields(Class c) { + if (_reflectedFields.containsKey(c)) { return _reflectedFields.get(c); } Collection<Field> fields = new ArrayList<Field>(); Class curr = c; - - while (curr != null) - { - try - { + + while (curr != null) { + try { Field[] local = curr.getDeclaredFields(); - for (Field field : local) - { - if (!field.isAccessible()) - { - try - { + for (Field field : local) { + if (!field.isAccessible()) { + try { field.setAccessible(true); + } catch (Exception ignored) { } - catch (Exception ignored) { } } - + int modifiers = field.getModifiers(); - if (!Modifier.isStatic(modifiers) && - !field.getName().startsWith("this$") && - !Modifier.isTransient(modifiers)) - { // speed up: do not count static fields, not go back up to enclosing object in nested case + if (!Modifier.isStatic(modifiers) + && !field.getName().startsWith("this$") + && !Modifier.isTransient(modifiers)) { // speed up: do not count static fields, not go back up to enclosing object in nested case fields.add(field); - } - } - } - catch (ThreadDeath t) - { + } + } + } catch (ThreadDeath t) { throw t; + } catch (Throwable ignored) { } - catch (Throwable ignored) - { } curr = curr.getSuperclass(); } _reflectedFields.put(c, fields); return fields; - } + } } diff --git a/hudson-core/src/main/java/hudson/util/DelegatingOutputStream.java b/hudson-core/src/main/java/hudson/util/DelegatingOutputStream.java index bac5e40..685c657 100644 --- a/hudson-core/src/main/java/hudson/util/DelegatingOutputStream.java +++ b/hudson-core/src/main/java/hudson/util/DelegatingOutputStream.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 + * * *******************************************************************************/ @@ -26,6 +26,7 @@ import java.io.IOException; * @author Kohsuke Kawaguchi */ public abstract class DelegatingOutputStream extends OutputStream { + protected OutputStream out; protected DelegatingOutputStream(OutputStream out) { diff --git a/hudson-core/src/main/java/hudson/util/DescribableList.java b/hudson-core/src/main/java/hudson/util/DescribableList.java index 910ba27..3b05750 100644 --- a/hudson-core/src/main/java/hudson/util/DescribableList.java +++ b/hudson-core/src/main/java/hudson/util/DescribableList.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 + * * *******************************************************************************/ @@ -40,26 +40,25 @@ import java.util.List; import java.util.Map; /** - * Persisted list of {@link Describable}s with some operations specific - * to {@link Descriptor}s. + * Persisted list of {@link Describable}s with some operations specific to + * {@link Descriptor}s. * - * <p> - * This class allows multiple instances of the same descriptor. Some clients - * use this semantics, while other clients use it as "up to one instance per - * one descriptor" model. + * <p> This class allows multiple instances of the same descriptor. Some clients + * use this semantics, while other clients use it as "up to one instance per one + * descriptor" model. * - * Some of the methods defined in this class only makes sense in the latter model, - * such as {@link #remove(Descriptor)}. + * Some of the methods defined in this class only makes sense in the latter + * model, such as {@link #remove(Descriptor)}. * * @author Kohsuke Kawaguchi */ public class DescribableList<T extends Describable<T>, D extends Descriptor<T>> extends PersistedList<T> { + protected DescribableList() { } /** - * @deprecated since 2008-08-15. - * Use {@link #DescribableList(Saveable)} + * @deprecated since 2008-08-15. Use {@link #DescribableList(Saveable)} */ public DescribableList(Owner owner) { setOwner(owner); @@ -75,8 +74,7 @@ public class DescribableList<T extends Describable<T>, D extends Descriptor<T>> } /** - * @deprecated since 2008-08-15. - * Use {@link #setOwner(Saveable)} + * @deprecated since 2008-08-15. Use {@link #setOwner(Saveable)} */ public void setOwner(Owner owner) { this.owner = owner; @@ -86,25 +84,27 @@ public class DescribableList<T extends Describable<T>, D extends Descriptor<T>> * Removes all instances of the same type, then add the new one. */ public void replace(T item) throws IOException { - removeAll((Class)item.getClass()); + removeAll((Class) item.getClass()); data.add(item); onModified(); } public T get(D descriptor) { - for (T t : data) - if(t.getDescriptor()==descriptor) + for (T t : data) { + if (t.getDescriptor() == descriptor) { return t; + } + } return null; } public boolean contains(D d) { - return get(d)!=null; + return get(d) != null; } public void remove(D descriptor) throws IOException { for (T t : data) { - if(t.getDescriptor()==descriptor) { + if (t.getDescriptor() == descriptor) { data.remove(t); onModified(); return; @@ -113,26 +113,29 @@ public class DescribableList<T extends Describable<T>, D extends Descriptor<T>> } /** - * Creates a detached map from the current snapshot of the data, keyed from a descriptor to an instance. + * Creates a detached map from the current snapshot of the data, keyed from + * a descriptor to an instance. */ @SuppressWarnings("unchecked") - public Map<D,T> toMap() { - return (Map)Descriptor.toMap(data); + public Map<D, T> toMap() { + return (Map) Descriptor.toMap(data); } /** * Rebuilds the list by creating a fresh instances from the submitted form. * <p/> - * <p/> - * This method is almost always used by the owner. - * This method does not invoke the save method. + * < + * p/> + * This method is almost always used by the owner. This method does not + * invoke the save method. * - * @param json Structured form data that includes the data for nested descriptor list. - * @deprecated as of 2.2.0, - * use {@link DescribableListUtil#buildFromJson(hudson.model.Saveable, org.kohsuke.stapler.StaplerRequest, net.sf.json.JSONObject, java.util.List)} + * @param json Structured form data that includes the data for nested + * descriptor list. + * @deprecated as of 2.2.0, use + * {@link DescribableListUtil#buildFromJson(hudson.model.Saveable, org.kohsuke.stapler.StaplerRequest, net.sf.json.JSONObject, java.util.List)} */ public void rebuild(StaplerRequest req, JSONObject json, List<? extends Descriptor<T>> descriptors) - throws FormException, IOException { + throws FormException, IOException { List<T> newList = new ArrayList<T>(); for (Descriptor<T> d : descriptors) { @@ -147,50 +150,51 @@ public class DescribableList<T extends Describable<T>, D extends Descriptor<T>> } /** - * @deprecated as of 1.271 - * Use {@link #rebuild(StaplerRequest, JSONObject, List)} instead. + * @deprecated as of 1.271 Use + * {@link #rebuild(StaplerRequest, JSONObject, List)} instead. */ public void rebuild(StaplerRequest req, JSONObject json, List<? extends Descriptor<T>> descriptors, String prefix) throws FormException, IOException { - rebuild(req,json,descriptors); + rebuild(req, json, descriptors); } /** * Rebuilds the list by creating a fresh instances from the submitted form. * <p/> * This version works with the the <f:hetero-list> UI tag, where the user - * is allowed to create multiple instances of the same descriptor. Order is also - * significant. + * is allowed to create multiple instances of the same descriptor. Order is + * also significant. * - * @deprecated as of 2.2.0, - * use {@link DescribableListUtil#buildFromHetero(hudson.model.Saveable, org.kohsuke.stapler.StaplerRequest, net.sf.json.JSONObject, String, java.util.Collection)} - * or {@link Descriptor#newInstancesFromHeteroList(org.kohsuke.stapler.StaplerRequest, net.sf.json.JSONObject, String, java.util.Collection)} + * @deprecated as of 2.2.0, use + * {@link DescribableListUtil#buildFromHetero(hudson.model.Saveable, org.kohsuke.stapler.StaplerRequest, net.sf.json.JSONObject, String, java.util.Collection)} + * or + * {@link Descriptor#newInstancesFromHeteroList(org.kohsuke.stapler.StaplerRequest, net.sf.json.JSONObject, String, java.util.Collection)} */ public void rebuildHetero(StaplerRequest req, - JSONObject formData, - Collection<? extends Descriptor<T>> descriptors, - String key) - throws FormException, IOException { + JSONObject formData, + Collection<? extends Descriptor<T>> descriptors, + String key) + throws FormException, IOException { replaceBy(Descriptor.newInstancesFromHeteroList(req, formData, key, descriptors)); } /** * Picks up {@link DependecyDeclarer}s and allow it to build dependencies. */ - public void buildDependencyGraph(AbstractProject owner,DependencyGraph graph) { + public void buildDependencyGraph(AbstractProject owner, DependencyGraph graph) { for (Object o : this) { if (o instanceof DependecyDeclarer) { DependecyDeclarer dd = (DependecyDeclarer) o; - dd.buildDependencyGraph(owner,graph); + dd.buildDependencyGraph(owner, graph); } } } -/* - The following two seemingly pointless method definitions are necessary to produce - backward compatible binary signatures. Without this we only get - get(Ljava/lang/Class;)Ljava/lang/Object; from PersistedList where we need - get(Ljava/lang/Class;)Lhudson/model/Describable; - */ + /* + The following two seemingly pointless method definitions are necessary to produce + backward compatible binary signatures. Without this we only get + get(Ljava/lang/Class;)Ljava/lang/Object; from PersistedList where we need + get(Ljava/lang/Class;)Lhudson/model/Describable; + */ public <U extends T> U get(Class<U> type) { return super.get(type); } @@ -200,8 +204,7 @@ public class DescribableList<T extends Describable<T>, D extends Descriptor<T>> } /** - * @deprecated since 2008-08-15. - * Just implement {@link Saveable}. + * @deprecated since 2008-08-15. Just implement {@link Saveable}. */ public interface Owner extends Saveable { } @@ -212,6 +215,7 @@ public class DescribableList<T extends Describable<T>, D extends Descriptor<T>> * Serializaion form is compatible with plain {@link List}. */ public static class ConverterImpl extends AbstractCollectionConverter { + CopyOnWriteList.ConverterImpl copyOnWriteListConverter; public ConverterImpl(Mapper mapper) { @@ -225,15 +229,16 @@ public class DescribableList<T extends Describable<T>, D extends Descriptor<T>> } public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { - for (Object o : (DescribableList) source) + for (Object o : (DescribableList) source) { writeItem(o, context, writer); + } } public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { CopyOnWriteList core = copyOnWriteListConverter.unmarshal(reader, context); try { - DescribableList r = (DescribableList)context.getRequiredType().newInstance(); + DescribableList r = (DescribableList) context.getRequiredType().newInstance(); r.data.replaceBy(core); return r; } catch (InstantiationException e) { diff --git a/hudson-core/src/main/java/hudson/util/DescribableListUtil.java b/hudson-core/src/main/java/hudson/util/DescribableListUtil.java index 3171d46..9ebdb4a 100644 --- a/hudson-core/src/main/java/hudson/util/DescribableListUtil.java +++ b/hudson-core/src/main/java/hudson/util/DescribableListUtil.java @@ -50,23 +50,24 @@ public final class DescribableListUtil { /** * Builds the list by creating a fresh instances from the submitted form. * <p/> - * This method is almost always used by the owner. - * This method does not invoke the save method. + * This method is almost always used by the owner. This method does not + * invoke the save method. * * @param owner represents owner of {@link DescribableList} * @param req {@link StaplerRequest} - * @param json Structured form data that includes the data for nested descriptor list. + * @param json Structured form data that includes the data for nested + * descriptor list. * @param descriptors list of descriptors to create instances from. * @return list. - * @throws IOException if any. + * @throws IOException if any. * @throws Descriptor.FormException if any. */ public static <T extends Describable<T>, D extends Descriptor<T>> DescribableList<T, D> buildFromJson( - Saveable owner, - StaplerRequest req, - JSONObject json, - List<D> descriptors) - throws Descriptor.FormException, IOException { + Saveable owner, + StaplerRequest req, + JSONObject json, + List<D> descriptors) + throws Descriptor.FormException, IOException { List<T> newList = new ArrayList<T>(); for (Descriptor<T> d : descriptors) { @@ -82,31 +83,36 @@ public final class DescribableListUtil { * Rebuilds the list by creating a fresh instances from the submitted form. * <p/> * This version works with the the <f:hetero-list> UI tag, where the user - * is allowed to create multiple instances of the same descriptor. Order is also - * significant. + * is allowed to create multiple instances of the same descriptor. Order is + * also significant. * * @param owner represents owner of {@link DescribableList} * @param req {@link StaplerRequest} * @param formData {@link JSONObject} populated based on form data, - * @param key the JSON property name for 'formData' that represents the data for the list of {@link Describable} + * @param key the JSON property name for 'formData' that represents the data + * for the list of {@link Describable} * @param descriptors list of descriptors to create instances from. * @return list. - * @throws IOException if any. + * @throws IOException if any. * @throws Descriptor.FormException if any. - * @see Descriptor#newInstancesFromHeteroList(org.kohsuke.stapler.StaplerRequest, net.sf.json.JSONObject, String, java.util.Collection) + * @see + * Descriptor#newInstancesFromHeteroList(org.kohsuke.stapler.StaplerRequest, + * net.sf.json.JSONObject, String, java.util.Collection) */ public static <T extends Describable<T>, D extends Descriptor<T>> DescribableList<T, D> buildFromHetero( - Saveable owner, - StaplerRequest req, JSONObject formData, - String key, - Collection<D> descriptors) - throws Descriptor.FormException, IOException { + Saveable owner, + StaplerRequest req, JSONObject formData, + String key, + Collection<D> descriptors) + throws Descriptor.FormException, IOException { return new DescribableList<T, D>(owner, Descriptor.newInstancesFromHeteroList(req, formData, key, descriptors)); } /** - * Converts describableList data to project properties map. {@link hudson.model.Descriptor#getJsonSafeClassName()} - * is used as key, value - {@link org.eclipse.hudson.model.project.property.BaseProjectProperty}. + * Converts describableList data to project properties map. + * {@link hudson.model.Descriptor#getJsonSafeClassName()} is used as key, + * value - + * {@link org.eclipse.hudson.model.project.property.BaseProjectProperty}. * * @param describableList source. * @param owner new owner for properties. @@ -114,8 +120,7 @@ public final class DescribableListUtil { * @param <D> Descriptor * @return map of converted properties. */ - public static <T extends Describable<T>, D extends Descriptor<T>> Map<String, ExternalProjectProperty<T>> - convertToProjectProperties(DescribableList<T, D> describableList, Job owner) { + public static <T extends Describable<T>, D extends Descriptor<T>> Map<String, ExternalProjectProperty<T>> convertToProjectProperties(DescribableList<T, D> describableList, Job owner) { Map<String, ExternalProjectProperty<T>> result = Maps.newConcurrentMap(); if (null != describableList) { for (Map.Entry<D, T> entry : describableList.toMap().entrySet()) { @@ -128,20 +133,23 @@ public final class DescribableListUtil { } return result; } + /** - * Converts collection of {@link ExternalProjectProperty} descriptors to {@link DescribableList} + * Converts collection of {@link ExternalProjectProperty} descriptors to + * {@link DescribableList} * * @param descriptors . * @param owner new owner for properties. * @return {@link DescribableList} */ public static <T extends Describable<T>> DescribableList<T, Descriptor<T>> convertToDescribableList( - List<Descriptor<T>> descriptors, Job owner) { + List<Descriptor<T>> descriptors, Job owner) { return convertToDescribableList(descriptors, owner, ExternalProjectProperty.class); } /** - * Converts collection of propertyClass descriptors to {@link DescribableList} + * Converts collection of propertyClass descriptors to + * {@link DescribableList} * * @param descriptors . * @param owner new owner for properties. @@ -149,13 +157,12 @@ public final class DescribableListUtil { * @return {@link DescribableList} */ @SuppressWarnings("unchecked") - public static <T extends Describable<T>, D extends Descriptor<T>, P extends IProjectProperty> DescribableList<T, D> - convertToDescribableList(List<D> descriptors, Job owner, Class<P> propertyClass) { + public static <T extends Describable<T>, D extends Descriptor<T>, P extends IProjectProperty> DescribableList<T, D> convertToDescribableList(List<D> descriptors, Job owner, Class<P> propertyClass) { List<T> describableList = new CopyOnWriteArrayList<T>(); DescribableList<T, D> result = new DescribableList<T, D>(owner); for (Descriptor<T> descriptor : descriptors) { IProjectProperty<T> property = - CascadingUtil.getProjectProperty(owner, descriptor.getJsonSafeClassName(), propertyClass); + CascadingUtil.getProjectProperty(owner, descriptor.getJsonSafeClassName(), propertyClass); if (null != property.getValue()) { describableList.add(property.getValue()); } @@ -169,5 +176,4 @@ public final class DescribableListUtil { } return result; } - } diff --git a/hudson-core/src/main/java/hudson/util/DescriptorList.java b/hudson-core/src/main/java/hudson/util/DescriptorList.java index 9196317..817b9c7 100644 --- a/hudson-core/src/main/java/hudson/util/DescriptorList.java +++ b/hudson-core/src/main/java/hudson/util/DescriptorList.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,27 +33,26 @@ import java.util.concurrent.CopyOnWriteArrayList; /** * List of {@link Descriptor}s. * - * <p> - * Before Hudson 1.286, this class stored {@link Descriptor}s directly, but since 1.286, - * this class works in two modes that are rather different. + * <p> Before Hudson 1.286, this class stored {@link Descriptor}s directly, but + * since 1.286, this class works in two modes that are rather different. * - * <p> - * One is the compatibility mode, where it works just like pre 1.286 and store everything locally, - * disconnected from any of the additions of 1.286. This is necessary for situations where - * {@link DescriptorList} is owned by pre-1.286 plugins where this class doesn't know 'T'. - * In this mode, {@link #legacy} is non-null but {@link #type} is null. + * <p> One is the compatibility mode, where it works just like pre 1.286 and + * store everything locally, disconnected from any of the additions of 1.286. + * This is necessary for situations where {@link DescriptorList} is owned by + * pre-1.286 plugins where this class doesn't know 'T'. In this mode, + * {@link #legacy} is non-null but {@link #type} is null. * - * <p> - * The other mode is the new mode, where the {@link Descriptor}s are actually stored in {@link ExtensionList} - * (see {@link Hudson#getDescriptorList(Class)}) and this class acts as a view to it. This enables - * bi-directional interoperability — both descriptors registred automatically and descriptors registered - * manually are visible from both {@link DescriptorList} and {@link ExtensionList}. In this mode, + * <p> The other mode is the new mode, where the {@link Descriptor}s are + * actually stored in {@link ExtensionList} (see + * {@link Hudson#getDescriptorList(Class)}) and this class acts as a view to it. + * This enables bi-directional interoperability — both descriptors + * registred automatically and descriptors registered manually are visible from + * both {@link DescriptorList} and {@link ExtensionList}. In this mode, * {@link #legacy} is null but {@link #type} is non-null. * - * <p> - * The number of plugins that define extension points are limited, so we expect to be able to remove - * this dual behavior first, then when everyone stops using {@link DescriptorList}, we can remove this class - * altogether. + * <p> The number of plugins that define extension points are limited, so we + * expect to be able to remove this dual behavior first, then when everyone + * stops using {@link DescriptorList}, we can remove this class altogether. * * @author Kohsuke Kawaguchi * @since 1.161 @@ -61,15 +60,13 @@ import java.util.concurrent.CopyOnWriteArrayList; public final class DescriptorList<T extends Describable<T>> extends AbstractList<Descriptor<T>> { private final Class<T> type; - private final CopyOnWriteArrayList<Descriptor<T>> legacy; /** - * This will create a legacy {@link DescriptorList} that is disconnected from - * {@link ExtensionList}. + * This will create a legacy {@link DescriptorList} that is disconnected + * from {@link ExtensionList}. * - * @deprecated - * As of 1.286. Use {@link #DescriptorList(Class)} instead. + * @deprecated As of 1.286. Use {@link #DescriptorList(Class)} instead. */ public DescriptorList(Descriptor<T>... descriptors) { this.type = null; @@ -102,9 +99,8 @@ public final class DescriptorList<T extends Describable<T>> extends AbstractList /** * {@inheritDoc} * - * @deprecated - * As of 1.286. Put {@link Extension} on your descriptor to have it auto-registered, - * instead of registering a descriptor manually. + * @deprecated As of 1.286. Put {@link Extension} on your descriptor to have + * it auto-registered, instead of registering a descriptor manually. */ @Override public boolean add(Descriptor<T> d) { @@ -114,9 +110,8 @@ public final class DescriptorList<T extends Describable<T>> extends AbstractList /** * {@inheritDoc} * - * @deprecated - * As of 1.286. Put {@link Extension} on your descriptor to have it auto-registered, - * instead of registering a descriptor manually. + * @deprecated As of 1.286. Put {@link Extension} on your descriptor to have + * it auto-registered, instead of registering a descriptor manually. */ @Override public void add(int index, Descriptor<T> element) { @@ -129,25 +124,27 @@ public final class DescriptorList<T extends Describable<T>> extends AbstractList } /** - * Gets the actual data store. This is the key to control the dual-mode nature of {@link DescriptorList} + * Gets the actual data store. This is the key to control the dual-mode + * nature of {@link DescriptorList} */ private List<Descriptor<T>> store() { - if(type==null) + if (type == null) { return legacy; - else - return Hudson.getInstance().<T,Descriptor<T>>getDescriptorList(type); + } else { + return Hudson.getInstance().<T, Descriptor<T>>getDescriptorList(type); + } } /** - * Creates a new instance of a {@link Describable} - * from the structured form submission data posted - * by a radio button group. + * Creates a new instance of a {@link Describable} from the structured form + * submission data posted by a radio button group. */ public T newInstanceFromRadioList(JSONObject config) throws FormException { - if(config.isNullObject()) + if (config.isNullObject()) { return null; // none was selected + } int idx = config.getInt("value"); - return get(idx).newInstance(Stapler.getCurrentRequest(),config); + return get(idx).newInstance(Stapler.getCurrentRequest(), config); } public T newInstanceFromRadioList(JSONObject parent, String name) throws FormException { @@ -160,21 +157,22 @@ public final class DescriptorList<T extends Describable<T>> extends AbstractList * If none is found, null is returned. */ public Descriptor<T> findByName(String id) { - for (Descriptor<T> d : this) - if(d.getId().equals(id)) + for (Descriptor<T> d : this) { + if (d.getId().equals(id)) { return d; + } + } return null; } /** * No-op method used to force the class initialization of the given class. - * The class initialization in turn is expected to put the descriptor - * into the {@link DescriptorList}. + * The class initialization in turn is expected to put the descriptor into + * the {@link DescriptorList}. * - * <p> - * This is necessary to resolve the class initialization order problem. - * Often a {@link DescriptorList} is defined in the base class, and - * when it tries to initialize itself by listing up descriptors of known + * <p> This is necessary to resolve the class initialization order problem. + * Often a {@link DescriptorList} is defined in the base class, and when it + * tries to initialize itself by listing up descriptors of known * sub-classes, they might not be available in time. * * @since 1.162 @@ -191,6 +189,6 @@ public final class DescriptorList<T extends Describable<T>> extends AbstractList * Finds the descriptor that has the matching fully-qualified class name. */ public Descriptor<T> find(String fqcn) { - return Descriptor.find(this,fqcn); + return Descriptor.find(this, fqcn); } } diff --git a/hudson-core/src/main/java/hudson/util/Digester2.java b/hudson-core/src/main/java/hudson/util/Digester2.java index 97cb543..14ad492 100644 --- a/hudson-core/src/main/java/hudson/util/Digester2.java +++ b/hudson-core/src/main/java/hudson/util/Digester2.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 - * + * * *******************************************************************************/ @@ -32,12 +32,14 @@ import org.xml.sax.Attributes; @Deprecated @RestrictedSince("2.1.2") public class Digester2 extends Digester { + @Override public void addObjectCreate(String pattern, Class clazz) { - addRule(pattern,new ObjectCreateRule2(clazz)); + addRule(pattern, new ObjectCreateRule2(clazz)); } private static final class ObjectCreateRule2 extends Rule { + private final Class clazz; public ObjectCreateRule2(Class clazz) { diff --git a/hudson-core/src/main/java/hudson/util/DirScanner.java b/hudson-core/src/main/java/hudson/util/DirScanner.java index 1d2d9df..a99847c 100644 --- a/hudson-core/src/main/java/hudson/util/DirScanner.java +++ b/hudson-core/src/main/java/hudson/util/DirScanner.java @@ -8,7 +8,7 @@ * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * + * * *******************************************************************************/ @@ -29,12 +29,14 @@ import static hudson.Util.fixEmpty; /** * Visits a directory and its contents and pass them to the {@link FileVisitor}. * - * A {@link DirScanner} encapsulates the logic of how it filters files in the directory. It is also remotable. + * A {@link DirScanner} encapsulates the logic of how it filters files in the + * directory. It is also remotable. * * @since 1.343 * @see FileVisitor */ public abstract class DirScanner implements Serializable { + /** * Scans the given directory and pass files onto the given visitor. */ @@ -44,6 +46,7 @@ public abstract class DirScanner implements Serializable { * Scans everything recursively. */ public static class Full extends DirScanner { + private void scan(File f, String path, FileVisitor visitor) throws IOException { if (f.canRead()) { if (visitor.understandsSymlink()) { @@ -51,20 +54,20 @@ public abstract class DirScanner implements Serializable { if (target != null) { visitor.visitSymlink(f, target, path + f.getName()); return; - } + } } - visitor.visit(f,path+f.getName()); - if(f.isDirectory()) { - for( File child : f.listFiles() ) - scan(child,path+f.getName()+'/',visitor); + visitor.visit(f, path + f.getName()); + if (f.isDirectory()) { + for (File child : f.listFiles()) { + scan(child, path + f.getName() + '/', visitor); + } } } } public void scan(File dir, FileVisitor visitor) throws IOException { - scan(dir,"",visitor); + scan(dir, "", visitor); } - private static final long serialVersionUID = 1L; } @@ -72,6 +75,7 @@ public abstract class DirScanner implements Serializable { * Scans by filtering things out from {@link FileFilter} */ public static class Filter extends Full { + private final FileFilter filter; public Filter(FileFilter filter) { @@ -80,9 +84,8 @@ public abstract class DirScanner implements Serializable { @Override public void scan(File dir, FileVisitor visitor) throws IOException { - super.scan(dir,visitor.with(filter)); + super.scan(dir, visitor.with(filter)); } - private static final long serialVersionUID = 1L; } @@ -90,6 +93,7 @@ public abstract class DirScanner implements Serializable { * Scans by using Ant GLOB syntax. */ public static class Glob extends DirScanner { + private final String includes, excludes; public Glob(String includes, String excludes) { @@ -98,25 +102,23 @@ public abstract class DirScanner implements Serializable { } public void scan(File dir, FileVisitor visitor) throws IOException { - if(fixEmpty(includes)==null && excludes==null) { + if (fixEmpty(includes) == null && excludes == null) { // optimization - new Full().scan(dir,visitor); + new Full().scan(dir, visitor); return; } - FileSet fs = Util.createFileSet(dir,includes,excludes); + FileSet fs = Util.createFileSet(dir, includes, excludes); - if(dir.exists()) { + if (dir.exists()) { DirectoryScanner ds = fs.getDirectoryScanner(new org.apache.tools.ant.Project()); - for( String f : ds.getIncludedFiles()) { + for (String f : ds.getIncludedFiles()) { File file = new File(dir, f); - visitor.visit(file,f); + visitor.visit(file, f); } } } - private static final long serialVersionUID = 1L; } - private static final long serialVersionUID = 1L; } diff --git a/hudson-core/src/main/java/hudson/util/DoubleLaunchChecker.java b/hudson-core/src/main/java/hudson/util/DoubleLaunchChecker.java index 7c10cbd..1301c3a 100644 --- a/hudson-core/src/main/java/hudson/util/DoubleLaunchChecker.java +++ b/hudson-core/src/main/java/hudson/util/DoubleLaunchChecker.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 + * * *******************************************************************************/ @@ -36,46 +36,42 @@ import java.lang.management.ManagementFactory; import java.lang.reflect.Method; /** - * Makes sure that no other Hudson uses our <tt>HUDSON_HOME</tt> directory, - * to forestall the problem of running multiple instances of Hudson that point to the same data directory. + * Makes sure that no other Hudson uses our <tt>HUDSON_HOME</tt> directory, to + * forestall the problem of running multiple instances of Hudson that point to + * the same data directory. * - * <p> - * This set up error occasionally happens especialy when the user is trying to reassign the context path of the app, - * and it results in a hard-to-diagnose error, so we actively check this. + * <p> This set up error occasionally happens especialy when the user is trying + * to reassign the context path of the app, and it results in a hard-to-diagnose + * error, so we actively check this. * - * <p> - * The mechanism is simple. This class occasionally updates a known file inside the hudson home directory, - * and whenever it does so, it monitors the timestamp of the file to make sure no one else is updating - * this file. In this way, while we cannot detect the problem right away, within a reasonable time frame - * we can detect the collision. + * <p> The mechanism is simple. This class occasionally updates a known file + * inside the hudson home directory, and whenever it does so, it monitors the + * timestamp of the file to make sure no one else is updating this file. In this + * way, while we cannot detect the problem right away, within a reasonable time + * frame we can detect the collision. * - * <p> - * More traditional way of doing this is to use a lock file with PID in it, but unfortunately in Java, - * there's no reliabe way to obtain PID. + * <p> More traditional way of doing this is to use a lock file with PID in it, + * but unfortunately in Java, there's no reliabe way to obtain PID. * * @author Kohsuke Kawaguchi * @since 1.178 */ public class DoubleLaunchChecker { + /** - * The timestamp of the owner file when we updated it for the last time. - * 0 to indicate that there was no update before. + * The timestamp of the owner file when we updated it for the last time. 0 + * to indicate that there was no update before. */ private long lastWriteTime = 0L; - /** - * Once the error is reported, the user can choose to ignore and proceed anyway, - * in which case the flag is set to true. + * Once the error is reported, the user can choose to ignore and proceed + * anyway, in which case the flag is set to true. */ private boolean ignore = false; - private final Random random = new Random(); - public final File home; - /** - * ID string of the other Hudson that we are colliding with. - * Can be null. + * ID string of the other Hudson that we are colliding with. Can be null. */ private String collidingId; @@ -84,10 +80,10 @@ public class DoubleLaunchChecker { } protected void execute() { - File timestampFile = new File(home,".owner"); + File timestampFile = new File(home, ".owner"); long t = timestampFile.lastModified(); - if(t!=0 && lastWriteTime!=0 && t!=lastWriteTime && !ignore) { + if (t != 0 && lastWriteTime != 0 && t != lastWriteTime && !ignore) { try { collidingId = FileUtils.readFileToString(timestampFile); } catch (IOException e) { @@ -96,7 +92,7 @@ public class DoubleLaunchChecker { // we noticed that someone else have updated this file. // switch GUI to display this error. WebAppController.get().install(this); - LOGGER.severe("Collision detected. timestamp="+t+", expected="+lastWriteTime); + LOGGER.severe("Collision detected. timestamp=" + t + ", expected=" + lastWriteTime); // we need to continue updating this file, so that the other Hudson would notice the problem, too. } @@ -105,7 +101,7 @@ public class DoubleLaunchChecker { lastWriteTime = timestampFile.lastModified(); } catch (IOException e) { // if failed to write, err on the safe side and assume things are OK. - lastWriteTime=0; + lastWriteTime = 0; } schedule(); @@ -118,15 +114,15 @@ public class DoubleLaunchChecker { Hudson h = Hudson.getInstance(); // in servlet 2.5, we can get the context path - String contextPath=""; + String contextPath = ""; try { Method m = ServletContext.class.getMethod("getContextPath"); - contextPath=" contextPath=\""+m.invoke(h.servletContext)+"\""; + contextPath = " contextPath=\"" + m.invoke(h.servletContext) + "\""; } catch (Exception e) { // maybe running with Servlet 2.4 } - return h.hashCode()+contextPath+" at "+ManagementFactory.getRuntimeMXBean().getName(); + return h.hashCode() + contextPath + " at " + ManagementFactory.getRuntimeMXBean().getName(); } public String getCollidingId() { @@ -138,12 +134,12 @@ public class DoubleLaunchChecker { */ public void schedule() { // randomize the scheduling so that multiple Hudson instances will write at the file at different time - long MINUTE = 1000*60; + long MINUTE = 1000 * 60; Trigger.timer.schedule(new SafeTimerTask() { protected void doRun() { execute(); } - },(random.nextInt(30)+60)*MINUTE); + }, (random.nextInt(30) + 60) * MINUTE); } /** @@ -151,7 +147,7 @@ public class DoubleLaunchChecker { */ public void doDynamic(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { rsp.setStatus(SC_INTERNAL_SERVER_ERROR); - req.getView(this,"index.jelly").forward(req,rsp); + req.getView(this, "index.jelly").forward(req, rsp); } /** @@ -160,8 +156,7 @@ public class DoubleLaunchChecker { public void doIgnore(StaplerRequest req, StaplerResponse rsp) throws IOException { ignore = true; WebAppController.get().install(Hudson.getInstance()); - rsp.sendRedirect2(req.getContextPath()+'/'); + rsp.sendRedirect2(req.getContextPath() + '/'); } - private static final Logger LOGGER = Logger.getLogger(DoubleLaunchChecker.class.getName()); } diff --git a/hudson-core/src/main/java/hudson/util/DualOutputStream.java b/hudson-core/src/main/java/hudson/util/DualOutputStream.java index 187401c..fdc47bd 100644 --- a/hudson-core/src/main/java/hudson/util/DualOutputStream.java +++ b/hudson-core/src/main/java/hudson/util/DualOutputStream.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 + * * *******************************************************************************/ @@ -23,7 +23,8 @@ import java.io.OutputStream; * @author Kohsuke Kawaguchi */ public class DualOutputStream extends OutputStream { - private final OutputStream lhs,rhs; + + private final OutputStream lhs, rhs; public DualOutputStream(OutputStream lhs, OutputStream rhs) { this.lhs = lhs; @@ -43,8 +44,8 @@ public class DualOutputStream extends OutputStream { @Override public void write(byte[] b, int off, int len) throws IOException { - lhs.write(b,off,len); - rhs.write(b,off,len); + lhs.write(b, off, len); + rhs.write(b, off, len); } @Override diff --git a/hudson-core/src/main/java/hudson/util/EditDistance.java b/hudson-core/src/main/java/hudson/util/EditDistance.java index a2b4b0a..9591bcd 100644 --- a/hudson-core/src/main/java/hudson/util/EditDistance.java +++ b/hudson-core/src/main/java/hudson/util/EditDistance.java @@ -20,36 +20,34 @@ import java.util.Arrays; /** * Computes the string edit distance. * - * <p> - * Refer to a computer science text book for the definition - * of the "string edit distance". + * <p> Refer to a computer science text book for the definition of the "string + * edit distance". * - * @author - * Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com) + * @author Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com) */ public class EditDistance { /** * Computes the edit distance between two strings. * - * <p> - * The complexity is O(nm) where n=a.length() and m=b.length(). + * <p> The complexity is O(nm) where n=a.length() and m=b.length(). */ - public static int editDistance( String a, String b ) { - return new EditDistance(a,b).calc(); + public static int editDistance(String a, String b) { + return new EditDistance(a, b).calc(); } /** - * Finds the string in the <code>group</code> closest to + * Finds the string in the + * <code>group</code> closest to * <code>key</code> and returns it. * * @return null if group.length==0. */ - public static String findNearest( String key, String[] group ) { - return findNearest(key,Arrays.asList(group)); + public static String findNearest(String key, String[] group) { + return findNearest(key, Arrays.asList(group)); } - public static String findNearest( String key, Collection<String> group ) { + public static String findNearest(String key, Collection<String> group) { int c = Integer.MAX_VALUE; String r = null; @@ -62,23 +60,28 @@ public class EditDistance { } return r; } - - /** cost vector. */ + /** + * cost vector. + */ private int[] cost; - /** back buffer. */ + /** + * back buffer. + */ private int[] back; + /** + * Two strings to be compared. + */ + private final String a, b; - /** Two strings to be compared. */ - private final String a,b; - - private EditDistance( String a, String b ) { - this.a=a; - this.b=b; - cost = new int[a.length()+1]; - back = new int[a.length()+1]; // back buffer + private EditDistance(String a, String b) { + this.a = a; + this.b = b; + cost = new int[a.length() + 1]; + back = new int[a.length() + 1]; // back buffer - for( int i=0; i<=a.length(); i++ ) + for (int i = 0; i <= a.length(); i++) { cost[i] = i; + } } /** @@ -90,17 +93,17 @@ public class EditDistance { back = t; } - private int min(int a,int b,int c) { - return Math.min(a,Math.min(b,c)); + private int min(int a, int b, int c) { + return Math.min(a, Math.min(b, c)); } private int calc() { - for( int j=0; j<b.length(); j++ ) { + for (int j = 0; j < b.length(); j++) { flip(); - cost[0] = j+1; - for( int i=0; i<a.length(); i++ ) { - int match = (a.charAt(i)==b.charAt(j))?0:1; - cost[i+1] = min( back[i]+match, cost[i]+1, back[i+1]+1 ); + cost[0] = j + 1; + for (int i = 0; i < a.length(); i++) { + int match = (a.charAt(i) == b.charAt(j)) ? 0 : 1; + cost[i + 1] = min(back[i] + match, cost[i] + 1, back[i + 1] + 1); } } return cost[a.length()]; diff --git a/hudson-core/src/main/java/hudson/util/EncodingStream.java b/hudson-core/src/main/java/hudson/util/EncodingStream.java index 3b324dc..fe2f7c0 100644 --- a/hudson-core/src/main/java/hudson/util/EncodingStream.java +++ b/hudson-core/src/main/java/hudson/util/EncodingStream.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,6 +29,7 @@ import java.io.OutputStream; * @see DecodingStream */ public class EncodingStream extends FilterOutputStream { + public EncodingStream(OutputStream out) { super(out); } @@ -38,6 +39,5 @@ public class EncodingStream extends FilterOutputStream { out.write(chars.charAt((b >> 4) & 0xF)); out.write(chars.charAt(b & 0xF)); } - private static final String chars = "0123456789ABCDEF"; } diff --git a/hudson-core/src/main/java/hudson/util/EnumConverter.java b/hudson-core/src/main/java/hudson/util/EnumConverter.java index 81592c4..2ea8d03 100644 --- a/hudson-core/src/main/java/hudson/util/EnumConverter.java +++ b/hudson-core/src/main/java/hudson/util/EnumConverter.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 + * * *******************************************************************************/ @@ -20,10 +20,12 @@ import org.apache.commons.beanutils.Converter; /** * {@link Converter} for enums. Used for form binding. + * * @author Kohsuke Kawaguchi */ public class EnumConverter implements Converter { + public Object convert(Class aClass, Object object) { - return Enum.valueOf(aClass,object.toString()); + return Enum.valueOf(aClass, object.toString()); } } diff --git a/hudson-core/src/main/java/hudson/util/ErrorObject.java b/hudson-core/src/main/java/hudson/util/ErrorObject.java index 41a498c..ec3310a 100644 --- a/hudson-core/src/main/java/hudson/util/ErrorObject.java +++ b/hudson-core/src/main/java/hudson/util/ErrorObject.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,9 @@ import java.io.IOException; * @author Kohsuke Kawaguchi */ public abstract class ErrorObject { + public void doDynamic(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException, InterruptedException { rsp.setStatus(SC_SERVICE_UNAVAILABLE); - req.getView(this,"index.jelly").forward(req,rsp); + req.getView(this, "index.jelly").forward(req, rsp); } } diff --git a/hudson-core/src/main/java/hudson/util/ExceptionCatchingThreadFactory.java b/hudson-core/src/main/java/hudson/util/ExceptionCatchingThreadFactory.java index 83b1ea6..d4b1268 100644 --- a/hudson-core/src/main/java/hudson/util/ExceptionCatchingThreadFactory.java +++ b/hudson-core/src/main/java/hudson/util/ExceptionCatchingThreadFactory.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 + * * *******************************************************************************/ @@ -22,13 +22,14 @@ import java.util.logging.Logger; import java.util.logging.Level; /** - * {@link ThreadFactory} that creates a thread, which in turn displays a stack trace - * when it terminates unexpectedly. + * {@link ThreadFactory} that creates a thread, which in turn displays a stack + * trace when it terminates unexpectedly. * * @author Kohsuke Kawaguchi * @since 1.226 */ public class ExceptionCatchingThreadFactory implements ThreadFactory, Thread.UncaughtExceptionHandler { + private final ThreadFactory core; public ExceptionCatchingThreadFactory() { @@ -46,8 +47,7 @@ public class ExceptionCatchingThreadFactory implements ThreadFactory, Thread.Unc } public void uncaughtException(Thread t, Throwable e) { - LOGGER.log(Level.WARNING, "Thread "+t.getName()+" terminated unexpectedly",e); + LOGGER.log(Level.WARNING, "Thread " + t.getName() + " terminated unexpectedly", e); } - private static final Logger LOGGER = Logger.getLogger(ExceptionCatchingThreadFactory.class.getName()); } diff --git a/hudson-core/src/main/java/hudson/util/FileVisitor.java b/hudson-core/src/main/java/hudson/util/FileVisitor.java index 1d7b145..dad7bc9 100644 --- a/hudson-core/src/main/java/hudson/util/FileVisitor.java +++ b/hudson-core/src/main/java/hudson/util/FileVisitor.java @@ -8,7 +8,7 @@ * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * + * * *******************************************************************************/ @@ -26,64 +26,67 @@ import java.io.Serializable; * @see DirScanner */ public abstract class FileVisitor { + /** - * Called for each file and directory that matches the criteria implied by {@link DirScanner} + * Called for each file and directory that matches the criteria implied by + * {@link DirScanner} * - * @param f - * Either a file or a directory. - * @param relativePath - * The file/directory name in question + * @param f Either a file or a directory. + * @param relativePath The file/directory name in question */ public abstract void visit(File f, String relativePath) throws IOException; /** - * Some visitors can handle symlinks as symlinks. Those visitors should implement - * this method to provide a different handling for symlink. - * <p> - * This method is invoked by those {@link DirScanner}s that can handle symlinks as symlinks - * (not every {@link DirScanner}s are capable of doing that, as proper symlink handling requires - * letting visitors decide whether or not to descend into a symlink directory. + * Some visitors can handle symlinks as symlinks. Those visitors should + * implement this method to provide a different handling for symlink. <p> + * This method is invoked by those {@link DirScanner}s that can handle + * symlinks as symlinks (not every {@link DirScanner}s are capable of doing + * that, as proper symlink handling requires letting visitors decide whether + * or not to descend into a symlink directory. */ public void visitSymlink(File link, String target, String relativePath) throws IOException { - visit(link,relativePath); + visit(link, relativePath); } /** - * Some visitors can handle symlinks as symlinks. Those visitors should implement - * this method and return true to have callers invoke {@link #visitSymlink(File, String, String)} + * Some visitors can handle symlinks as symlinks. Those visitors should + * implement this method and return true to have callers invoke + * {@link #visitSymlink(File, String, String)} */ public boolean understandsSymlink() { return false; } - + /** * Decorates a visitor by a given filter. */ public final FileVisitor with(FileFilter f) { - if(f==null) return this; - return new FilterFileVisitor(f,this); + if (f == null) { + return this; + } + return new FilterFileVisitor(f, this); } private static final class FilterFileVisitor extends FileVisitor implements Serializable { + private final FileFilter filter; private final FileVisitor visitor; private FilterFileVisitor(FileFilter filter, FileVisitor visitor) { - this.filter = filter!=null ? filter : PASS_THROUGH; + this.filter = filter != null ? filter : PASS_THROUGH; this.visitor = visitor; } public void visit(File f, String relativePath) throws IOException { - if(f.isDirectory() || filter.accept(f)) - visitor.visit(f,relativePath); + if (f.isDirectory() || filter.accept(f)) { + visitor.visit(f, relativePath); + } } - private static final FileFilter PASS_THROUGH = new FileFilter() { public boolean accept(File pathname) { return true; } }; - private static final long serialVersionUID = 1L; } } diff --git a/hudson-core/src/main/java/hudson/util/FlushProofOutputStream.java b/hudson-core/src/main/java/hudson/util/FlushProofOutputStream.java index 848519d..9c50396 100644 --- a/hudson-core/src/main/java/hudson/util/FlushProofOutputStream.java +++ b/hudson-core/src/main/java/hudson/util/FlushProofOutputStream.java @@ -8,7 +8,7 @@ * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * + * * *******************************************************************************/ @@ -19,10 +19,12 @@ import java.io.OutputStream; /** * {@link OutputStream} that blocks {@link #flush()} method. + * * @author Kohsuke Kawaguchi * @since 1.349 */ public class FlushProofOutputStream extends DelegatingOutputStream { + public FlushProofOutputStream(OutputStream out) { super(out); } @@ -31,4 +33,3 @@ public class FlushProofOutputStream extends DelegatingOutputStream { public void flush() throws IOException { } } - diff --git a/hudson-core/src/main/java/hudson/util/ForkOutputStream.java b/hudson-core/src/main/java/hudson/util/ForkOutputStream.java index da75aac..28e5169 100644 --- a/hudson-core/src/main/java/hudson/util/ForkOutputStream.java +++ b/hudson-core/src/main/java/hudson/util/ForkOutputStream.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 + * * *******************************************************************************/ @@ -23,6 +23,7 @@ import java.io.OutputStream; * @author Kohsuke Kawaguchi */ public class ForkOutputStream extends OutputStream { + private final OutputStream lhs; private final OutputStream rhs; diff --git a/hudson-core/src/main/java/hudson/util/FormFieldValidator.java b/hudson-core/src/main/java/hudson/util/FormFieldValidator.java index b62d79a..a560fa8 100644 --- a/hudson-core/src/main/java/hudson/util/FormFieldValidator.java +++ b/hudson-core/src/main/java/hudson/util/FormFieldValidator.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, Tom Huybrechts - * + * * *******************************************************************************/ @@ -44,63 +44,63 @@ import org.springframework.security.AccessDeniedException; import org.kohsuke.stapler.Stapler; /** - * Base class that provides the framework for doing on-the-fly form field validation. + * Base class that provides the framework for doing on-the-fly form field + * validation. * - * <p> - * The {@link #check()} method is to be implemented by derived classes to perform - * the validation. See hudson-behavior.js 'validated' CSS class and 'checkUrl' attribute. + * <p> The {@link #check()} method is to be implemented by derived classes to + * perform the validation. See hudson-behavior.js 'validated' CSS class and + * 'checkUrl' attribute. * * @author Kohsuke Kawaguchi - * @deprecated as of 1.294 - * Use {@link FormValidation} as a return value in your check method. + * @deprecated as of 1.294 Use {@link FormValidation} as a return value in your + * check method. */ public abstract class FormFieldValidator { - public static final Permission CHECK = Hudson.ADMINISTER; + public static final Permission CHECK = Hudson.ADMINISTER; protected final StaplerRequest request; protected final StaplerResponse response; /** - * Permission to check, or null if this check doesn't require any permission. + * Permission to check, or null if this check doesn't require any + * permission. */ protected final Permission permission; - /** - * The object to which the permission is checked against. - * If {@link #permission} is non-null, must be non-null. + * The object to which the permission is checked against. If + * {@link #permission} is non-null, must be non-null. */ protected final AccessControlled subject; /** - * @param adminOnly - * Pass true to only let admin users to run the check. This is necessary - * for security reason, so that unauthenticated user cannot obtain sensitive - * information or run a process that may have side-effect. + * @param adminOnly Pass true to only let admin users to run the check. This + * is necessary for security reason, so that unauthenticated user cannot + * obtain sensitive information or run a process that may have side-effect. */ protected FormFieldValidator(StaplerRequest request, StaplerResponse response, boolean adminOnly) { - this(request, response, adminOnly?Hudson.getInstance():null, adminOnly?CHECK:null); + this(request, response, adminOnly ? Hudson.getInstance() : null, adminOnly ? CHECK : null); } /** - * @deprecated - * Use {@link #FormFieldValidator(Permission)} and remove {@link StaplerRequest} and {@link StaplerResponse} - * from your "doCheck..." method parameter + * @deprecated Use {@link #FormFieldValidator(Permission)} and remove + * {@link StaplerRequest} and {@link StaplerResponse} from your "doCheck..." + * method parameter */ protected FormFieldValidator(StaplerRequest request, StaplerResponse response, Permission permission) { - this(request,response,Hudson.getInstance(),permission); + this(request, response, Hudson.getInstance(), permission); } /** - * @param permission - * Permission needed to perform this validation, or null if no permission is necessary. + * @param permission Permission needed to perform this validation, or null + * if no permission is necessary. */ protected FormFieldValidator(Permission permission) { - this(Stapler.getCurrentRequest(),Stapler.getCurrentResponse(),permission); + this(Stapler.getCurrentRequest(), Stapler.getCurrentResponse(), permission); } /** - * @deprecated - * Use {@link #FormFieldValidator(AccessControlled,Permission)} and remove {@link StaplerRequest} and {@link StaplerResponse} - * from your "doCheck..." method parameter + * @deprecated Use {@link #FormFieldValidator(AccessControlled,Permission)} + * and remove {@link StaplerRequest} and {@link StaplerResponse} from your + * "doCheck..." method parameter */ protected FormFieldValidator(StaplerRequest request, StaplerResponse response, AccessControlled subject, Permission permission) { this.request = request; @@ -110,24 +110,27 @@ public abstract class FormFieldValidator { } protected FormFieldValidator(AccessControlled subject, Permission permission) { - this(Stapler.getCurrentRequest(),Stapler.getCurrentResponse(),subject,permission); + this(Stapler.getCurrentRequest(), Stapler.getCurrentResponse(), subject, permission); } /** * Runs the validation code. */ public final void process() throws IOException, ServletException { - if(permission!=null) + if (permission != null) { try { - if(subject==null) + if (subject == null) { throw new AccessDeniedException("No subject"); + } subject.checkPermission(permission); } catch (AccessDeniedException e) { // if the user has hudson-wisde admin permission, all checks are allowed // this is to protect Hudson administrator from broken ACL/SecurityRealm implementation/configuration. - if(!Hudson.getInstance().hasPermission(Hudson.ADMINISTER)) + if (!Hudson.getInstance().hasPermission(Hudson.ADMINISTER)) { throw e; + } } + } check(); } @@ -159,78 +162,74 @@ public abstract class FormFieldValidator { /** * Sends out a string error message that indicates an error. * - * @param message - * Human readable message to be sent. <tt>error(null)</tt> - * can be used as <tt>ok()</tt>. + * @param message Human readable message to be sent. <tt>error(null)</tt> + * can be used as <tt>ok()</tt>. */ public void error(String message) throws IOException, ServletException { - errorWithMarkup(message==null?null:Util.escape(message)); + errorWithMarkup(message == null ? null : Util.escape(message)); } public void warning(String message) throws IOException, ServletException { - warningWithMarkup(message==null?null:Util.escape(message)); + warningWithMarkup(message == null ? null : Util.escape(message)); } public void ok(String message) throws IOException, ServletException { - okWithMarkup(message==null?null:Util.escape(message)); + okWithMarkup(message == null ? null : Util.escape(message)); } /** - * Sends out a string error message that indicates an error, - * by formatting it with {@link String#format(String, Object[])} + * Sends out a string error message that indicates an error, by formatting + * it with {@link String#format(String, Object[])} */ public void error(String format, Object... args) throws IOException, ServletException { - error(String.format(format,args)); + error(String.format(format, args)); } public void warning(String format, Object... args) throws IOException, ServletException { - warning(String.format(format,args)); + warning(String.format(format, args)); } public void ok(String format, Object... args) throws IOException, ServletException { - ok(String.format(format,args)); + ok(String.format(format, args)); } /** * Sends out an HTML fragment that indicates an error. * - * <p> - * This method must be used with care to avoid cross-site scripting + * <p> This method must be used with care to avoid cross-site scripting * attack. * - * @param message - * Human readable message to be sent. <tt>error(null)</tt> - * can be used as <tt>ok()</tt>. + * @param message Human readable message to be sent. <tt>error(null)</tt> + * can be used as <tt>ok()</tt>. */ public void errorWithMarkup(String message) throws IOException, ServletException { - _errorWithMarkup(message,"error"); + _errorWithMarkup(message, "error"); } public void warningWithMarkup(String message) throws IOException, ServletException { - _errorWithMarkup(message,"warning"); + _errorWithMarkup(message, "warning"); } public void okWithMarkup(String message) throws IOException, ServletException { - _errorWithMarkup(message,"ok"); + _errorWithMarkup(message, "ok"); } private void _errorWithMarkup(String message, String cssClass) throws IOException, ServletException { - if(message==null) { + if (message == null) { ok(); } else { response.setContentType("text/html;charset=UTF-8"); // 1x16 spacer needed for IE since it doesn't support min-height - response.getWriter().print("<div class="+ cssClass +"><img src='"+ - request.getContextPath()+Hudson.RESOURCE_PATH+"/images/none.gif' height=16 width=1>"+ - message+"</div>"); + response.getWriter().print("<div class=" + cssClass + "><img src='" + + request.getContextPath() + Hudson.RESOURCE_PATH + "/images/none.gif' height=16 width=1>" + + message + "</div>"); } } /** * Convenient base class for checking the validity of URLs * - * @deprecated as of 1.294 - * Use {@link FormValidation.URLCheck} + * @deprecated as of 1.294 Use {@link FormValidation.URLCheck} */ public static abstract class URLCheck extends FormFieldValidator { @@ -241,8 +240,8 @@ public abstract class FormFieldValidator { } /** - * Opens the given URL and reads text content from it. - * This method honors Content-type header. + * Opens the given URL and reads text content from it. This method + * honors Content-type header. */ protected BufferedReader open(URL url) throws IOException { // use HTTP content type to find out the charset. @@ -251,46 +250,51 @@ public abstract class FormFieldValidator { throw new IOException(url.toExternalForm()); } return new BufferedReader( - new InputStreamReader(con.getInputStream(),getCharset(con))); + new InputStreamReader(con.getInputStream(), getCharset(con))); } /** * Finds the string literal from the given reader. - * @return - * true if found, false otherwise. + * + * @return true if found, false otherwise. */ protected boolean findText(BufferedReader in, String literal) throws IOException { String line; - while((line=in.readLine())!=null) - if(line.indexOf(literal)!=-1) + while ((line = in.readLine()) != null) { + if (line.indexOf(literal) != -1) { return true; + } + } return false; } /** - * Calls the {@link #error(String)} method with a reasonable error message. - * Use this method when the {@link #open(URL)} or {@link #findText(BufferedReader, String)} fails. + * Calls the {@link #error(String)} method with a reasonable error + * message. Use this method when the {@link #open(URL)} or + * {@link #findText(BufferedReader, String)} fails. * - * @param url - * Pass in the URL that was connected. Used for error diagnosis. + * @param url Pass in the URL that was connected. Used for error + * diagnosis. */ protected void handleIOException(String url, IOException e) throws IOException, ServletException { // any invalid URL comes here - if(e.getMessage().equals(url)) - // Sun JRE (and probably others too) often return just the URL in the error. - error("Unable to connect "+url); - else + if (e.getMessage().equals(url)) // Sun JRE (and probably others too) often return just the URL in the error. + { + error("Unable to connect " + url); + } else { error(e.getMessage()); + } } /** * Figures out the charset from the content-type header. */ private String getCharset(URLConnection con) { - for( String t : con.getContentType().split(";") ) { + for (String t : con.getContentType().split(";")) { t = t.trim().toLowerCase(Locale.ENGLISH); - if(t.startsWith("charset=")) + if (t.startsWith("charset=")) { return t.substring(8); + } } // couldn't find it. HTML spec says default is US-ASCII, // but UTF-8 is a better choice since @@ -302,35 +306,39 @@ public abstract class FormFieldValidator { /** * Checks if the given value is an URL to some Hudson's top page. + * * @since 1.192 */ public static class HudsonURL extends URLCheck { + public HudsonURL(StaplerRequest request, StaplerResponse response) { super(request, response); } protected void check() throws IOException, ServletException { String value = fixEmpty(request.getParameter("value")); - if(value==null) {// nothing entered yet + if (value == null) {// nothing entered yet ok(); return; } - if(!value.endsWith("/")) value+='/'; + if (!value.endsWith("/")) { + value += '/'; + } try { URL url = new URL(value); - HttpURLConnection con = (HttpURLConnection)url.openConnection(); + HttpURLConnection con = (HttpURLConnection) url.openConnection(); con.connect(); - if(con.getResponseCode()!=200 - || con.getHeaderField("X-Hudson")==null) { - error(value+" is not Hudson ("+con.getResponseMessage()+")"); + if (con.getResponseCode() != 200 + || con.getHeaderField("X-Hudson") == null) { + error(value + " is not Hudson (" + con.getResponseMessage() + ")"); return; } ok(); } catch (IOException e) { - handleIOException(value,e); + handleIOException(value, e); } } } @@ -338,10 +346,13 @@ public abstract class FormFieldValidator { /** * Checks the file mask (specified in the 'value' query parameter) against * the current workspace. + * * @since 1.90. - * @deprecated as of 1.294. Use {@link FilePath#validateFileMask(String, boolean)} + * @deprecated as of 1.294. Use + * {@link FilePath#validateFileMask(String, boolean)} */ public static class WorkspaceFileMask extends FormFieldValidator { + private final boolean errorIfNotExist; public WorkspaceFileMask(StaplerRequest request, StaplerResponse response) { @@ -356,9 +367,9 @@ public abstract class FormFieldValidator { protected void check() throws IOException, ServletException { String value = fixEmpty(request.getParameter("value")); - AbstractProject<?,?> p = (AbstractProject<?,?>)subject; + AbstractProject<?, ?> p = (AbstractProject<?, ?>) subject; - if(value==null || p==null) { + if (value == null || p == null) { ok(); // none entered yet, or something is seriously wrong return; } @@ -366,14 +377,17 @@ public abstract class FormFieldValidator { try { FilePath ws = getBaseDirectory(p); - if(ws==null || !ws.exists()) {// no workspace. can't check + if (ws == null || !ws.exists()) {// no workspace. can't check ok(); return; } String msg = ws.validateAntFileMask(value); - if(errorIfNotExist) error(msg); - else warning(msg); + if (errorIfNotExist) { + error(msg); + } else { + warning(msg); + } } catch (InterruptedException e) { ok(); // coundn't check } @@ -382,19 +396,22 @@ public abstract class FormFieldValidator { /** * The base directory from which the path name is resolved. */ - protected FilePath getBaseDirectory(AbstractProject<?,?> p) { + protected FilePath getBaseDirectory(AbstractProject<?, ?> p) { return p.getSomeWorkspace(); } } /** - * Checks a valid directory name (specified in the 'value' query parameter) against - * the current workspace. + * Checks a valid directory name (specified in the 'value' query parameter) + * against the current workspace. + * * @since 1.116 - * @deprecated as of 1.294. Use {@link FilePath#validateRelativeDirectory(String, boolean)} - * (see {@link hudson.tasks.JavadocArchiver.DescriptorImpl#doCheck(AbstractProject, String)} + * @deprecated as of 1.294. Use + * {@link FilePath#validateRelativeDirectory(String, boolean)} (see + * {@link hudson.tasks.JavadocArchiver.DescriptorImpl#doCheck(AbstractProject, String)} */ public static class WorkspaceDirectory extends WorkspaceFilePath { + public WorkspaceDirectory(StaplerRequest request, StaplerResponse response, boolean errorIfNotExist) { super(request, response, errorIfNotExist, false); } @@ -405,12 +422,15 @@ public abstract class FormFieldValidator { } /** - * Checks a valid file name or directory (specified in the 'value' query parameter) against - * the current workspace. + * Checks a valid file name or directory (specified in the 'value' query + * parameter) against the current workspace. + * * @since 1.160 - * @deprecated as of 1.294. Use {@link FilePath#validateRelativePath(String, boolean, boolean)} + * @deprecated as of 1.294. Use + * {@link FilePath#validateRelativePath(String, boolean, boolean)} */ public static class WorkspaceFilePath extends FormFieldValidator { + private final boolean errorIfNotExist; private final boolean expectingFile; @@ -423,14 +443,14 @@ public abstract class FormFieldValidator { protected void check() throws IOException, ServletException { String value = fixEmpty(request.getParameter("value")); - AbstractProject<?,?> p = (AbstractProject<?,?>)subject; + AbstractProject<?, ?> p = (AbstractProject<?, ?>) subject; - if(value==null || p==null) { + if (value == null || p == null) { ok(); // none entered yet, or something is seriously wrong return; } - if(value.contains("*")) { + if (value.contains("*")) { // a common mistake is to use wildcard error("Wildcard is not allowed here"); return; @@ -439,32 +459,37 @@ public abstract class FormFieldValidator { try { FilePath ws = getBaseDirectory(p); - if(ws==null) {// can't check + if (ws == null) {// can't check ok(); return; } - if(!ws.exists()) {// no workspace. can't check + if (!ws.exists()) {// no workspace. can't check ok(); return; } - if(ws.child(value).exists()) { + if (ws.child(value).exists()) { if (expectingFile) { - if(!ws.child(value).isDirectory()) + if (!ws.child(value).isDirectory()) { ok(); - else - error(value+" is not a file"); + } else { + error(value + " is not a file"); + } } else { - if(ws.child(value).isDirectory()) + if (ws.child(value).isDirectory()) { ok(); - else - error(value+" is not a directory"); + } else { + error(value + " is not a directory"); + } } } else { - String msg = "No such "+(expectingFile?"file":"directory")+": " + value; - if(errorIfNotExist) error(msg); - else warning(msg); + String msg = "No such " + (expectingFile ? "file" : "directory") + ": " + value; + if (errorIfNotExist) { + error(msg); + } else { + warning(msg); + } } } catch (InterruptedException e) { ok(); // coundn't check @@ -474,24 +499,24 @@ public abstract class FormFieldValidator { /** * The base directory from which the path name is resolved. */ - protected FilePath getBaseDirectory(AbstractProject<?,?> p) { + protected FilePath getBaseDirectory(AbstractProject<?, ?> p) { return p.getSomeWorkspace(); } } /** - * Checks a valid executable binary (specified in the 'value' query parameter). - * It has to be either given as a full path to the executable, or else - * it will be searched in PATH. + * Checks a valid executable binary (specified in the 'value' query + * parameter). It has to be either given as a full path to the executable, + * or else it will be searched in PATH. * - * <p> - * This file also handles ".exe" omission in Windows --- I thought Windows - * has actually more generic mechanism for the executable extension omission, - * so perhaps this needs to be extended to handle that correctly. More info - * needed. + * <p> This file also handles ".exe" omission in Windows --- I thought + * Windows has actually more generic mechanism for the executable extension + * omission, so perhaps this needs to be extended to handle that correctly. + * More info needed. * * @since 1.124 - * @deprecated as of 1.294. Use {@link FormValidation#validateExecutable(String)} + * @deprecated as of 1.294. Use + * {@link FormValidation#validateExecutable(String)} */ public static class Executable extends FormFieldValidator { @@ -502,70 +527,69 @@ public abstract class FormFieldValidator { protected void check() throws IOException, ServletException { String exe = fixEmpty(request.getParameter("value")); - if(exe==null) { + if (exe == null) { ok(); // nothing entered yet return; } - if(exe.indexOf(File.separatorChar)>=0) { + if (exe.indexOf(File.separatorChar) >= 0) { // this is full path File f = new File(exe); - if(f.exists()) { + if (f.exists()) { checkExecutable(f); return; } - File fexe = new File(exe+".exe"); - if(fexe.exists()) { + File fexe = new File(exe + ".exe"); + if (fexe.exists()) { checkExecutable(fexe); return; } - error("There's no such file: "+exe); + error("There's no such file: " + exe); } else { // look in PATH String path = EnvVars.masterEnvVars.get("PATH"); String tokenizedPath = ""; String delimiter = null; - if(path!=null) { - for (String _dir : Util.tokenize(path.replace("\\", "\\\\"),File.pathSeparator)) { + if (path != null) { + for (String _dir : Util.tokenize(path.replace("\\", "\\\\"), File.pathSeparator)) { if (delimiter == null) { - delimiter = ", "; - } - else { - tokenizedPath += delimiter; + delimiter = ", "; + } else { + tokenizedPath += delimiter; } tokenizedPath += _dir.replace('\\', '/'); - + File dir = new File(_dir); - File f = new File(dir,exe); - if(f.exists()) { + File f = new File(dir, exe); + if (f.exists()) { checkExecutable(f); return; } - File fexe = new File(dir,exe+".exe"); - if(fexe.exists()) { + File fexe = new File(dir, exe + ".exe"); + if (fexe.exists()) { checkExecutable(fexe); return; } } - + tokenizedPath += "."; - } - else { - tokenizedPath = "unavailable."; + } else { + tokenizedPath = "unavailable."; } // didn't find it - error("There's no such executable "+exe+" in PATH: "+tokenizedPath); + error("There's no such executable " + exe + " in PATH: " + tokenizedPath); } } /** - * Provides an opportunity for derived classes to do additional checks on the executable. + * Provides an opportunity for derived classes to do additional checks + * on the executable. */ protected void checkExecutable(File exe) throws IOException, ServletException { ok(); @@ -576,10 +600,12 @@ public abstract class FormFieldValidator { * Verifies that the 'value' parameter is correct base64 encoded text. * * @since 1.257 - * @deprecated as of 1.305 - * Use {@link FormValidation#validateBase64(String, boolean, boolean, String)} instead. + * @deprecated as of 1.305 Use + * {@link FormValidation#validateBase64(String, boolean, boolean, String)} + * instead. */ public static class Base64 extends FormFieldValidator { + private final boolean allowWhitespace; private final boolean allowEmpty; private final String errorMessage; @@ -594,18 +620,18 @@ public abstract class FormFieldValidator { protected void check() throws IOException, ServletException { try { String v = request.getParameter("value"); - if(!allowWhitespace) { - if(v.indexOf(' ')>=0 || v.indexOf('\n')>=0) { + if (!allowWhitespace) { + if (v.indexOf(' ') >= 0 || v.indexOf('\n') >= 0) { fail(); return; } } - v=v.trim(); - if(!allowEmpty && v.length()==0) { + v = v.trim(); + if (!allowEmpty && v.length() == 0) { fail(); return; } - + org.apache.commons.codec.binary.Base64.decodeBase64(v); ok(); } catch (IOException e) { @@ -622,10 +648,11 @@ public abstract class FormFieldValidator { * Verifies that the 'value' parameter is an integer >= 0. * * @since 1.282 - * @deprecated as of 1.294 - * Use {@link FormValidation#validateNonNegativeInteger(String)} + * @deprecated as of 1.294 Use + * {@link FormValidation#validateNonNegativeInteger(String)} */ public static class NonNegativeInteger extends FormFieldValidator { + public NonNegativeInteger() { super(null); } @@ -633,10 +660,11 @@ public abstract class FormFieldValidator { protected void check() throws IOException, ServletException { try { String value = request.getParameter("value"); - if(Integer.parseInt(value)<0) + if (Integer.parseInt(value) < 0) { error(hudson.model.Messages.Hudson_NotAPositiveNumber()); - else + } else { ok(); + } } catch (NumberFormatException e) { error(hudson.model.Messages.Hudson_NotANumber()); } diff --git a/hudson-core/src/main/java/hudson/util/FormValidation.java b/hudson-core/src/main/java/hudson/util/FormValidation.java index e3c953e..b098756 100644 --- a/hudson-core/src/main/java/hudson/util/FormValidation.java +++ b/hudson-core/src/main/java/hudson/util/FormValidation.java @@ -7,10 +7,10 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: + * Contributors: + * + * * - * - * * *******************************************************************************/ @@ -41,23 +41,23 @@ import org.apache.commons.codec.binary.Base64; /** * Represents the result of the form field validation. * - * <p> - * Use one of the factory methods to create an instance, then return it from your <tt>doCheckXyz</tt> - * method. (Via {@link HttpResponse}, the returned object will render the result into {@link StaplerResponse}.) - * This way of designing form field validation allows you to reuse {@code doCheckXyz()} methods - * programmatically as well (by using {@link #kind}. + * <p> Use one of the factory methods to create an instance, then return it from + * your <tt>doCheckXyz</tt> method. (Via {@link HttpResponse}, the returned + * object will render the result into {@link StaplerResponse}.) This way of + * designing form field validation allows you to reuse {@code doCheckXyz()} + * methods programmatically as well (by using {@link #kind}. * - * <p> - * For typical validation needs, this class offers a number of {@code validateXXX(...)} methods, such as - * {@link #validateExecutable(String)}. {@link FilePath} also has a number of {@code validateXXX(...)} methods - * that you may be able to reuse. + * <p> For typical validation needs, this class offers a number of + * {@code validateXXX(...)} methods, such as + * {@link #validateExecutable(String)}. {@link FilePath} also has a number of + * {@code validateXXX(...)} methods that you may be able to reuse. * - * <p> - * Also see {@link CVSSCM.DescriptorImpl#doCheckCvsRoot(String)} as an example. + * <p> Also see {@link CVSSCM.DescriptorImpl#doCheckCvsRoot(String)} as an + * example. * - * <p> - * This class extends {@link IOException} so that it can be thrown from a method. This allows one to reuse - * the checking logic as a part of the real computation, such as: + * <p> This class extends {@link IOException} so that it can be thrown from a + * method. This allows one to reuse the checking logic as a part of the real + * computation, such as: * * <pre> * String getAntVersion(File antHome) throws FormValidation { @@ -69,37 +69,36 @@ import org.apache.commons.codec.binary.Base64; * * ... * - * public FormValidation doCheckAntVersion(@QueryParameter String f) { - * try { - * return ok(getAntVersion(new File(f))); - * } catch (FormValidation f) { - * return f; - * } - * } + * public FormValidation doCheckAntVersion( + * + * @QueryParameter String f) { try { return ok(getAntVersion(new File(f))); } + * catch (FormValidation f) { return f; } } * * ... * - * public void {@linkplain hudson.tasks.Builder#perform(hudson.model.AbstractBuild, hudson.Launcher, hudson.model.BuildListener) perform}(...) { - * String version = getAntVersion(antHome); - * ... - * } + * public void + * {@linkplain hudson.tasks.Builder#perform(hudson.model.AbstractBuild, hudson.Launcher, hudson.model.BuildListener) perform}(...) + * { String version = getAntVersion(antHome); ... } * </pre> * * @author Kohsuke Kawaguchi * @since 1.294 */ public abstract class FormValidation extends IOException implements HttpResponse { + /** * Indicates the kind of result. */ public enum Kind { + /** * Form field value was OK and no problem was detected. */ OK, /** - * Form field value contained something suspicious. For some limited use cases - * the value could be valid, but we suspect the user made a mistake. + * Form field value contained something suspicious. For some limited use + * cases the value could be valid, but we suspect the user made a + * mistake. */ WARNING, /** @@ -111,53 +110,52 @@ public abstract class FormValidation extends IOException implements HttpResponse /** * Sends out a string error message that indicates an error. * - * @param message - * Human readable message to be sent. <tt>error(null)</tt> - * can be used as <tt>ok()</tt>. + * @param message Human readable message to be sent. <tt>error(null)</tt> + * can be used as <tt>ok()</tt>. */ public static FormValidation error(String message) { - return errorWithMarkup(message==null?null: Util.escape(message)); + return errorWithMarkup(message == null ? null : Util.escape(message)); } public static FormValidation warning(String message) { - return warningWithMarkup(message==null?null:Util.escape(message)); + return warningWithMarkup(message == null ? null : Util.escape(message)); } public static FormValidation ok(String message) { - return okWithMarkup(message==null?null:Util.escape(message)); + return okWithMarkup(message == null ? null : Util.escape(message)); } - /** * Singleton instance that represents "OK". */ - private static final FormValidation OK = respond(Kind.OK,"<div/>"); + private static final FormValidation OK = respond(Kind.OK, "<div/>"); public static FormValidation ok() { return OK; } /** - * Sends out a string error message that indicates an error, - * by formatting it with {@link String#format(String, Object[])} + * Sends out a string error message that indicates an error, by formatting + * it with {@link String#format(String, Object[])} */ public static FormValidation error(String format, Object... args) { - return error(String.format(format,args)); + return error(String.format(format, args)); } public static FormValidation warning(String format, Object... args) { - return warning(String.format(format,args)); + return warning(String.format(format, args)); } public static FormValidation ok(String format, Object... args) { - return ok(String.format(format,args)); + return ok(String.format(format, args)); } /** - * Sends out a string error message, with optional "show details" link that expands to the full stack trace. + * Sends out a string error message, with optional "show details" link that + * expands to the full stack trace. * - * <p> - * Use this with caution, so that anonymous users do not gain too much insights into the state of the system, - * as error stack trace often reveals a lot of information. Consider if a check operation needs to be exposed + * <p> Use this with caution, so that anonymous users do not gain too much + * insights into the state of the system, as error stack trace often reveals + * a lot of information. Consider if a check operation needs to be exposed * to everyone or just those who have higher access to job/hudson/etc. */ public static FormValidation error(Throwable e, String message) { @@ -169,59 +167,57 @@ public abstract class FormValidation extends IOException implements HttpResponse } private static FormValidation _error(Kind kind, Throwable e, String message) { - if (e==null) return _errorWithMarkup(Util.escape(message),kind); - - return _errorWithMarkup(Util.escape(message)+ - " <a href='#' class='showDetails'>" - + Messages.FormValidation_Error_Details() - + "</a><pre style='display:none'>" - + Functions.printThrowable(e) + - "</pre>",kind - ); + if (e == null) { + return _errorWithMarkup(Util.escape(message), kind); + } + + return _errorWithMarkup(Util.escape(message) + + " <a href='#' class='showDetails'>" + + Messages.FormValidation_Error_Details() + + "</a><pre style='display:none'>" + + Functions.printThrowable(e) + + "</pre>", kind); } public static FormValidation error(Throwable e, String format, Object... args) { - return error(e,String.format(format,args)); + return error(e, String.format(format, args)); } public static FormValidation warning(Throwable e, String format, Object... args) { - return warning(e,String.format(format,args)); + return warning(e, String.format(format, args)); } - - /** * Sends out an HTML fragment that indicates an error. * - * <p> - * This method must be used with care to avoid cross-site scripting + * <p> This method must be used with care to avoid cross-site scripting * attack. * - * @param message - * Human readable message to be sent. <tt>error(null)</tt> - * can be used as <tt>ok()</tt>. + * @param message Human readable message to be sent. <tt>error(null)</tt> + * can be used as <tt>ok()</tt>. */ public static FormValidation errorWithMarkup(String message) { - return _errorWithMarkup(message,Kind.ERROR); + return _errorWithMarkup(message, Kind.ERROR); } public static FormValidation warningWithMarkup(String message) { - return _errorWithMarkup(message,Kind.WARNING); + return _errorWithMarkup(message, Kind.WARNING); } public static FormValidation okWithMarkup(String message) { - return _errorWithMarkup(message,Kind.OK); + return _errorWithMarkup(message, Kind.OK); } private static FormValidation _errorWithMarkup(final String message, final Kind kind) { - if(message==null) + if (message == null) { return ok(); + } return new FormValidation(kind, message) { public String renderHtml() { // 1x16 spacer needed for IE since it doesn't support min-height - return "<div class="+ kind.name().toLowerCase(Locale.ENGLISH) +"><img src='"+ - Stapler.getCurrentRequest().getContextPath()+ Hudson.RESOURCE_PATH+"/images/none.gif' height=16 width=1>"+ - message+"</div>"; + return "<div class=" + kind.name().toLowerCase(Locale.ENGLISH) + "><img src='" + + Stapler.getCurrentRequest().getContextPath() + Hudson.RESOURCE_PATH + "/images/none.gif' height=16 width=1>" + + message + "</div>"; } }; } @@ -240,12 +236,11 @@ public abstract class FormValidation extends IOException implements HttpResponse /** * Performs an application-specific validation on the given file. * - * <p> - * This is used as a piece in a bigger validation effort. + * <p> This is used as a piece in a bigger validation effort. */ public static abstract class FileValidator { - public abstract FormValidation validate(File f); + public abstract FormValidation validate(File f); /** * Singleton instance that does no check. */ @@ -266,52 +261,62 @@ public abstract class FormValidation extends IOException implements HttpResponse /** * Makes sure that the given string points to an executable file. * - * @param exeValidator - * If the validation process discovers a valid executable program on the given path, - * the specified {@link FileValidator} can perform additional checks (such as making sure - * that it has the right version, etc.) + * @param exeValidator If the validation process discovers a valid + * executable program on the given path, the specified {@link FileValidator} + * can perform additional checks (such as making sure that it has the right + * version, etc.) */ public static FormValidation validateExecutable(String exe, FileValidator exeValidator) { // insufficient permission to perform validation? - if(!Hudson.getInstance().hasPermission(Hudson.ADMINISTER)) return ok(); + if (!Hudson.getInstance().hasPermission(Hudson.ADMINISTER)) { + return ok(); + } exe = fixEmpty(exe); - if(exe==null) + if (exe == null) { return ok(); + } - if(exe.indexOf(File.separatorChar)>=0) { + if (exe.indexOf(File.separatorChar) >= 0) { // this is full path File f = new File(exe); - if(f.exists()) return exeValidator.validate(f); + if (f.exists()) { + return exeValidator.validate(f); + } - File fexe = new File(exe+".exe"); - if(fexe.exists()) return exeValidator.validate(fexe); + File fexe = new File(exe + ".exe"); + if (fexe.exists()) { + return exeValidator.validate(fexe); + } - return error("There's no such file: "+exe); + return error("There's no such file: " + exe); } // look in PATH String path = EnvVars.masterEnvVars.get("PATH"); String tokenizedPath = ""; String delimiter = null; - if(path!=null) { - for (String _dir : Util.tokenize(path.replace("\\", "\\\\"),File.pathSeparator)) { + if (path != null) { + for (String _dir : Util.tokenize(path.replace("\\", "\\\\"), File.pathSeparator)) { if (delimiter == null) { - delimiter = ", "; - } - else { - tokenizedPath += delimiter; + delimiter = ", "; + } else { + tokenizedPath += delimiter; } tokenizedPath += _dir.replace('\\', '/'); File dir = new File(_dir); - File f = new File(dir,exe); - if(f.exists()) return exeValidator.validate(f); + File f = new File(dir, exe); + if (f.exists()) { + return exeValidator.validate(f); + } - File fexe = new File(dir,exe+".exe"); - if(fexe.exists()) return exeValidator.validate(fexe); + File fexe = new File(dir, exe + ".exe"); + if (fexe.exists()) { + return exeValidator.validate(fexe); + } } tokenizedPath += "."; @@ -320,7 +325,7 @@ public abstract class FormValidation extends IOException implements HttpResponse } // didn't find it - return error("There's no such executable "+exe+" in PATH: "+tokenizedPath); + return error("There's no such executable " + exe + " in PATH: " + tokenizedPath); } /** @@ -328,8 +333,9 @@ public abstract class FormValidation extends IOException implements HttpResponse */ public static FormValidation validateNonNegativeInteger(String value) { try { - if(Integer.parseInt(value)<0) + if (Integer.parseInt(value) < 0) { return error(hudson.model.Messages.Hudson_NotANonNegativeNumber()); + } return ok(); } catch (NumberFormatException e) { return error(hudson.model.Messages.Hudson_NotANumber()); @@ -341,8 +347,9 @@ public abstract class FormValidation extends IOException implements HttpResponse */ public static FormValidation validatePositiveInteger(String value) { try { - if(Integer.parseInt(value)<=0) + if (Integer.parseInt(value) <= 0) { return error(hudson.model.Messages.Hudson_NotAPositiveNumber()); + } return ok(); } catch (NumberFormatException e) { return error(hudson.model.Messages.Hudson_NotANumber()); @@ -353,20 +360,19 @@ public abstract class FormValidation extends IOException implements HttpResponse * Makes sure that the given string is not null or empty. */ public static FormValidation validateRequired(String value) { - if (Util.fixEmptyAndTrim(value) == null) + if (Util.fixEmptyAndTrim(value) == null) { return error(Messages.FormValidation_ValidateRequired()); + } return ok(); } /** * Makes sure that the given string is a base64 encoded text. * - * @param allowWhitespace - * if you allow whitespace (CR,LF,etc) in base64 encoding - * @param allowEmpty - * Is empty string allowed? - * @param errorMessage - * Error message. + * @param allowWhitespace if you allow whitespace (CR,LF,etc) in base64 + * encoding + * @param allowEmpty Is empty string allowed? + * @param errorMessage Error message. * @since 1.305 */ public static FormValidation validateBase64(String value, boolean allowWhitespace, boolean allowEmpty, String errorMessage) { @@ -388,13 +394,14 @@ public abstract class FormValidation extends IOException implements HttpResponse /** * Convenient base class for checking the validity of URLs. * - * <p> - * This allows the check method to call various utility methods in a concise syntax. + * <p> This allows the check method to call various utility methods in a + * concise syntax. */ public static abstract class URLCheck { + /** - * Opens the given URL and reads text content from it. - * This method honors Content-type header. + * Opens the given URL and reads text content from it. This method + * honors Content-type header. */ protected BufferedReader open(URL url) throws IOException { // use HTTP content type to find out the charset. @@ -403,46 +410,51 @@ public abstract class FormValidation extends IOException implements HttpResponse throw new IOException(url.toExternalForm()); } return new BufferedReader( - new InputStreamReader(con.getInputStream(),getCharset(con))); + new InputStreamReader(con.getInputStream(), getCharset(con))); } /** * Finds the string literal from the given reader. - * @return - * true if found, false otherwise. + * + * @return true if found, false otherwise. */ protected boolean findText(BufferedReader in, String literal) throws IOException { String line; - while((line=in.readLine())!=null) - if(line.indexOf(literal)!=-1) + while ((line = in.readLine()) != null) { + if (line.indexOf(literal) != -1) { return true; + } + } return false; } /** - * Calls the {@link FormValidation#error(String)} method with a reasonable error message. - * Use this method when the {@link #open(URL)} or {@link #findText(BufferedReader, String)} fails. + * Calls the {@link FormValidation#error(String)} method with a + * reasonable error message. Use this method when the {@link #open(URL)} + * or {@link #findText(BufferedReader, String)} fails. * - * @param url - * Pass in the URL that was connected. Used for error diagnosis. + * @param url Pass in the URL that was connected. Used for error + * diagnosis. */ protected FormValidation handleIOException(String url, IOException e) throws IOException, ServletException { // any invalid URL comes here - if(e.getMessage().equals(url)) - // Sun JRE (and probably others too) often return just the URL in the error. - return error("Unable to connect "+url); - else + if (e.getMessage().equals(url)) // Sun JRE (and probably others too) often return just the URL in the error. + { + return error("Unable to connect " + url); + } else { return error(e.getMessage()); + } } /** * Figures out the charset from the content-type header. */ private String getCharset(URLConnection con) { - for( String t : con.getContentType().split(";") ) { + for (String t : con.getContentType().split(";")) { t = t.trim().toLowerCase(Locale.ENGLISH); - if(t.startsWith("charset=")) + if (t.startsWith("charset=")) { return t.substring(8); + } } // couldn't find it. HTML spec says default is US-ASCII, // but UTF-8 is a better choice since @@ -452,13 +464,12 @@ public abstract class FormValidation extends IOException implements HttpResponse } /** - * Implement the actual form validation logic, by using other convenience methosd defined in this class. - * If you are not using any of those, you don't need to extend from this class. + * Implement the actual form validation logic, by using other + * convenience methosd defined in this class. If you are not using any + * of those, you don't need to extend from this class. */ protected abstract FormValidation check() throws IOException, ServletException; } - - //TODO: review and check whether we can do it private public final Kind kind; @@ -468,6 +479,7 @@ public abstract class FormValidation extends IOException implements HttpResponse /** * Instances should be created via one of the factory methods above. + * * @param kind */ private FormValidation(Kind kind) { diff --git a/hudson-core/src/main/java/hudson/util/Function1.java b/hudson-core/src/main/java/hudson/util/Function1.java index 9d37081..40d5dff 100644 --- a/hudson-core/src/main/java/hudson/util/Function1.java +++ b/hudson-core/src/main/java/hudson/util/Function1.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 + * * *******************************************************************************/ @@ -18,7 +18,7 @@ package hudson.util; /** * Unary function <tt>y=f(x)</tt>. - * + * * @author Kohsuke Kawaguchi */ public interface Function1<R,P1> { diff --git a/hudson-core/src/main/java/hudson/util/Futures.java b/hudson-core/src/main/java/hudson/util/Futures.java index 7d33907..a505abd 100644 --- a/hudson-core/src/main/java/hudson/util/Futures.java +++ b/hudson-core/src/main/java/hudson/util/Futures.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 + * * *******************************************************************************/ @@ -22,12 +22,14 @@ import java.util.concurrent.TimeUnit; /** * Various {@link Future} implementations. - * + * * @author Kohsuke Kawaguchi */ public class Futures { + /** - * Creates a {@link Future} instance that already has its value pre-computed. + * Creates a {@link Future} instance that already has its value + * pre-computed. */ public static <T> Future<T> precomputed(final T value) { return new Future<T>() { diff --git a/hudson-core/src/main/java/hudson/util/Graph.java b/hudson-core/src/main/java/hudson/util/Graph.java index 27c37f8..e800b44 100644 --- a/hudson-core/src/main/java/hudson/util/Graph.java +++ b/hudson-core/src/main/java/hudson/util/Graph.java @@ -8,7 +8,7 @@ * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * + * * *******************************************************************************/ @@ -18,7 +18,7 @@ import java.util.Calendar; /** * Exists solely for backward compatibility - * + * * @author Winston Prakash * @see org.eclipse.hudson.graph.Graph */ diff --git a/hudson-core/src/main/java/hudson/util/HeadBufferingStream.java b/hudson-core/src/main/java/hudson/util/HeadBufferingStream.java index 942d6f1..610889f 100644 --- a/hudson-core/src/main/java/hudson/util/HeadBufferingStream.java +++ b/hudson-core/src/main/java/hudson/util/HeadBufferingStream.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 + * * *******************************************************************************/ @@ -23,15 +23,16 @@ import java.io.InputStream; import java.io.IOException; /** - * {@link FilterInputStream} that buffers the first N bytes to a byte array on the side. - * This byte array can be then accessed later. + * {@link FilterInputStream} that buffers the first N bytes to a byte array on + * the side. This byte array can be then accessed later. * - * <p> - * Useful for sniffing the content of the stream after the error is discovered. + * <p> Useful for sniffing the content of the stream after the error is + * discovered. * * @author Kohsuke Kawaguchi */ public class HeadBufferingStream extends FilterInputStream { + private final ByteArrayOutputStream side; private final int sideBufferSize; @@ -44,18 +45,20 @@ public class HeadBufferingStream extends FilterInputStream { @Override public int read() throws IOException { int i = in.read(); - if(i>=0 && space()>0) + if (i >= 0 && space() > 0) { side.write(i); + } return i; } @Override public int read(byte b[], int off, int len) throws IOException { int r = in.read(b, off, len); - if(r>0) { + if (r > 0) { int sp = space(); - if(sp>0) - side.write(b,off,Math.min(r, sp)); + if (sp > 0) { + side.write(b, off, Math.min(r, sp)); + } } return r; } @@ -64,7 +67,7 @@ public class HeadBufferingStream extends FilterInputStream { * Available space in the {@link #side} buffer. */ private int space() { - return sideBufferSize-side.size(); + return sideBufferSize - side.size(); } /** @@ -72,9 +75,10 @@ public class HeadBufferingStream extends FilterInputStream { */ public void fillSide() throws IOException { byte[] buf = new byte[space()]; - while(space()>0) { - if(read(buf)<0) + while (space() > 0) { + if (read(buf) < 0) { return; + } } } diff --git a/hudson-core/src/main/java/hudson/util/HeapSpaceStringConverter.java b/hudson-core/src/main/java/hudson/util/HeapSpaceStringConverter.java index c81a2f9..c421fbd 100644 --- a/hudson-core/src/main/java/hudson/util/HeapSpaceStringConverter.java +++ b/hudson-core/src/main/java/hudson/util/HeapSpaceStringConverter.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 + * * *******************************************************************************/ @@ -20,13 +20,11 @@ import com.thoughtworks.xstream.converters.basic.AbstractSingleValueConverter; import com.thoughtworks.xstream.converters.basic.StringConverter; /** - * The default {@link StringConverter} in XStream - * uses {@link String#intern()}, which stresses the - * (rather limited) PermGen space with a large XML file. + * The default {@link StringConverter} in XStream uses {@link String#intern()}, + * which stresses the (rather limited) PermGen space with a large XML file. * - * <p> - * Use this to avoid that (instead those strings will - * now be allocated to the heap space.) + * <p> Use this to avoid that (instead those strings will now be allocated to + * the heap space.) * * @author Kohsuke Kawaguchi */ diff --git a/hudson-core/src/main/java/hudson/util/HexBinaryConverter.java b/hudson-core/src/main/java/hudson/util/HexBinaryConverter.java index 3451155..34d26d7 100644 --- a/hudson-core/src/main/java/hudson/util/HexBinaryConverter.java +++ b/hudson-core/src/main/java/hudson/util/HexBinaryConverter.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,7 +29,7 @@ import hudson.Util; public class HexBinaryConverter implements Converter { public boolean canConvert(Class type) { - return type==byte[].class; + return type == byte[].class; } public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { diff --git a/hudson-core/src/main/java/hudson/util/HudsonFailedToLoad.java b/hudson-core/src/main/java/hudson/util/HudsonFailedToLoad.java index f68a4bc..72bce1b 100644 --- a/hudson-core/src/main/java/hudson/util/HudsonFailedToLoad.java +++ b/hudson-core/src/main/java/hudson/util/HudsonFailedToLoad.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 + * * *******************************************************************************/ @@ -19,14 +19,15 @@ package hudson.util; import hudson.Functions; /** - * Model object used to display the generic error when Hudson start up fails fatally during initialization. + * Model object used to display the generic error when Hudson start up fails + * fatally during initialization. * - * <p> - * <tt>index.jelly</tt> would display a nice friendly error page. + * <p> <tt>index.jelly</tt> would display a nice friendly error page. * * @author Kohsuke Kawaguchi */ public class HudsonFailedToLoad extends ErrorObject { + public final Throwable exception; public HudsonFailedToLoad(Throwable exception) { diff --git a/hudson-core/src/main/java/hudson/util/HudsonIsLoading.java b/hudson-core/src/main/java/hudson/util/HudsonIsLoading.java index 1d277ff..6993312 100644 --- a/hudson-core/src/main/java/hudson/util/HudsonIsLoading.java +++ b/hudson-core/src/main/java/hudson/util/HudsonIsLoading.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.util; @@ -26,14 +26,15 @@ import java.io.IOException; /** * Model object used to display "Hudson is loading data". * - * Set this object to {@link ServletContext#setAttribute(String, Object)} "app" while - * the loading activity is taking place. - * + * Set this object to {@link ServletContext#setAttribute(String, Object)} "app" + * while the loading activity is taking place. + * * @author Kohsuke Kawaguchi */ public class HudsonIsLoading { + public void doDynamic(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException, InterruptedException { rsp.setStatus(SC_SERVICE_UNAVAILABLE); - req.getView(this,"index.jelly").forward(req,rsp); + req.getView(this, "index.jelly").forward(req, rsp); } } diff --git a/hudson-core/src/main/java/hudson/util/HudsonIsRestarting.java b/hudson-core/src/main/java/hudson/util/HudsonIsRestarting.java index 38cd05f..97fbc1e 100644 --- a/hudson-core/src/main/java/hudson/util/HudsonIsRestarting.java +++ b/hudson-core/src/main/java/hudson/util/HudsonIsRestarting.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 + * * *******************************************************************************/ @@ -25,16 +25,16 @@ import static javax.servlet.http.HttpServletResponse.SC_SERVICE_UNAVAILABLE; import java.io.IOException; /** - * Model object used to display "Hudson is restarting". - * <p> - * Set this object to {@link ServletContext#setAttribute(String, Object)} "app" while - * the loading activity is taking place. + * Model object used to display "Hudson is restarting". <p> Set this object to + * {@link ServletContext#setAttribute(String, Object)} "app" while the loading + * activity is taking place. * * @author Kohsuke Kawaguchi */ public class HudsonIsRestarting { + public void doDynamic(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException, InterruptedException { rsp.setStatus(SC_SERVICE_UNAVAILABLE); - req.getView(this,"index.jelly").forward(req,rsp); + req.getView(this, "index.jelly").forward(req, rsp); } } diff --git a/hudson-core/src/main/java/hudson/util/IOException2.java b/hudson-core/src/main/java/hudson/util/IOException2.java index 5c10139..2106c15 100644 --- a/hudson-core/src/main/java/hudson/util/IOException2.java +++ b/hudson-core/src/main/java/hudson/util/IOException2.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 + * * *******************************************************************************/ @@ -23,7 +23,8 @@ import java.io.IOException; * * @author Kohsuke Kawaguchi */ -public class IOException2 extends IOException { +public class IOException2 extends IOException { + private final Throwable cause; public IOException2(Throwable cause) { diff --git a/hudson-core/src/main/java/hudson/util/IOUtils.java b/hudson-core/src/main/java/hudson/util/IOUtils.java index a5ce6f4..1459474 100644 --- a/hudson-core/src/main/java/hudson/util/IOUtils.java +++ b/hudson-core/src/main/java/hudson/util/IOUtils.java @@ -8,7 +8,7 @@ * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * + * * *******************************************************************************/ @@ -24,18 +24,19 @@ import java.util.regex.Pattern; * @since 1.337 */ public class IOUtils extends org.apache.commons.io.IOUtils { + /** * Drains the input stream and closes it. */ public static void drain(InputStream in) throws IOException { - copy(in,new NullStream()); + copy(in, new NullStream()); in.close(); } public static void copy(File src, OutputStream out) throws IOException { FileInputStream in = new FileInputStream(src); try { - copy(in,out); + copy(in, out); } finally { closeQuietly(in); } @@ -44,21 +45,23 @@ public class IOUtils extends org.apache.commons.io.IOUtils { public static void copy(InputStream in, File out) throws IOException { FileOutputStream fos = new FileOutputStream(out); try { - copy(in,fos); + copy(in, fos); } finally { closeQuietly(fos); } } /** - * Ensures that the given directory exists (if not, it's created, including all the parent directories.) + * Ensures that the given directory exists (if not, it's created, including + * all the parent directories.) * - * @return - * This method returns the 'dir' parameter so that the method call flows better. + * @return This method returns the 'dir' parameter so that the method call + * flows better. */ public static File mkdirs(File dir) throws IOException { - if(dir.mkdirs() || dir.exists()) + if (dir.mkdirs() || dir.exists()) { return dir; + } // following Ant <mkdir> task to avoid possible race condition. try { @@ -67,25 +70,28 @@ public class IOUtils extends org.apache.commons.io.IOUtils { // ignore } - if (dir.mkdirs() || dir.exists()) + if (dir.mkdirs() || dir.exists()) { return dir; + } - throw new IOException("Failed to create a directory at "+dir); + throw new IOException("Failed to create a directory at " + dir); } /** * Fully skips the specified size from the given input stream. * - * <p> - * {@link InputStream#skip(long)} has two problems. One is that - * it doesn't let us reliably differentiate "hit EOF" case vs "inpustream just returning 0 since there's no data - * currently available at hand", and some subtypes (such as {@link FileInputStream#skip(long)} returning -1. + * <p> {@link InputStream#skip(long)} has two problems. One is that it + * doesn't let us reliably differentiate "hit EOF" case vs "inpustream just + * returning 0 since there's no data currently available at hand", and some + * subtypes (such as {@link FileInputStream#skip(long)} returning -1. * - * <p> - * So to reliably skip just the N bytes, we'll actually read all those bytes. + * <p> So to reliably skip just the N bytes, we'll actually read all those + * bytes. * * @since 1.349 - * @deprecated use {@link org.apache.commons.io.IOUtils#skip(java.io.InputStream, long)} instead + * @deprecated use + * {@link org.apache.commons.io.IOUtils#skip(java.io.InputStream, long)} + * instead * @since 2.1.2 */ public static long skip(InputStream in, long size) throws IOException { @@ -93,30 +99,36 @@ public class IOUtils extends org.apache.commons.io.IOUtils { } /** - * Resolves the given path with respect to given base. If the path represents an absolute path, a file representing - * it is returned, otherwise a file representing a path relative to base is returned. - * <p> - * It would be nice if File#File(File, String) were doing this. - * @param base File that represents the parent, may be null if path is absolute + * Resolves the given path with respect to given base. If the path + * represents an absolute path, a file representing it is returned, + * otherwise a file representing a path relative to base is returned. <p> It + * would be nice if File#File(File, String) were doing this. + * + * @param base File that represents the parent, may be null if path is + * absolute * @param path Path of the file, may not be null - * @return new File(name) if name represents an absolute path, new File(base, name) otherwise - * @see hudson.FilePath#absolutize() + * @return new File(name) if name represents an absolute path, new + * File(base, name) otherwise + * @see hudson.FilePath#absolutize() */ public static File absolutize(File base, String path) { - if (isAbsolute(path)) + if (isAbsolute(path)) { return new File(path); + } return new File(base, path); } /** * See {@link hudson.FilePath#isAbsolute(String)}. - * @param path String representing <code> Platform Specific </code> (unlike FilePath, which may get Platform agnostic paths), may not be null - * @return true if String represents absolute path on this platform, false otherwise + * + * @param path String representing <code> Platform Specific </code> (unlike + * FilePath, which may get Platform agnostic paths), may not be null + * @return true if String represents absolute path on this platform, false + * otherwise */ public static boolean isAbsolute(String path) { Pattern DRIVE_PATTERN = Pattern.compile("[A-Za-z]:[\\\\/].*"); return path.startsWith("/") || DRIVE_PATTERN.matcher(path).matches(); } - private static final byte[] SKIP_BUFFER = new byte[8192]; } diff --git a/hudson-core/src/main/java/hudson/util/IncompatibleAntVersionDetected.java b/hudson-core/src/main/java/hudson/util/IncompatibleAntVersionDetected.java index 3a47d4f..37fec14 100644 --- a/hudson-core/src/main/java/hudson/util/IncompatibleAntVersionDetected.java +++ b/hudson-core/src/main/java/hudson/util/IncompatibleAntVersionDetected.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 + * * *******************************************************************************/ @@ -22,15 +22,15 @@ import java.io.IOException; import java.net.URL; /** - * Model object used to display the error top page if - * we find out that the container is picking up its own Ant and that's not 1.7. + * Model object used to display the error top page if we find out that the + * container is picking up its own Ant and that's not 1.7. * - * <p> - * <tt>index.jelly</tt> would display a nice friendly error page. + * <p> <tt>index.jelly</tt> would display a nice friendly error page. * * @author Kohsuke Kawaguchi */ public class IncompatibleAntVersionDetected extends ErrorObject { + private final Class antClass; public IncompatibleAntVersionDetected(Class antClass) { diff --git a/hudson-core/src/main/java/hudson/util/IncompatibleServletVersionDetected.java b/hudson-core/src/main/java/hudson/util/IncompatibleServletVersionDetected.java index b551d87..b288de8 100644 --- a/hudson-core/src/main/java/hudson/util/IncompatibleServletVersionDetected.java +++ b/hudson-core/src/main/java/hudson/util/IncompatibleServletVersionDetected.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 + * * *******************************************************************************/ @@ -22,21 +22,21 @@ import java.io.IOException; import java.net.URL; /** - * Model object used to display the error top page if - * we find out that the container doesn't support servlet 2.4. + * Model object used to display the error top page if we find out that the + * container doesn't support servlet 2.4. * - * <p> - * <tt>index.jelly</tt> would display a nice friendly error page. + * <p> <tt>index.jelly</tt> would display a nice friendly error page. * * @author Kohsuke Kawaguchi */ public class IncompatibleServletVersionDetected extends ErrorObject { + private final Class servletClass; public IncompatibleServletVersionDetected(Class servletClass) { this.servletClass = servletClass; } - + public URL getWhereServletIsLoaded() throws IOException { return Which.jarURL(servletClass); } diff --git a/hudson-core/src/main/java/hudson/util/IncompatibleVMDetected.java b/hudson-core/src/main/java/hudson/util/IncompatibleVMDetected.java index e809e78..fbfbd80 100644 --- a/hudson-core/src/main/java/hudson/util/IncompatibleVMDetected.java +++ b/hudson-core/src/main/java/hudson/util/IncompatibleVMDetected.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 + * * *******************************************************************************/ @@ -19,11 +19,10 @@ package hudson.util; import java.util.Map; /** - * Model object used to display the error top page if - * we find out that XStream is running in pure-java mode. + * Model object used to display the error top page if we find out that XStream + * is running in pure-java mode. * - * <p> - * <tt>index.jelly</tt> would display a nice friendly error page. + * <p> <tt>index.jelly</tt> would display a nice friendly error page. * * @author Kohsuke Kawaguchi */ diff --git a/hudson-core/src/main/java/hudson/util/InsufficientPermissionDetected.java b/hudson-core/src/main/java/hudson/util/InsufficientPermissionDetected.java index b6d5280..8e80886 100644 --- a/hudson-core/src/main/java/hudson/util/InsufficientPermissionDetected.java +++ b/hudson-core/src/main/java/hudson/util/InsufficientPermissionDetected.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 + * * *******************************************************************************/ @@ -19,16 +19,16 @@ package hudson.util; import hudson.Functions; /** - * Model object used to display the error top page if - * we find that we don't have enough permissions to run. + * Model object used to display the error top page if we find that we don't have + * enough permissions to run. * - * <p> - * <tt>index.jelly</tt> would display a nice friendly error page. + * <p> <tt>index.jelly</tt> would display a nice friendly error page. * * @author Kohsuke Kawaguchi */ public class InsufficientPermissionDetected extends ErrorObject { //TODO: review and check whether we can do it private + public final SecurityException exception; public SecurityException getException() { diff --git a/hudson-core/src/main/java/hudson/util/InterceptingProxy.java b/hudson-core/src/main/java/hudson/util/InterceptingProxy.java index cb19632..6ba9457 100644 --- a/hudson-core/src/main/java/hudson/util/InterceptingProxy.java +++ b/hudson-core/src/main/java/hudson/util/InterceptingProxy.java @@ -8,7 +8,7 @@ * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * + * * *******************************************************************************/ @@ -25,6 +25,7 @@ import java.lang.reflect.InvocationTargetException; * @author Kohsuke Kawaguchi */ public abstract class InterceptingProxy { + /** * Intercepts every method call. */ @@ -34,7 +35,7 @@ public abstract class InterceptingProxy { return type.cast(Proxy.newProxyInstance(type.getClassLoader(), new Class[]{type}, new InvocationHandler() { public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { try { - return call(object,method,args); + return call(object, method, args); } catch (InvocationTargetException e) { throw e.getTargetException(); } diff --git a/hudson-core/src/main/java/hudson/util/InvocationInterceptor.java b/hudson-core/src/main/java/hudson/util/InvocationInterceptor.java index c5f32a6..88428bf 100644 --- a/hudson-core/src/main/java/hudson/util/InvocationInterceptor.java +++ b/hudson-core/src/main/java/hudson/util/InvocationInterceptor.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 + * * *******************************************************************************/ @@ -26,12 +26,12 @@ import java.lang.reflect.InvocationHandler; * @since 1.232 */ public interface InvocationInterceptor { + /** - * This method can intercept the invocation of {@link InvocationHandler} either before or after - * the invocation happens. + * This method can intercept the invocation of {@link InvocationHandler} + * either before or after the invocation happens. * - * <p> - * The general coding pattern is: + * <p> The general coding pattern is: * * <pre> * Object invoke(Object proxy, Method method, Object[] args, InvocationHandler delegate) { @@ -42,9 +42,8 @@ public interface InvocationInterceptor { * } * </pre> * - * <p> - * But the implementation may choose to skip calling the 'delegate' object, alter arguments, - * and alter the return value. + * <p> But the implementation may choose to skip calling the 'delegate' + * object, alter arguments, and alter the return value. */ public Object invoke(Object proxy, Method method, Object[] args, InvocationHandler delegate) throws Throwable; } diff --git a/hudson-core/src/main/java/hudson/util/Iterators.java b/hudson-core/src/main/java/hudson/util/Iterators.java index 05886b0..76a36cc 100644 --- a/hudson-core/src/main/java/hudson/util/Iterators.java +++ b/hudson-core/src/main/java/hudson/util/Iterators.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,6 +33,7 @@ import java.util.HashSet; * @see AdaptedIterator */ public class Iterators { + /** * Returns the empty iterator. */ @@ -43,7 +44,8 @@ public class Iterators { /** * Produces {A,B,C,D,E,F} from {{A,B},{C},{},{D,E,F}}. */ - public static abstract class FlattenIterator<U,T> implements Iterator<U> { + public static abstract class FlattenIterator<U, T> implements Iterator<U> { + private final Iterator<? extends T> core; private Iterator<U> cur; @@ -59,16 +61,19 @@ public class Iterators { protected abstract Iterator<U> expand(T t); public boolean hasNext() { - while(!cur.hasNext()) { - if(!core.hasNext()) + while (!cur.hasNext()) { + if (!core.hasNext()) { return false; + } cur = expand(core.next()); } return true; } public U next() { - if(!hasNext()) throw new NoSuchElementException(); + if (!hasNext()) { + throw new NoSuchElementException(); + } return cur.next(); } @@ -83,6 +88,7 @@ public class Iterators { * @since 1.150 */ public static abstract class FilterIterator<T> implements Iterator<T> { + private final Iterator<? extends T> core; private T next; private boolean fetched; @@ -96,9 +102,9 @@ public class Iterators { } private void fetch() { - while(!fetched && core.hasNext()) { + while (!fetched && core.hasNext()) { T n = core.next(); - if(filter(n)) { + if (filter(n)) { next = n; fetched = true; } @@ -108,9 +114,8 @@ public class Iterators { /** * Filter out items in the original collection. * - * @return - * true to leave this item and return this item from this iterator. - * false to hide this item. + * @return true to leave this item and return this item from this + * iterator. false to hide this item. */ protected abstract boolean filter(T t); @@ -121,7 +126,9 @@ public class Iterators { public T next() { fetch(); - if(!fetched) throw new NoSuchElementException(); + if (!fetched) { + throw new NoSuchElementException(); + } fetched = false; return next; } @@ -135,6 +142,7 @@ public class Iterators { * Remove duplicates from another iterator. */ public static final class DuplicateFilterIterator<T> extends FilterIterator<T> { + private final Set<T> seen = new HashSet<T>(); public DuplicateFilterIterator(Iterator<? extends T> core) { @@ -185,14 +193,17 @@ public class Iterators { */ public static List<Integer> sequence(final int start, int end, final int step) { - final int size = (end-start)/step; - if(size<0) throw new IllegalArgumentException("List size is negative"); + final int size = (end - start) / step; + if (size < 0) { + throw new IllegalArgumentException("List size is negative"); + } return new AbstractList<Integer>() { public Integer get(int index) { - if(index<0 || index>=size) + if (index < 0 || index >= size) { throw new IndexOutOfBoundsException(); - return start+index*step; + } + return start + index * step; } public int size() { @@ -202,7 +213,7 @@ public class Iterators { } public static List<Integer> sequence(int start, int end) { - return sequence(start,end,1); + return sequence(start, end, 1); } /** @@ -211,11 +222,11 @@ public class Iterators { * @since 1.150 */ public static List<Integer> reverseSequence(int start, int end, int step) { - return sequence(end-1,start-1,-step); + return sequence(end - 1, start - 1, -step); } public static List<Integer> reverseSequence(int start, int end) { - return reverseSequence(start,end,1); + return reverseSequence(start, end, 1); } /** @@ -223,7 +234,7 @@ public class Iterators { */ @SuppressWarnings({"unchecked"}) public static <T> Iterator<T> cast(Iterator<? extends T> itr) { - return (Iterator)itr; + return (Iterator) itr; } /** @@ -231,15 +242,15 @@ public class Iterators { */ @SuppressWarnings({"unchecked"}) public static <T> Iterable<T> cast(Iterable<? extends T> itr) { - return (Iterable)itr; + return (Iterable) itr; } /** * Returns an {@link Iterator} that only returns items of the given subtype. */ @SuppressWarnings({"unchecked"}) - public static <U,T extends U> Iterator<T> subType(Iterator<U> itr, final Class<T> type) { - return (Iterator)new FilterIterator<U>(itr) { + public static <U, T extends U> Iterator<T> subType(Iterator<U> itr, final Class<T> type) { + return (Iterator) new FilterIterator<U>(itr) { protected boolean filter(U u) { return type.isInstance(u); } @@ -272,21 +283,21 @@ public class Iterators { return new FilterIterator<T>(itr) { @Override protected boolean filter(T t) { - return t!=null; + return t != null; } }; } /** - * Returns an {@link Iterable} that iterates over all the given {@link Iterable}s. + * Returns an {@link Iterable} that iterates over all the given + * {@link Iterable}s. * - * <p> - * That is, this creates {A,B,C,D} from {A,B},{C,D}. + * <p> That is, this creates {A,B,C,D} from {A,B},{C,D}. */ - public static <T> Iterable<T> sequence( final Iterable<? extends T>... iterables ) { + public static <T> Iterable<T> sequence(final Iterable<? extends T>... iterables) { return new Iterable<T>() { public Iterator<T> iterator() { - return new FlattenIterator<T,Iterable<? extends T>>(Arrays.asList(iterables)) { + return new FlattenIterator<T, Iterable<? extends T>>(Arrays.asList(iterables)) { protected Iterator<T> expand(Iterable<? extends T> iterable) { return cast(iterable).iterator(); } diff --git a/hudson-core/src/main/java/hudson/util/JNADoublyLoaded.java b/hudson-core/src/main/java/hudson/util/JNADoublyLoaded.java index 40169fa..b13bc3f 100644 --- a/hudson-core/src/main/java/hudson/util/JNADoublyLoaded.java +++ b/hudson-core/src/main/java/hudson/util/JNADoublyLoaded.java @@ -8,7 +8,7 @@ * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * + * * *******************************************************************************/ @@ -20,6 +20,7 @@ package hudson.util; * @author Kohsuke Kawaguchi */ public class JNADoublyLoaded extends HudsonFailedToLoad { + public JNADoublyLoaded(Throwable exception) { super(exception); } diff --git a/hudson-core/src/main/java/hudson/util/JSONCanonicalUtils.java b/hudson-core/src/main/java/hudson/util/JSONCanonicalUtils.java index eebb942..74b6163 100644 --- a/hudson-core/src/main/java/hudson/util/JSONCanonicalUtils.java +++ b/hudson-core/src/main/java/hudson/util/JSONCanonicalUtils.java @@ -29,6 +29,7 @@ import net.sf.json.util.JSONUtils; * Json utils for canonical writing. */ public class JSONCanonicalUtils { + /** * Write JSON object to writer in canonical form. * @@ -139,7 +140,7 @@ public class JSONCanonicalUtils { if (c < ' ') { String t = "000" + Integer.toHexString(c); sb.append("\\u") - .append(t.substring(t.length() - 4)); + .append(t.substring(t.length() - 4)); } else { sb.append(c); } diff --git a/hudson-core/src/main/java/hudson/util/JVMBuilder.java b/hudson-core/src/main/java/hudson/util/JVMBuilder.java index 1f12469..7fb118f 100644 --- a/hudson-core/src/main/java/hudson/util/JVMBuilder.java +++ b/hudson-core/src/main/java/hudson/util/JVMBuilder.java @@ -7,10 +7,10 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: + * Contributors: + * + * * - * - * * *******************************************************************************/ @@ -32,12 +32,12 @@ import java.util.TreeMap; * @since 1.361 */ public class JVMBuilder implements Serializable { + private final ClasspathBuilder classpath = new ClasspathBuilder(); - private final Map<String,String> systemProperties = new TreeMap<String,String>(); + private final Map<String, String> systemProperties = new TreeMap<String, String>(); private final ArgumentListBuilder args = new ArgumentListBuilder(); private final ArgumentListBuilder vmopts = new ArgumentListBuilder(); private FilePath pwd; - private String mainClass; /** @@ -48,16 +48,18 @@ public class JVMBuilder implements Serializable { } public JVMBuilder systemProperty(String key, String value) { - this.systemProperties.put(key,value); + this.systemProperties.put(key, value); return this; } - public Map<String,String> systemProperties() { + public Map<String, String> systemProperties() { return this.systemProperties; } - public JVMBuilder systemProperties(Map<String,String> props) { - if (props!=null) this.systemProperties.putAll(props); + public JVMBuilder systemProperties(Map<String, String> props) { + if (props != null) { + this.systemProperties.putAll(props); + } return this; } @@ -87,13 +89,13 @@ public class JVMBuilder implements Serializable { * Enables the debugger support on the given port. */ public JVMBuilder debug(int port) { - vmopts.add("-Xrunjdwp:transport=dt_socket,server=y,address="+port); + vmopts.add("-Xrunjdwp:transport=dt_socket,server=y,address=" + port); return this; } /** - * Sets the current directory for the new JVM. - * This overloaded version only makes sense when you are launching JVM locally. + * Sets the current directory for the new JVM. This overloaded version only + * makes sense when you are launching JVM locally. */ public JVMBuilder pwd(File pwd) { return pwd(new FilePath(pwd)); @@ -110,8 +112,8 @@ public class JVMBuilder implements Serializable { public ArgumentListBuilder toFullArguments() { ArgumentListBuilder args = new ArgumentListBuilder(); - args.add(new File(System.getProperty("java.home"),"bin/java")); // TODO: if we are to support a remote launch, JVM would be on a different path. - args.addKeyValuePairs("-D",systemProperties); + args.add(new File(System.getProperty("java.home"), "bin/java")); // TODO: if we are to support a remote launch, JVM would be on a different path. + args.addKeyValuePairs("-D", systemProperties); args.add("-cp").add(classpath.toString()); args.add(this.vmopts.toCommandArray()); args.add(mainClass); @@ -120,12 +122,11 @@ public class JVMBuilder implements Serializable { } /** - * Fills a {@link ProcStarter} with all the parameters configured by this builder. + * Fills a {@link ProcStarter} with all the parameters configured by this + * builder. */ public ProcStarter launch(Launcher launcher) { return launcher.launch().cmds(toFullArguments()).pwd(pwd); } - - private static final long serialVersionUID = 1L; } diff --git a/hudson-core/src/main/java/hudson/util/KeyedDataStorage.java b/hudson-core/src/main/java/hudson/util/KeyedDataStorage.java index 074b69e..6c00f2c 100644 --- a/hudson-core/src/main/java/hudson/util/KeyedDataStorage.java +++ b/hudson-core/src/main/java/hudson/util/KeyedDataStorage.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,40 +28,44 @@ import java.util.concurrent.atomic.AtomicInteger; /** * Convenient base class for implementing data storage. * - * <p> - * One typical pattern of data storage in Hudson is the one that {@link Fingerprint} - * uses, where each data is keyed by an unique key (MD5 sum), and that key is used - * to determine the file system location of the data. + * <p> One typical pattern of data storage in Hudson is the one that + * {@link Fingerprint} uses, where each data is keyed by an unique key (MD5 + * sum), and that key is used to determine the file system location of the data. * * On memory, each data is represented by one object ({@link Fingerprint}), and * write access to the same data is coordinated by using synchronization. * - * <p> - * With such storage, care has to be taken to ensure that there's only one data - * object in memory for any given key. That means load and create operation - * needs to be synchronized. This class implements this logic in a fairly efficient - * way, and thus intends to help plugins that want to use such data storage. + * <p> With such storage, care has to be taken to ensure that there's only one + * data object in memory for any given key. That means load and create operation + * needs to be synchronized. This class implements this logic in a fairly + * efficient way, and thus intends to help plugins that want to use such data + * storage. * * @since 1.87 * @author Kohsuke Kawaguchi * @see FingerprintMap */ -public abstract class KeyedDataStorage<T,P> { +public abstract class KeyedDataStorage<T, P> { + /** - * The value is either {@code SoftReference<Fingerprint>} or {@link Loading}. + * The value is either {@code SoftReference<Fingerprint>} or + * {@link Loading}. * - * If it's {@link SoftReference}, that represents the currently available value. - * If it's {@link Loading}, then that indicates the fingerprint is being loaded. - * The thread can wait on this object to be notified when the loading completes. + * If it's {@link SoftReference}, that represents the currently available + * value. If it's {@link Loading}, then that indicates the fingerprint is + * being loaded. The thread can wait on this object to be notified when the + * loading completes. */ - private final ConcurrentHashMap<String,Object> core = new ConcurrentHashMap<String,Object>(); + private final ConcurrentHashMap<String, Object> core = new ConcurrentHashMap<String, Object>(); /** - * Used in {@link KeyedDataStorage#core} to indicate that the loading of a fingerprint - * is in progress, so that we can avoid creating two {@link Fingerprint}s for the same hash code, - * but do so without having a single lock. + * Used in {@link KeyedDataStorage#core} to indicate that the loading of a + * fingerprint is in progress, so that we can avoid creating two + * {@link Fingerprint}s for the same hash code, but do so without having a + * single lock. */ private static class Loading<T> { + private T value; private boolean set; @@ -72,13 +76,14 @@ public abstract class KeyedDataStorage<T,P> { } /** - * Blocks until the value is {@link #set(Object)} by another thread - * and returns the value. + * Blocks until the value is {@link #set(Object)} by another thread and + * returns the value. */ public synchronized T get() { try { - while(!set) + while (!set) { wait(); + } return value; } catch (InterruptedException e) { // assume the loading failed, but make sure we process interruption properly later @@ -92,51 +97,51 @@ public abstract class KeyedDataStorage<T,P> { * Atomically gets the existing data object if any, or if it doesn't exist * {@link #create(String,Object) create} it and return it. * - * @return - * Never null. - * @param createParams - * Additional parameters needed to create a new data object. Can be null. + * @return Never null. + * @param createParams Additional parameters needed to create a new data + * object. Can be null. */ public T getOrCreate(String key, P createParams) throws IOException { - return get(key,true,createParams); + return get(key, true, createParams); } /** - * Finds the data object that matches the given key if available, or null - * if not found. + * Finds the data object that matches the given key if available, or null if + * not found. */ public T get(String key) throws IOException { - return get(key,false,null); + return get(key, false, null); } /** * Implementation of get/getOrCreate. */ protected T get(String key, boolean createIfNotExist, P createParams) throws IOException { - while(true) { + while (true) { totalQuery.incrementAndGet(); Object value = core.get(key); - if(value instanceof SoftReference) { + if (value instanceof SoftReference) { SoftReference<T> wfp = (SoftReference<T>) value; T t = wfp.get(); - if(t!=null) { + if (t != null) { cacheHit.incrementAndGet(); return t; // found it } weakRefLost.incrementAndGet(); } - if(value instanceof Loading) { + if (value instanceof Loading) { // another thread is loading it. get the value from there. - T t = ((Loading<T>)value).get(); - if(t!=null || !createIfNotExist) + T t = ((Loading<T>) value).get(); + if (t != null || !createIfNotExist) { return t; // found it (t!=null) or we are just 'get' (!createIfNotExist) + } } // the fingerprint doesn't seem to be loaded thus far, so let's load it now. // the care needs to be taken that other threads might be trying to do the same. Loading<T> l = new Loading<T>(); - if(value==null ? core.putIfAbsent(key,l)!=null : !core.replace(key,value,l)) { + if (value == null ? core.putIfAbsent(key, l) != null : !core.replace(key, value, l)) { // the value has changed since then. another thread is attempting to do the same. // go back to square 1 and try it again. continue; @@ -145,12 +150,13 @@ public abstract class KeyedDataStorage<T,P> { T t = null; try { t = load(key); - if(t==null && createIfNotExist) { - t = create(key,createParams); // create the new data - if(t==null) + if (t == null && createIfNotExist) { + t = create(key, createParams); // create the new data + if (t == null) { throw new IllegalStateException(); // bug in the derived classes + } } - } catch(IOException e) { + } catch (IOException e) { loadFailure.incrementAndGet(); throw e; } finally { @@ -160,10 +166,11 @@ public abstract class KeyedDataStorage<T,P> { } // the map needs to be updated to reflect the result of loading - if(t!=null) - core.put(key,new SoftReference<T>(t)); - else + if (t != null) { + core.put(key, new SoftReference<T>(t)); + } else { core.remove(key); + } return t; } @@ -173,37 +180,30 @@ public abstract class KeyedDataStorage<T,P> { /** * Attempts to load an existing data object from disk. * - * <p> - * {@link KeyedDataStorage} class serializes the requests so that - * no two threads call the {@link #load(String)} method with the - * same parameter concurrently. This ensures that there's only - * up to one data object for any key. + * <p> {@link KeyedDataStorage} class serializes the requests so that no two + * threads call the {@link #load(String)} method with the same parameter + * concurrently. This ensures that there's only up to one data object for + * any key. * - * @return - * null if no such data exists. - * @throws IOException - * if load operation fails. This exception will be - * propagated to the caller. + * @return null if no such data exists. + * @throws IOException if load operation fails. This exception will be + * propagated to the caller. */ protected abstract T load(String key) throws IOException; /** * Creates a new data object. * - * <p> - * This method is called by {@link #getOrCreate(String,Object)} - * if the data that matches the specified key does not exist. - * <p> - * Because of concurrency, another thread might call {@link #get(String)} - * as soon as a new data object is created, so it's important that - * this method returns a properly initialized "valid" object. + * <p> This method is called by {@link #getOrCreate(String,Object)} if the + * data that matches the specified key does not exist. <p> Because of + * concurrency, another thread might call {@link #get(String)} as soon as a + * new data object is created, so it's important that this method returns a + * properly initialized "valid" object. * - * @return - * never null. If construction fails, abort with an exception. - * @throws IOException - * if the method fails to create a new data object, it can throw - * {@link IOException} (or any other exception) and that will be - * propagated to the caller. + * @return never null. If construction fails, abort with an exception. + * @throws IOException if the method fails to create a new data object, it + * can throw {@link IOException} (or any other exception) and that will be + * propagated to the caller. */ protected abstract T create(String key, P createParams) throws IOException; @@ -222,12 +222,11 @@ public abstract class KeyedDataStorage<T,P> { int hit = cacheHit.get(); int weakRef = weakRefLost.get(); int failure = loadFailure.get(); - int miss = total-hit-weakRef; + int miss = total - hit - weakRef; return MessageFormat.format("total={0} hit={1}% lostRef={2}% failure={3}% miss={4}%", - total,hit,weakRef,failure,miss); + total, hit, weakRef, failure, miss); } - /** * Total number of queries into this storage. */ @@ -237,8 +236,8 @@ public abstract class KeyedDataStorage<T,P> { */ public final AtomicInteger cacheHit = new AtomicInteger(); /** - * Among cache misses, number of times when we had {@link SoftReference} - * but lost its value due to GC. + * Among cache misses, number of times when we had {@link SoftReference} but + * lost its value due to GC. * * <tt>totalQuery-cacheHit-weakRefLost</tt> means cache miss. */ diff --git a/hudson-core/src/main/java/hudson/util/LineEndNormalizingWriter.java b/hudson-core/src/main/java/hudson/util/LineEndNormalizingWriter.java index 618b6f2..1d3e400 100644 --- a/hudson-core/src/main/java/hudson/util/LineEndNormalizingWriter.java +++ b/hudson-core/src/main/java/hudson/util/LineEndNormalizingWriter.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 + * * *******************************************************************************/ @@ -23,11 +23,10 @@ import java.io.IOException; /** * Finds the lone LF and converts that to CR+LF. * - * <p> - * Internet Explorer's <tt>XmlHttpRequest.responseText</tt> seems to - * normalize the line end, and if we only send LF without CR, it will - * not recognize that as a new line. To work around this problem, - * we use this filter to always convert LF to CR+LF. + * <p> Internet Explorer's <tt>XmlHttpRequest.responseText</tt> seems to + * normalize the line end, and if we only send LF without CR, it will not + * recognize that as a new line. To work around this problem, we use this filter + * to always convert LF to CR+LF. * * @author Kohsuke Kawaguchi * @deprecated since 2008-05-28. moved to stapler @@ -45,53 +44,53 @@ public class LineEndNormalizingWriter extends FilterWriter { } public void write(String str) throws IOException { - write(str,0,str.length()); + write(str, 0, str.length()); } public void write(int c) throws IOException { - if(!seenCR && c==LF) + if (!seenCR && c == LF) { super.write("\r\n"); - else + } else { super.write(c); - seenCR = (c==CR); + } + seenCR = (c == CR); } public void write(char cbuf[], int off, int len) throws IOException { - int end = off+len; + int end = off + len; int writeBegin = off; - for( int i=off; i<end; i++ ) { + for (int i = off; i < end; i++) { char ch = cbuf[i]; - if(!seenCR && ch==LF) { + if (!seenCR && ch == LF) { // write up to the char before LF - super.write(cbuf,writeBegin,i-writeBegin); + super.write(cbuf, writeBegin, i - writeBegin); super.write("\r\n"); - writeBegin=i+1; + writeBegin = i + 1; } - seenCR = (ch==CR); + seenCR = (ch == CR); } - super.write(cbuf,writeBegin,end-writeBegin); + super.write(cbuf, writeBegin, end - writeBegin); } public void write(String str, int off, int len) throws IOException { - int end = off+len; + int end = off + len; int writeBegin = off; - for( int i=off; i<end; i++ ) { + for (int i = off; i < end; i++) { char ch = str.charAt(i); - if(!seenCR && ch==LF) { + if (!seenCR && ch == LF) { // write up to the char before LF - super.write(str,writeBegin,i-writeBegin); + super.write(str, writeBegin, i - writeBegin); super.write("\r\n"); - writeBegin=i+1; + writeBegin = i + 1; } - seenCR = (ch==CR); + seenCR = (ch == CR); } - super.write(str,writeBegin,end-writeBegin); + super.write(str, writeBegin, end - writeBegin); } - private static final int CR = 0x0D; private static final int LF = 0x0A; } diff --git a/hudson-core/src/main/java/hudson/util/ListBoxModel.java b/hudson-core/src/main/java/hudson/util/ListBoxModel.java index 4055bd7..3960516 100644 --- a/hudson-core/src/main/java/hudson/util/ListBoxModel.java +++ b/hudson-core/src/main/java/hudson/util/ListBoxModel.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,13 +33,10 @@ import java.util.Collection; /** * Model object of dynamically filled list box. * - * <h2>Usage</h2> - * <p> - * The dynamic list box support allows the SELECT element to change its options dynamically - * by using the values given by the server. + * <h2>Usage</h2> <p> The dynamic list box support allows the SELECT element to + * change its options dynamically by using the values given by the server. * - * <p> - * To use this, HTML needs to declare the SELECT element: + * <p> To use this, HTML needs to declare the SELECT element: * * <pre><xmp> * <select id='foo'> @@ -47,47 +44,44 @@ import java.util.Collection; * </select> * </xmp></pre> * - * <p> - * The SELECT element may have initial option values (in fact in most cases having initial - * values are desirable to avoid the client from submitting the form before the AJAX call - * updates the SELECT element.) It should also have an ID (although if you can get - * to the DOM element by other means, that's fine, too.) + * <p> The SELECT element may have initial option values (in fact in most cases + * having initial values are desirable to avoid the client from submitting the + * form before the AJAX call updates the SELECT element.) It should also have an + * ID (although if you can get to the DOM element by other means, that's fine, + * too.) * - * <p> - * Other parts of the HTML can initiate the SELECT element update by using the "updateListBox" - * function, defined in <tt>hudson-behavior.js</tt>. The following example does it - * when the value of the textbox changes: + * <p> Other parts of the HTML can initiate the SELECT element update by using + * the "updateListBox" function, defined in <tt>hudson-behavior.js</tt>. The + * following example does it when the value of the textbox changes: * * <pre><xmp> * <input type="textbox" onchange="updateListBox('list','optionValues?value='+encode(this.value))"/> * </xmp></pre> * - * <p> - * The first argument is the SELECT element or the ID of it (see Prototype.js <tt>$(...)</tt> function.) - * The second argument is the URL that returns the options list. + * <p> The first argument is the SELECT element or the ID of it (see + * Prototype.js <tt>$(...)</tt> function.) The second argument is the URL that + * returns the options list. * - * <p> - * The URL usually maps to the <tt>doXXX</tt> method on the server, which uses {@link ListBoxModel} - * for producing option values. See the following example: + * <p> The URL usually maps to the <tt>doXXX</tt> method on the server, which + * uses {@link ListBoxModel} for producing option values. See the following + * example: * * <pre> - * public ListBoxModel doOptionValues(@QueryParameter("value") String value) throws IOException, ServletException { - * ListBoxModel m = new ListBoxModel(); - * for(int i=0; i<5; i++) - * m.add(value+i,value+i); - * // make the third option selected initially - * m.get(3).selected = true; - * return m; - * } - * </pre> + * public ListBoxModel doOptionValues( + * + * @QueryParameter("value") String value) throws IOException, ServletException { + * ListBoxModel m = new ListBoxModel(); for(int i=0; i<5; i++) + * m.add(value+i,value+i); // make the third option selected initially + * m.get(3).selected = true; return m; } </pre> * @since 1.123 * @author Kohsuke Kawaguchi */ @ExportedBean public class ListBoxModel extends ArrayList<ListBoxModel.Option> implements HttpResponse { - @ExportedBean(defaultVisibility=999) + @ExportedBean(defaultVisibility = 999) public static final class Option { + /** * Text to be displayed to user. */ @@ -100,7 +94,6 @@ public class ListBoxModel extends ArrayList<ListBoxModel.Option> implements Http //TODO: review and check whether we can do it private @Exported public String value; - /** * True to make this item selected. */ @@ -121,11 +114,11 @@ public class ListBoxModel extends ArrayList<ListBoxModel.Option> implements Http } public Option(String name, String value) { - this(name,value,false); + this(name, value, false); } public Option(String name) { - this(name,name,false); + this(name, name, false); } public Option(String name, String value, boolean selected) { @@ -151,7 +144,7 @@ public class ListBoxModel extends ArrayList<ListBoxModel.Option> implements Http } public void add(String displayName, String value) { - add(new Option(displayName,value)); + add(new Option(displayName, value)); } public void add(ModelObject usedForDisplayName, String value) { @@ -159,24 +152,24 @@ public class ListBoxModel extends ArrayList<ListBoxModel.Option> implements Http } /** - * A version of the {@link #add(String, String)} method where the display name and the value are the same. + * A version of the {@link #add(String, String)} method where the display + * name and the value are the same. */ public ListBoxModel add(String nameAndValue) { - add(nameAndValue,nameAndValue); + add(nameAndValue, nameAndValue); return this; } - public void writeTo(StaplerRequest req,StaplerResponse rsp) throws IOException, ServletException { - rsp.serveExposedBean(req,this,Flavor.JSON); + public void writeTo(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + rsp.serveExposedBean(req, this, Flavor.JSON); } public void generateResponse(StaplerRequest req, StaplerResponse rsp, Object node) throws IOException, ServletException { - writeTo(req,rsp); + writeTo(req, rsp); } /** - * @deprecated - * Exposed for stapler. Not meant for programatic consumption. + * @deprecated Exposed for stapler. Not meant for programatic consumption. */ @Exported public Option[] values() { diff --git a/hudson-core/src/main/java/hudson/util/LogTaskListener.java b/hudson-core/src/main/java/hudson/util/LogTaskListener.java index 8d89eb4..e91e2c8 100644 --- a/hudson-core/src/main/java/hudson/util/LogTaskListener.java +++ b/hudson-core/src/main/java/hudson/util/LogTaskListener.java @@ -7,10 +7,10 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: + * Contributors: + * + * * - * - * * *******************************************************************************/ @@ -32,7 +32,7 @@ import java.util.logging.Logger; * {@link TaskListener} which sends messages to a {@link Logger}. */ public class LogTaskListener extends AbstractTaskListener implements Serializable { - + private final TaskListener delegate; public LogTaskListener(Logger logger, Level level) { @@ -104,8 +104,6 @@ public class LogTaskListener extends AbstractTaskListener implements Serializabl public void close() throws IOException { flush(); } - } - private static final long serialVersionUID = 1L; } diff --git a/hudson-core/src/main/java/hudson/util/MaskingClassLoader.java b/hudson-core/src/main/java/hudson/util/MaskingClassLoader.java index 56ec15b..da0fe48 100644 --- a/hudson-core/src/main/java/hudson/util/MaskingClassLoader.java +++ b/hudson-core/src/main/java/hudson/util/MaskingClassLoader.java @@ -7,10 +7,10 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: + * Contributors: + * + * * - * - * * *******************************************************************************/ @@ -19,15 +19,15 @@ package hudson.util; import java.util.Collection; /** - * {@link ClassLoader} that masks a specified set of classes - * from its parent class loader. + * {@link ClassLoader} that masks a specified set of classes from its parent + * class loader. * - * <p> - * This code is used to create an isolated environment. + * <p> This code is used to create an isolated environment. * * @author Kohsuke Kawaguchi */ public class MaskingClassLoader extends ClassLoader { + /** * Prefix of the packages that should be hidden. */ @@ -45,8 +45,9 @@ public class MaskingClassLoader extends ClassLoader { @Override protected synchronized Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { for (String mask : masks) { - if(name.startsWith(mask)) + if (name.startsWith(mask)) { throw new ClassNotFoundException(); + } } return super.loadClass(name, resolve); diff --git a/hudson-core/src/main/java/hudson/util/Memoizer.java b/hudson-core/src/main/java/hudson/util/Memoizer.java index 04729d5..d8eb327 100644 --- a/hudson-core/src/main/java/hudson/util/Memoizer.java +++ b/hudson-core/src/main/java/hudson/util/Memoizer.java @@ -7,10 +7,10 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: + * Contributors: + * + * * - * - * * *******************************************************************************/ @@ -21,28 +21,32 @@ import java.util.concurrent.ConcurrentHashMap; /** * Implements memoization semantics. * - * <p> - * Conceputually a function from K -> V that computes values lazily and remembers the results. - * Often used to implement a data store per key. + * <p> Conceputually a function from K -> V that computes values lazily and + * remembers the results. Often used to implement a data store per key. * * @author Kohsuke Kawaguchi * @since 1.281 */ -public abstract class Memoizer<K,V> { - private final ConcurrentHashMap<K,V> store = new ConcurrentHashMap<K,V>(); +public abstract class Memoizer<K, V> { + + private final ConcurrentHashMap<K, V> store = new ConcurrentHashMap<K, V>(); public V get(K key) { V v = store.get(key); - if(v!=null) return v; + if (v != null) { + return v; + } // TODO: if we want to, we can avoid locking altogether by putting a sentinel value // that represents "the value is being computed". FingerprintMap does this. synchronized (this) { v = store.get(key); - if(v!=null) return v; + if (v != null) { + return v; + } v = compute(key); - store.put(key,v); + store.put(key, v); return v; } } diff --git a/hudson-core/src/main/java/hudson/util/MultipartFormDataParser.java b/hudson-core/src/main/java/hudson/util/MultipartFormDataParser.java index 09eac03..96502c2 100644 --- a/hudson-core/src/main/java/hudson/util/MultipartFormDataParser.java +++ b/hudson-core/src/main/java/hudson/util/MultipartFormDataParser.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 + * * *******************************************************************************/ @@ -34,13 +34,15 @@ import java.util.HashMap; * @author Kohsuke Kawaguchi */ public class MultipartFormDataParser { + private final ServletFileUpload upload = new ServletFileUpload(new DiskFileItemFactory()); - private final Map<String,FileItem> byName = new HashMap<String,FileItem>(); + private final Map<String, FileItem> byName = new HashMap<String, FileItem>(); public MultipartFormDataParser(HttpServletRequest request) throws ServletException { try { - for( FileItem fi : (List<FileItem>)upload.parseRequest(request) ) - byName.put(fi.getFieldName(),fi); + for (FileItem fi : (List<FileItem>) upload.parseRequest(request)) { + byName.put(fi.getFieldName(), fi); + } } catch (FileUploadException e) { throw new ServletException(e); } @@ -48,7 +50,9 @@ public class MultipartFormDataParser { public String get(String key) { FileItem fi = byName.get(key); - if(fi==null) return null; + if (fi == null) { + return null; + } return fi.getString(); } @@ -57,11 +61,12 @@ public class MultipartFormDataParser { } /** - * If any file is created on the disk, delete them all. - * Even if this method is not called, the resource will be still cleaned up later by GC. + * If any file is created on the disk, delete them all. Even if this method + * is not called, the resource will be still cleaned up later by GC. */ public void cleanUp() { - for (FileItem item : byName.values()) + for (FileItem item : byName.values()) { item.delete(); + } } } diff --git a/hudson-core/src/main/java/hudson/util/NoHomeDir.java b/hudson-core/src/main/java/hudson/util/NoHomeDir.java index b473d61..237b81d 100644 --- a/hudson-core/src/main/java/hudson/util/NoHomeDir.java +++ b/hudson-core/src/main/java/hudson/util/NoHomeDir.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 + * * *******************************************************************************/ @@ -19,15 +19,15 @@ package hudson.util; import java.io.File; /** - * Model object used to display the error top page if - * we couldn't create the home directory. + * Model object used to display the error top page if we couldn't create the + * home directory. * - * <p> - * <tt>index.jelly</tt> would display a nice friendly error page. + * <p> <tt>index.jelly</tt> would display a nice friendly error page. * * @author Kohsuke Kawaguchi */ public class NoHomeDir extends ErrorObject { + public final File home; public NoHomeDir(File home) { diff --git a/hudson-core/src/main/java/hudson/util/NoTempDir.java b/hudson-core/src/main/java/hudson/util/NoTempDir.java index 4a4f526..38950c8 100644 --- a/hudson-core/src/main/java/hudson/util/NoTempDir.java +++ b/hudson-core/src/main/java/hudson/util/NoTempDir.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,15 +21,15 @@ import hudson.Functions; import java.io.IOException; /** - * Model object used to display the error top page if - * there appears to be no temporary directory. + * Model object used to display the error top page if there appears to be no + * temporary directory. * - * <p> - * <tt>index.jelly</tt> would display a nice friendly error page. + * <p> <tt>index.jelly</tt> would display a nice friendly error page. * * @author Kohsuke Kawaguchi */ public class NoTempDir extends ErrorObject { + public final IOException exception; public NoTempDir(IOException exception) { diff --git a/hudson-core/src/main/java/hudson/util/NullStream.java b/hudson-core/src/main/java/hudson/util/NullStream.java index fab774a6..927d072 100644 --- a/hudson-core/src/main/java/hudson/util/NullStream.java +++ b/hudson-core/src/main/java/hudson/util/NullStream.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 + * * *******************************************************************************/ @@ -22,7 +22,9 @@ import java.io.OutputStream; * @author Kohsuke Kawaguchi */ public final class NullStream extends OutputStream { - public NullStream() {} + + public NullStream() { + } @Override public void write(byte b[]) { diff --git a/hudson-core/src/main/java/hudson/util/OneShotEvent.java b/hudson-core/src/main/java/hudson/util/OneShotEvent.java index 73a4eb7..dc7fed2 100644 --- a/hudson-core/src/main/java/hudson/util/OneShotEvent.java +++ b/hudson-core/src/main/java/hudson/util/OneShotEvent.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 + * * *******************************************************************************/ @@ -19,18 +19,17 @@ package hudson.util; /** * OConcurrency primitive. * - * <p> - * A {@link OneShotEvent} is like a pandora's box. - * It starts with the closed (non-signaled) state. - * Multiple threads can wait for the event to become the signaled state. + * <p> A {@link OneShotEvent} is like a pandora's box. It starts with the closed + * (non-signaled) state. Multiple threads can wait for the event to become the + * signaled state. * - * <p> - * Once the event becomes signaled, or the pandora's box is opened, - * every thread gets through freely, and there's no way to turn it back off. + * <p> Once the event becomes signaled, or the pandora's box is opened, every + * thread gets through freely, and there's no way to turn it back off. * * @author Kohsuke Kawaguchi */ public final class OneShotEvent { + private boolean signaled; private final Object lock; @@ -47,7 +46,9 @@ public final class OneShotEvent { */ public void signal() { synchronized (lock) { - if(signaled) return; + if (signaled) { + return; + } this.signaled = true; lock.notifyAll(); } @@ -56,27 +57,27 @@ public final class OneShotEvent { /** * Blocks until the event becomes the signaled state. * - * <p> - * This method blocks infinitely until a value is offered. + * <p> This method blocks infinitely until a value is offered. */ public void block() throws InterruptedException { synchronized (lock) { - while(!signaled) + while (!signaled) { lock.wait(); + } } } /** * Blocks until the event becomes the signaled state. * - * <p> - * If the specified amount of time elapses, - * this method returns null even if the value isn't offered. + * <p> If the specified amount of time elapses, this method returns null + * even if the value isn't offered. */ public void block(long timeout) throws InterruptedException { synchronized (lock) { - if(!signaled) + if (!signaled) { lock.wait(timeout); + } } } diff --git a/hudson-core/src/main/java/hudson/util/PackedMap.java b/hudson-core/src/main/java/hudson/util/PackedMap.java index 81e1358..26a26c9 100644 --- a/hudson-core/src/main/java/hudson/util/PackedMap.java +++ b/hudson-core/src/main/java/hudson/util/PackedMap.java @@ -7,7 +7,7 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: + * Contributors: * *******************************************************************************/ @@ -34,7 +34,6 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ - package hudson.util; import com.thoughtworks.xstream.converters.UnmarshallingContext; @@ -54,55 +53,52 @@ import java.util.Set; import java.util.TreeMap; /** - * Read-only map implementation that uses less memory than {@link HashMap}/{@link TreeMap}. + * Read-only map implementation that uses less memory than + * {@link HashMap}/{@link TreeMap}. * - * <p> - * The implementation is backed by a single exact-length array, so this implementation has the following - * performance characteristics. + * <p> The implementation is backed by a single exact-length array, so this + * implementation has the following performance characteristics. * - * <ul> - * <li>iteration is fast (but creates a lot of short-lived objects.) - * <li>lookup is O(N) - * <li>memory consumption is low - * </ul> + * <ul> <li>iteration is fast (but creates a lot of short-lived objects.) + * <li>lookup is O(N) <li>memory consumption is low </ul> * * @author Kohsuke Kawaguchi */ @SuppressWarnings({"unchecked"}) -public final class PackedMap<K,V> extends AbstractMap<K,V> { +public final class PackedMap<K, V> extends AbstractMap<K, V> { + private Object[] kvpairs; /** * - * @param src - * Map to copy contents from. Iteration order is preserved. + * @param src Map to copy contents from. Iteration order is preserved. */ - public static <K,V> PackedMap<K,V> of(Map<? extends K,? extends V> src) { + public static <K, V> PackedMap<K, V> of(Map<? extends K, ? extends V> src) { return new PackedMap<K, V>(src); } - private PackedMap(Map<? extends K,? extends V> src) { - kvpairs = new Object[src.size()*2]; - int i=0; + private PackedMap(Map<? extends K, ? extends V> src) { + kvpairs = new Object[src.size() * 2]; + int i = 0; for (Entry<? extends K, ? extends V> e : src.entrySet()) { kvpairs[i++] = e.getKey(); kvpairs[i++] = e.getValue(); } } - - private final Set<Entry<K,V>> entrySet = new AbstractSet<Entry<K, V>>() { + private final Set<Entry<K, V>> entrySet = new AbstractSet<Entry<K, V>>() { @Override public Iterator<Entry<K, V>> iterator() { return new Iterator<Entry<K, V>>() { - int index=0; + int index = 0; + public boolean hasNext() { - return index<kvpairs.length; + return index < kvpairs.length; } @SuppressWarnings({"unchecked"}) public Entry<K, V> next() { - final K k = (K)kvpairs[index++]; - final V v = (V)kvpairs[index++]; + final K k = (K) kvpairs[index++]; + final V v = (V) kvpairs[index++]; return new Entry<K, V>() { public K getKey() { return k; @@ -126,7 +122,7 @@ public final class PackedMap<K,V> extends AbstractMap<K,V> { @Override public int size() { - return kvpairs.length/2; + return kvpairs.length / 2; } }; @@ -137,17 +133,21 @@ public final class PackedMap<K,V> extends AbstractMap<K,V> { @Override public boolean containsKey(Object key) { - for (int i=0; i<kvpairs.length; i+=2) - if (key.equals(kvpairs[i])) + for (int i = 0; i < kvpairs.length; i += 2) { + if (key.equals(kvpairs[i])) { return true; + } + } return false; } @Override public V get(Object key) { - for (int i=0; i<kvpairs.length; i+=2) - if (key.equals(kvpairs[i])) - return (V)kvpairs[i+1]; + for (int i = 0; i < kvpairs.length; i += 2) { + if (key.equals(kvpairs[i])) { + return (V) kvpairs[i + 1]; + } + } return null; } @@ -156,7 +156,7 @@ public final class PackedMap<K,V> extends AbstractMap<K,V> { return new AbstractList<V>() { @Override public V get(int index) { - return (V)kvpairs[index*2]; + return (V) kvpairs[index * 2]; } @Override @@ -170,23 +170,24 @@ public final class PackedMap<K,V> extends AbstractMap<K,V> { * Should persist like a regular map. */ public static class ConverterImpl extends MapConverter { + public ConverterImpl(Mapper mapper) { super(mapper); } @Override public boolean canConvert(Class type) { - return type==PackedMap.class; + return type == PackedMap.class; } @Override protected Object createCollection(Class type) { - return new LinkedHashMap<String,String>(); + return new LinkedHashMap<String, String>(); } @Override public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { - return PackedMap.of((Map)super.unmarshal(reader, context)); + return PackedMap.of((Map) super.unmarshal(reader, context)); } } } diff --git a/hudson-core/src/main/java/hudson/util/PersistedList.java b/hudson-core/src/main/java/hudson/util/PersistedList.java index aef7002..7d5b27e 100644 --- a/hudson-core/src/main/java/hudson/util/PersistedList.java +++ b/hudson-core/src/main/java/hudson/util/PersistedList.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, Nikita Levyankov - * + * * *******************************************************************************/ @@ -41,6 +41,7 @@ import org.apache.commons.lang3.builder.HashCodeBuilder; * @since 1.MULTISOURCE */ public class PersistedList<T> implements Iterable<T> { + protected final CopyOnWriteList<T> data = new CopyOnWriteList<T>(); protected Saveable owner = Saveable.NOOP; @@ -79,9 +80,11 @@ public class PersistedList<T> implements Iterable<T> { } public <U extends T> U get(Class<U> type) { - for (T t : data) - if(type.isInstance(t)) + for (T t : data) { + if (type.isInstance(t)) { return type.cast(t); + } + } return null; } @@ -90,9 +93,11 @@ public class PersistedList<T> implements Iterable<T> { */ public <U extends T> List<U> getAll(Class<U> type) { List<U> r = new ArrayList<U>(); - for (T t : data) - if(type.isInstance(t)) + for (T t : data) { + if (type.isInstance(t)) { r.add(type.cast(t)); + } + } return r; } @@ -105,7 +110,7 @@ public class PersistedList<T> implements Iterable<T> { */ public void remove(Class<? extends T> type) throws IOException { for (T t : data) { - if(t.getClass()==type) { + if (t.getClass() == type) { data.remove(t); onModified(); return; @@ -115,23 +120,25 @@ public class PersistedList<T> implements Iterable<T> { public boolean remove(T o) throws IOException { boolean b = data.remove(o); - if (b) onModified(); + if (b) { + onModified(); + } return b; } public void removeAll(Class<? extends T> type) throws IOException { - boolean modified=false; + boolean modified = false; for (T t : data) { - if(t.getClass()==type) { + if (t.getClass() == type) { data.remove(t); - modified=true; + modified = true; } } - if(modified) + if (modified) { onModified(); + } } - public void clear() { data.clear(); } @@ -175,6 +182,7 @@ public class PersistedList<T> implements Iterable<T> { * Serializaion form is compatible with plain {@link List}. */ public static class ConverterImpl extends AbstractCollectionConverter { + CopyOnWriteList.ConverterImpl copyOnWriteListConverter; public ConverterImpl(Mapper mapper) { @@ -188,15 +196,16 @@ public class PersistedList<T> implements Iterable<T> { } public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { - for (Object o : (PersistedList) source) + for (Object o : (PersistedList) source) { writeItem(o, context, writer); + } } public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { CopyOnWriteList core = copyOnWriteListConverter.unmarshal(reader, context); try { - PersistedList r = (PersistedList)context.getRequiredType().newInstance(); + PersistedList r = (PersistedList) context.getRequiredType().newInstance(); r.data.replaceBy(core); return r; } catch (InstantiationException e) { @@ -222,18 +231,16 @@ public class PersistedList<T> implements Iterable<T> { PersistedList that = (PersistedList) o; return new EqualsBuilder() - .append(data, that.data) - .append(owner, that.owner) - .isEquals(); + .append(data, that.data) + .append(owner, that.owner) + .isEquals(); } @Override public int hashCode() { return new HashCodeBuilder() - .append(data) - .append(owner) - .toHashCode(); + .append(data) + .append(owner) + .toHashCode(); } } - - diff --git a/hudson-core/src/main/java/hudson/util/PluginServletFilter.java b/hudson-core/src/main/java/hudson/util/PluginServletFilter.java index 9e6cbb0..228d54d 100644 --- a/hudson-core/src/main/java/hudson/util/PluginServletFilter.java +++ b/hudson-core/src/main/java/hudson/util/PluginServletFilter.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 + * * *******************************************************************************/ @@ -30,73 +30,73 @@ import java.util.List; import java.util.Vector; /** - * Servlet {@link Filter} that chains multiple {@link Filter}s, provided by plugins + * Servlet {@link Filter} that chains multiple {@link Filter}s, provided by + * plugins * - * <p> - * While this class by itself is not an extension point, I'm marking this class - * as an extension point so that this class will be more discoverable. + * <p> While this class by itself is not an extension point, I'm marking this + * class as an extension point so that this class will be more discoverable. * - * <p> - * {@link SecurityRealm} that wants to contribute {@link Filter}s should first - * check if {@link SecurityRealm#createFilter(FilterConfig)} is more appropriate. + * <p> {@link SecurityRealm} that wants to contribute {@link Filter}s should + * first check if {@link SecurityRealm#createFilter(FilterConfig)} is more + * appropriate. * * @see SecurityRealm */ public class PluginServletFilter implements Filter, ExtensionPoint { - private static final List<Filter> LIST = new Vector<Filter>(); - - private static FilterConfig filterConfig; - + private static final List<Filter> LIST = new Vector<Filter>(); + private static FilterConfig filterConfig; + public PluginServletFilter() { } public void init(FilterConfig filterConfig) throws ServletException { - PluginServletFilter.filterConfig = filterConfig; - synchronized (LIST) { - for (Filter f : LIST) { - f.init(filterConfig); - } - } + PluginServletFilter.filterConfig = filterConfig; + synchronized (LIST) { + for (Filter f : LIST) { + f.init(filterConfig); + } + } } - + public static void addFilter(Filter filter) throws ServletException { - synchronized (LIST) { - if (filterConfig != null) { - filter.init(filterConfig); - } - LIST.add(filter); - } + synchronized (LIST) { + if (filterConfig != null) { + filter.init(filterConfig); + } + LIST.add(filter); + } } public static void removeFilter(Filter filter) throws ServletException { - synchronized (LIST) { + synchronized (LIST) { LIST.remove(filter); - } + } } public void doFilter(ServletRequest request, ServletResponse response, final FilterChain chain) throws IOException, ServletException { new FilterChain() { - private int position=0; + private int position = 0; // capture the array for thread-safety private final Filter[] filters = LIST.toArray(new Filter[LIST.size()]); public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException { - if(position==filters.length) { + if (position == filters.length) { // reached to the end - chain.doFilter(request,response); + chain.doFilter(request, response); } else { // call next - filters[position++].doFilter(request,response,this); + filters[position++].doFilter(request, response, this); } } - }.doFilter(request,response); + }.doFilter(request, response); } public void destroy() { - synchronized (LIST) { - for (Filter f : LIST) + synchronized (LIST) { + for (Filter f : LIST) { f.destroy(); + } } } } diff --git a/hudson-core/src/main/java/hudson/util/ProcessKiller.java b/hudson-core/src/main/java/hudson/util/ProcessKiller.java index 2f3a4aa..71c661b 100644 --- a/hudson-core/src/main/java/hudson/util/ProcessKiller.java +++ b/hudson-core/src/main/java/hudson/util/ProcessKiller.java @@ -7,10 +7,10 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: + * Contributors: + * + * * - * - * * *******************************************************************************/ @@ -27,28 +27,29 @@ import java.io.Serializable; * Extension point that defines more elaborate way of killing processes, such as * sudo or pfexec, for {@link ProcessTree}. * - * <h2>Lifecycle</h2> - * <p> - * Each implementation of {@link ProcessKiller} is instantiated once on the master. - * Whenever a process needs to be killed, those implementations are serialized and sent over - * to the appropriate slave, then the {@link #kill(hudson.util.ProcessTree.OSProcess)} method is invoked - * to attempt to kill the process. + * <h2>Lifecycle</h2> <p> Each implementation of {@link ProcessKiller} is + * instantiated once on the master. Whenever a process needs to be killed, those + * implementations are serialized and sent over to the appropriate slave, then + * the {@link #kill(hudson.util.ProcessTree.OSProcess)} method is invoked to + * attempt to kill the process. * - * <p> - * One of the consequences of this design is that the implementation should be stateless - * and concurrent-safe. That is, the {@link #kill(hudson.util.ProcessTree.OSProcess)} method can be invoked by multiple threads - * concurrently on the single instance. + * <p> One of the consequences of this design is that the implementation should + * be stateless and concurrent-safe. That is, the + * {@link #kill(hudson.util.ProcessTree.OSProcess)} method can be invoked by + * multiple threads concurrently on the single instance. * - * <p> - * Another consequence of this design is that if your {@link ProcessKiller} requires configuration, - * it needs to be serializable, and configuration needs to be updated atomically, as another - * thread may be calling into {@link #kill(hudson.util.ProcessTree.OSProcess)} just when you are updating your configuration. + * <p> Another consequence of this design is that if your {@link ProcessKiller} + * requires configuration, it needs to be serializable, and configuration needs + * to be updated atomically, as another thread may be calling into + * {@link #kill(hudson.util.ProcessTree.OSProcess)} just when you are updating + * your configuration. * * @author jpederzolli * @author Kohsuke Kawaguchi * @since 1.362 */ public abstract class ProcessKiller implements ExtensionPoint, Serializable { + /** * Returns all the registered {@link ProcessKiller} descriptors. */ @@ -59,19 +60,19 @@ public abstract class ProcessKiller implements ExtensionPoint, Serializable { /** * Attempts to kill the given process. * - * @param process process to be killed. Always a {@linkplain ProcessTree.Local local process}. - * @return - * true if the killing was successful, and Hudson won't try to use other {@link ProcessKiller} - * implementations to kill the process. false if the killing failed or is unattempted, and Hudson will continue - * to use the rest of the {@link ProcessKiller} implementations to try to kill the process. - * @throws IOException - * The caller will log this exception and otherwise treat as if the method returned false, and moves on - * to the next killer. - * @throws InterruptedException - * if the callee performs a time consuming operation and if the thread is canceled, do not catch - * {@link InterruptedException} and just let it thrown from the method. + * @param process process to be killed. Always a + * {@linkplain ProcessTree.Local local process}. + * @return true if the killing was successful, and Hudson won't try to use + * other {@link ProcessKiller} implementations to kill the process. false if + * the killing failed or is unattempted, and Hudson will continue to use the + * rest of the {@link ProcessKiller} implementations to try to kill the + * process. + * @throws IOException The caller will log this exception and otherwise + * treat as if the method returned false, and moves on to the next killer. + * @throws InterruptedException if the callee performs a time consuming + * operation and if the thread is canceled, do not catch + * {@link InterruptedException} and just let it thrown from the method. */ public abstract boolean kill(ProcessTree.OSProcess process) throws IOException, InterruptedException; - private static final long serialVersionUID = 1L; } diff --git a/hudson-core/src/main/java/hudson/util/ProcessTree.java b/hudson-core/src/main/java/hudson/util/ProcessTree.java index 96dbc49..4707373 100644 --- a/hudson-core/src/main/java/hudson/util/ProcessTree.java +++ b/hudson-core/src/main/java/hudson/util/ProcessTree.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 + * * *******************************************************************************/ @@ -61,32 +61,32 @@ import org.slf4j.LoggerFactory; /** * Represents a snapshot of the process tree of the current system. * - * <p> - * A {@link ProcessTree} is really conceptually a map from process ID to a {@link OSProcess} object. - * When Hudson runs on platforms that support process introspection, this allows you to introspect - * and do some useful things on processes. On other platforms, the implementation falls back to - * "do nothing" behavior. + * <p> A {@link ProcessTree} is really conceptually a map from process ID to a + * {@link OSProcess} object. When Hudson runs on platforms that support process + * introspection, this allows you to introspect and do some useful things on + * processes. On other platforms, the implementation falls back to "do nothing" + * behavior. * - * <p> - * {@link ProcessTree} is remotable. + * <p> {@link ProcessTree} is remotable. * * @author Kohsuke Kawaguchi * @since 1.315 */ public abstract class ProcessTree implements Iterable<OSProcess>, IProcessTree, Serializable { + /** * To be filled in the constructor of the derived type. */ protected final Map<Integer/*pid*/, OSProcess> processes = new HashMap<Integer, OSProcess>(); - /** - * Lazily obtained {@link ProcessKiller}s to be applied on this process tree. + * Lazily obtained {@link ProcessKiller}s to be applied on this process + * tree. */ private transient volatile List<ProcessKiller> killers; // instantiation only allowed for subtypes in this class - private ProcessTree() {} - + private ProcessTree() { + } private static Logger logger = LoggerFactory.getLogger(ProcessTree.class); /** @@ -104,46 +104,48 @@ public abstract class ProcessTree implements Iterable<OSProcess>, IProcessTree, } /** - * Try to convert {@link Process} into this process object - * or null if it fails (for example, maybe the snapshot is taken after - * this process has already finished.) + * Try to convert {@link Process} into this process object or null if it + * fails (for example, maybe the snapshot is taken after this process has + * already finished.) */ public abstract OSProcess get(Process proc); /** * Kills all the processes that have matching environment variables. * - * <p> - * In this method, the method is given a - * "model environment variables", which is a list of environment variables - * and their values that are characteristic to the launched process. - * The implementation is expected to find processes - * in the system that inherit these environment variables, and kill - * them all. This is suitable for locating daemon processes - * that cannot be tracked by the regular ancestor/descendant relationship. + * <p> In this method, the method is given a "model environment variables", + * which is a list of environment variables and their values that are + * characteristic to the launched process. The implementation is expected to + * find processes in the system that inherit these environment variables, + * and kill them all. This is suitable for locating daemon processes that + * cannot be tracked by the regular ancestor/descendant relationship. */ public abstract void killAll(Map<String, String> modelEnvVars) throws InterruptedException; /** - * Convenience method that does {@link #killAll(Map)} and {@link OSProcess#killRecursively()}. - * This is necessary to reliably kill the process and its descendants, as some OS - * may not implement {@link #killAll(Map)}. + * Convenience method that does {@link #killAll(Map)} and + * {@link OSProcess#killRecursively()}. This is necessary to reliably kill + * the process and its descendants, as some OS may not implement + * {@link #killAll(Map)}. * * Either of the parameter can be null. */ public void killAll(Process proc, Map<String, String> modelEnvVars) throws InterruptedException { logger.info("killAll (process started by build): process=" + proc + " and envs=" + modelEnvVars); OSProcess p = get(proc); - if(p!=null) p.killRecursively(); - if(modelEnvVars!=null) + if (p != null) { + p.killRecursively(); + } + if (modelEnvVars != null) { killAll(modelEnvVars); + } } /** * Obtains the list of killers. */ /*package*/ final List<ProcessKiller> getKillers() throws InterruptedException { - if (killers==null) + if (killers == null) { try { killers = SlaveComputer.getChannelToMaster().call(new Callable<List<ProcessKiller>, IOException>() { public List<ProcessKiller> call() throws IOException { @@ -151,9 +153,10 @@ public abstract class ProcessTree implements Iterable<OSProcess>, IProcessTree, } }); } catch (IOException e) { - logger.info("Failed to obtain killers (process started by build) ",e); + logger.info("Failed to obtain killers (process started by build) ", e); killers = Collections.emptyList(); } + } return killers; } @@ -161,6 +164,7 @@ public abstract class ProcessTree implements Iterable<OSProcess>, IProcessTree, * Represents a process. */ public abstract class OSProcess implements IOSProcess, Serializable { + final int pid; // instantiation only allowed for subtypes in this class @@ -171,10 +175,11 @@ public abstract class ProcessTree implements Iterable<OSProcess>, IProcessTree, public final int getPid() { return pid; } + /** - * Gets the parent process. This method may return null, because - * there's no guarantee that we are getting a consistent snapshot - * of the whole system state. + * Gets the parent process. This method may return null, because there's + * no guarantee that we are getting a consistent snapshot of the whole + * system state. */ public abstract OSProcess getParent(); @@ -187,9 +192,11 @@ public abstract class ProcessTree implements Iterable<OSProcess>, IProcessTree, */ public final List<OSProcess> getChildren() { List<OSProcess> r = new ArrayList<OSProcess>(); - for (OSProcess p : ProcessTree.this) - if(p.getParent()==this) + for (OSProcess p : ProcessTree.this) { + if (p.getParent() == this) { r.add(p); + } + } return r; } @@ -199,68 +206,70 @@ public abstract class ProcessTree implements Iterable<OSProcess>, IProcessTree, public abstract void kill() throws InterruptedException; void killByKiller() throws InterruptedException { - for (ProcessKiller killer : getKillers()) + for (ProcessKiller killer : getKillers()) { try { - if (killer.kill(this)) + if (killer.kill(this)) { break; + } } catch (IOException e) { - logger.info("Failed to kill the process started by process - "+getPid(),e); + logger.info("Failed to kill the process started by process - " + getPid(), e); } + } } /** - * Kills this process and all the descendants. - * <p> - * Note that the notion of "descendants" is somewhat vague, - * in the presence of such things like daemons. On platforms - * where the recursive operation is not supported, this just kills - * the current process. + * Kills this process and all the descendants. <p> Note that the notion + * of "descendants" is somewhat vague, in the presence of such things + * like daemons. On platforms where the recursive operation is not + * supported, this just kills the current process. */ public abstract void killRecursively() throws InterruptedException; /** * Gets the command-line arguments of this process. * - * <p> - * On Windows, where the OS models command-line arguments as a single string, this method - * computes the approximated tokenization. + * <p> On Windows, where the OS models command-line arguments as a + * single string, this method computes the approximated tokenization. */ public abstract List<String> getArguments(); /** * Obtains the environment variables of this process. * - * @return - * empty map if failed (for example because the process is already dead, - * or the permission was denied.) + * @return empty map if failed (for example because the process is + * already dead, or the permission was denied.) */ public abstract EnvVars getEnvironmentVariables(); /** - * Given the environment variable of a process and the "model environment variable" that Hudson - * used for launching the build, returns true if there's a match (which means the process should - * be considered a descendant of a build.) + * Given the environment variable of a process and the "model + * environment variable" that Hudson used for launching the build, + * returns true if there's a match (which means the process should be + * considered a descendant of a build.) */ - public final boolean hasMatchingEnvVars(Map<String,String> modelEnvVar) { - if(modelEnvVar.isEmpty()) - // sanity check so that we don't start rampage. + public final boolean hasMatchingEnvVars(Map<String, String> modelEnvVar) { + if (modelEnvVar.isEmpty()) // sanity check so that we don't start rampage. + { return false; + } - SortedMap<String,String> envs = getEnvironmentVariables(); - for (Entry<String,String> e : modelEnvVar.entrySet()) { + SortedMap<String, String> envs = getEnvironmentVariables(); + for (Entry<String, String> e : modelEnvVar.entrySet()) { String v = envs.get(e.getKey()); - if(v==null || !v.equals(e.getValue())) + if (v == null || !v.equals(e.getValue())) { return false; // no match + } } return true; } /** - * Executes a chunk of code at the same machine where this process resides. + * Executes a chunk of code at the same machine where this process + * resides. */ public <T> T act(ProcessCallable<T> callable) throws IOException, InterruptedException { - return callable.invoke(this,Hudson.MasterComputer.localChannel); + return callable.invoke(this, Hudson.MasterComputer.localChannel); } Object writeReplace() { @@ -272,6 +281,7 @@ public abstract class ProcessTree implements Iterable<OSProcess>, IProcessTree, * Serialized form of {@link OSProcess} is the PID and {@link ProcessTree} */ private final class SerializedProcess implements Serializable { + private final int pid; private static final long serialVersionUID = 1L; @@ -285,29 +295,29 @@ public abstract class ProcessTree implements Iterable<OSProcess>, IProcessTree, } /** - * Code that gets executed on the machine where the {@link OSProcess} is local. - * Used to act on {@link OSProcess}. + * Code that gets executed on the machine where the {@link OSProcess} is + * local. Used to act on {@link OSProcess}. * * @see OSProcess#act(ProcessCallable) */ public static interface ProcessCallable<T> extends Serializable { + /** - * Performs the computational task on the node where the data is located. + * Performs the computational task on the node where the data is + * located. * - * @param process - * {@link OSProcess} that represents the local process. - * @param channel - * The "back pointer" of the {@link Channel} that represents the communication - * with the node from where the code was sent. + * @param process {@link OSProcess} that represents the local process. + * @param channel The "back pointer" of the {@link Channel} that + * represents the communication with the node from where the code was + * sent. */ T invoke(OSProcess process, VirtualChannel channel) throws IOException; } - /** - * Gets the {@link ProcessTree} of the current system - * that JVM runs in, or in the worst case return the default one - * that's not capable of killing descendants at all. + * Gets the {@link ProcessTree} of the current system that JVM runs in, or + * in the worst case return the default one that's not capable of killing + * descendants at all. * * @return ProcessTree of the current system. */ @@ -316,42 +326,45 @@ public abstract class ProcessTree implements Iterable<OSProcess>, IProcessTree, } /** - * Gets the {@link ProcessTree} of the current system - * that JVM runs in, or in the worst case return the default one - * that's not capable of killing descendants at all. + * Gets the {@link ProcessTree} of the current system that JVM runs in, or + * in the worst case return the default one that's not capable of killing + * descendants at all. * * @param nativeUtils instance of NativeUtils. * @return ProcessTree of the current system. */ public static ProcessTree get(NativeUtils nativeUtils) { - if(!enabled) + if (!enabled) { return DEFAULT; + } try { - if(File.pathSeparatorChar==';') + if (File.pathSeparatorChar == ';') { return new Windows(nativeUtils); + } String os = Util.fixNull(System.getProperty("os.name")); - if(os.equals("Linux")) + if (os.equals("Linux")) { return new Linux(); - if(os.equals("SunOS")) + } + if (os.equals("SunOS")) { return new Solaris(); - if(os.equals("Mac OS X")) + } + if (os.equals("Mac OS X")) { return new Darwin(nativeUtils); + } } catch (LinkageError e) { - logger.warn("Failed to load winp. Reverting to the default",e); + logger.warn("Failed to load winp. Reverting to the default", e); enabled = false; } return DEFAULT; } - // // // implementation follows //------------------------------------------- // - /** * Empty process list as a default value if the platform doesn't support it. */ @@ -387,7 +400,6 @@ public abstract class ProcessTree implements Iterable<OSProcess>, IProcessTree, } }; - private static final class Windows extends Local { private NativeUtils nativeUtils; @@ -397,7 +409,7 @@ public abstract class ProcessTree implements Iterable<OSProcess>, IProcessTree, try { for (final NativeProcess p : nativeUtils.getWindowsProcesses()) { int pid = p.getPid(); - super.processes.put(pid,new OSProcess(pid) { + super.processes.put(pid, new OSProcess(pid) { private EnvVars env; private List<String> args; @@ -419,13 +431,17 @@ public abstract class ProcessTree implements Iterable<OSProcess>, IProcessTree, @Override public synchronized List<String> getArguments() { - if(args==null) args = Arrays.asList(QuotedStringTokenizer.tokenize(p.getCommandLine())); + if (args == null) { + args = Arrays.asList(QuotedStringTokenizer.tokenize(p.getCommandLine())); + } return args; } @Override public synchronized EnvVars getEnvironmentVariables() { - if(env==null) env = new EnvVars(p.getEnvironmentVariables()); + if (env == null) { + env = new EnvVars(p.getEnvironmentVariables()); + } return env; } }); @@ -453,24 +469,25 @@ public abstract class ProcessTree implements Iterable<OSProcess>, IProcessTree, } boolean matched; - + try { matched = p.hasMatchingEnvVars(modelEnvVars); } catch (NativeAccessException e) { // likely a missing privilege - logger.debug( " Failed to check environment variable match", e); + logger.debug(" Failed to check environment variable match", e); continue; } if (matched) { logger.debug("Killing process started by build " + p.getPid()); p.killRecursively(); - } + } } } } static abstract class Unix extends Local { + @Override public OSProcess get(Process proc) { try { @@ -483,22 +500,26 @@ public abstract class ProcessTree implements Iterable<OSProcess>, IProcessTree, } public void killAll(Map<String, String> modelEnvVars) throws InterruptedException { - for (OSProcess p : this) - if(p.hasMatchingEnvVars(modelEnvVars)) + for (OSProcess p : this) { + if (p.hasMatchingEnvVars(modelEnvVars)) { p.killRecursively(); + } + } } } + /** * {@link ProcessTree} based on /proc. */ static abstract class ProcfsUnix extends Unix { + ProcfsUnix() { File[] processes = new File("/proc").listFiles(new FileFilter() { public boolean accept(File f) { return f.isDirectory(); } }); - if(processes==null) { + if (processes == null) { logger.info("No /proc"); return; } @@ -512,7 +533,7 @@ public abstract class ProcessTree implements Iterable<OSProcess>, IProcessTree, continue; } try { - this.processes.put(pid,createProcess(pid)); + this.processes.put(pid, createProcess(pid)); } catch (IOException e) { // perhaps the process status has changed since we obtained a directory listing } @@ -526,12 +547,13 @@ public abstract class ProcessTree implements Iterable<OSProcess>, IProcessTree, * A process. */ public abstract class UnixProcess extends OSProcess { + protected UnixProcess(int pid) { super(pid); } protected final File getFile(String relativePath) { - return new File(new File("/proc/"+getPid()),relativePath); + return new File(new File("/proc/" + getPid()), relativePath); } /** @@ -540,7 +562,7 @@ public abstract class ProcessTree implements Iterable<OSProcess>, IProcessTree, public void kill() throws InterruptedException { try { int pid = getPid(); - logger.debug("Killing pid="+pid); + logger.debug("Killing pid=" + pid); UnixReflection.DESTROY_PROCESS.invoke(null, pid); } catch (IllegalAccessException e) { // this is impossible @@ -549,27 +571,28 @@ public abstract class ProcessTree implements Iterable<OSProcess>, IProcessTree, throw x; } catch (InvocationTargetException e) { // tunnel serious errors - if(e.getTargetException() instanceof Error) - throw (Error)e.getTargetException(); + if (e.getTargetException() instanceof Error) { + throw (Error) e.getTargetException(); + } // otherwise log and let go. I need to see when this happens - logger.info( "Failed to terminate pid="+getPid(),e); + logger.info("Failed to terminate pid=" + getPid(), e); } killByKiller(); } public void killRecursively() throws InterruptedException { - logger.debug("Recursively killing pid="+getPid()); - for (OSProcess p : getChildren()) + logger.debug("Recursively killing pid=" + getPid()); + for (OSProcess p : getChildren()) { p.killRecursively(); + } kill(); } /** * Obtains the argument list of this process. * - * @return - * empty list if failed (for example because the process is already dead, - * or the permission was denied.) + * @return empty list if failed (for example because the process is + * already dead, or the permission was denied.) */ public abstract List<String> getArguments(); } @@ -578,11 +601,11 @@ public abstract class ProcessTree implements Iterable<OSProcess>, IProcessTree, * Reflection used in the Unix support. */ private static final class UnixReflection { + /** * Field to access the PID of the process. */ private static final Field PID_FIELD; - /** * Method to destroy a process, given pid. */ @@ -594,7 +617,7 @@ public abstract class ProcessTree implements Iterable<OSProcess>, IProcessTree, PID_FIELD = clazz.getDeclaredField("pid"); PID_FIELD.setAccessible(true); - DESTROY_PROCESS = clazz.getDeclaredMethod("destroyProcess",int.class); + DESTROY_PROCESS = clazz.getDeclaredMethod("destroyProcess", int.class); DESTROY_PROCESS.setAccessible(true); } catch (ClassNotFoundException e) { LinkageError x = new LinkageError(); @@ -612,13 +635,14 @@ public abstract class ProcessTree implements Iterable<OSProcess>, IProcessTree, } } - static class Linux extends ProcfsUnix { + protected LinuxProcess createProcess(int pid) throws IOException { return new LinuxProcess(pid); } class LinuxProcess extends UnixProcess { + private int ppid = -1; private EnvVars envVars; private List<String> arguments; @@ -629,9 +653,9 @@ public abstract class ProcessTree implements Iterable<OSProcess>, IProcessTree, BufferedReader r = new BufferedReader(new FileReader(getFile("status"))); try { String line; - while((line=r.readLine())!=null) { - line=line.toLowerCase(Locale.ENGLISH); - if(line.startsWith("ppid:")) { + while ((line = r.readLine()) != null) { + line = line.toLowerCase(Locale.ENGLISH); + if (line.startsWith("ppid:")) { ppid = Integer.parseInt(line.substring(5).trim()); break; } @@ -639,8 +663,9 @@ public abstract class ProcessTree implements Iterable<OSProcess>, IProcessTree, } finally { r.close(); } - if(ppid==-1) - throw new IOException("Failed to parse PPID from /proc/"+pid+"/status"); + if (ppid == -1) { + throw new IOException("Failed to parse PPID from /proc/" + pid + "/status"); + } } public OSProcess getParent() { @@ -648,17 +673,18 @@ public abstract class ProcessTree implements Iterable<OSProcess>, IProcessTree, } public synchronized List<String> getArguments() { - if(arguments!=null) + if (arguments != null) { return arguments; + } arguments = new ArrayList<String>(); try { byte[] cmdline = FileUtils.readFileToByteArray(getFile("cmdline")); - int pos=0; + int pos = 0; for (int i = 0; i < cmdline.length; i++) { byte b = cmdline[i]; - if(b==0) { - arguments.add(new String(cmdline,pos,i-pos)); - pos=i+1; + if (b == 0) { + arguments.add(new String(cmdline, pos, i - pos)); + pos = i + 1; } } } catch (IOException e) { @@ -670,17 +696,18 @@ public abstract class ProcessTree implements Iterable<OSProcess>, IProcessTree, } public synchronized EnvVars getEnvironmentVariables() { - if(envVars !=null) + if (envVars != null) { return envVars; + } envVars = new EnvVars(); try { byte[] environ = FileUtils.readFileToByteArray(getFile("environ")); - int pos=0; + int pos = 0; for (int i = 0; i < environ.length; i++) { byte b = environ[i]; - if(b==0) { - envVars.addLine(new String(environ,pos,i-pos)); - pos=i+1; + if (b == 0) { + envVars.addLine(new String(environ, pos, i - pos)); + pos = i + 1; } } } catch (IOException e) { @@ -695,22 +722,25 @@ public abstract class ProcessTree implements Iterable<OSProcess>, IProcessTree, /** * Implementation for Solaris that uses <tt>/proc</tt>. * - * Amazingly, this single code works for both 32bit and 64bit Solaris, despite the fact - * that does a lot of pointer manipulation and what not. + * Amazingly, this single code works for both 32bit and 64bit Solaris, + * despite the fact that does a lot of pointer manipulation and what not. */ static class Solaris extends ProcfsUnix { + protected OSProcess createProcess(final int pid) throws IOException { return new SolarisProcess(pid); } private class SolarisProcess extends UnixProcess { + private final int ppid; /** - * Address of the environment vector. Even on 64bit Solaris this is still 32bit pointer. + * Address of the environment vector. Even on 64bit Solaris this is + * still 32bit pointer. */ private final int envp; /** - * Similarly, address of the arguments vector. + * Similarly, address of the arguments vector. */ private final int argp; private final int argc; @@ -720,7 +750,7 @@ public abstract class ProcessTree implements Iterable<OSProcess>, IProcessTree, private SolarisProcess(int pid) throws IOException { super(pid); - RandomAccessFile psinfo = new RandomAccessFile(getFile("psinfo"),"r"); + RandomAccessFile psinfo = new RandomAccessFile(getFile("psinfo"), "r"); try { // see http://cvs.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/uts/common/sys/procfs.h //typedef struct psinfo { @@ -760,8 +790,9 @@ public abstract class ProcessTree implements Iterable<OSProcess>, IProcessTree, // for how to read this information psinfo.seek(8); - if(adjust(psinfo.readInt())!=pid) + if (adjust(psinfo.readInt()) != pid) { throw new IOException("psinfo PID mismatch"); // sanity check + } ppid = adjust(psinfo.readInt()); psinfo.seek(188); // now jump to pr_argc @@ -771,8 +802,9 @@ public abstract class ProcessTree implements Iterable<OSProcess>, IProcessTree, } finally { psinfo.close(); } - if(ppid==-1) - throw new IOException("Failed to parse PPID from /proc/"+pid+"/status"); + if (ppid == -1) { + throw new IOException("Failed to parse PPID from /proc/" + pid + "/status"); + } } @@ -781,22 +813,24 @@ public abstract class ProcessTree implements Iterable<OSProcess>, IProcessTree, } public synchronized List<String> getArguments() { - if(arguments!=null) + if (arguments != null) { return arguments; + } arguments = new ArrayList<String>(argc); try { - RandomAccessFile as = new RandomAccessFile(getFile("as"),"r"); - if(logger.isTraceEnabled()) - logger.debug("Reading "+getFile("as")); + RandomAccessFile as = new RandomAccessFile(getFile("as"), "r"); + if (logger.isTraceEnabled()) { + logger.debug("Reading " + getFile("as")); + } try { - for( int n=0; n<argc; n++ ) { + for (int n = 0; n < argc; n++) { // read a pointer to one entry - as.seek(to64(argp+n*4)); + as.seek(to64(argp + n * 4)); int p = adjust(as.readInt()); - arguments.add(readLine(as, p, "argv["+ n +"]")); + arguments.add(readLine(as, p, "argv[" + n + "]")); } } finally { as.close(); @@ -811,24 +845,26 @@ public abstract class ProcessTree implements Iterable<OSProcess>, IProcessTree, } public synchronized EnvVars getEnvironmentVariables() { - if(envVars !=null) + if (envVars != null) { return envVars; + } envVars = new EnvVars(); try { - RandomAccessFile as = new RandomAccessFile(getFile("as"),"r"); - if(logger.isTraceEnabled()) - logger.debug("Reading "+getFile("as")); + RandomAccessFile as = new RandomAccessFile(getFile("as"), "r"); + if (logger.isTraceEnabled()) { + logger.debug("Reading " + getFile("as")); + } try { - for( int n=0; ; n++ ) { + for (int n = 0;; n++) { // read a pointer to one entry - as.seek(to64(envp+n*4)); + as.seek(to64(envp + n * 4)); int p = adjust(as.readInt()); - if(p==0) + if (p == 0) { break; // completed the walk - + } // now read the null-terminated string - envVars.addLine(readLine(as, p, "env["+ n +"]")); + envVars.addLine(readLine(as, p, "env[" + n + "]")); } } finally { as.close(); @@ -842,21 +878,24 @@ public abstract class ProcessTree implements Iterable<OSProcess>, IProcessTree, } private String readLine(RandomAccessFile as, int p, String prefix) throws IOException { - if(logger.isTraceEnabled()) - logger.debug("Reading "+prefix+" at "+p); + if (logger.isTraceEnabled()) { + logger.debug("Reading " + prefix + " at " + p); + } as.seek(to64(p)); ByteArrayOutputStream buf = new ByteArrayOutputStream(); - int ch,i=0; - while((ch=as.read())>0) { - if((++i)%100==0 && logger.isTraceEnabled()) - logger.debug(prefix +" is so far "+buf.toString()); + int ch, i = 0; + while ((ch = as.read()) > 0) { + if ((++i) % 100 == 0 && logger.isTraceEnabled()) { + logger.debug(prefix + " is so far " + buf.toString()); + } buf.write(ch); } String line = buf.toString(); - if(logger.isTraceEnabled()) - logger.debug(prefix+" was "+line); + if (logger.isTraceEnabled()) { + logger.debug(prefix + " was " + line); + } return line; } } @@ -865,20 +904,20 @@ public abstract class ProcessTree implements Iterable<OSProcess>, IProcessTree, * int to long conversion with zero-padding. */ private static long to64(int i) { - return i&0xFFFFFFFFL; + return i & 0xFFFFFFFFL; } /** - * {@link DataInputStream} reads a value in big-endian, so - * convert it to the correct value on little-endian systems. + * {@link DataInputStream} reads a value in big-endian, so convert it to + * the correct value on little-endian systems. */ private static int adjust(int i) { - if(IS_LITTLE_ENDIAN) - return (i<<24) |((i<<8) & 0x00FF0000) | ((i>>8) & 0x0000FF00) | (i>>>24); - else + if (IS_LITTLE_ENDIAN) { + return (i << 24) | ((i << 8) & 0x00FF0000) | ((i >> 8) & 0x0000FF00) | (i >>> 24); + } else { return i; + } } - } /** @@ -890,7 +929,7 @@ public abstract class ProcessTree implements Iterable<OSProcess>, IProcessTree, Darwin(NativeUtils nativeUtils) { this.nativeUtils = nativeUtils; - try { + try { for (final NativeProcess process : nativeUtils.getMacProcesses()) { try { super.processes.put(process.getPid(), new DarwinProcess(process)); @@ -901,13 +940,14 @@ public abstract class ProcessTree implements Iterable<OSProcess>, IProcessTree, } } catch (NativeAccessException exc) { // Don't fail if the Native Mac access plugin is not installed. - logger.warn( "Failed to fecth Native Mac Processes", exc.getLocalizedMessage()); + logger.warn("Failed to fecth Native Mac Processes", exc.getLocalizedMessage()); } } private class DarwinProcess extends UnixProcess { + NativeProcess process; - + private DarwinProcess(NativeProcess process) { super(process.getPid()); this.process = process; @@ -920,7 +960,7 @@ public abstract class ProcessTree implements Iterable<OSProcess>, IProcessTree, public synchronized EnvVars getEnvironmentVariables() { EnvVars envVars = new EnvVars(); for (String key : process.getEnvironmentVariables().keySet()) { - envVars.put(key, process.getEnvironmentVariables().get(key)); + envVars.put(key, process.getEnvironmentVariables().get(key)); } return envVars; } @@ -930,7 +970,7 @@ public abstract class ProcessTree implements Iterable<OSProcess>, IProcessTree, StringTokenizer tokenizer = new StringTokenizer(process.getCommandLine()); // Skip the exec name tokenizer.nextToken(); - while (tokenizer.hasMoreTokens()){ + while (tokenizer.hasMoreTokens()) { arguments.add(tokenizer.nextToken()); } return arguments; @@ -939,10 +979,11 @@ public abstract class ProcessTree implements Iterable<OSProcess>, IProcessTree, } /** - * Represents a local process tree, where this JVM and the process tree run on the same system. - * (The opposite of {@link Remote}.) + * Represents a local process tree, where this JVM and the process tree run + * on the same system. (The opposite of {@link Remote}.) */ public static abstract class Local extends ProcessTree { + Local() { } } @@ -951,12 +992,14 @@ public abstract class ProcessTree implements Iterable<OSProcess>, IProcessTree, * Represents a process tree over a channel. */ public static class Remote extends ProcessTree implements Serializable { + private final IProcessTree proxy; public Remote(ProcessTree proxy, Channel ch) { - this.proxy = ch.export(IProcessTree.class,proxy); - for (Entry<Integer,OSProcess> e : proxy.processes.entrySet()) - processes.put(e.getKey(),new RemoteProcess(e.getValue(),ch)); + this.proxy = ch.export(IProcessTree.class, proxy); + for (Entry<Integer, OSProcess> e : proxy.processes.entrySet()) { + processes.put(e.getKey(), new RemoteProcess(e.getValue(), ch)); + } } @Override @@ -972,20 +1015,22 @@ public abstract class ProcessTree implements Iterable<OSProcess>, IProcessTree, Object writeReplace() { return this; // cancel out super.writeReplace() } - private static final long serialVersionUID = 1L; private class RemoteProcess extends OSProcess implements Serializable { + private final IOSProcess proxy; RemoteProcess(OSProcess proxy, Channel ch) { super(proxy.getPid()); - this.proxy = ch.export(IOSProcess.class,proxy); + this.proxy = ch.export(IOSProcess.class, proxy); } public OSProcess getParent() { IOSProcess p = proxy.getParent(); - if (p==null) return null; + if (p == null) { + return null; + } return get(p.getPid()); } @@ -1012,8 +1057,6 @@ public abstract class ProcessTree implements Iterable<OSProcess>, IProcessTree, public <T> T act(ProcessCallable<T> callable) throws IOException, InterruptedException { return proxy.act(callable); } - - private static final long serialVersionUID = 1L; } } @@ -1022,9 +1065,8 @@ public abstract class ProcessTree implements Iterable<OSProcess>, IProcessTree, * Use {@link Remote} as the serialized form. */ /*package*/ Object writeReplace() { - return new Remote(this,Channel.current()); + return new Remote(this, Channel.current()); } - // public static void main(String[] args) { // // dump everything // LOGGER.setLevel(Level.ALL); @@ -1042,30 +1084,26 @@ public abstract class ProcessTree implements Iterable<OSProcess>, IProcessTree, // } /* - On MacOS X, there's no procfs <http://www.osxbook.com/book/bonus/chapter11/procfs/> - instead you'd do it with the sysctl <http://search.cpan.org/src/DURIST/Proc-ProcessTable-0.42/os/darwin.c> - <http://developer.apple.com/documentation/Darwin/Reference/ManPages/man3/sysctl.3.html> + On MacOS X, there's no procfs <http://www.osxbook.com/book/bonus/chapter11/procfs/> + instead you'd do it with the sysctl <http://search.cpan.org/src/DURIST/Proc-ProcessTable-0.42/os/darwin.c> + <http://developer.apple.com/documentation/Darwin/Reference/ManPages/man3/sysctl.3.html> - There's CLI but that doesn't seem to offer the access to per-process info - <http://developer.apple.com/documentation/Darwin/Reference/ManPages/man8/sysctl.8.html> + There's CLI but that doesn't seem to offer the access to per-process info + <http://developer.apple.com/documentation/Darwin/Reference/ManPages/man8/sysctl.8.html> - On HP-UX, pstat_getcommandline get you command line, but I'm not seeing any environment variables. + On HP-UX, pstat_getcommandline get you command line, but I'm not seeing any environment variables. */ - private static final boolean IS_LITTLE_ENDIAN = "little".equals(System.getProperty("sun.cpu.endian")); - /** * Flag to control this feature. * - * <p> - * This feature involves some native code, so we are allowing the user to disable this - * in case there's a fatal problem. + * <p> This feature involves some native code, so we are allowing the user + * to disable this in case there's a fatal problem. * - * <p> - * This property supports two names for a compatibility reason. + * <p> This property supports two names for a compatibility reason. */ - public static boolean enabled = !Boolean.getBoolean(ProcessTreeKiller.class.getName()+".disable") - && !Boolean.getBoolean(ProcessTree.class.getName()+".disable"); + public static boolean enabled = !Boolean.getBoolean(ProcessTreeKiller.class.getName() + ".disable") + && !Boolean.getBoolean(ProcessTree.class.getName() + ".disable"); } diff --git a/hudson-core/src/main/java/hudson/util/ProcessTreeKiller.java b/hudson-core/src/main/java/hudson/util/ProcessTreeKiller.java index 01051db..a88bdbe 100644 --- a/hudson-core/src/main/java/hudson/util/ProcessTreeKiller.java +++ b/hudson-core/src/main/java/hudson/util/ProcessTreeKiller.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,57 +29,56 @@ import java.util.Map; * @deprecated as of 1.315. Use {@link ProcessTree}. */ public final class ProcessTreeKiller { + /** * Short for {@code kill(proc,null)} * * @deprecated Use {@link OSProcess#killRecursively()} */ public void kill(Process proc) throws InterruptedException { - kill(proc,null); + kill(proc, null); } /** - * In addition to what {@link #kill(Process)} does, also tries to - * kill all the daemon processes launched. + * In addition to what {@link #kill(Process)} does, also tries to kill all + * the daemon processes launched. * - * <p> - * Kills the given process (like {@link Process#destroy()} - * but also attempts to kill descendant processes created from the given - * process. + * <p> Kills the given process (like {@link Process#destroy()} but also + * attempts to kill descendant processes created from the given process. * - * <p> - * In addition, optionally perform "search and destroy" based on environment - * variables. In this method, the method is given a - * "model environment variables", which is a list of environment variables - * and their values that are characteristic to the launched process. - * The implementation is expected to find processes - * in the system that inherit these environment variables, and kill - * them all. This is suitable for locating daemon processes - * that cannot be tracked by the regular ancestor/descendant relationship. + * <p> In addition, optionally perform "search and destroy" based on + * environment variables. In this method, the method is given a "model + * environment variables", which is a list of environment variables and + * their values that are characteristic to the launched process. The + * implementation is expected to find processes in the system that inherit + * these environment variables, and kill them all. This is suitable for + * locating daemon processes that cannot be tracked by the regular + * ancestor/descendant relationship. * - * <p> - * The implementation is obviously OS-dependent. + * <p> The implementation is obviously OS-dependent. * - * @param proc - * Process to be killed recursively. Can be null. - * @param modelEnvVars - * If non-null, search-and-destroy will be performed. - * @deprecated Use {@link ProcessTree#killAll(Map)} and {@link OSProcess#killRecursively()} + * @param proc Process to be killed recursively. Can be null. + * @param modelEnvVars If non-null, search-and-destroy will be performed. + * @deprecated Use {@link ProcessTree#killAll(Map)} and + * {@link OSProcess#killRecursively()} */ public void kill(Process proc, Map<String, String> modelEnvVars) throws InterruptedException { ProcessTree pt = ProcessTree.get(); - if(proc!=null) + if (proc != null) { pt.get(proc).killRecursively(); - if(modelEnvVars!=null) + } + if (modelEnvVars != null) { pt.killAll(modelEnvVars); + } } /** * Short for {@code kill(null,modelEnvVars)} + * * @deprecated Use {@link ProcessTree#killAll(Map)} */ public void kill(Map<String, String> modelEnvVars) throws InterruptedException { - kill(null,modelEnvVars); + kill(null, modelEnvVars); } /** @@ -93,9 +92,9 @@ public final class ProcessTreeKiller { } /** - * Gets the {@link ProcessTreeKiller} suitable for the current system - * that JVM runs in, or in the worst case return the default one - * that's not capable of killing descendants at all. + * Gets the {@link ProcessTreeKiller} suitable for the current system that + * JVM runs in, or in the worst case return the default one that's not + * capable of killing descendants at all. */ public static ProcessTreeKiller get() { return new ProcessTreeKiller(); diff --git a/hudson-core/src/main/java/hudson/util/ProcessTreeRemoting.java b/hudson-core/src/main/java/hudson/util/ProcessTreeRemoting.java index 34954b5..2cc1802 100644 --- a/hudson-core/src/main/java/hudson/util/ProcessTreeRemoting.java +++ b/hudson-core/src/main/java/hudson/util/ProcessTreeRemoting.java @@ -8,7 +8,7 @@ * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * + * * *******************************************************************************/ @@ -30,17 +30,26 @@ import java.util.Map; * @author Kohsuke Kawaguchi */ public class ProcessTreeRemoting { + public interface IProcessTree { + void killAll(Map<String, String> modelEnvVars) throws InterruptedException; } public interface IOSProcess { + int getPid(); + IOSProcess getParent(); + void kill() throws InterruptedException; + void killRecursively() throws InterruptedException; + List<String> getArguments(); + EnvVars getEnvironmentVariables(); + <T> T act(ProcessCallable<T> callable) throws IOException, InterruptedException; } } diff --git a/hudson-core/src/main/java/hudson/util/Protector.java b/hudson-core/src/main/java/hudson/util/Protector.java index ffc96ac..69401f6 100644 --- a/hudson-core/src/main/java/hudson/util/Protector.java +++ b/hudson-core/src/main/java/hudson/util/Protector.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 - * + * * *******************************************************************************/ @@ -26,14 +26,15 @@ import java.security.NoSuchAlgorithmException; import org.apache.commons.codec.binary.Base64; /** - * Encrypt/decrypt data by using a "session" key that only lasts for - * the duration of the server instance. + * Encrypt/decrypt data by using a "session" key that only lasts for the + * duration of the server instance. * * @author Kohsuke Kawaguchi * @see Scrambler * @since 1.162 */ public class Protector { + private static final String ALGORITHM = "DES"; private static final String MAGIC = ":::"; @@ -41,7 +42,7 @@ public class Protector { try { Cipher cipher = Secret.getCipher(ALGORITHM); cipher.init(Cipher.ENCRYPT_MODE, DES_KEY); - return new String(Base64.encodeBase64(cipher.doFinal((secret+ MAGIC).getBytes("UTF-8")))); + return new String(Base64.encodeBase64(cipher.doFinal((secret + MAGIC).getBytes("UTF-8")))); } catch (GeneralSecurityException e) { throw new Error(e); // impossible } catch (UnsupportedEncodingException e) { @@ -53,13 +54,16 @@ public class Protector { * Returns null if fails to decrypt properly. */ public static String unprotect(String data) { - if(data==null) return null; + if (data == null) { + return null; + } try { Cipher cipher = Secret.getCipher(ALGORITHM); cipher.init(Cipher.DECRYPT_MODE, DES_KEY); String plainText = new String(cipher.doFinal(Base64.decodeBase64(data)), "UTF-8"); - if(plainText.endsWith(MAGIC)) - return plainText.substring(0,plainText.length()-3); + if (plainText.endsWith(MAGIC)) { + return plainText.substring(0, plainText.length() - 3); + } return null; } catch (GeneralSecurityException e) { return null; @@ -69,7 +73,6 @@ public class Protector { return null; } } - private static final SecretKey DES_KEY; static { diff --git a/hudson-core/src/main/java/hudson/util/QueryParameterMap.java b/hudson-core/src/main/java/hudson/util/QueryParameterMap.java index c7e5914..6457f6d 100644 --- a/hudson-core/src/main/java/hudson/util/QueryParameterMap.java +++ b/hudson-core/src/main/java/hudson/util/QueryParameterMap.java @@ -7,9 +7,9 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: - * - * + * Contributors: + * + * * *******************************************************************************/ @@ -36,7 +36,6 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ - package hudson.util; import javax.servlet.http.HttpServletRequest; @@ -51,35 +50,37 @@ import java.util.Map; /** * Parses the query string of the URL into a key/value pair. * - * <p> - * This class is even useful on the server side, as {@link HttpServletRequest#getParameter(String)} - * can try to parse into the payload (and that can cause an exception if the payload is already consumed. + * <p> This class is even useful on the server side, as + * {@link HttpServletRequest#getParameter(String)} can try to parse into the + * payload (and that can cause an exception if the payload is already consumed. * See HUDSON-8056.) * - * <p> - * So if you are handling the payload yourself and only want to access the query parameters, - * use this class. + * <p> So if you are handling the payload yourself and only want to access the + * query parameters, use this class. * * @author Kohsuke Kawaguchi * @since 1.394 */ public class QueryParameterMap { - private final Map<String,List<String>> store = new HashMap<String, List<String>>(); + + private final Map<String, List<String>> store = new HashMap<String, List<String>>(); /** - * @param queryString - * String that looks like "abc=def&ghi=jkl" + * @param queryString String that looks like "abc=def&ghi=jkl" */ public QueryParameterMap(String queryString) { - if (queryString==null || queryString.length()==0) return; + if (queryString == null || queryString.length() == 0) { + return; + } try { for (String param : queryString.split("&")) { String[] kv = param.split("="); String key = URLDecoder.decode(kv[0], "UTF-8"); String value = URLDecoder.decode(kv[1], "UTF-8"); List<String> values = store.get(key); - if (values == null) + if (values == null) { store.put(key, values = new ArrayList<String>()); + } values.add(value); } } catch (UnsupportedEncodingException e) { @@ -93,11 +94,11 @@ public class QueryParameterMap { public String get(String name) { List<String> v = store.get(name); - return v!=null?v.get(0):null; + return v != null ? v.get(0) : null; } public List<String> getAll(String name) { List<String> v = store.get(name); - return v!=null? Collections.unmodifiableList(v) : Collections.<String>emptyList(); + return v != null ? Collections.unmodifiableList(v) : Collections.<String>emptyList(); } } diff --git a/hudson-core/src/main/java/hudson/util/QuotedStringTokenizer.java b/hudson-core/src/main/java/hudson/util/QuotedStringTokenizer.java index b1d46e4..5e0bc17 100644 --- a/hudson-core/src/main/java/hudson/util/QuotedStringTokenizer.java +++ b/hudson-core/src/main/java/hudson/util/QuotedStringTokenizer.java @@ -25,7 +25,6 @@ // See the License for the specific language governing permissions and // limitations under the License. // ======================================================================== - package hudson.util; import java.util.NoSuchElementException; @@ -34,234 +33,214 @@ import java.util.List; import java.util.ArrayList; /* ------------------------------------------------------------ */ -/** StringTokenizer with Quoting support. +/** + * StringTokenizer with Quoting support. * - * This class is a copy of the java.util.StringTokenizer API and - * the behaviour is the same, except that single and doulbe quoted - * string values are recognized. - * Delimiters within quotes are not considered delimiters. - * Quotes can be escaped with '\'. + * This class is a copy of the java.util.StringTokenizer API and the behaviour + * is the same, except that single and doulbe quoted string values are + * recognized. Delimiters within quotes are not considered delimiters. Quotes + * can be escaped with '\'. * * @see java.util.StringTokenizer * @author Greg Wilkins (gregw) */ public class QuotedStringTokenizer - extends StringTokenizer -{ - private final static String __delim=" \t\n\r"; + extends StringTokenizer { + + private final static String __delim = " \t\n\r"; private String _string; private String _delim = __delim; - private boolean _returnQuotes=false; - private boolean _returnDelimiters=false; + private boolean _returnQuotes = false; + private boolean _returnDelimiters = false; private StringBuffer _token; - private boolean _hasToken=false; - private int _i=0; - private int _lastStart=0; - private boolean _double=true; - private boolean _single=true; + private boolean _hasToken = false; + private int _i = 0; + private int _lastStart = 0; + private boolean _double = true; + private boolean _single = true; public static String[] tokenize(String str) { return new QuotedStringTokenizer(str).toArray(); } public static String[] tokenize(String str, String delimiters) { - return new QuotedStringTokenizer(str,delimiters).toArray(); + return new QuotedStringTokenizer(str, delimiters).toArray(); } /* ------------------------------------------------------------ */ /** * - * @param str - * String to tokenize. - * @param delim - * List of delimiter characters as string. Can be null, to default to ' \t\n\r' - * @param returnDelimiters - * If true, {@link #nextToken()} will include the delimiters, not just tokenized - * tokens. - * @param returnQuotes - * If true, {@link #nextToken()} will include the quotation characters when they are present. + * @param str String to tokenize. + * @param delim List of delimiter characters as string. Can be null, to + * default to ' \t\n\r' + * @param returnDelimiters If true, {@link #nextToken()} will include the + * delimiters, not just tokenized tokens. + * @param returnQuotes If true, {@link #nextToken()} will include the + * quotation characters when they are present. */ public QuotedStringTokenizer(String str, - String delim, - boolean returnDelimiters, - boolean returnQuotes) - { + String delim, + boolean returnDelimiters, + boolean returnQuotes) { super(""); - _string=str; - if (delim!=null) - _delim=delim; - _returnDelimiters=returnDelimiters; - _returnQuotes=returnQuotes; + _string = str; + if (delim != null) { + _delim = delim; + } + _returnDelimiters = returnDelimiters; + _returnQuotes = returnQuotes; - if (_delim.indexOf('\'')>=0 || - _delim.indexOf('"')>=0) - throw new Error("Can't use quotes as delimiters: "+_delim); + if (_delim.indexOf('\'') >= 0 + || _delim.indexOf('"') >= 0) { + throw new Error("Can't use quotes as delimiters: " + _delim); + } - _token=new StringBuffer(_string.length()>1024?512:_string.length()/2); + _token = new StringBuffer(_string.length() > 1024 ? 512 : _string.length() / 2); } /* ------------------------------------------------------------ */ public QuotedStringTokenizer(String str, - String delim, - boolean returnDelimiters) - { - this(str,delim,returnDelimiters,false); + String delim, + boolean returnDelimiters) { + this(str, delim, returnDelimiters, false); } /* ------------------------------------------------------------ */ public QuotedStringTokenizer(String str, - String delim) - { - this(str,delim,false,false); + String delim) { + this(str, delim, false, false); } /* ------------------------------------------------------------ */ - public QuotedStringTokenizer(String str) - { - this(str,null,false,false); + public QuotedStringTokenizer(String str) { + this(str, null, false, false); } public String[] toArray() { List<String> r = new ArrayList<String>(); - while(hasMoreTokens()) + while (hasMoreTokens()) { r.add(nextToken()); + } return r.toArray(new String[r.size()]); } /* ------------------------------------------------------------ */ @Override - public boolean hasMoreTokens() - { + public boolean hasMoreTokens() { // Already found a token - if (_hasToken) + if (_hasToken) { return true; + } + + _lastStart = _i; + + int state = 0; + boolean escape = false; + while (_i < _string.length()) { + char c = _string.charAt(_i++); + + switch (state) { + case 0: // Start + if (_delim.indexOf(c) >= 0) { + if (_returnDelimiters) { + _token.append(c); + return _hasToken = true; + } + } else if (c == '\'' && _single) { + if (_returnQuotes) { + _token.append(c); + } + state = 2; + } else if (c == '\"' && _double) { + if (_returnQuotes) { + _token.append(c); + } + state = 3; + } else { + _token.append(c); + _hasToken = true; + state = 1; + } + continue; - _lastStart=_i; - - int state=0; - boolean escape=false; - while (_i<_string.length()) - { - char c=_string.charAt(_i++); - - switch (state) - { - case 0: // Start - if(_delim.indexOf(c)>=0) - { - if (_returnDelimiters) - { - _token.append(c); - return _hasToken=true; - } - } - else if (c=='\'' && _single) - { - if (_returnQuotes) - _token.append(c); - state=2; - } - else if (c=='\"' && _double) - { - if (_returnQuotes) - _token.append(c); - state=3; - } - else - { - _token.append(c); - _hasToken=true; - state=1; - } - continue; - - case 1: // Token - _hasToken=true; - if (escape) - { - escape=false; - if(ESCAPABLE_CHARS.indexOf(c)<0) - _token.append('\\'); - _token.append(c); - } - else if(_delim.indexOf(c)>=0) - { - if (_returnDelimiters) - _i--; - return _hasToken; - } - else if (c=='\'' && _single) - { - if (_returnQuotes) - _token.append(c); - state=2; - } - else if (c=='\"' && _double) - { - if (_returnQuotes) - _token.append(c); - state=3; - } - else if (c=='\\') - { - escape=true; - } - else - _token.append(c); - continue; - - - case 2: // Single Quote - _hasToken=true; - if (escape) - { - escape=false; - if(ESCAPABLE_CHARS.indexOf(c)<0) - _token.append('\\'); - _token.append(c); - } - else if (c=='\'') - { - if (_returnQuotes) - _token.append(c); - state=1; - } - else if (c=='\\') - { - if (_returnQuotes) - _token.append(c); - escape=true; - } - else - _token.append(c); - continue; - - - case 3: // Double Quote - _hasToken=true; - if (escape) - { - escape=false; - if(ESCAPABLE_CHARS.indexOf(c)<0) - _token.append('\\'); - _token.append(c); - } - else if (c=='\"') - { - if (_returnQuotes) - _token.append(c); - state=1; - } - else if (c=='\\') - { - if (_returnQuotes) - _token.append(c); - escape=true; - } - else - _token.append(c); - continue; + case 1: // Token + _hasToken = true; + if (escape) { + escape = false; + if (ESCAPABLE_CHARS.indexOf(c) < 0) { + _token.append('\\'); + } + _token.append(c); + } else if (_delim.indexOf(c) >= 0) { + if (_returnDelimiters) { + _i--; + } + return _hasToken; + } else if (c == '\'' && _single) { + if (_returnQuotes) { + _token.append(c); + } + state = 2; + } else if (c == '\"' && _double) { + if (_returnQuotes) { + _token.append(c); + } + state = 3; + } else if (c == '\\') { + escape = true; + } else { + _token.append(c); + } + continue; + + + case 2: // Single Quote + _hasToken = true; + if (escape) { + escape = false; + if (ESCAPABLE_CHARS.indexOf(c) < 0) { + _token.append('\\'); + } + _token.append(c); + } else if (c == '\'') { + if (_returnQuotes) { + _token.append(c); + } + state = 1; + } else if (c == '\\') { + if (_returnQuotes) { + _token.append(c); + } + escape = true; + } else { + _token.append(c); + } + continue; + + + case 3: // Double Quote + _hasToken = true; + if (escape) { + escape = false; + if (ESCAPABLE_CHARS.indexOf(c) < 0) { + _token.append('\\'); + } + _token.append(c); + } else if (c == '\"') { + if (_returnQuotes) { + _token.append(c); + } + state = 1; + } else if (c == '\\') { + if (_returnQuotes) { + _token.append(c); + } + escape = true; + } else { + _token.append(c); + } + continue; } } @@ -271,76 +250,72 @@ public class QuotedStringTokenizer /* ------------------------------------------------------------ */ @Override public String nextToken() - throws NoSuchElementException - { - if (!hasMoreTokens() || _token==null) + throws NoSuchElementException { + if (!hasMoreTokens() || _token == null) { throw new NoSuchElementException(); - String t=_token.toString(); + } + String t = _token.toString(); _token.setLength(0); - _hasToken=false; + _hasToken = false; return t; } /* ------------------------------------------------------------ */ @Override public String nextToken(String delim) - throws NoSuchElementException - { - _delim=delim; - _i=_lastStart; + throws NoSuchElementException { + _delim = delim; + _i = _lastStart; _token.setLength(0); - _hasToken=false; + _hasToken = false; return nextToken(); } /* ------------------------------------------------------------ */ @Override - public boolean hasMoreElements() - { + public boolean hasMoreElements() { return hasMoreTokens(); } /* ------------------------------------------------------------ */ @Override public Object nextElement() - throws NoSuchElementException - { + throws NoSuchElementException { return nextToken(); } /* ------------------------------------------------------------ */ - /** Not implemented. + /** + * Not implemented. */ @Override - public int countTokens() - { + public int countTokens() { return -1; } /* ------------------------------------------------------------ */ - /** Quote a string. - * The string is quoted only if quoting is required due to - * embeded delimiters, quote characters or the - * empty string. + /** + * Quote a string. The string is quoted only if quoting is required due to + * embeded delimiters, quote characters or the empty string. + * * @param s The string to quote. * @return quoted string */ - public static String quote(String s, String delim) - { - if (s==null) + public static String quote(String s, String delim) { + if (s == null) { return null; - if (s.length()==0) + } + if (s.length() == 0) { return "\"\""; + } - for (int i=0;i<s.length();i++) - { + for (int i = 0; i < s.length(); i++) { char c = s.charAt(i); - if (c=='\\' || c=='"' || c=='\'' || Character.isWhitespace(c) || delim.indexOf(c)>=0) - { - StringBuffer b=new StringBuffer(s.length()+8); - quote(b,s); + if (c == '\\' || c == '"' || c == '\'' || Character.isWhitespace(c) || delim.indexOf(c) >= 0) { + StringBuffer b = new StringBuffer(s.length() + 8); + quote(b, s); return b.toString(); } } @@ -349,43 +324,42 @@ public class QuotedStringTokenizer } /* ------------------------------------------------------------ */ - /** Quote a string. - * The string is quoted only if quoting is required due to - * embeded delimiters, quote characters or the - * empty string. + /** + * Quote a string. The string is quoted only if quoting is required due to + * embeded delimiters, quote characters or the empty string. + * * @param s The string to quote. * @return quoted string */ - public static String quote(String s) - { - if (s==null) + public static String quote(String s) { + if (s == null) { return null; - if (s.length()==0) + } + if (s.length() == 0) { return "\"\""; + } - StringBuffer b=new StringBuffer(s.length()+8); - quote(b,s); + StringBuffer b = new StringBuffer(s.length() + 8); + quote(b, s); return b.toString(); } /* ------------------------------------------------------------ */ - /** Quote a string into a StringBuffer. - * The characters ", \, \n, \r, \t, \f and \b are escaped + /** + * Quote a string into a StringBuffer. The characters ", \, \n, \r, \t, \f + * and \b are escaped + * * @param buf The StringBuffer * @param s The String to quote. */ - public static void quote(StringBuffer buf, String s) - { - synchronized(buf) - { + public static void quote(StringBuffer buf, String s) { + synchronized (buf) { buf.append('"'); - for (int i=0;i<s.length();i++) - { + for (int i = 0; i < s.length(); i++) { char c = s.charAt(i); - switch(c) - { + switch (c) { case '"': buf.append("\\\""); continue; @@ -418,35 +392,35 @@ public class QuotedStringTokenizer } /* ------------------------------------------------------------ */ - /** Unquote a string. + /** + * Unquote a string. + * * @param s The string to unquote. * @return quoted string */ - public static String unquote(String s) - { - if (s==null) + public static String unquote(String s) { + if (s == null) { return null; - if (s.length()<2) + } + if (s.length() < 2) { return s; + } - char first=s.charAt(0); - char last=s.charAt(s.length()-1); - if (first!=last || (first!='"' && first!='\'')) + char first = s.charAt(0); + char last = s.charAt(s.length() - 1); + if (first != last || (first != '"' && first != '\'')) { return s; + } - StringBuffer b=new StringBuffer(s.length()-2); - synchronized(b) - { - boolean escape=false; - for (int i=1;i<s.length()-1;i++) - { + StringBuffer b = new StringBuffer(s.length() - 2); + synchronized (b) { + boolean escape = false; + for (int i = 1; i < s.length() - 1; i++) { char c = s.charAt(i); - if (escape) - { - escape=false; - switch (c) - { + if (escape) { + escape = false; + switch (c) { case 'n': b.append('\n'); break; @@ -463,25 +437,20 @@ public class QuotedStringTokenizer b.append('\b'); break; case 'u': - b.append((char)( - (convertHexDigit((byte)s.charAt(i++))<<24)+ - (convertHexDigit((byte)s.charAt(i++))<<16)+ - (convertHexDigit((byte)s.charAt(i++))<<8)+ - (convertHexDigit((byte)s.charAt(i++))) - ) - ); + b.append((char) ((convertHexDigit((byte) s.charAt(i++)) << 24) + + (convertHexDigit((byte) s.charAt(i++)) << 16) + + (convertHexDigit((byte) s.charAt(i++)) << 8) + + (convertHexDigit((byte) s.charAt(i++))))); break; default: b.append(c); } - } - else if (c=='\\') - { - escape=true; + } else if (c == '\\') { + escape = true; continue; - } - else + } else { b.append(c); + } } return b.toString(); @@ -492,8 +461,7 @@ public class QuotedStringTokenizer /** * @return handle double quotes if true */ - public boolean getDouble() - { + public boolean getDouble() { return _double; } @@ -501,17 +469,15 @@ public class QuotedStringTokenizer /** * @param d handle double quotes if true */ - public void setDouble(boolean d) - { - _double=d; + public void setDouble(boolean d) { + _double = d; } /* ------------------------------------------------------------ */ /** * @return handle single quotes if true */ - public boolean getSingle() - { + public boolean getSingle() { return _single; } @@ -519,40 +485,32 @@ public class QuotedStringTokenizer /** * @param single handle single quotes if true */ - public void setSingle(boolean single) - { - _single=single; + public void setSingle(boolean single) { + _single = single; } /** * @param b An ASCII encoded character 0-9 a-f A-F * @return The byte value of the character 0-16. */ - public static byte convertHexDigit( byte b ) - { - if ((b >= '0') && (b <= '9')) return (byte)(b - '0'); - if ((b >= 'a') && (b <= 'f')) return (byte)(b - 'a' + 10); - if ((b >= 'A') && (b <= 'F')) return (byte)(b - 'A' + 10); + public static byte convertHexDigit(byte b) { + if ((b >= '0') && (b <= '9')) { + return (byte) (b - '0'); + } + if ((b >= 'a') && (b <= 'f')) { + return (byte) (b - 'a' + 10); + } + if ((b >= 'A') && (b <= 'F')) { + return (byte) (b - 'A' + 10); + } return 0; } - /** * Characters that can be escaped with \. * - * Others, like, say, \W will be left alone instead of becoming just W. - * This is important to keep Hudson behave on Windows, which uses '\' as - * the directory separator. + * Others, like, say, \W will be left alone instead of becoming just W. This + * is important to keep Hudson behave on Windows, which uses '\' as the + * directory separator. */ private static final String ESCAPABLE_CHARS = "\\\"' "; } - - - - - - - - - - - diff --git a/hudson-core/src/main/java/hudson/util/ReflectionUtils.java b/hudson-core/src/main/java/hudson/util/ReflectionUtils.java index a392666..9b01057 100644 --- a/hudson-core/src/main/java/hudson/util/ReflectionUtils.java +++ b/hudson-core/src/main/java/hudson/util/ReflectionUtils.java @@ -7,10 +7,10 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: + * Contributors: + * + * * - * - * * *******************************************************************************/ @@ -37,13 +37,17 @@ import java.util.Map; * @since 1.351 */ public class ReflectionUtils extends org.springframework.util.ReflectionUtils { + /** - * Finds a public method of the given name, regardless of its parameter definitions, + * Finds a public method of the given name, regardless of its parameter + * definitions, */ public static Method getPublicMethodNamed(Class c, String methodName) { - for( Method m : c.getMethods() ) - if(m.getName().equals(methodName)) + for (Method m : c.getMethods()) { + if (m.getName().equals(methodName)) { return m; + } + } return null; } @@ -56,13 +60,13 @@ public class ReflectionUtils extends org.springframework.util.ReflectionUtils { public static Object getPublicProperty(Object o, String p) throws InvocationTargetException, NoSuchMethodException, IllegalAccessException { PropertyDescriptor pd = PropertyUtils.getPropertyDescriptor(o, p); - if(pd==null) { + if (pd == null) { // field? try { Field f = o.getClass().getField(p); return f.get(o); } catch (NoSuchFieldException e) { - throw new IllegalArgumentException("No such property "+p+" on "+o.getClass()); + throw new IllegalArgumentException("No such property " + p + " on " + o.getClass()); } } else { return PropertyUtils.getProperty(o, p); @@ -75,6 +79,7 @@ public class ReflectionUtils extends org.springframework.util.ReflectionUtils { * more object-oriented per-parameter view. */ private static final class MethodInfo extends AbstractList<Parameter> { + private final Method method; private final Class<?>[] types; private Type[] genericTypes; @@ -88,7 +93,7 @@ public class ReflectionUtils extends org.springframework.util.ReflectionUtils { @Override public Parameter get(int index) { - return new Parameter(this,index); + return new Parameter(this, index); } @Override @@ -97,25 +102,29 @@ public class ReflectionUtils extends org.springframework.util.ReflectionUtils { } public Type[] genericTypes() { - if (genericTypes==null) + if (genericTypes == null) { genericTypes = method.getGenericParameterTypes(); + } return genericTypes; } public Annotation[][] annotations() { - if (annotations==null) + if (annotations == null) { annotations = method.getParameterAnnotations(); + } return annotations; } public String[] names() { - if (names==null) + if (names == null) { names = ClassDescriptor.loadParameterNames(method); + } return names; } } public static final class Parameter { + private final MethodInfo parent; private final int index; @@ -156,9 +165,11 @@ public class ReflectionUtils extends org.springframework.util.ReflectionUtils { * Gets the specified annotation on this parameter or null. */ public <A extends Annotation> A annotation(Class<A> type) { - for (Annotation a : annotations()) - if (a.annotationType()==type) + for (Annotation a : annotations()) { + if (a.annotationType() == type) { return type.cast(a); + } + } return null; } @@ -169,23 +180,25 @@ public class ReflectionUtils extends org.springframework.util.ReflectionUtils { */ public String name() { String[] names = parent.names(); - if (index<names.length) + if (index < names.length) { return names[index]; + } return null; } } /** - * Given the primitive type, returns the VM default value for that type in a boxed form. + * Given the primitive type, returns the VM default value for that type in a + * boxed form. */ public static Object getVmDefaultValueForPrimitiveType(Class<?> type) { return defaultPrimitiveValue.get(type); } + private static final Map<Class, Object> defaultPrimitiveValue = new HashMap<Class, Object>(); - private static final Map<Class,Object> defaultPrimitiveValue = new HashMap<Class, Object>(); static { - defaultPrimitiveValue.put(boolean.class,false); - defaultPrimitiveValue.put(int.class,0); - defaultPrimitiveValue.put(long.class,0L); + defaultPrimitiveValue.put(boolean.class, false); + defaultPrimitiveValue.put(int.class, 0); + defaultPrimitiveValue.put(long.class, 0L); } } diff --git a/hudson-core/src/main/java/hudson/util/RemotingDiagnostics.java b/hudson-core/src/main/java/hudson/util/RemotingDiagnostics.java index d38f035..3ef8595 100644 --- a/hudson-core/src/main/java/hudson/util/RemotingDiagnostics.java +++ b/hudson-core/src/main/java/hudson/util/RemotingDiagnostics.java @@ -168,7 +168,6 @@ public final class RemotingDiagnostics { */ public static FilePath getHeapDump(VirtualChannel channel) throws IOException, InterruptedException { return channel.call(new Callable<FilePath, IOException>() { - public FilePath call() throws IOException { final File hprof = File.createTempFile("hudson-heapdump", "hprof"); hprof.delete(); diff --git a/hudson-core/src/main/java/hudson/util/RingBufferLogHandler.java b/hudson-core/src/main/java/hudson/util/RingBufferLogHandler.java index dc29c8d..c3ca982 100644 --- a/hudson-core/src/main/java/hudson/util/RingBufferLogHandler.java +++ b/hudson-core/src/main/java/hudson/util/RingBufferLogHandler.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 + * * *******************************************************************************/ @@ -42,8 +42,8 @@ public class RingBufferLogHandler extends Handler { public synchronized void publish(LogRecord record) { int len = records.length; - records[(start+size)%len]=record; - if(size==len) { + records[(start + size) % len] = record; + if (size == len) { start++; } else { size++; @@ -53,15 +53,14 @@ public class RingBufferLogHandler extends Handler { /** * Returns the list view of {@link LogRecord}s in the ring buffer. * - * <p> - * New records are always placed early in the list. + * <p> New records are always placed early in the list. */ public List<LogRecord> getView() { return new AbstractList<LogRecord>() { public LogRecord get(int index) { // flip the order synchronized (RingBufferLogHandler.this) { - return records[(start+(size-(index+1)))%records.length]; + return records[(start + (size - (index + 1))) % records.length]; } } @@ -72,6 +71,9 @@ public class RingBufferLogHandler extends Handler { } // noop - public void flush() {} - public void close() throws SecurityException {} + public void flush() { + } + + public void close() throws SecurityException { + } } diff --git a/hudson-core/src/main/java/hudson/util/RobustCollectionConverter.java b/hudson-core/src/main/java/hudson/util/RobustCollectionConverter.java index 6b6f3fe..132d0ee 100644 --- a/hudson-core/src/main/java/hudson/util/RobustCollectionConverter.java +++ b/hudson-core/src/main/java/hudson/util/RobustCollectionConverter.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 - * + * * *******************************************************************************/ @@ -35,27 +35,28 @@ import static java.util.logging.Level.WARNING; /** * {@link CollectionConverter} that ignores {@link CannotResolveClassException}. * - * <p> - * This allows Hudson to load XML files that contain non-existent classes - * (the expected scenario is that those classes belong to plugins that were unloaded.) + * <p> This allows Hudson to load XML files that contain non-existent classes + * (the expected scenario is that those classes belong to plugins that were + * unloaded.) * * @author Kohsuke Kawaguchi */ public class RobustCollectionConverter extends CollectionConverter { + private final SerializableConverter sc; public RobustCollectionConverter(XStream xs) { - this(xs.getMapper(),xs.getReflectionProvider()); + this(xs.getMapper(), xs.getReflectionProvider()); } public RobustCollectionConverter(Mapper mapper, ReflectionProvider reflectionProvider) { super(mapper); - sc = new SerializableConverter(mapper,reflectionProvider); + sc = new SerializableConverter(mapper, reflectionProvider); } @Override public boolean canConvert(Class type) { - return super.canConvert(type) || type==CopyOnWriteArrayList.class || type==CopyOnWriteArraySet.class; + return super.canConvert(type) || type == CopyOnWriteArrayList.class || type == CopyOnWriteArraySet.class; } @Override @@ -63,8 +64,8 @@ public class RobustCollectionConverter extends CollectionConverter { // CopyOnWriteArrayList used to serialize as custom serialization, // so read it in a compatible fashion. String s = reader.getAttribute("serialization"); - if(s!=null && s.equals("custom")) { - return sc.unmarshal(reader,context); + if (s != null && s.equals("custom")) { + return sc.unmarshal(reader, context); } else { return super.unmarshal(reader, context); } @@ -87,6 +88,5 @@ public class RobustCollectionConverter extends CollectionConverter { reader.moveUp(); } } - private static final Logger LOGGER = Logger.getLogger(RobustCollectionConverter.class.getName()); } diff --git a/hudson-core/src/main/java/hudson/util/RobustReflectionConverter.java b/hudson-core/src/main/java/hudson/util/RobustReflectionConverter.java index 3e72775..8b4d231 100644 --- a/hudson-core/src/main/java/hudson/util/RobustReflectionConverter.java +++ b/hudson-core/src/main/java/hudson/util/RobustReflectionConverter.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 - * + * * *******************************************************************************/ @@ -52,12 +52,9 @@ import static java.util.logging.Level.WARNING; /** * Custom {@link ReflectionConverter} that handle errors more gracefully. * - * <ul> - * <li>If the field is missing, the value is ignored instead of causing an error. - * This makes evolution easy. - * <li>If the type found in XML is no longer available, the element is skipped - * instead of causing an error. - * </ul> + * <ul> <li>If the field is missing, the value is ignored instead of causing an + * error. This makes evolution easy. <li>If the type found in XML is no longer + * available, the element is skipped instead of causing an error. </ul> * */ public class RobustReflectionConverter implements Converter { @@ -92,11 +89,15 @@ public class RobustReflectionConverter implements Converter { final Set seenAsAttributes = new HashSet(); // Attributes might be preferred to child elements ... - reflectionProvider.visitSerializableFields(source, new ReflectionProvider.Visitor() { + reflectionProvider.visitSerializableFields(source, new ReflectionProvider.Visitor() { public void visit(String fieldName, Class type, Class definedIn, Object value) { SingleValueConverter converter = mapper.getConverterFromItemType(fieldName, type, definedIn); - if (converter == null) converter = mapper.getConverterFromItemType(fieldName, type); - if (converter == null) converter = mapper.getConverterFromItemType(type); + if (converter == null) { + converter = mapper.getConverterFromItemType(fieldName, type); + } + if (converter == null) { + converter = mapper.getConverterFromItemType(type); + } if (converter != null) { if (value != null) { final String str = converter.toString(value); @@ -152,15 +153,14 @@ public class RobustReflectionConverter implements Converter { writer.addAttribute(mapper.aliasForAttribute("defined-in"), mapper.serializedClass(definedIn)); } - Field field = reflectionProvider.getField(definedIn,fieldName); + Field field = reflectionProvider.getField(definedIn, fieldName); marshallField(context, newObj, field); writer.endNode(); } catch (RuntimeException e) { // intercept an exception so that the stack trace shows how we end up marshalling the object in question - throw new RuntimeException("Failed to serialize "+definedIn.getName()+"#"+fieldName+" for "+source.getClass(),e); + throw new RuntimeException("Failed to serialize " + definedIn.getName() + "#" + fieldName + " for " + source.getClass(), e); } } - }); } @@ -178,8 +178,9 @@ public class RobustReflectionConverter implements Converter { final SeenFields seenFields = new SeenFields(); Iterator it = reader.getAttributeNames(); // Remember outermost Saveable encountered, for reporting below - if (result instanceof Saveable && context.get("Saveable") == null) + if (result instanceof Saveable && context.get("Saveable") == null) { context.put("Saveable", result); + } // Process attributes before recursing into child elements. while (it.hasNext()) { @@ -189,7 +190,7 @@ public class RobustReflectionConverter implements Converter { boolean fieldExistsInClass = fieldDefinedInClass(result, attrName); if (fieldExistsInClass) { Field field = reflectionProvider.getField(result.getClass(), attrName); - SingleValueConverter converter = mapper.getConverterFromAttribute(field.getDeclaringClass(),attrName,field.getType()); + SingleValueConverter converter = mapper.getConverterFromAttribute(field.getDeclaringClass(), attrName, field.getType()); Class type = field.getType(); if (converter == null) { converter = mapper.getConverterFromItemType(type); @@ -217,12 +218,12 @@ public class RobustReflectionConverter implements Converter { boolean implicitCollectionHasSameName = mapper.getImplicitCollectionDefForFieldName(result.getClass(), reader.getNodeName()) != null; Class classDefiningField = determineWhichClassDefinesField(reader); - boolean fieldExistsInClass = !implicitCollectionHasSameName && fieldDefinedInClass(result,fieldName); + boolean fieldExistsInClass = !implicitCollectionHasSameName && fieldDefinedInClass(result, fieldName); Class type = determineType(reader, fieldExistsInClass, result, fieldName, classDefiningField); final Object value; if (fieldExistsInClass) { - Field field = reflectionProvider.getField(result.getClass(),fieldName); + Field field = reflectionProvider.getField(result.getClass(), fieldName); value = unmarshalField(context, result, type, field); // TODO the reflection provider should have returned the proper field in first place .... Class definedType = reflectionProvider.getFieldType(result, fieldName, classDefiningField); @@ -260,23 +261,24 @@ public class RobustReflectionConverter implements Converter { // Report any class/field errors in Saveable objects if (context.get("ReadError") != null && context.get("Saveable") == result) { - OldDataMonitor.report((Saveable)result, (ArrayList<Throwable>)context.get("ReadError")); + OldDataMonitor.report((Saveable) result, (ArrayList<Throwable>) context.get("ReadError")); context.put("ReadError", null); } return result; } public static void addErrorInContext(UnmarshallingContext context, Throwable e) { - ArrayList<Throwable> list = (ArrayList<Throwable>)context.get("ReadError"); - if (list == null) + ArrayList<Throwable> list = (ArrayList<Throwable>) context.get("ReadError"); + if (list == null) { context.put("ReadError", list = new ArrayList<Throwable>()); + } list.add(e); } private boolean fieldDefinedInClass(Object result, String attrName) { // during unmarshalling, unmarshal into transient fields like XStream 1.1.3 //boolean fieldExistsInClass = reflectionProvider.fieldDefinedInClass(attrName, result.getClass()); - return reflectionProvider.getFieldOrNull(result.getClass(),attrName)!=null; + return reflectionProvider.getFieldOrNull(result.getClass(), attrName) != null; } protected Object unmarshalField(final UnmarshallingContext context, final Object result, Class type, Field field) { @@ -293,13 +295,13 @@ public class RobustReflectionConverter implements Converter { if (collection == null) { Class fieldType = mapper.defaultImplementationOf(reflectionProvider.getFieldType(result, fieldName, null)); if (!Collection.class.isAssignableFrom(fieldType)) { - throw new ObjectAccessException("Field " + fieldName + " of " + result.getClass().getName() + - " is configured for an implicit Collection, but field is of type " + fieldType.getName()); + throw new ObjectAccessException("Field " + fieldName + " of " + result.getClass().getName() + + " is configured for an implicit Collection, but field is of type " + fieldType.getName()); } if (pureJavaReflectionProvider == null) { pureJavaReflectionProvider = new PureJavaReflectionProvider(); } - collection = (Collection)pureJavaReflectionProvider.newInstance(fieldType); + collection = (Collection) pureJavaReflectionProvider.newInstance(fieldType); reflectionProvider.writeField(result, fieldName, collection, null); implicitCollections.put(fieldName, collection); } @@ -320,8 +322,9 @@ public class RobustReflectionConverter implements Converter { Object currentObject = context.currentObject(); if (currentObject != null) { - if (type.isInstance(currentObject)) + if (type.isInstance(currentObject)) { return currentObject; + } } return reflectionProvider.newInstance(type); } @@ -341,7 +344,6 @@ public class RobustReflectionConverter implements Converter { seen.add(uniqueKey); } } - } private Class determineType(HierarchicalStreamReader reader, boolean validField, Object result, String fieldName, Class definedInCls) { @@ -349,10 +351,11 @@ public class RobustReflectionConverter implements Converter { Class fieldType = reflectionProvider.getFieldType(result, fieldName, definedInCls); if (classAttribute != null) { Class specifiedType = mapper.realClass(classAttribute); - if(fieldType.isAssignableFrom(specifiedType)) - // make sure that the specified type in XML is compatible with the field type. - // this allows the code to evolve in more flexible way. + if (fieldType.isAssignableFrom(specifiedType)) // make sure that the specified type in XML is compatible with the field type. + // this allows the code to evolve in more flexible way. + { return specifiedType; + } } if (!validField) { Class itemType = mapper.getItemTypeForItemFieldName(result.getClass(), fieldName); @@ -372,11 +375,11 @@ public class RobustReflectionConverter implements Converter { } public static class DuplicateFieldException extends ConversionException { + public DuplicateFieldException(String msg) { super(msg); add("duplicate-field", msg); } } - private static final Logger LOGGER = Logger.getLogger(RobustReflectionConverter.class.getName()); } diff --git a/hudson-core/src/main/java/hudson/util/RunList.java b/hudson-core/src/main/java/hudson/util/RunList.java index 6a88140..4f083e7 100644 --- a/hudson-core/src/main/java/hudson/util/RunList.java +++ b/hudson-core/src/main/java/hudson/util/RunList.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 - * + * * *******************************************************************************/ @@ -42,6 +42,7 @@ import java.util.List; * @author Kohsuke Kawaguchi */ public class RunList<R extends Run> extends ArrayList<R> { + public RunList() { } @@ -50,7 +51,7 @@ public class RunList<R extends Run> extends ArrayList<R> { } public R getFirstBuild() { - return isEmpty() ? null : get(size()-1); + return isEmpty() ? null : get(size() - 1); } public R getLastBuild() { @@ -58,25 +59,27 @@ public class RunList<R extends Run> extends ArrayList<R> { } public RunList(View view) {// this is a type unsafe operation - for (Item item : view.getItems()) - for (Job<?,?> j : item.getAllJobs()) - addAll((Collection<R>)j.getBuilds()); - Collections.sort(this,Run.ORDER_BY_DATE); + for (Item item : view.getItems()) { + for (Job<?, ?> j : item.getAllJobs()) { + addAll((Collection<R>) j.getBuilds()); + } + } + Collections.sort(this, Run.ORDER_BY_DATE); } public RunList(Collection<? extends Job> jobs) { - for (Job j : jobs) + for (Job j : jobs) { addAll(j.getBuilds()); - Collections.sort(this,Run.ORDER_BY_DATE); + } + Collections.sort(this, Run.ORDER_BY_DATE); } private RunList(Collection<? extends R> c, boolean dummy) { super(c); } - public static <R extends Run> - RunList<R> fromRuns(Collection<? extends R> runs) { - return new RunList<R>(runs,false); + public static <R extends Run> RunList<R> fromRuns(Collection<? extends R> runs) { + return new RunList<R>(runs, false); } /** @@ -85,8 +88,9 @@ public class RunList<R extends Run> extends ArrayList<R> { public RunList<R> failureOnly() { for (Iterator<R> itr = iterator(); itr.hasNext();) { Run r = itr.next(); - if(r.getResult()==Result.SUCCESS) + if (r.getResult() == Result.SUCCESS) { itr.remove(); + } } return this; } @@ -97,7 +101,7 @@ public class RunList<R extends Run> extends ArrayList<R> { public RunList<R> node(Node node) { for (Iterator<R> itr = iterator(); itr.hasNext();) { Run r = itr.next(); - if (!(r instanceof AbstractBuild) || ((AbstractBuild)r).getBuiltOn()!=node) { + if (!(r instanceof AbstractBuild) || ((AbstractBuild) r).getBuiltOn() != node) { itr.remove(); } } @@ -110,8 +114,9 @@ public class RunList<R extends Run> extends ArrayList<R> { public RunList<R> regressionOnly() { for (Iterator<R> itr = iterator(); itr.hasNext();) { Run r = itr.next(); - if(!r.getBuildStatusSummary().isWorse) + if (!r.getBuildStatusSummary().isWorse) { itr.remove(); + } } return this; } @@ -133,46 +138,56 @@ public class RunList<R extends Run> extends ArrayList<R> { }; Comparator<Long> DESCENDING_ORDER = new Comparator<Long>() { public int compare(Long o1, Long o2) { - if (o1 > o2) return -1; - if (o1 < o2) return +1; + if (o1 > o2) { + return -1; + } + if (o1 < o2) { + return +1; + } return 0; } }; int s = Collections.binarySearch(TIMESTAMP_ADAPTER, start, DESCENDING_ORDER); - if (s<0) s=-(s+1); // min is inclusive - int e = Collections.binarySearch(TIMESTAMP_ADAPTER, end, DESCENDING_ORDER); - if (e<0) e=-(e+1); else e++; // max is exclusive, so the exact match should be excluded - - return fromRuns(subList(e,s)); + if (s < 0) { + s = -(s + 1); // min is inclusive + } + int e = Collections.binarySearch(TIMESTAMP_ADAPTER, end, DESCENDING_ORDER); + if (e < 0) { + e = -(e + 1); + } else { + e++; // max is exclusive, so the exact match should be excluded + } + return fromRuns(subList(e, s)); } /** - * Reduce the size of the list by only leaving relatively new ones. - * This also removes on-going builds, as RSS cannot be used to publish information - * if it changes. + * Reduce the size of the list by only leaving relatively new ones. This + * also removes on-going builds, as RSS cannot be used to publish + * information if it changes. */ public RunList<R> newBuilds() { GregorianCalendar threshold = new GregorianCalendar(); - threshold.add(Calendar.DAY_OF_YEAR,-7); + threshold.add(Calendar.DAY_OF_YEAR, -7); - int count=0; + int count = 0; for (Iterator<R> itr = iterator(); itr.hasNext();) { R r = itr.next(); - if(r.isBuilding()) { + if (r.isBuilding()) { // can't publish on-going builds itr.remove(); continue; } // at least put 10 items - if(count<10) { + if (count < 10) { count++; continue; } // anything older than 7 days will be ignored - if(r.getTimestamp().before(threshold)) + if (r.getTimestamp().before(threshold)) { itr.remove(); + } } return this; } diff --git a/hudson-core/src/main/java/hudson/util/Scrambler.java b/hudson-core/src/main/java/hudson/util/Scrambler.java index 0148bd0..6da731a 100644 --- a/hudson-core/src/main/java/hudson/util/Scrambler.java +++ b/hudson-core/src/main/java/hudson/util/Scrambler.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 + * * *******************************************************************************/ @@ -23,17 +23,19 @@ import org.apache.commons.codec.binary.Base64; /** * Used when storing passwords in configuration files. * - * <p> - * This doesn't make passwords secure, but it prevents unwanted - * exposure to passwords, such as when one is grepping the file system - * or looking at config files for trouble-shooting. + * <p> This doesn't make passwords secure, but it prevents unwanted exposure to + * passwords, such as when one is grepping the file system or looking at config + * files for trouble-shooting. * * @author Kohsuke Kawaguchi * @see Protector */ public class Scrambler { + public static String scramble(String secret) { - if(secret==null) return null; + if (secret == null) { + return null; + } try { return new String(Base64.encodeBase64(secret.getBytes("UTF-8"))); } catch (UnsupportedEncodingException e) { @@ -42,9 +44,11 @@ public class Scrambler { } public static String descramble(String scrambled) { - if(scrambled==null) return null; + if (scrambled == null) { + return null; + } try { - return new String(Base64.decodeBase64(scrambled),"UTF-8"); + return new String(Base64.decodeBase64(scrambled), "UTF-8"); } catch (IOException e) { return ""; // corrupted data. } diff --git a/hudson-core/src/main/java/hudson/util/Secret.java b/hudson-core/src/main/java/hudson/util/Secret.java index fe0ead0..426f66e 100644 --- a/hudson-core/src/main/java/hudson/util/Secret.java +++ b/hudson-core/src/main/java/hudson/util/Secret.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 - * + * * *******************************************************************************/ @@ -34,19 +34,20 @@ import java.security.GeneralSecurityException; import org.apache.commons.codec.binary.Base64; /** - * Glorified {@link String} that uses encryption in the persisted form, to avoid accidental exposure of a secret. + * Glorified {@link String} that uses encryption in the persisted form, to avoid + * accidental exposure of a secret. * - * <p> - * Note that since the cryptography relies on {@link Hudson#getSecretKey()}, this is not meant as a protection - * against code running in the same VM, nor against an attacker who has local file system access. + * <p> Note that since the cryptography relies on {@link Hudson#getSecretKey()}, + * this is not meant as a protection against code running in the same VM, nor + * against an attacker who has local file system access. * - * <p> - * {@link Secret}s can correctly read-in plain text password, so this allows the existing - * String field to be updated to {@link Secret}. + * <p> {@link Secret}s can correctly read-in plain text password, so this allows + * the existing String field to be updated to {@link Secret}. * * @author Kohsuke Kawaguchi */ public final class Secret implements Serializable { + /** * Unencrypted secret text. */ @@ -60,9 +61,9 @@ public final class Secret implements Serializable { * Obtains the secret in a plain text. * * @see #getEncryptedValue() - * @deprecated as of 1.356 - * Use {@link #toString(Secret)} to avoid NPE in case Secret is null. - * Or if you really know what you are doing, use the {@link #getPlainText()} method. + * @deprecated as of 1.356 Use {@link #toString(Secret)} to avoid NPE in + * case Secret is null. Or if you really know what you are doing, use the + * {@link #getPlainText()} method. */ @Override public String toString() { @@ -70,9 +71,9 @@ public final class Secret implements Serializable { } /** - * Obtains the plain text password. - * Before using this method, ask yourself if you'd be better off using {@link Secret#toString(Secret)} - * to avoid NPE. + * Obtains the plain text password. Before using this method, ask yourself + * if you'd be better off using {@link Secret#toString(Secret)} to avoid + * NPE. */ public String getPlainText() { return value; @@ -80,7 +81,7 @@ public final class Secret implements Serializable { @Override public boolean equals(Object that) { - return that instanceof Secret && value.equals(((Secret)that).value); + return that instanceof Secret && value.equals(((Secret) that).value); } @Override @@ -89,25 +90,27 @@ public final class Secret implements Serializable { } /** - * Turns {@link Hudson#getSecretKey()} into an AES key. + * Turns {@link Hudson#getSecretKey()} into an AES key. */ private static SecretKey getKey() throws UnsupportedEncodingException, GeneralSecurityException { String secret = SECRET; - if(secret==null) return Hudson.getInstance().getSecretKeyAsAES128(); + if (secret == null) { + return Hudson.getInstance().getSecretKeyAsAES128(); + } return Util.toAes128Key(secret); } /** * Encrypts {@link #value} and returns it in an encoded printable form. * - * @see #toString() + * @see #toString() */ public String getEncryptedValue() { try { Cipher cipher = getCipher("AES"); cipher.init(Cipher.ENCRYPT_MODE, getKey()); // add the magic suffix which works like a check sum. - return new String(Base64.encodeBase64(cipher.doFinal((value+MAGIC).getBytes("UTF-8")))); + return new String(Base64.encodeBase64(cipher.doFinal((value + MAGIC).getBytes("UTF-8")))); } catch (GeneralSecurityException e) { throw new Error(e); // impossible } catch (UnsupportedEncodingException e) { @@ -116,17 +119,20 @@ public final class Secret implements Serializable { } /** - * Reverse operation of {@link #getEncryptedValue()}. Returns null - * if the given cipher text was invalid. + * Reverse operation of {@link #getEncryptedValue()}. Returns null if the + * given cipher text was invalid. */ public static Secret decrypt(String data) { - if(data==null) return null; + if (data == null) { + return null; + } try { Cipher cipher = getCipher("AES"); cipher.init(Cipher.DECRYPT_MODE, getKey()); String plainText = new String(cipher.doFinal(Base64.decodeBase64(data)), "UTF-8"); - if(plainText.endsWith(MAGIC)) - return new Secret(plainText.substring(0,plainText.length()-MAGIC.length())); + if (plainText.endsWith(MAGIC)) { + return new Secret(plainText.substring(0, plainText.length() - MAGIC.length())); + } return null; } catch (GeneralSecurityException e) { return null; @@ -138,47 +144,51 @@ public final class Secret implements Serializable { } /** - * Workaround for HUDSON-6459 / http://java.net/jira/browse/GLASSFISH-11862 . - * This method uses specific provider selected via hudson.util.Secret.provider system property - * to provide a workaround for the above bug where default provide gives an unusable instance. - * (Glassfish Enterprise users should set value of this property to "SunJCE") + * Workaround for HUDSON-6459 / http://java.net/jira/browse/GLASSFISH-11862 + * . This method uses specific provider selected via + * hudson.util.Secret.provider system property to provide a workaround for + * the above bug where default provide gives an unusable instance. + * (Glassfish Enterprise users should set value of this property to + * "SunJCE") */ public static Cipher getCipher(String algorithm) throws GeneralSecurityException { return PROVIDER != null ? Cipher.getInstance(algorithm, PROVIDER) - : Cipher.getInstance(algorithm); + : Cipher.getInstance(algorithm); } /** - * Attempts to treat the given string first as a cipher text, and if it doesn't work, - * treat the given string as the unencrypted secret value. + * Attempts to treat the given string first as a cipher text, and if it + * doesn't work, treat the given string as the unencrypted secret value. * - * <p> - * Useful for recovering a value from a form field. + * <p> Useful for recovering a value from a form field. * * @return never null */ public static Secret fromString(String data) { data = Util.fixNull(data); Secret s = decrypt(data); - if(s==null) s=new Secret(data); + if (s == null) { + s = new Secret(data); + } return s; } /** - * Works just like {@link Secret#toString()} but avoids NPE when the secret is null. - * To be consistent with {@link #fromString(String)}, this method doesn't distinguish - * empty password and null password. + * Works just like {@link Secret#toString()} but avoids NPE when the secret + * is null. To be consistent with {@link #fromString(String)}, this method + * doesn't distinguish empty password and null password. */ public static String toString(Secret s) { - return s==null ? "" : s.value; + return s == null ? "" : s.value; } public static final class ConverterImpl implements Converter { + public ConverterImpl() { } public boolean canConvert(Class type) { - return type==Secret.class; + return type == Secret.class; } public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { @@ -190,20 +200,19 @@ public final class Secret implements Serializable { return fromString(reader.getValue()); } } - private static final String MAGIC = "::::MAGIC::::"; - /** - * Workaround for HUDSON-6459 / http://java.net/jira/browse/GLASSFISH-11862 . + * Workaround for HUDSON-6459 / http://java.net/jira/browse/GLASSFISH-11862 + * . + * * @see #getCipher(String) */ - private static final String PROVIDER = System.getProperty(Secret.class.getName()+".provider"); - + private static final String PROVIDER = System.getProperty(Secret.class.getName() + ".provider"); /** - * For testing only. Override the secret key so that we can test this class without {@link Hudson}. + * For testing only. Override the secret key so that we can test this class + * without {@link Hudson}. */ /*package*/ static String SECRET = null; - private static final long serialVersionUID = 1L; static { diff --git a/hudson-core/src/main/java/hudson/util/SecurityFailedToInit.java b/hudson-core/src/main/java/hudson/util/SecurityFailedToInit.java index 80aae52..f52a3b7 100644 --- a/hudson-core/src/main/java/hudson/util/SecurityFailedToInit.java +++ b/hudson-core/src/main/java/hudson/util/SecurityFailedToInit.java @@ -7,24 +7,25 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: + * Contributors: * * Winston Prakash - * + * *******************************************************************************/ package hudson.util; import hudson.Functions; /** - * Model object used to display error page if any Hudson Security initialization error occurs. + * Model object used to display error page if any Hudson Security initialization + * error occurs. * - * <p> - * <tt>index.jelly</tt> would display a nice friendly error page. + * <p> <tt>index.jelly</tt> would display a nice friendly error page. * * @author Winston Prakash */ public class SecurityFailedToInit extends ErrorObject { + public final Throwable exception; public SecurityFailedToInit(Throwable exception) { diff --git a/hudson-core/src/main/java/hudson/util/SequentialExecutionQueue.java b/hudson-core/src/main/java/hudson/util/SequentialExecutionQueue.java index c18ecec..fa3dcdf 100644 --- a/hudson-core/src/main/java/hudson/util/SequentialExecutionQueue.java +++ b/hudson-core/src/main/java/hudson/util/SequentialExecutionQueue.java @@ -8,7 +8,7 @@ * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * + * * *******************************************************************************/ @@ -22,27 +22,27 @@ import java.util.concurrent.Executor; import java.util.concurrent.ExecutorService; /** - * {@link Executor} that collapses two equal {@link Runnable}s into one, - * and makes sure no two equal {@link Runnable}s get executed simultaneously. + * {@link Executor} that collapses two equal {@link Runnable}s into one, and + * makes sure no two equal {@link Runnable}s get executed simultaneously. * - * <p> - * That is, if a {@link Runnable} is executing and another one gets submitted, - * the 2nd one waits for the completion of the 1st one. + * <p> That is, if a {@link Runnable} is executing and another one gets + * submitted, the 2nd one waits for the completion of the 1st one. * - * {@link Object#equals(Object)} is used on {@link Runnable} to identify - * two equal {@link Runnable}s. + * {@link Object#equals(Object)} is used on {@link Runnable} to identify two + * equal {@link Runnable}s. * * @author Kohsuke Kawaguchi */ public class SequentialExecutionQueue implements Executor { + /** * Access is sycnhronized by {@code Queue.this} */ - private final Map<Runnable,QueueEntry> entries = new HashMap<Runnable,QueueEntry>(); + private final Map<Runnable, QueueEntry> entries = new HashMap<Runnable, QueueEntry>(); private ExecutorService executors; - /** - * {@link Runnable}s that are currently executing. Useful for trouble-shooting. + * {@link Runnable}s that are currently executing. Useful for + * trouble-shooting. */ private final Set<QueueEntry> inProgress = new HashSet<QueueEntry>(); @@ -60,9 +60,8 @@ public class SequentialExecutionQueue implements Executor { /** * Starts using a new {@link ExecutorService} to carry out executions. * - * <p> - * The older {@link ExecutorService} will be shut down (but it's still expected to - * complete whatever they are doing and scheduled.) + * <p> The older {@link ExecutorService} will be shut down (but it's still + * expected to complete whatever they are doing and scheduled.) */ public synchronized void setExecutors(ExecutorService svc) { ExecutorService old = this.executors; @@ -71,12 +70,11 @@ public class SequentialExecutionQueue implements Executor { old.shutdown(); } - public synchronized void execute(Runnable item) { QueueEntry e = entries.get(item); - if(e==null) { + if (e == null) { e = new QueueEntry(item); - entries.put(item,e); + entries.put(item, e); e.submit(); } else { e.queued = true; @@ -84,14 +82,16 @@ public class SequentialExecutionQueue implements Executor { } /** - * Returns true if too much time is spent since some {@link Runnable} is submitted into the queue - * until they get executed. + * Returns true if too much time is spent since some {@link Runnable} is + * submitted into the queue until they get executed. */ public synchronized boolean isStarving(long threshold) { long now = System.currentTimeMillis(); - for (QueueEntry e : entries.values()) - if (now-e.submissionTime > threshold) + for (QueueEntry e : entries.values()) { + if (now - e.submissionTime > threshold) { return true; + } + } return false; } @@ -107,6 +107,7 @@ public class SequentialExecutionQueue implements Executor { } private final class QueueEntry implements Runnable { + private final Runnable item; private boolean queued; private long submissionTime; @@ -132,11 +133,12 @@ public class SequentialExecutionQueue implements Executor { item.run(); } finally { synchronized (SequentialExecutionQueue.this) { - if(queued) - // another polling for this job is requested while we were doing the polling. do it again. + if (queued) // another polling for this job is requested while we were doing the polling. do it again. + { submit(); - else + } else { entries.remove(item); + } inProgress.remove(this); } } diff --git a/hudson-core/src/main/java/hudson/util/Service.java b/hudson-core/src/main/java/hudson/util/Service.java index c8fc745..96c0745 100644 --- a/hudson-core/src/main/java/hudson/util/Service.java +++ b/hudson-core/src/main/java/hudson/util/Service.java @@ -10,7 +10,7 @@ * * Contributors: * -* Kohsuke Kawaguchi + * Kohsuke Kawaguchi * * ****************************************************************************** @@ -46,7 +46,7 @@ public class Service { final Enumeration<URL> e = classLoader.getResources("META-INF/services/" + type.getName()); BufferedReader configFile = null; - try { + try { while (e.hasMoreElements()) { URL url = e.nextElement(); configFile = new BufferedReader(new InputStreamReader(url.openStream(), "UTF-8")); diff --git a/hudson-core/src/main/java/hudson/util/SignatureOutputStream.java b/hudson-core/src/main/java/hudson/util/SignatureOutputStream.java index 42231f0..f9d9742 100644 --- a/hudson-core/src/main/java/hudson/util/SignatureOutputStream.java +++ b/hudson-core/src/main/java/hudson/util/SignatureOutputStream.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.util; @@ -27,6 +27,7 @@ import java.io.IOException; * @author Kohsuke Kawaguchi */ public class SignatureOutputStream extends FilterOutputStream { + private final Signature sig; public SignatureOutputStream(OutputStream out, Signature sig) { @@ -35,26 +36,26 @@ public class SignatureOutputStream extends FilterOutputStream { } public SignatureOutputStream(Signature sig) { - this(new NullOutputStream(),sig); + this(new NullOutputStream(), sig); } @Override public void write(int b) throws IOException { try { - sig.update((byte)b); + sig.update((byte) b); out.write(b); } catch (SignatureException e) { - throw (IOException)new IOException(e.getMessage()).initCause(e); + throw (IOException) new IOException(e.getMessage()).initCause(e); } } @Override public void write(byte[] b, int off, int len) throws IOException { try { - sig.update(b,off,len); - out.write(b,off,len); + sig.update(b, off, len); + out.write(b, off, len); } catch (SignatureException e) { - throw (IOException)new IOException(e.getMessage()).initCause(e); + throw (IOException) new IOException(e.getMessage()).initCause(e); } } } diff --git a/hudson-core/src/main/java/hudson/util/StreamCopyThread.java b/hudson-core/src/main/java/hudson/util/StreamCopyThread.java index 3e40cbc..7182e00 100644 --- a/hudson-core/src/main/java/hudson/util/StreamCopyThread.java +++ b/hudson-core/src/main/java/hudson/util/StreamCopyThread.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 + * * *******************************************************************************/ @@ -26,6 +26,7 @@ import java.io.OutputStream; * @author Kohsuke Kawaguchi */ public class StreamCopyThread extends Thread { + private final InputStream in; private final OutputStream out; private final boolean closeOut; @@ -41,7 +42,7 @@ public class StreamCopyThread extends Thread { } public StreamCopyThread(String threadName, InputStream in, OutputStream out) { - this(threadName,in,out,false); + this(threadName, in, out, false); } @Override @@ -50,14 +51,16 @@ public class StreamCopyThread extends Thread { try { byte[] buf = new byte[8192]; int len; - while ((len = in.read(buf)) > 0) + while ((len = in.read(buf)) > 0) { out.write(buf, 0, len); + } } finally { // it doesn't make sense not to close InputStream that's already EOF-ed, // so there's no 'closeIn' flag. in.close(); - if(closeOut) + if (closeOut) { out.close(); + } } } catch (IOException e) { // TODO: what to do? diff --git a/hudson-core/src/main/java/hudson/util/StreamResource.java b/hudson-core/src/main/java/hudson/util/StreamResource.java index 0ba03a5..a509b98 100644 --- a/hudson-core/src/main/java/hudson/util/StreamResource.java +++ b/hudson-core/src/main/java/hudson/util/StreamResource.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 + * * *******************************************************************************/ @@ -23,14 +23,15 @@ import java.io.IOException; /** * Wraps {@link InputStream} to {@link Resource}. + * * @author Kohsuke Kawaguchi */ public class StreamResource extends Resource { + private final InputStream in; /** - * @param name - * Used for display purpose. + * @param name Used for display purpose. */ public StreamResource(String name, InputStream in) { this.in = in; diff --git a/hudson-core/src/main/java/hudson/util/StreamTaskListener.java b/hudson-core/src/main/java/hudson/util/StreamTaskListener.java index ce21a63..a00f39d 100644 --- a/hudson-core/src/main/java/hudson/util/StreamTaskListener.java +++ b/hudson-core/src/main/java/hudson/util/StreamTaskListener.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 + * * *******************************************************************************/ @@ -43,35 +43,36 @@ import java.util.logging.Logger; /** * {@link TaskListener} that generates output into a single stream. * - * <p> - * This object is remotable. - * + * <p> This object is remotable. + * * @author Kohsuke Kawaguchi */ public class StreamTaskListener extends AbstractTaskListener implements Serializable, Closeable { + private PrintStream out; private Charset charset; /** - * @deprecated as of 1.349 - * The caller should use {@link #StreamTaskListener(OutputStream, Charset)} to pass in - * the charset and output stream separately, so that this class can handle encoding correctly, - * or use {@link #fromStdout()} or {@link #fromStderr()}. + * @deprecated as of 1.349 The caller should use + * {@link #StreamTaskListener(OutputStream, Charset)} to pass in the charset + * and output stream separately, so that this class can handle encoding + * correctly, or use {@link #fromStdout()} or {@link #fromStderr()}. */ public StreamTaskListener(PrintStream out) { - this(out,null); + this(out, null); } public StreamTaskListener(OutputStream out) { - this(out,null); + this(out, null); } public StreamTaskListener(OutputStream out, Charset charset) { try { - if (charset == null) - this.out = (out instanceof PrintStream) ? (PrintStream)out : new PrintStream(out, false); - else + if (charset == null) { + this.out = (out instanceof PrintStream) ? (PrintStream) out : new PrintStream(out, false); + } else { this.out = new PrintStream(out, false, charset.name()); + } this.charset = charset; } catch (UnsupportedEncodingException e) { // it's not very pretty to do this, but otherwise we'd have to touch too many call sites. @@ -80,14 +81,14 @@ public class StreamTaskListener extends AbstractTaskListener implements Serializ } public StreamTaskListener(File out) throws IOException { - this(out,null); + this(out, null); } public StreamTaskListener(File out, Charset charset) throws IOException { // don't do buffering so that what's written to the listener // gets reflected to the file immediately, which can then be // served to the browser immediately - this(new FileOutputStream(out),charset); + this(new FileOutputStream(out), charset); } public StreamTaskListener(Writer w) throws IOException { @@ -95,19 +96,18 @@ public class StreamTaskListener extends AbstractTaskListener implements Serializ } /** - * @deprecated as of 1.349 - * Use {@link #NULL} + * @deprecated as of 1.349 Use {@link #NULL} */ public StreamTaskListener() throws IOException { this(new NullStream()); } public static StreamTaskListener fromStdout() { - return new StreamTaskListener(System.out,Charset.defaultCharset()); + return new StreamTaskListener(System.out, Charset.defaultCharset()); } public static StreamTaskListener fromStderr() { - return new StreamTaskListener(System.err,Charset.defaultCharset()); + return new StreamTaskListener(System.err, Charset.defaultCharset()); } public PrintStream getLogger() { @@ -127,23 +127,23 @@ public class StreamTaskListener extends AbstractTaskListener implements Serializ // for signature compatibility, we have to swallow this error } return new PrintWriter( - charset!=null ? new OutputStreamWriter(out,charset) : new OutputStreamWriter(out),true); + charset != null ? new OutputStreamWriter(out, charset) : new OutputStreamWriter(out), true); } public PrintWriter error(String msg) { - return _error("ERROR: ",msg); + return _error("ERROR: ", msg); } public PrintWriter error(String format, Object... args) { - return error(String.format(format,args)); + return error(String.format(format, args)); } public PrintWriter fatalError(String msg) { - return _error("FATAL: ",msg); + return _error("FATAL: ", msg); } public PrintWriter fatalError(String format, Object... args) { - return fatalError(String.format(format,args)); + return fatalError(String.format(format, args)); } public void annotate(ConsoleNote ann) throws IOException { @@ -152,13 +152,13 @@ public class StreamTaskListener extends AbstractTaskListener implements Serializ private void writeObject(ObjectOutputStream out) throws IOException { out.writeObject(new RemoteOutputStream(new CloseProofOutputStream(this.out))); - out.writeObject(charset==null? null : charset.name()); + out.writeObject(charset == null ? null : charset.name()); } private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { - out = new PrintStream((OutputStream)in.readObject(),true); - String name = (String)in.readObject(); - charset = name==null ? null : Charset.forName(name); + out = new PrintStream((OutputStream) in.readObject(), true); + String name = (String) in.readObject(); + charset = name == null ? null : Charset.forName(name); } public void close() throws IOException { @@ -174,11 +174,9 @@ public class StreamTaskListener extends AbstractTaskListener implements Serializ try { close(); } catch (IOException e) { - LOGGER.log(Level.WARNING,"Failed to close",e); + LOGGER.log(Level.WARNING, "Failed to close", e); } } - private static final long serialVersionUID = 1L; - private static final Logger LOGGER = Logger.getLogger(StreamTaskListener.class.getName()); } diff --git a/hudson-core/src/main/java/hudson/util/StringConverter2.java b/hudson-core/src/main/java/hudson/util/StringConverter2.java index 5fe27ad..43f7243 100644 --- a/hudson-core/src/main/java/hudson/util/StringConverter2.java +++ b/hudson-core/src/main/java/hudson/util/StringConverter2.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 + * * *******************************************************************************/ @@ -20,17 +20,14 @@ import com.thoughtworks.xstream.converters.basic.AbstractSingleValueConverter; import com.thoughtworks.xstream.converters.basic.StringConverter; /** - * The default {@link StringConverter} in XStream - * uses {@link String#intern()}, which stresses the - * (rather limited) PermGen space with a large XML file. + * The default {@link StringConverter} in XStream uses {@link String#intern()}, + * which stresses the (rather limited) PermGen space with a large XML file. * - * <p> - * Use this to avoid that (instead those strings will - * now be allocated to the heap space.) + * <p> Use this to avoid that (instead those strings will now be allocated to + * the heap space.) * * @author Kohsuke Kawaguchi - * @deprecated since 2009-11-06 - * Use {@link HeapSpaceStringConverter} instead. + * @deprecated since 2009-11-06 Use {@link HeapSpaceStringConverter} instead. */ @Deprecated public class StringConverter2 extends AbstractSingleValueConverter { diff --git a/hudson-core/src/main/java/hudson/util/SubClassGenerator.java b/hudson-core/src/main/java/hudson/util/SubClassGenerator.java index 3a80dec..bfee251 100644 --- a/hudson-core/src/main/java/hudson/util/SubClassGenerator.java +++ b/hudson-core/src/main/java/hudson/util/SubClassGenerator.java @@ -7,10 +7,10 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: + * Contributors: + * + * * - * - * * *******************************************************************************/ @@ -32,6 +32,7 @@ import static org.objectweb.asm.Opcodes.*; * @author Kohsuke Kawaguchi */ public class SubClassGenerator extends ClassLoader { + public SubClassGenerator(ClassLoader parent) { super(parent); } @@ -39,20 +40,21 @@ public class SubClassGenerator extends ClassLoader { public <T> Class<? extends T> generate(Class<T> base, String name) { ClassWriter cw = new ClassWriter(false, false);//? cw.visit(49, ACC_PUBLIC, name.replace('.', '/'), null, - Type.getInternalName(base),null); + Type.getInternalName(base), null); for (Constructor c : base.getDeclaredConstructors()) { Class[] et = c.getExceptionTypes(); String[] exceptions = new String[et.length]; - for (int i = 0; i < et.length; i++) + for (int i = 0; i < et.length; i++) { exceptions[i] = Type.getInternalName(et[i]); + } String methodDescriptor = getMethodDescriptor(c); MethodVisitor m = cw.visitMethod(c.getModifiers(), "<init>", methodDescriptor, null, exceptions); m.visitCode(); - int index=1; - m.visitVarInsn(ALOAD,0); + int index = 1; + m.visitVarInsn(ALOAD, 0); for (Class param : c.getParameterTypes()) { Type t = Type.getType(param); m.visitVarInsn(t.getOpcode(ILOAD), index); @@ -60,7 +62,7 @@ public class SubClassGenerator extends ClassLoader { } m.visitMethodInsn(INVOKESPECIAL, Type.getInternalName(base), "<init>", methodDescriptor); m.visitInsn(RETURN); - m.visitMaxs(index,index); + m.visitMaxs(index, index); m.visitEnd(); } @@ -70,17 +72,19 @@ public class SubClassGenerator extends ClassLoader { Class<? extends T> c = defineClass(name, image, 0, image.length).asSubclass(base); Hudson h = Hudson.getInstance(); - if (h!=null) // null only during tests. - ((UberClassLoader)h.pluginManager.uberClassLoader).addNamedClass(name,c); // can't change the field type as it breaks binary compatibility - + if (h != null) // null only during tests. + { + ((UberClassLoader) h.pluginManager.uberClassLoader).addNamedClass(name, c); // can't change the field type as it breaks binary compatibility + } return c; } private String getMethodDescriptor(Constructor c) { StringBuilder buf = new StringBuilder(); buf.append('('); - for (Class p : c.getParameterTypes()) + for (Class p : c.getParameterTypes()) { buf.append(Type.getDescriptor(p)); + } buf.append(")V"); return buf.toString(); diff --git a/hudson-core/src/main/java/hudson/util/TableNestChecker.java b/hudson-core/src/main/java/hudson/util/TableNestChecker.java index 1292708..e1850e4 100644 --- a/hudson-core/src/main/java/hudson/util/TableNestChecker.java +++ b/hudson-core/src/main/java/hudson/util/TableNestChecker.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 + * * *******************************************************************************/ @@ -34,14 +34,12 @@ import java.util.Arrays; /** * {@link XMLFilter} that checks the proper nesting of table related tags. * - * <p> - * Browser often "fixes" HTML by moving tables into the right place, - * so failure to generate proper tables can result in a hard-to-track bugs. + * <p> Browser often "fixes" HTML by moving tables into the right place, so + * failure to generate proper tables can result in a hard-to-track bugs. * - * <p> - * TODO: where to apply this in stapler? - * JellyClassTearOff creates XMLOutput. Perhaps we define a decorator? - * We can also wrap Script. would that work better? + * <p> TODO: where to apply this in stapler? JellyClassTearOff creates + * XMLOutput. Perhaps we define a decorator? We can also wrap Script. would that + * work better? * * @author Kohsuke Kawaguchi */ @@ -68,11 +66,14 @@ public class TableNestChecker extends XMLFilterImpl { String tagName = localName.toUpperCase(Locale.ENGLISH); // make sure that this tag occurs in the proper context - if(!elements.peek().isAllowed(tagName)) - throw new SAXException(tagName+" is not allowed inside "+tagNames.peek()); + if (!elements.peek().isAllowed(tagName)) { + throw new SAXException(tagName + " is not allowed inside " + tagNames.peek()); + } Checker next = CHECKERS.get(tagName); - if(next==null) next = ALL_ALLOWED; + if (next == null) { + next = ALL_ALLOWED; + } elements.push(next); tagNames.push(tagName); @@ -86,11 +87,10 @@ public class TableNestChecker extends XMLFilterImpl { super.endElement(uri, localName, qName); } - private interface Checker { + boolean isAllowed(String childTag); } - private static final Checker ALL_ALLOWED = new Checker() { public boolean isAllowed(String childTag) { return true; @@ -98,6 +98,7 @@ public class TableNestChecker extends XMLFilterImpl { }; private static final class InList implements Checker { + private final Set<String> tags; private InList(String... tags) { @@ -108,14 +109,13 @@ public class TableNestChecker extends XMLFilterImpl { return tags.contains(childTag); } } - - private static final Map<String,Checker> CHECKERS = new HashMap<String, Checker>(); + private static final Map<String, Checker> CHECKERS = new HashMap<String, Checker>(); static { - CHECKERS.put("TABLE",new InList("TR","THEAD","TBODY")); + CHECKERS.put("TABLE", new InList("TR", "THEAD", "TBODY")); InList rows = new InList("TR"); - CHECKERS.put("THEAD",rows); - CHECKERS.put("THEAD",rows); - CHECKERS.put("TR", new InList("TD","TH")); + CHECKERS.put("THEAD", rows); + CHECKERS.put("THEAD", rows); + CHECKERS.put("TR", new InList("TD", "TH")); } } diff --git a/hudson-core/src/main/java/hudson/util/TagCloud.java b/hudson-core/src/main/java/hudson/util/TagCloud.java index 99cb4c9..c588917 100644 --- a/hudson-core/src/main/java/hudson/util/TagCloud.java +++ b/hudson-core/src/main/java/hudson/util/TagCloud.java @@ -7,10 +7,10 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: + * Contributors: + * + * * - * - * * *******************************************************************************/ @@ -21,16 +21,19 @@ import java.util.ArrayList; import java.util.List; /** - * Represents an order-preserving tag cloud (http://en.wikipedia.org/wiki/Tag_cloud) - * where each keyword gets a weight and displayed according to their weight. + * Represents an order-preserving tag cloud + * (http://en.wikipedia.org/wiki/Tag_cloud) where each keyword gets a weight and + * displayed according to their weight. * * TODO: define a view on its own. - * + * * @since 1.322 */ public class TagCloud<T> extends AbstractList<TagCloud<T>.Entry> { + public final class Entry { //TODO: review and check whether we can do it private + public final T item; public final float weight; @@ -41,11 +44,11 @@ public class TagCloud<T> extends AbstractList<TagCloud<T>.Entry> { public float scale() { // TODO: it's not obvious if linear scaling is the right approach or not. - return weight*9/max; + return weight * 9 / max; } public String getClassName() { - return "tag"+((int)scale()); + return "tag" + ((int) scale()); } public T getItem() { @@ -58,22 +61,21 @@ public class TagCloud<T> extends AbstractList<TagCloud<T>.Entry> { } public interface WeightFunction<T> { + float weight(T item); } - private final List<Entry> entries = new ArrayList<Entry>(); private float max = 1; /** * Creates a tag cloud. * - * @param f - * Assigns weight to each item. + * @param f Assigns weight to each item. */ public TagCloud(Iterable<? extends T> inputs, WeightFunction<T> f) { for (T input : inputs) { float w = Math.abs(f.weight(input)); - max = Math.max(w,max); + max = Math.max(w, max); entries.add(new Entry(input, w)); } } diff --git a/hudson-core/src/main/java/hudson/util/TextFile.java b/hudson-core/src/main/java/hudson/util/TextFile.java index 47dfcc7..fa35ad4 100644 --- a/hudson-core/src/main/java/hudson/util/TextFile.java +++ b/hudson-core/src/main/java/hudson/util/TextFile.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,6 +32,7 @@ import java.io.StringWriter; * @author Kohsuke Kawaguchi */ public class TextFile { + public final File file; public TextFile(File file) { @@ -52,12 +53,13 @@ public class TextFile { public String read() throws IOException { StringWriter out = new StringWriter(); PrintWriter w = new PrintWriter(out); - BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(file),"UTF-8")); + BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8")); try { String line; - while((line=in.readLine())!=null) + while ((line = in.readLine()) != null) { w.println(line); - } finally{ + } + } finally { in.close(); } return out.toString(); diff --git a/hudson-core/src/main/java/hudson/util/TimeUnit2.java b/hudson-core/src/main/java/hudson/util/TimeUnit2.java index d751bdd..383af10 100644 --- a/hudson-core/src/main/java/hudson/util/TimeUnit2.java +++ b/hudson-core/src/main/java/hudson/util/TimeUnit2.java @@ -7,10 +7,10 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: -* -* Kohsuke Kawaguchi, Stephen Connolly - * + * Contributors: + * + * Kohsuke Kawaguchi, Stephen Connolly + * * *******************************************************************************/ @@ -19,124 +19,387 @@ package hudson.util; import java.util.concurrent.TimeUnit; /** - * A <tt>TimeUnit</tt> represents time durations at a given unit of - * granularity and provides utility methods to convert across units, - * and to perform timing and delay operations in these units. A - * <tt>TimeUnit</tt> does not maintain time information, but only - * helps organize and use time representations that may be maintained - * separately across various contexts. A nanosecond is defined as one - * thousandth of a microsecond, a microsecond as one thousandth of a - * millisecond, a millisecond as one thousandth of a second, a minute - * as sixty seconds, an hour as sixty minutes, and a day as twenty four - * hours. + * A <tt>TimeUnit</tt> represents time durations at a given unit of granularity + * and provides utility methods to convert across units, and to perform timing + * and delay operations in these units. A <tt>TimeUnit</tt> does not maintain + * time information, but only helps organize and use time representations that + * may be maintained separately across various contexts. A nanosecond is defined + * as one thousandth of a microsecond, a microsecond as one thousandth of a + * millisecond, a millisecond as one thousandth of a second, a minute as sixty + * seconds, an hour as sixty minutes, and a day as twenty four hours. * - * <p>A <tt>TimeUnit</tt> is mainly used to inform time-based methods - * how a given timing parameter should be interpreted. For example, - * the following code will timeout in 50 milliseconds if the {@link + * <p>A <tt>TimeUnit</tt> is mainly used to inform time-based methods how a + * given timing parameter should be interpreted. For example, the following code + * will timeout in 50 milliseconds if the {@link * java.util.concurrent.locks.Lock lock} is not available: * * <pre> Lock lock = ...; * if ( lock.tryLock(50L, TimeUnit.MILLISECONDS) ) ... - * </pre> - * while this code will timeout in 50 seconds: + * </pre> while this code will timeout in 50 seconds: * <pre> * Lock lock = ...; * if ( lock.tryLock(50L, TimeUnit.SECONDS) ) ... * </pre> * * Note however, that there is no guarantee that a particular timeout - * implementation will be able to notice the passage of time at the - * same granularity as the given <tt>TimeUnit</tt>. + * implementation will be able to notice the passage of time at the same + * granularity as the given <tt>TimeUnit</tt>. * * @since 1.5 * @author Doug Lea */ public enum TimeUnit2 { + NANOSECONDS { - @Override public long toNanos(long d) { return d; } - @Override public long toMicros(long d) { return d/(C1/C0); } - @Override public long toMillis(long d) { return d/(C2/C0); } - @Override public long toSeconds(long d) { return d/(C3/C0); } - @Override public long toMinutes(long d) { return d/(C4/C0); } - @Override public long toHours(long d) { return d/(C5/C0); } - @Override public long toDays(long d) { return d/(C6/C0); } - @Override public long convert(long d, TimeUnit2 u) { return u.toNanos(d); } - @Override public long convert(long d, TimeUnit u) { return u.toNanos(d); } - int excessNanos(long d, long m) { return (int)(d - (m*C2)); } + @Override + public long toNanos(long d) { + return d; + } + + @Override + public long toMicros(long d) { + return d / (C1 / C0); + } + + @Override + public long toMillis(long d) { + return d / (C2 / C0); + } + + @Override + public long toSeconds(long d) { + return d / (C3 / C0); + } + + @Override + public long toMinutes(long d) { + return d / (C4 / C0); + } + + @Override + public long toHours(long d) { + return d / (C5 / C0); + } + + @Override + public long toDays(long d) { + return d / (C6 / C0); + } + + @Override + public long convert(long d, TimeUnit2 u) { + return u.toNanos(d); + } + + @Override + public long convert(long d, TimeUnit u) { + return u.toNanos(d); + } + + int excessNanos(long d, long m) { + return (int) (d - (m * C2)); + } }, MICROSECONDS { - @Override public long toNanos(long d) { return x(d, C1/C0, MAX/(C1/C0)); } - @Override public long toMicros(long d) { return d; } - @Override public long toMillis(long d) { return d/(C2/C1); } - @Override public long toSeconds(long d) { return d/(C3/C1); } - @Override public long toMinutes(long d) { return d/(C4/C1); } - @Override public long toHours(long d) { return d/(C5/C1); } - @Override public long toDays(long d) { return d/(C6/C1); } - @Override public long convert(long d, TimeUnit2 u) { return u.toMicros(d); } - @Override public long convert(long d, TimeUnit u) { return u.toMicros(d); } - int excessNanos(long d, long m) { return (int)((d*C1) - (m*C2)); } + @Override + public long toNanos(long d) { + return x(d, C1 / C0, MAX / (C1 / C0)); + } + + @Override + public long toMicros(long d) { + return d; + } + + @Override + public long toMillis(long d) { + return d / (C2 / C1); + } + + @Override + public long toSeconds(long d) { + return d / (C3 / C1); + } + + @Override + public long toMinutes(long d) { + return d / (C4 / C1); + } + + @Override + public long toHours(long d) { + return d / (C5 / C1); + } + + @Override + public long toDays(long d) { + return d / (C6 / C1); + } + + @Override + public long convert(long d, TimeUnit2 u) { + return u.toMicros(d); + } + + @Override + public long convert(long d, TimeUnit u) { + return u.toMicros(d); + } + + int excessNanos(long d, long m) { + return (int) ((d * C1) - (m * C2)); + } }, MILLISECONDS { - @Override public long toNanos(long d) { return x(d, C2/C0, MAX/(C2/C0)); } - @Override public long toMicros(long d) { return x(d, C2/C1, MAX/(C2/C1)); } - @Override public long toMillis(long d) { return d; } - @Override public long toSeconds(long d) { return d/(C3/C2); } - @Override public long toMinutes(long d) { return d/(C4/C2); } - @Override public long toHours(long d) { return d/(C5/C2); } - @Override public long toDays(long d) { return d/(C6/C2); } - @Override public long convert(long d, TimeUnit2 u) { return u.toMillis(d); } - @Override public long convert(long d, TimeUnit u) { return u.toMillis(d); } - int excessNanos(long d, long m) { return 0; } + @Override + public long toNanos(long d) { + return x(d, C2 / C0, MAX / (C2 / C0)); + } + + @Override + public long toMicros(long d) { + return x(d, C2 / C1, MAX / (C2 / C1)); + } + + @Override + public long toMillis(long d) { + return d; + } + + @Override + public long toSeconds(long d) { + return d / (C3 / C2); + } + + @Override + public long toMinutes(long d) { + return d / (C4 / C2); + } + + @Override + public long toHours(long d) { + return d / (C5 / C2); + } + + @Override + public long toDays(long d) { + return d / (C6 / C2); + } + + @Override + public long convert(long d, TimeUnit2 u) { + return u.toMillis(d); + } + + @Override + public long convert(long d, TimeUnit u) { + return u.toMillis(d); + } + + int excessNanos(long d, long m) { + return 0; + } }, SECONDS { - @Override public long toNanos(long d) { return x(d, C3/C0, MAX/(C3/C0)); } - @Override public long toMicros(long d) { return x(d, C3/C1, MAX/(C3/C1)); } - @Override public long toMillis(long d) { return x(d, C3/C2, MAX/(C3/C2)); } - @Override public long toSeconds(long d) { return d; } - @Override public long toMinutes(long d) { return d/(C4/C3); } - @Override public long toHours(long d) { return d/(C5/C3); } - @Override public long toDays(long d) { return d/(C6/C3); } - @Override public long convert(long d, TimeUnit2 u) { return u.toSeconds(d); } - @Override public long convert(long d, TimeUnit u) { return u.toSeconds(d); } - int excessNanos(long d, long m) { return 0; } + @Override + public long toNanos(long d) { + return x(d, C3 / C0, MAX / (C3 / C0)); + } + + @Override + public long toMicros(long d) { + return x(d, C3 / C1, MAX / (C3 / C1)); + } + + @Override + public long toMillis(long d) { + return x(d, C3 / C2, MAX / (C3 / C2)); + } + + @Override + public long toSeconds(long d) { + return d; + } + + @Override + public long toMinutes(long d) { + return d / (C4 / C3); + } + + @Override + public long toHours(long d) { + return d / (C5 / C3); + } + + @Override + public long toDays(long d) { + return d / (C6 / C3); + } + + @Override + public long convert(long d, TimeUnit2 u) { + return u.toSeconds(d); + } + + @Override + public long convert(long d, TimeUnit u) { + return u.toSeconds(d); + } + + int excessNanos(long d, long m) { + return 0; + } }, MINUTES { - @Override public long toNanos(long d) { return x(d, C4/C0, MAX/(C4/C0)); } - @Override public long toMicros(long d) { return x(d, C4/C1, MAX/(C4/C1)); } - @Override public long toMillis(long d) { return x(d, C4/C2, MAX/(C4/C2)); } - @Override public long toSeconds(long d) { return x(d, C4/C3, MAX/(C4/C3)); } - @Override public long toMinutes(long d) { return d; } - @Override public long toHours(long d) { return d/(C5/C4); } - @Override public long toDays(long d) { return d/(C6/C4); } - @Override public long convert(long d, TimeUnit2 u) { return u.toMinutes(d); } - @Override public long convert(long d, TimeUnit u) { return SECONDS.toMinutes(u.toSeconds(d)); } - int excessNanos(long d, long m) { return 0; } + @Override + public long toNanos(long d) { + return x(d, C4 / C0, MAX / (C4 / C0)); + } + + @Override + public long toMicros(long d) { + return x(d, C4 / C1, MAX / (C4 / C1)); + } + + @Override + public long toMillis(long d) { + return x(d, C4 / C2, MAX / (C4 / C2)); + } + + @Override + public long toSeconds(long d) { + return x(d, C4 / C3, MAX / (C4 / C3)); + } + + @Override + public long toMinutes(long d) { + return d; + } + + @Override + public long toHours(long d) { + return d / (C5 / C4); + } + + @Override + public long toDays(long d) { + return d / (C6 / C4); + } + + @Override + public long convert(long d, TimeUnit2 u) { + return u.toMinutes(d); + } + + @Override + public long convert(long d, TimeUnit u) { + return SECONDS.toMinutes(u.toSeconds(d)); + } + + int excessNanos(long d, long m) { + return 0; + } }, HOURS { - @Override public long toNanos(long d) { return x(d, C5/C0, MAX/(C5/C0)); } - @Override public long toMicros(long d) { return x(d, C5/C1, MAX/(C5/C1)); } - @Override public long toMillis(long d) { return x(d, C5/C2, MAX/(C5/C2)); } - @Override public long toSeconds(long d) { return x(d, C5/C3, MAX/(C5/C3)); } - @Override public long toMinutes(long d) { return x(d, C5/C4, MAX/(C5/C4)); } - @Override public long toHours(long d) { return d; } - @Override public long toDays(long d) { return d/(C6/C5); } - @Override public long convert(long d, TimeUnit2 u) { return u.toHours(d); } - @Override public long convert(long d, TimeUnit u) { return SECONDS.toHours(u.toSeconds(d)); } - int excessNanos(long d, long m) { return 0; } + @Override + public long toNanos(long d) { + return x(d, C5 / C0, MAX / (C5 / C0)); + } + + @Override + public long toMicros(long d) { + return x(d, C5 / C1, MAX / (C5 / C1)); + } + + @Override + public long toMillis(long d) { + return x(d, C5 / C2, MAX / (C5 / C2)); + } + + @Override + public long toSeconds(long d) { + return x(d, C5 / C3, MAX / (C5 / C3)); + } + + @Override + public long toMinutes(long d) { + return x(d, C5 / C4, MAX / (C5 / C4)); + } + + @Override + public long toHours(long d) { + return d; + } + + @Override + public long toDays(long d) { + return d / (C6 / C5); + } + + @Override + public long convert(long d, TimeUnit2 u) { + return u.toHours(d); + } + + @Override + public long convert(long d, TimeUnit u) { + return SECONDS.toHours(u.toSeconds(d)); + } + + int excessNanos(long d, long m) { + return 0; + } }, DAYS { - @Override public long toNanos(long d) { return x(d, C6/C0, MAX/(C6/C0)); } - @Override public long toMicros(long d) { return x(d, C6/C1, MAX/(C6/C1)); } - @Override public long toMillis(long d) { return x(d, C6/C2, MAX/(C6/C2)); } - @Override public long toSeconds(long d) { return x(d, C6/C3, MAX/(C6/C3)); } - @Override public long toMinutes(long d) { return x(d, C6/C4, MAX/(C6/C4)); } - @Override public long toHours(long d) { return x(d, C6/C5, MAX/(C6/C5)); } - @Override public long toDays(long d) { return d; } - @Override public long convert(long d, TimeUnit2 u) { return u.toDays(d); } - @Override public long convert(long d, TimeUnit u) { return SECONDS.toDays(u.toSeconds(d)); } - int excessNanos(long d, long m) { return 0; } - }; + @Override + public long toNanos(long d) { + return x(d, C6 / C0, MAX / (C6 / C0)); + } + + @Override + public long toMicros(long d) { + return x(d, C6 / C1, MAX / (C6 / C1)); + } + + @Override + public long toMillis(long d) { + return x(d, C6 / C2, MAX / (C6 / C2)); + } + + @Override + public long toSeconds(long d) { + return x(d, C6 / C3, MAX / (C6 / C3)); + } + + @Override + public long toMinutes(long d) { + return x(d, C6 / C4, MAX / (C6 / C4)); + } + + @Override + public long toHours(long d) { + return x(d, C6 / C5, MAX / (C6 / C5)); + } + + @Override + public long toDays(long d) { + return d; + } + + @Override + public long convert(long d, TimeUnit2 u) { + return u.toDays(d); + } + @Override + public long convert(long d, TimeUnit u) { + return SECONDS.toDays(u.toSeconds(d)); + } + + int excessNanos(long d, long m) { + return 0; + } + }; // Handy constants for conversion methods static final long C0 = 1L; static final long C1 = C0 * 1000L; @@ -145,16 +408,19 @@ public enum TimeUnit2 { static final long C4 = C3 * 60L; static final long C5 = C4 * 60L; static final long C6 = C5 * 24L; - static final long MAX = Long.MAX_VALUE; /** - * Scale d by m, checking for overflow. - * This has a short name to make above code more readable. + * Scale d by m, checking for overflow. This has a short name to make above + * code more readable. */ static long x(long d, long m, long over) { - if (d > over) return Long.MAX_VALUE; - if (d < -over) return Long.MIN_VALUE; + if (d > over) { + return Long.MAX_VALUE; + } + if (d < -over) { + return Long.MIN_VALUE; + } return d * m; } @@ -162,48 +428,45 @@ public enum TimeUnit2 { // clarity of the generated javadoc (see 6287639: Abstract methods in // enum classes should not be listed as abstract), method convert // etc. are not declared abstract but otherwise act as abstract methods. - /** - * Convert the given time duration in the given unit to this - * unit. Conversions from finer to coarser granularities - * truncate, so lose precision. For example converting - * <tt>999</tt> milliseconds to seconds results in - * <tt>0</tt>. Conversions from coarser to finer granularities + * Convert the given time duration in the given unit to this unit. + * Conversions from finer to coarser granularities truncate, so lose + * precision. For example converting <tt>999</tt> milliseconds to seconds + * results in <tt>0</tt>. Conversions from coarser to finer granularities * with arguments that would numerically overflow saturate to - * <tt>Long.MIN_VALUE</tt> if negative or <tt>Long.MAX_VALUE</tt> - * if positive. + * <tt>Long.MIN_VALUE</tt> if negative or <tt>Long.MAX_VALUE</tt> if + * positive. * * <p>For example, to convert 10 minutes to milliseconds, use: * <tt>TimeUnit.MILLISECONDS.convert(10L, TimeUnit.MINUTES)</tt> * * @param sourceDuration the time duration in the given <tt>sourceUnit</tt> * @param sourceUnit the unit of the <tt>sourceDuration</tt> argument - * @return the converted duration in this unit, - * or <tt>Long.MIN_VALUE</tt> if conversion would negatively - * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow. + * @return the converted duration in this unit, or <tt>Long.MIN_VALUE</tt> + * if conversion would negatively overflow, or <tt>Long.MAX_VALUE</tt> if it + * would positively overflow. */ public long convert(long sourceDuration, TimeUnit2 sourceUnit) { throw new AbstractMethodError(); } /** - * Convert the given time duration in the given unit to this - * unit. Conversions from finer to coarser granularities - * truncate, so lose precision. For example converting - * <tt>999</tt> milliseconds to seconds results in - * <tt>0</tt>. Conversions from coarser to finer granularities + * Convert the given time duration in the given unit to this unit. + * Conversions from finer to coarser granularities truncate, so lose + * precision. For example converting <tt>999</tt> milliseconds to seconds + * results in <tt>0</tt>. Conversions from coarser to finer granularities * with arguments that would numerically overflow saturate to - * <tt>Long.MIN_VALUE</tt> if negative or <tt>Long.MAX_VALUE</tt> - * if positive. + * <tt>Long.MIN_VALUE</tt> if negative or <tt>Long.MAX_VALUE</tt> if + * positive. * * <p>For example, to convert 10 minutes to milliseconds, use: * <tt>TimeUnit.MILLISECONDS.convert(10L, TimeUnit.MINUTES)</tt> * * @param sourceDuration the time duration in the given <tt>sourceUnit</tt> * @param sourceUnit the unit of the <tt>sourceDuration</tt> argument - * @return the converted duration in this unit, - * or <tt>Long.MIN_VALUE</tt> if conversion would negatively - * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow. + * @return the converted duration in this unit, or <tt>Long.MIN_VALUE</tt> + * if conversion would negatively overflow, or <tt>Long.MAX_VALUE</tt> if it + * would positively overflow. */ public long convert(long sourceDuration, TimeUnit sourceUnit) { throw new AbstractMethodError(); @@ -211,10 +474,11 @@ public enum TimeUnit2 { /** * Equivalent to <tt>NANOSECONDS.convert(duration, this)</tt>. + * * @param duration the duration - * @return the converted duration, - * or <tt>Long.MIN_VALUE</tt> if conversion would negatively - * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow. + * @return the converted duration, or <tt>Long.MIN_VALUE</tt> if conversion + * would negatively overflow, or <tt>Long.MAX_VALUE</tt> if it would + * positively overflow. * @see #convert */ public long toNanos(long duration) { @@ -223,10 +487,11 @@ public enum TimeUnit2 { /** * Equivalent to <tt>MICROSECONDS.convert(duration, this)</tt>. + * * @param duration the duration - * @return the converted duration, - * or <tt>Long.MIN_VALUE</tt> if conversion would negatively - * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow. + * @return the converted duration, or <tt>Long.MIN_VALUE</tt> if conversion + * would negatively overflow, or <tt>Long.MAX_VALUE</tt> if it would + * positively overflow. * @see #convert */ public long toMicros(long duration) { @@ -235,10 +500,11 @@ public enum TimeUnit2 { /** * Equivalent to <tt>MILLISECONDS.convert(duration, this)</tt>. + * * @param duration the duration - * @return the converted duration, - * or <tt>Long.MIN_VALUE</tt> if conversion would negatively - * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow. + * @return the converted duration, or <tt>Long.MIN_VALUE</tt> if conversion + * would negatively overflow, or <tt>Long.MAX_VALUE</tt> if it would + * positively overflow. * @see #convert */ public long toMillis(long duration) { @@ -247,10 +513,11 @@ public enum TimeUnit2 { /** * Equivalent to <tt>SECONDS.convert(duration, this)</tt>. + * * @param duration the duration - * @return the converted duration, - * or <tt>Long.MIN_VALUE</tt> if conversion would negatively - * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow. + * @return the converted duration, or <tt>Long.MIN_VALUE</tt> if conversion + * would negatively overflow, or <tt>Long.MAX_VALUE</tt> if it would + * positively overflow. * @see #convert */ public long toSeconds(long duration) { @@ -259,10 +526,11 @@ public enum TimeUnit2 { /** * Equivalent to <tt>MINUTES.convert(duration, this)</tt>. + * * @param duration the duration - * @return the converted duration, - * or <tt>Long.MIN_VALUE</tt> if conversion would negatively - * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow. + * @return the converted duration, or <tt>Long.MIN_VALUE</tt> if conversion + * would negatively overflow, or <tt>Long.MAX_VALUE</tt> if it would + * positively overflow. * @see #convert * @since 1.6 */ @@ -272,10 +540,11 @@ public enum TimeUnit2 { /** * Equivalent to <tt>HOURS.convert(duration, this)</tt>. + * * @param duration the duration - * @return the converted duration, - * or <tt>Long.MIN_VALUE</tt> if conversion would negatively - * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow. + * @return the converted duration, or <tt>Long.MIN_VALUE</tt> if conversion + * would negatively overflow, or <tt>Long.MAX_VALUE</tt> if it would + * positively overflow. * @see #convert * @since 1.6 */ @@ -285,6 +554,7 @@ public enum TimeUnit2 { /** * Equivalent to <tt>DAYS.convert(duration, this)</tt>. + * * @param duration the duration * @return the converted duration * @see #convert @@ -295,8 +565,8 @@ public enum TimeUnit2 { } /** - * Utility to compute the excess-nanosecond argument to wait, - * sleep, join. + * Utility to compute the excess-nanosecond argument to wait, sleep, join. + * * @param d the duration * @param m the number of milliseconds * @return the number of nanoseconds @@ -304,12 +574,12 @@ public enum TimeUnit2 { abstract int excessNanos(long d, long m); /** - * Performs a timed <tt>Object.wait</tt> using this time unit. - * This is a convenience method that converts timeout arguments - * into the form required by the <tt>Object.wait</tt> method. + * Performs a timed <tt>Object.wait</tt> using this time unit. This is a + * convenience method that converts timeout arguments into the form required + * by the <tt>Object.wait</tt> method. * - * <p>For example, you could implement a blocking <tt>poll</tt> - * method (see {@link java.util.concurrent.BlockingQueue#poll BlockingQueue.poll}) + * <p>For example, you could implement a blocking <tt>poll</tt> method (see + * {@link java.util.concurrent.BlockingQueue#poll BlockingQueue.poll}) * using: * * <pre> public synchronized Object poll(long timeout, TimeUnit unit) throws InterruptedException { @@ -320,13 +590,13 @@ public enum TimeUnit2 { * }</pre> * * @param obj the object to wait on - * @param timeout the maximum time to wait. If less than - * or equal to zero, do not wait at all. + * @param timeout the maximum time to wait. If less than or equal to zero, + * do not wait at all. * @throws InterruptedException if interrupted while waiting. * @see Object#wait(long, int) */ public void timedWait(Object obj, long timeout) - throws InterruptedException { + throws InterruptedException { if (timeout > 0) { long ms = toMillis(timeout); int ns = excessNanos(timeout, ms); @@ -335,17 +605,18 @@ public enum TimeUnit2 { } /** - * Performs a timed <tt>Thread.join</tt> using this time unit. - * This is a convenience method that converts time arguments into the - * form required by the <tt>Thread.join</tt> method. + * Performs a timed <tt>Thread.join</tt> using this time unit. This is a + * convenience method that converts time arguments into the form required by + * the <tt>Thread.join</tt> method. + * * @param thread the thread to wait for - * @param timeout the maximum time to wait. If less than - * or equal to zero, do not wait at all. + * @param timeout the maximum time to wait. If less than or equal to zero, + * do not wait at all. * @throws InterruptedException if interrupted while waiting. * @see Thread#join(long, int) */ public void timedJoin(Thread thread, long timeout) - throws InterruptedException { + throws InterruptedException { if (timeout > 0) { long ms = toMillis(timeout); int ns = excessNanos(timeout, ms); @@ -354,11 +625,12 @@ public enum TimeUnit2 { } /** - * Performs a <tt>Thread.sleep</tt> using this unit. - * This is a convenience method that converts time arguments into the - * form required by the <tt>Thread.sleep</tt> method. - * @param timeout the minimum time to sleep. If less than - * or equal to zero, do not sleep at all. + * Performs a <tt>Thread.sleep</tt> using this unit. This is a convenience + * method that converts time arguments into the form required by the + * <tt>Thread.sleep</tt> method. + * + * @param timeout the minimum time to sleep. If less than or equal to zero, + * do not sleep at all. * @throws InterruptedException if interrupted while sleeping. * @see Thread#sleep */ @@ -369,5 +641,4 @@ public enum TimeUnit2 { Thread.sleep(ms, ns); } } - } diff --git a/hudson-core/src/main/java/hudson/util/UnbufferedBase64InputStream.java b/hudson-core/src/main/java/hudson/util/UnbufferedBase64InputStream.java index 1ac2e01..258f9a4 100644 --- a/hudson-core/src/main/java/hudson/util/UnbufferedBase64InputStream.java +++ b/hudson-core/src/main/java/hudson/util/UnbufferedBase64InputStream.java @@ -8,7 +8,7 @@ * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * + * * *******************************************************************************/ @@ -24,14 +24,15 @@ import java.io.InputStream; /** * Filter InputStream that decodes base64 without doing any buffering. * - * <p> - * This is slower implementation, but it won't consume unnecessary bytes from the underlying {@link InputStream}, - * allowing the reader to switch between the unencoded bytes and base64 bytes. + * <p> This is slower implementation, but it won't consume unnecessary bytes + * from the underlying {@link InputStream}, allowing the reader to switch + * between the unencoded bytes and base64 bytes. * * @author Kohsuke Kawaguchi * @since 1.349 */ public class UnbufferedBase64InputStream extends FilterInputStream { + private byte[] encoded = new byte[4]; private byte[] decoded; private int pos; @@ -47,37 +48,44 @@ public class UnbufferedBase64InputStream extends FilterInputStream { @Override public int read() throws IOException { - if (decoded.length==0) + if (decoded.length == 0) { return -1; // EOF - - if (pos==decoded.length) { + } + if (pos == decoded.length) { din.readFully(encoded); decoded = Base64.decodeBase64(encoded); - if (decoded.length==0) return -1; // EOF + if (decoded.length == 0) { + return -1; // EOF + } pos = 0; } - return (decoded[pos++])&0xFF; + return (decoded[pos++]) & 0xFF; } @Override public int read(byte[] b, int off, int len) throws IOException { int i; - for (i=0; i<len; i++) { + for (i = 0; i < len; i++) { int ch = read(); - if (ch<0) break; - b[off+i] = (byte)ch; + if (ch < 0) { + break; + } + b[off + i] = (byte) ch; } - return i==0 ? -1 : i; + return i == 0 ? -1 : i; } @Override public long skip(long n) throws IOException { - long r=0; - while (n>0) { + long r = 0; + while (n > 0) { int ch = read(); - if (ch<0) break; - n--; r++; + if (ch < 0) { + break; + } + n--; + r++; } return r; } diff --git a/hudson-core/src/main/java/hudson/util/VariableResolver.java b/hudson-core/src/main/java/hudson/util/VariableResolver.java index aa0d47e..9a8e2a9 100644 --- a/hudson-core/src/main/java/hudson/util/VariableResolver.java +++ b/hudson-core/src/main/java/hudson/util/VariableResolver.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 + * * *******************************************************************************/ @@ -20,31 +20,26 @@ import java.util.Collection; import java.util.Map; /** - * Resolves variables to its value, while encapsulating - * how that resolution happens. + * Resolves variables to its value, while encapsulating how that resolution + * happens. * * @author Kohsuke Kawaguchi */ public interface VariableResolver<V> { + /** * Receives a variable name and obtains the value associated with the name. * - * <p> - * This can be implemented simply on top of a {@link Map} (see {@link ByMap}), or - * this can be used like an expression evaluator. + * <p> This can be implemented simply on top of a {@link Map} (see + * {@link ByMap}), or this can be used like an expression evaluator. * - * @param name - * Name of the variable to be resolved. - * Never null, never empty. The name shouldn't include the syntactic - * marker of an expression. IOW, it should be "foo" but not "${foo}". - * A part of the goal of this design is to abstract away the expression - * marker syntax. - * @return - * Object referenced by the name. - * Null if not found. + * @param name Name of the variable to be resolved. Never null, never empty. + * The name shouldn't include the syntactic marker of an expression. IOW, it + * should be "foo" but not "${foo}". A part of the goal of this design is to + * abstract away the expression marker syntax. + * @return Object referenced by the name. Null if not found. */ public abstract V resolve(String name); - /** * Empty resolver that always returns null. */ @@ -58,7 +53,8 @@ public interface VariableResolver<V> { * {@link VariableResolver} backed by a {@link Map}. */ public static final class ByMap<V> implements VariableResolver<V> { - private final Map<String,V> data; + + private final Map<String, V> data; public ByMap(Map<String, V> data) { this.data = data; @@ -73,6 +69,7 @@ public interface VariableResolver<V> { * Union of multiple {@link VariableResolver}. */ public static final class Union<V> implements VariableResolver<V> { + private final VariableResolver<? extends V>[] resolvers; public Union(VariableResolver<? extends V>... resolvers) { @@ -86,7 +83,9 @@ public interface VariableResolver<V> { public V resolve(String name) { for (VariableResolver<? extends V> r : resolvers) { V v = r.resolve(name); - if(v!=null) return v; + if (v != null) { + return v; + } } return null; } diff --git a/hudson-core/src/main/java/hudson/util/VersionNumber.java b/hudson-core/src/main/java/hudson/util/VersionNumber.java index 7b24292..8dfb6bb 100644 --- a/hudson-core/src/main/java/hudson/util/VersionNumber.java +++ b/hudson-core/src/main/java/hudson/util/VersionNumber.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 - * + * * *******************************************************************************/ @@ -19,62 +19,60 @@ package hudson.util; import java.util.StringTokenizer; /** - * Immutable representation of a dot or '-'-separated digits (such as "1.0.1" or "1.0-52"). + * Immutable representation of a dot or '-'-separated digits (such as "1.0.1" or + * "1.0-52"). * * {@link VersionNumber}s are {@link Comparable}. * - * <h2>Special tokens</h2> - * <p> - * We allow a component to be not just a number, but also "ea", "ea1", "ea2". - * "ea" is treated as "ea0", and eaN < M for any M > 0. + * <h2>Special tokens</h2> <p> We allow a component to be not just a number, but + * also "ea", "ea1", "ea2". "ea" is treated as "ea0", and eaN < M for any M > + * 0. * - * <p> - * '*' is also allowed as a component, and '*' > M for any M > 0. + * <p> '*' is also allowed as a component, and '*' > M for any M > 0. * - * <p> - * 'SNAPSHOT' is also allowed as a component, and "N.SNAPSHOT" is interpreted as "N-1.*" + * <p> 'SNAPSHOT' is also allowed as a component, and "N.SNAPSHOT" is + * interpreted as "N-1.*" * * <pre> * 2.0.* > 2.0.1 > 2.0.1-SNAPSHOT > 2.0.0.99 > 2.0.0 > 2.0.ea > 2.0 * </pre> * - * @author - * Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com) + * @author Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com) * @since 1.139 */ public class VersionNumber implements Comparable<VersionNumber> { + private final int[] digits; /** * Parses a string like "1.0.2" into the version number. * - * @throws IllegalArgumentException - * if the parsing fails. + * @throws IllegalArgumentException if the parsing fails. */ - public VersionNumber( String num ) { - StringTokenizer tokens = new StringTokenizer(num,".-_"); + public VersionNumber(String num) { + StringTokenizer tokens = new StringTokenizer(num, ".-_"); digits = new int[tokens.countTokens()]; - if(digits.length<2) - throw new IllegalArgumentException("Failed to parse "+num+" as version number"); + if (digits.length < 2) { + throw new IllegalArgumentException("Failed to parse " + num + " as version number"); + } - int i=0; - while( tokens.hasMoreTokens() ) { + int i = 0; + while (tokens.hasMoreTokens()) { String token = tokens.nextToken().toLowerCase(); - if(token.equals("*")) { + if (token.equals("*")) { digits[i++] = 1000; - } else - if(token.startsWith("snapshot")) { - digits[i-1]--; + } else if (token.startsWith("snapshot")) { + digits[i - 1]--; digits[i++] = 1000; break; - } else - if(token.startsWith("ea")) { - if(token.length()==2) + } else if (token.startsWith("ea")) { + if (token.length() == 2) { digits[i++] = -1000; // just "ea" - else + } else { digits[i++] = -1000 + Integer.parseInt(token.substring(2)); // "eaNNN" + } } else { - int n =0; + int n = 0; try { n = Integer.parseInt(token); } catch (NumberFormatException e) { @@ -92,47 +90,56 @@ public class VersionNumber implements Comparable<VersionNumber> { @Override public String toString() { StringBuilder buf = new StringBuilder(); - for( int i=0; i<digits.length; i++ ) { - if(i!=0) buf.append('.'); - buf.append( Integer.toString(digits[i]) ); + for (int i = 0; i < digits.length; i++) { + if (i != 0) { + buf.append('.'); + } + buf.append(Integer.toString(digits[i])); } return buf.toString(); } - public boolean isOlderThan( VersionNumber rhs ) { - return compareTo(rhs)<0; + public boolean isOlderThan(VersionNumber rhs) { + return compareTo(rhs) < 0; } - public boolean isNewerThan( VersionNumber rhs ) { - return compareTo(rhs)>0; + public boolean isNewerThan(VersionNumber rhs) { + return compareTo(rhs) > 0; } - @Override - public boolean equals( Object o ) { - if (!(o instanceof VersionNumber)) return false; - return compareTo((VersionNumber)o)==0; + public boolean equals(Object o) { + if (!(o instanceof VersionNumber)) { + return false; + } + return compareTo((VersionNumber) o) == 0; } @Override public int hashCode() { - int x=0; - for (int i : digits) + int x = 0; + for (int i : digits) { x = (x << 1) | i; + } return x; } public int compareTo(VersionNumber rhs) { - for( int i=0; ; i++ ) { - if( i==this.digits.length && i==rhs.digits.length ) + for (int i = 0;; i++) { + if (i == this.digits.length && i == rhs.digits.length) { return 0; // equals - if( i==this.digits.length ) + } + if (i == this.digits.length) { return -1; // rhs is larger - if( i==rhs.digits.length ) + } + if (i == rhs.digits.length) { return 1; + } int r = this.digits[i] - rhs.digits[i]; - if(r!=0) return r; + if (r != 0) { + return r; + } } } } diff --git a/hudson-core/src/main/java/hudson/util/WriterOutputStream.java b/hudson-core/src/main/java/hudson/util/WriterOutputStream.java index 6506e52..fdccd9c 100644 --- a/hudson-core/src/main/java/hudson/util/WriterOutputStream.java +++ b/hudson-core/src/main/java/hudson/util/WriterOutputStream.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 + * * *******************************************************************************/ @@ -27,17 +27,16 @@ import java.nio.charset.UnsupportedCharsetException; import java.nio.*; /** - * {@link OutputStream} that writes to {@link Writer} - * by assuming the platform default encoding. + * {@link OutputStream} that writes to {@link Writer} by assuming the platform + * default encoding. * * @author Kohsuke Kawaguchi - * @deprecated since 2008-05-28. - * Use the one in stapler. + * @deprecated since 2008-05-28. Use the one in stapler. */ public class WriterOutputStream extends OutputStream { + private final Writer writer; private final CharsetDecoder decoder; - private java.nio.ByteBuffer buf = java.nio.ByteBuffer.allocate(1024); private CharBuffer out = CharBuffer.allocate(1024); @@ -49,17 +48,19 @@ public class WriterOutputStream extends OutputStream { } public void write(int b) throws IOException { - if(buf.remaining()==0) + if (buf.remaining() == 0) { decode(false); - buf.put((byte)b); + } + buf.put((byte) b); } public void write(byte b[], int off, int len) throws IOException { - while(len>0) { - if(buf.remaining()==0) + while (len > 0) { + if (buf.remaining() == 0) { decode(false); - int sz = Math.min(buf.remaining(),len); - buf.put(b,off,sz); + } + int sz = Math.min(buf.remaining(), len); + buf.put(b, off, sz); off += sz; len -= sz; } @@ -72,7 +73,7 @@ public class WriterOutputStream extends OutputStream { } private void flushOutput() throws IOException { - writer.write(out.array(),0,out.position()); + writer.write(out.array(), 0, out.position()); out.clear(); } @@ -88,22 +89,20 @@ public class WriterOutputStream extends OutputStream { * Decodes the contents of {@link #buf} as much as possible to {@link #out}. * If necessary {@link #out} is further sent to {@link #writer}. * - * <p> - * When this method returns, the {@link #buf} is back to the 'accumulation' - * mode. + * <p> When this method returns, the {@link #buf} is back to the + * 'accumulation' mode. * - * @param last - * if true, tell the decoder that all the input bytes are ready. + * @param last if true, tell the decoder that all the input bytes are ready. */ private void decode(boolean last) throws IOException { buf.flip(); - while(true) { + while (true) { CoderResult r = decoder.decode(buf, out, last); - if(r==CoderResult.OVERFLOW) { + if (r == CoderResult.OVERFLOW) { flushOutput(); continue; } - if(r==CoderResult.UNDERFLOW) { + if (r == CoderResult.UNDERFLOW) { buf.compact(); return; } @@ -111,7 +110,6 @@ public class WriterOutputStream extends OutputStream { r.throwException(); } } - private static final Charset DEFAULT_CHARSET = getDefaultCharset(); private static Charset getDefaultCharset() { diff --git a/hudson-core/src/main/java/hudson/util/XStream2.java b/hudson-core/src/main/java/hudson/util/XStream2.java index 772b364..5e4e068 100644 --- a/hudson-core/src/main/java/hudson/util/XStream2.java +++ b/hudson-core/src/main/java/hudson/util/XStream2.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, Alan Harder - * + * * *******************************************************************************/ @@ -45,10 +45,13 @@ import java.lang.reflect.InvocationTargetException; import java.util.concurrent.ConcurrentHashMap; /** - * {@link XStream} enhanced for additional Java5 support and improved robustness. + * {@link XStream} enhanced for additional Java5 support and improved + * robustness. + * * @author Kohsuke Kawaguchi */ public class XStream2 extends XStream { + private Converter reflectionConverter; private ThreadLocal<Boolean> oldData = new ThreadLocal<Boolean>(); @@ -66,14 +69,16 @@ public class XStream2 extends XStream { // init() is too early to do this // defensive because some use of XStream happens before plugins are initialized. Hudson h = Hudson.getInstance(); - if(h!=null && h.pluginManager!=null && h.pluginManager.uberClassLoader!=null) { + if (h != null && h.pluginManager != null && h.pluginManager.uberClassLoader != null) { setClassLoader(h.pluginManager.uberClassLoader); } - Object o = super.unmarshal(reader,root,dataHolder); - if (oldData.get()!=null) { + Object o = super.unmarshal(reader, root, dataHolder); + if (oldData.get() != null) { oldData.remove(); - if (o instanceof Saveable) OldDataMonitor.report((Saveable)o, "1.106"); + if (o instanceof Saveable) { + OldDataMonitor.report((Saveable) o, "1.106"); + } } return o; } @@ -81,7 +86,7 @@ public class XStream2 extends XStream { @Override protected Converter createDefaultConverter() { // replace default reflection converter - reflectionConverter = new RobustReflectionConverter(getMapper(),new JVM().bestReflectionProvider()); + reflectionConverter = new RobustReflectionConverter(getMapper(), new JVM().bestReflectionProvider()); return reflectionConverter; } @@ -89,16 +94,16 @@ public class XStream2 extends XStream { // list up types that should be marshalled out like a value, without referencial integrity tracking. addImmutableType(Result.class); - registerConverter(new RobustCollectionConverter(getMapper(),getReflectionProvider()),10); - registerConverter(new ImmutableMapConverter(getMapper(),getReflectionProvider()),10); - registerConverter(new ConcurrentHashMapConverter(getMapper(),getReflectionProvider()),10); - registerConverter(new CopyOnWriteMap.Tree.ConverterImpl(getMapper()),10); // needs to override MapConverter - registerConverter(new DescribableList.ConverterImpl(getMapper()),10); // explicitly added to handle subtypes - registerConverter(new Label.ConverterImpl(),10); + registerConverter(new RobustCollectionConverter(getMapper(), getReflectionProvider()), 10); + registerConverter(new ImmutableMapConverter(getMapper(), getReflectionProvider()), 10); + registerConverter(new ConcurrentHashMapConverter(getMapper(), getReflectionProvider()), 10); + registerConverter(new CopyOnWriteMap.Tree.ConverterImpl(getMapper()), 10); // needs to override MapConverter + registerConverter(new DescribableList.ConverterImpl(getMapper()), 10); // explicitly added to handle subtypes + registerConverter(new Label.ConverterImpl(), 10); // this should come after all the XStream's default simpler converters, // but before reflection-based one kicks in. - registerConverter(new AssociatedConverterImpl(this),-10); + registerConverter(new AssociatedConverterImpl(this), -10); } @Override @@ -106,10 +111,11 @@ public class XStream2 extends XStream { Mapper m = new CompatibilityMapper(new MapperWrapper(next) { @Override public String serializedClass(Class type) { - if (type != null && ImmutableMap.class.isAssignableFrom(type)) + if (type != null && ImmutableMap.class.isAssignableFrom(type)) { return super.serializedClass(ImmutableMap.class); - else + } else { return super.serializedClass(type); + } } }); AnnotationMapper a = new AnnotationMapper(m, getConverterRegistry(), getClassLoader(), getReflectionProvider(), getJvm()); @@ -118,13 +124,15 @@ public class XStream2 extends XStream { } /** - * Prior to Hudson 1.106, XStream 1.1.x was used which encoded "$" in class names - * as "-" instead of "_-" that is used now. Up through Hudson 1.348 compatibility - * for old serialized data was maintained via {@code XStream11XmlFriendlyMapper}. - * However, it was found (HUDSON-5768) that this caused fields with "__" to fail - * deserialization due to double decoding. Now this class is used for compatibility. + * Prior to Hudson 1.106, XStream 1.1.x was used which encoded "$" in class + * names as "-" instead of "_-" that is used now. Up through Hudson 1.348 + * compatibility for old serialized data was maintained via + * {@code XStream11XmlFriendlyMapper}. However, it was found (HUDSON-5768) + * that this caused fields with "__" to fail deserialization due to double + * decoding. Now this class is used for compatibility. */ private class CompatibilityMapper extends MapperWrapper { + private CompatibilityMapper(Mapper wrapped) { super(wrapped); } @@ -135,11 +143,14 @@ public class XStream2 extends XStream { return super.realClass(elementName); } catch (CannotResolveClassException e) { // If a "-" is found, retry with mapping this to "$" - if (elementName.indexOf('-') >= 0) try { - Class c = super.realClass(elementName.replace('-', '$')); - oldData.set(Boolean.TRUE); - return c; - } catch (CannotResolveClassException e2) { } + if (elementName.indexOf('-') >= 0) { + try { + Class c = super.realClass(elementName.replace('-', '$')); + oldData.set(Boolean.TRUE); + return c; + } catch (CannotResolveClassException e2) { + } + } // Throw original exception throw e; } @@ -147,13 +158,15 @@ public class XStream2 extends XStream { } /** - * If a class defines a nested {@code ConverterImpl} subclass, use that as a {@link Converter}. - * Its constructor may have XStream/XStream2 and/or Mapper parameters (or no params). + * If a class defines a nested {@code ConverterImpl} subclass, use that as a + * {@link Converter}. Its constructor may have XStream/XStream2 and/or + * Mapper parameters (or no params). */ private static final class AssociatedConverterImpl implements Converter { + private final XStream xstream; - private final ConcurrentHashMap<Class,Converter> cache = - new ConcurrentHashMap<Class,Converter>(); + private final ConcurrentHashMap<Class, Converter> cache = + new ConcurrentHashMap<Class, Converter>(); private AssociatedConverterImpl(XStream xstream) { this.xstream = xstream; @@ -161,30 +174,33 @@ public class XStream2 extends XStream { private Converter findConverter(Class t) { Converter result = cache.get(t); - if (result != null) - // ConcurrentHashMap does not allow null, so use this object to represent null + if (result != null) // ConcurrentHashMap does not allow null, so use this object to represent null + { return result == this ? null : result; + } try { - if(t==null || t.getClassLoader()==null) + if (t == null || t.getClassLoader() == null) { return null; + } Class<?> cl = t.getClassLoader().loadClass(t.getName() + "$ConverterImpl"); Constructor<?> c = cl.getConstructors()[0]; Class<?>[] p = c.getParameterTypes(); Object[] args = new Object[p.length]; for (int i = 0; i < p.length; i++) { - if(p[i]==XStream.class || p[i]==XStream2.class) + if (p[i] == XStream.class || p[i] == XStream2.class) { args[i] = xstream; - else if(p[i]== Mapper.class) + } else if (p[i] == Mapper.class) { args[i] = xstream.getMapper(); - else - throw new InstantiationError("Unrecognized constructor parameter: "+p[i]); + } else { + throw new InstantiationError("Unrecognized constructor parameter: " + p[i]); + } } - ConverterMatcher cm = (ConverterMatcher)c.newInstance(args); + ConverterMatcher cm = (ConverterMatcher) c.newInstance(args); result = cm instanceof SingleValueConverter - ? new SingleValueConverterWrapper((SingleValueConverter)cm) - : (Converter)cm; + ? new SingleValueConverterWrapper((SingleValueConverter) cm) + : (Converter) cm; cache.put(t, result); return result; } catch (ClassNotFoundException e) { @@ -206,28 +222,31 @@ public class XStream2 extends XStream { } public boolean canConvert(Class type) { - return findConverter(type)!=null; + return findConverter(type) != null; } public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { - findConverter(source.getClass()).marshal(source,writer,context); + findConverter(source.getClass()).marshal(source, writer, context); } public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { - return findConverter(context.getRequiredType()).unmarshal(reader,context); + return findConverter(context.getRequiredType()).unmarshal(reader, context); } } /** - * Create a nested {@code ConverterImpl} subclass that extends this class to run some - * callback code just after a type is unmarshalled by RobustReflectionConverter. - * Example: <pre> public static class ConverterImpl extends XStream2.PassthruConverter<MyType> { + * Create a nested {@code ConverterImpl} subclass that extends this class to + * run some callback code just after a type is unmarshalled by + * RobustReflectionConverter. Example: + * <pre> public static class ConverterImpl extends XStream2.PassthruConverter<MyType> { * public ConverterImpl(XStream2 xstream) { super(xstream); } - * @Override protected void callback(MyType obj, UnmarshallingContext context) { - * ... + * + * @Override protected void callback(MyType obj, UnmarshallingContext + * context) { ... * </pre> */ public static abstract class PassthruConverter<T> implements Converter { + private Converter converter; public PassthruConverter(XStream2 xstream) { @@ -245,7 +264,7 @@ public class XStream2 extends XStream { public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { Object obj = converter.unmarshal(reader, context); - callback((T)obj, context); + callback((T) obj, context); return obj; } diff --git a/hudson-core/src/main/java/hudson/util/io/Archiver.java b/hudson-core/src/main/java/hudson/util/io/Archiver.java index 460c069..5f97a77 100644 --- a/hudson-core/src/main/java/hudson/util/io/Archiver.java +++ b/hudson-core/src/main/java/hudson/util/io/Archiver.java @@ -7,10 +7,10 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: + * Contributors: + * + * * - * - * * *******************************************************************************/ @@ -27,7 +27,8 @@ import java.io.Closeable; * @see ArchiverFactory */ public abstract class Archiver extends FileVisitor implements Closeable { - protected int entriesWritten =0; + + protected int entriesWritten = 0; /** * Number of files/directories archived. diff --git a/hudson-core/src/main/java/hudson/util/io/ArchiverFactory.java b/hudson-core/src/main/java/hudson/util/io/ArchiverFactory.java index cf88cf7..8a2aee0 100644 --- a/hudson-core/src/main/java/hudson/util/io/ArchiverFactory.java +++ b/hudson-core/src/main/java/hudson/util/io/ArchiverFactory.java @@ -7,10 +7,10 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: + * Contributors: + * + * * - * - * * *******************************************************************************/ @@ -27,31 +27,28 @@ import java.io.Serializable; * * @author Kohsuke Kawaguchi * @since 1.359 -*/ + */ public abstract class ArchiverFactory implements Serializable { + /** * Creates an archiver on top of the given stream. */ public abstract Archiver create(OutputStream out) throws IOException; - /** * Uncompressed tar format. */ public static ArchiverFactory TAR = new TarArchiverFactory(TarCompression.NONE); - /** * tar+gz */ public static ArchiverFactory TARGZ = new TarArchiverFactory(TarCompression.GZIP); - /** * Zip format. */ public static ArchiverFactory ZIP = new ZipArchiverFactory(); - - private static final class TarArchiverFactory extends ArchiverFactory { + private final TarCompression method; private TarArchiverFactory(TarCompression method) { @@ -61,17 +58,15 @@ public abstract class ArchiverFactory implements Serializable { public Archiver create(OutputStream out) throws IOException { return new TarArchiver(method.compress(out)); } - private static final long serialVersionUID = 1L; } private static final class ZipArchiverFactory extends ArchiverFactory { + public Archiver create(OutputStream out) { return new ZipArchiver(out); } - private static final long serialVersionUID = 1L; } - private static final long serialVersionUID = 1L; } diff --git a/hudson-core/src/main/java/hudson/util/io/ReopenableFileOutputStream.java b/hudson-core/src/main/java/hudson/util/io/ReopenableFileOutputStream.java index 564d2c3..fc0c1a3 100644 --- a/hudson-core/src/main/java/hudson/util/io/ReopenableFileOutputStream.java +++ b/hudson-core/src/main/java/hudson/util/io/ReopenableFileOutputStream.java @@ -7,9 +7,9 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: - * - * + * Contributors: + * + * * *******************************************************************************/ @@ -36,7 +36,6 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ - package hudson.util.io; import hudson.util.IOException2; @@ -50,15 +49,14 @@ import java.io.OutputStream; /** * {@link OutputStream} that writes to a file. * - * <p> - * Unlike regular {@link FileOutputStream}, this implementation allows the caller to close, - * and then keep writing. + * <p> Unlike regular {@link FileOutputStream}, this implementation allows the + * caller to close, and then keep writing. * * @author Kohsuke Kawaguchi */ public class ReopenableFileOutputStream extends OutputStream { - private final File out; + private final File out; private OutputStream current; private boolean appendOnNextOpen = false; @@ -67,12 +65,13 @@ public class ReopenableFileOutputStream extends OutputStream { } private synchronized OutputStream current() throws IOException { - if (current==null) + if (current == null) { try { - current = new FileOutputStream(out,appendOnNextOpen); + current = new FileOutputStream(out, appendOnNextOpen); } catch (FileNotFoundException e) { - throw new IOException2("Failed to open "+out,e); + throw new IOException2("Failed to open " + out, e); } + } return current; } @@ -98,7 +97,7 @@ public class ReopenableFileOutputStream extends OutputStream { @Override public synchronized void close() throws IOException { - if (current!=null) { + if (current != null) { current.close(); appendOnNextOpen = true; current = null; @@ -106,7 +105,8 @@ public class ReopenableFileOutputStream extends OutputStream { } /** - * In addition to close, ensure that the next "open" would truncate the file. + * In addition to close, ensure that the next "open" would truncate the + * file. */ public synchronized void rewind() throws IOException { close(); diff --git a/hudson-core/src/main/java/hudson/util/io/TarArchiver.java b/hudson-core/src/main/java/hudson/util/io/TarArchiver.java index 90ec093..6faa1a3 100644 --- a/hudson-core/src/main/java/hudson/util/io/TarArchiver.java +++ b/hudson-core/src/main/java/hudson/util/io/TarArchiver.java @@ -7,10 +7,10 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: + * Contributors: + * + * * - * - * * *******************************************************************************/ @@ -37,6 +37,7 @@ import static org.apache.tools.tar.TarConstants.LF_SYMLINK; * @see ArchiverFactory#TAR */ final class TarArchiver extends Archiver { + private final byte[] buf = new byte[8192]; private final TarOutputStream tar; @@ -75,15 +76,18 @@ final class TarArchiver extends Archiver { } public void visit(File file, String relativePath) throws IOException { - if(Functions.isWindows()) - relativePath = relativePath.replace('\\','/'); + if (Functions.isWindows()) { + relativePath = relativePath.replace('\\', '/'); + } - if(file.isDirectory()) - relativePath+='/'; + if (file.isDirectory()) { + relativePath += '/'; + } TarEntry te = new TarEntry(relativePath); te.setModTime(file.lastModified()); - if(!file.isDirectory()) + if (!file.isDirectory()) { te.setSize(file.length()); + } tar.putNextEntry(te); @@ -91,8 +95,9 @@ final class TarArchiver extends Archiver { FileInputStream in = new FileInputStream(file); try { int len; - while((len=in.read(buf))>=0) - tar.write(buf,0,len); + while ((len = in.read(buf)) >= 0) { + tar.write(buf, 0, len); + } } finally { in.close(); } @@ -105,7 +110,6 @@ final class TarArchiver extends Archiver { public void close() throws IOException { tar.close(); } - private static final Field LINKNAME_FIELD = getTarEntryLinkNameField(); private static Field getTarEntryLinkNameField() { diff --git a/hudson-core/src/main/java/hudson/util/io/ZipArchiver.java b/hudson-core/src/main/java/hudson/util/io/ZipArchiver.java index 38d7502..ee0a109 100644 --- a/hudson-core/src/main/java/hudson/util/io/ZipArchiver.java +++ b/hudson-core/src/main/java/hudson/util/io/ZipArchiver.java @@ -7,10 +7,10 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: + * Contributors: + * + * * - * - * * *******************************************************************************/ @@ -31,10 +31,9 @@ import java.io.OutputStream; * @see ArchiverFactory#ZIP */ final class ZipArchiver extends Archiver { - + // Bitmask indicating directories in 'external attributes' of a ZIP archive entry. - private static final long BITMASK_IS_DIRECTORY = 1 << 4; - + private static final long BITMASK_IS_DIRECTORY = 1 << 4; private final byte[] buf = new byte[8192]; private final ZipOutputStream zip; diff --git a/hudson-core/src/main/java/hudson/util/jelly/MorphTagLibrary.java b/hudson-core/src/main/java/hudson/util/jelly/MorphTagLibrary.java index 3133059..c2cc7f7 100644 --- a/hudson-core/src/main/java/hudson/util/jelly/MorphTagLibrary.java +++ b/hudson-core/src/main/java/hudson/util/jelly/MorphTagLibrary.java @@ -8,7 +8,7 @@ * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * + * * *******************************************************************************/ @@ -33,32 +33,34 @@ import java.util.Collections; import java.util.Map; /** - * Jelly tag library for literal-like tags, with an ability to add arbitrary attributes taken from a map. + * Jelly tag library for literal-like tags, with an ability to add arbitrary + * attributes taken from a map. * - * <p> - * Tags from this namespace ("jelly:hudson.util.jelly.MorphTagLibrary") behaves mostly like literal static tags, - * except it interprets two attributes "ATTRIBUTES" and "EXCEPT" in a special way. + * <p> Tags from this namespace ("jelly:hudson.util.jelly.MorphTagLibrary") + * behaves mostly like literal static tags, except it interprets two attributes + * "ATTRIBUTES" and "EXCEPT" in a special way. * - * The "ATTRIBUTES" attribute should have a Jelly expression that points to a {@link Map} object, - * and the contents of the map are added as attributes of this tag, with the exceptions of entries whose key - * values are listed in the "EXCEPT" attribute. + * The "ATTRIBUTES" attribute should have a Jelly expression that points to a + * {@link Map} object, and the contents of the map are added as attributes of + * this tag, with the exceptions of entries whose key values are listed in the + * "EXCEPT" attribute. * - * The "EXCEPT" attribute takes a white-space separated list of attribute names that should be ignored even - * if it's in the map. + * The "EXCEPT" attribute takes a white-space separated list of attribute names + * that should be ignored even if it's in the map. * - * <p> - * The explicit literal attributes, if specified, always take precedence over the dynamic attributes added by the map. + * <p> The explicit literal attributes, if specified, always take precedence + * over the dynamic attributes added by the map. * - * <p> - * See textbox.jelly as an example of using this tag library. + * <p> See textbox.jelly as an example of using this tag library. * * @author Kohsuke Kawaguchi * @since 1.342 */ public class MorphTagLibrary extends TagLibrary { + /** - * This code is really only used for dealing with dynamic tag libraries, so no point in implementing - * this for statically used tag libraries. + * This code is really only used for dealing with dynamic tag libraries, so + * no point in implementing this for statically used tag libraries. */ @Override public Tag createTag(final String name, Attributes attributes) throws JellyException { @@ -70,19 +72,24 @@ public class MorphTagLibrary extends TagLibrary { return new TagScript() { private Object evalAttribute(String name, JellyContext context) { ExpressionAttribute e = attributes.get(name); - if (e==null) return null; + if (e == null) { + return null; + } return e.exp.evaluate(context); } private Collection<?> getExclusions(JellyContext context) { - Object exclusion = evalAttribute(EXCEPT_ATTRIBUTES,context); - if (exclusion==null) + Object exclusion = evalAttribute(EXCEPT_ATTRIBUTES, context); + if (exclusion == null) { return Collections.emptySet(); - if (exclusion instanceof String) + } + if (exclusion instanceof String) { return Arrays.asList(exclusion.toString().split("\\s+")); // split by whitespace - if (exclusion instanceof Collection) - return (Collection)exclusion; - throw new IllegalArgumentException("Expected collection for exclusion but found :"+exclusion); + } + if (exclusion instanceof Collection) { + return (Collection) exclusion; + } + throw new IllegalArgumentException("Expected collection for exclusion but found :" + exclusion); } @Override @@ -91,41 +98,50 @@ public class MorphTagLibrary extends TagLibrary { Collection<?> exclusions = getExclusions(context); - Map<String,?> meta = (Map)evalAttribute(META_ATTRIBUTES,context); - if (meta!=null) { - for (Map.Entry<String,?> e : meta.entrySet()) { + Map<String, ?> meta = (Map) evalAttribute(META_ATTRIBUTES, context); + if (meta != null) { + for (Map.Entry<String, ?> e : meta.entrySet()) { String key = e.getKey(); // @see jelly.impl.DynamicTag.setAttribute() -- ${attrs} has duplicates with "Attr" suffix - if (key.endsWith("Attr") && meta.containsKey(key.substring(0, key.length()-4))) continue; + if (key.endsWith("Attr") && meta.containsKey(key.substring(0, key.length() - 4))) { + continue; + } // @see http://github.com/hudson/jelly/commit/4ae67d15957b5b4d32751619997a3cb2a6ad56ed - if (key.equals("ownerTag")) continue; + if (key.equals("ownerTag")) { + continue; + } if (!exclusions.contains(key)) { Object v = e.getValue(); - if (v!=null) - actual.addAttribute("", key, key,"CDATA", v.toString()); + if (v != null) { + actual.addAttribute("", key, key, "CDATA", v.toString()); + } } } } else { meta = Collections.emptyMap(); } - for (Map.Entry<String,ExpressionAttribute> e : attributes.entrySet()) { + for (Map.Entry<String, ExpressionAttribute> e : attributes.entrySet()) { String name = e.getKey(); - if (name.equals(META_ATTRIBUTES) || name.equals(EXCEPT_ATTRIBUTES)) continue; // already handled + if (name.equals(META_ATTRIBUTES) || name.equals(EXCEPT_ATTRIBUTES)) { + continue; // already handled + } if (meta.containsKey(name)) { // if the explicit value is also generated by a map, delete it first. // this is O(N) operation, but we don't expect there to be a lot of collisions. int idx = actual.getIndex(name); - if(idx>=0) actual.removeAttribute(idx); + if (idx >= 0) { + actual.removeAttribute(idx); + } } Expression expression = e.getValue().exp; - actual.addAttribute("",name,name,"CDATA",expression.evaluateAsString(context)); + actual.addAttribute("", name, name, "CDATA", expression.evaluateAsString(context)); } try { - output.startElement(tagName,actual); - getTagBody().run(context,output); + output.startElement(tagName, actual); + getTagBody().run(context, output); output.endElement(tagName); } catch (SAXException x) { throw new JellyTagException(x); @@ -133,7 +149,6 @@ public class MorphTagLibrary extends TagLibrary { } }; } - private static final String META_ATTRIBUTES = "ATTRIBUTES"; private static final String EXCEPT_ATTRIBUTES = "EXCEPT"; } diff --git a/hudson-core/src/main/java/hudson/util/package.html b/hudson-core/src/main/java/hudson/util/package.html index 8006f5f..c102cd4 100644 --- a/hudson-core/src/main/java/hudson/util/package.html +++ b/hudson-core/src/main/java/hudson/util/package.html @@ -16,5 +16,5 @@ --> <html><head/><body> -Other miscellaneous utility code -</body></html>
\ No newline at end of file + Other miscellaneous utility code + </body></html>
\ No newline at end of file diff --git a/hudson-core/src/main/java/hudson/util/xstream/ImmutableMapConverter.java b/hudson-core/src/main/java/hudson/util/xstream/ImmutableMapConverter.java index d88631e..870b76b 100644 --- a/hudson-core/src/main/java/hudson/util/xstream/ImmutableMapConverter.java +++ b/hudson-core/src/main/java/hudson/util/xstream/ImmutableMapConverter.java @@ -7,10 +7,10 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: + * Contributors: + * + * * - * - * * *******************************************************************************/ @@ -30,20 +30,22 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; /** - * {@link ConcurrentHashMap} should convert like a map, instead of via serialization. + * {@link ConcurrentHashMap} should convert like a map, instead of via + * serialization. * * @author Kohsuke Kawaguchi */ public class ImmutableMapConverter extends MapConverter { + private final SerializableConverter sc; public ImmutableMapConverter(XStream xs) { - this(xs.getMapper(),xs.getReflectionProvider()); + this(xs.getMapper(), xs.getReflectionProvider()); } public ImmutableMapConverter(Mapper mapper, ReflectionProvider reflectionProvider) { super(mapper); - sc = new SerializableConverter(mapper,reflectionProvider); + sc = new SerializableConverter(mapper, reflectionProvider); } @Override @@ -53,7 +55,7 @@ public class ImmutableMapConverter extends MapConverter { @Override public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { - return ImmutableMap.copyOf((Map)super.unmarshal(reader, context)); + return ImmutableMap.copyOf((Map) super.unmarshal(reader, context)); } @Override |

