Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWinston Prakash2012-02-14 19:17:52 -0500
committerWinston Prakash2012-02-14 19:17:52 -0500
commitc39f59a75a338fa95e733a6afbb7660fab1715c5 (patch)
treecec83630c6a33cabf2b21b8720425e4dcd617d59 /hudson-core/src
parent82acf4773947a90450ae04bef07c3f11688d7908 (diff)
parenta98426587708c26e1641e8f734e39749c4889e8f (diff)
downloadorg.eclipse.hudson.core-c39f59a75a338fa95e733a6afbb7660fab1715c5.tar.gz
org.eclipse.hudson.core-c39f59a75a338fa95e733a6afbb7660fab1715c5.tar.xz
org.eclipse.hudson.core-c39f59a75a338fa95e733a6afbb7660fab1715c5.zip
Merger with master
Diffstat (limited to 'hudson-core/src')
-rw-r--r--hudson-core/src/main/java/hudson/ExtensionFinder.java4
-rw-r--r--hudson-core/src/main/java/hudson/Functions.java4
-rw-r--r--hudson-core/src/main/java/hudson/RestrictedSince.java5
-rw-r--r--hudson-core/src/main/java/hudson/Util.java492
-rw-r--r--hudson-core/src/main/java/hudson/cli/ClientAuthenticationCache.java2
-rw-r--r--hudson-core/src/main/java/hudson/cli/handlers/AbstractProjectOptionHandler.java4
-rw-r--r--hudson-core/src/main/java/hudson/cli/handlers/TopLevelItemOptionHandler.java4
-rw-r--r--hudson-core/src/main/java/hudson/console/AnnotatedLargeText.java6
-rw-r--r--hudson-core/src/main/java/hudson/diagnosis/HudsonHomeDiskUsageChecker.java2
-rw-r--r--hudson-core/src/main/java/hudson/init/InitReactorListener.java3
-rw-r--r--hudson-core/src/main/java/hudson/init/InitStrategy.java3
-rw-r--r--hudson-core/src/main/java/hudson/lifecycle/WindowsInstallerLink.java73
-rw-r--r--hudson-core/src/main/java/hudson/model/AbstractItem.java14
-rw-r--r--hudson-core/src/main/java/hudson/model/AbstractProject.java1008
-rw-r--r--hudson-core/src/main/java/hudson/model/ExternalRun.java2
-rw-r--r--hudson-core/src/main/java/hudson/model/Job.java3
-rw-r--r--hudson-core/src/main/java/hudson/model/Node.java2
-rw-r--r--hudson-core/src/main/java/hudson/model/UpdateSite.java13
-rw-r--r--hudson-core/src/main/java/hudson/model/UsageStatistics.java4
-rw-r--r--hudson-core/src/main/java/hudson/model/User.java2
-rw-r--r--hudson-core/src/main/java/hudson/node_monitors/DiskSpaceMonitorDescriptor.java2
-rw-r--r--hudson-core/src/main/java/hudson/node_monitors/TemporarySpaceMonitor.java2
-rw-r--r--hudson-core/src/main/java/hudson/os/EmbeddedSu.java180
-rw-r--r--hudson-core/src/main/java/hudson/os/SU.java5
-rw-r--r--hudson-core/src/main/java/hudson/os/SuAuthenticationFailureException.java32
-rw-r--r--hudson-core/src/main/java/hudson/tasks/Mailer.java4
-rw-r--r--hudson-core/src/main/java/hudson/tools/ZipExtractionInstaller.java2
-rw-r--r--hudson-core/src/main/java/hudson/util/CertificateUtil.java87
-rw-r--r--hudson-core/src/main/java/hudson/util/ConsistentHash.java3
-rw-r--r--hudson-core/src/main/java/hudson/util/Digester2.java4
-rw-r--r--hudson-core/src/main/java/hudson/util/FormFieldValidator.java2
-rw-r--r--hudson-core/src/main/java/hudson/util/FormValidation.java23
-rw-r--r--hudson-core/src/main/java/hudson/util/Protector.java7
-rw-r--r--hudson-core/src/main/java/hudson/util/Scrambler.java7
-rw-r--r--hudson-core/src/main/java/hudson/util/Secret.java6
-rw-r--r--hudson-core/src/main/java/hudson/util/SignatureOutputStream.java60
-rw-r--r--hudson-core/src/main/java/hudson/util/jna/NativeUtils.java23
-rw-r--r--hudson-core/src/main/java/hudson/util/ssh/DEREncoder.java117
-rw-r--r--hudson-core/src/main/java/hudson/util/ssh/KeyReader.java65
-rw-r--r--hudson-core/src/main/java/hudson/util/ssh/PuTTYKey.java276
-rw-r--r--hudson-core/src/main/java/hudson/util/ssh/SFTPClient.java13
-rw-r--r--hudson-core/src/main/java/org/eclipse/hudson/util/plugin/PluginMarker.java101
-rw-r--r--hudson-core/src/main/resources/META-INF/services/org.kohsuke.args4j.spi.OptionHandler2
-rw-r--r--hudson-core/src/main/resources/hudson/model/BuildTimelineWidget/control.jelly2
-rw-r--r--hudson-core/src/main/resources/hudson/model/Messages.properties3
-rw-r--r--hudson-core/src/main/resources/hudson/security/SecurityRealm/loginDialog.jelly15
-rw-r--r--hudson-core/src/main/resources/hudson/security/SecurityRealm/loginLink.jelly12
-rw-r--r--hudson-core/src/main/resources/lib/layout/layout.jelly2
48 files changed, 1745 insertions, 962 deletions
diff --git a/hudson-core/src/main/java/hudson/ExtensionFinder.java b/hudson-core/src/main/java/hudson/ExtensionFinder.java
index 3edf7899..e756cc2e 100644
--- a/hudson-core/src/main/java/hudson/ExtensionFinder.java
+++ b/hudson-core/src/main/java/hudson/ExtensionFinder.java
@@ -22,8 +22,6 @@ import net.java.sezpoz.Index;
import net.java.sezpoz.IndexItem;
import hudson.model.Hudson;
import hudson.model.Descriptor;
-import org.kohsuke.accmod.Restricted;
-import org.kohsuke.accmod.restrictions.NoExternalUse;
import java.util.Collections;
import java.util.logging.Logger;
@@ -54,7 +52,7 @@ public abstract class ExtensionFinder implements ExtensionPoint {
* @deprecated as of 1.356
* Use and implement {@link #find(Class, Hudson)} that allows us to put some metadata.
*/
- @Restricted(NoExternalUse.class)
+ @Deprecated
public <T> Collection<T> findExtensions(Class<T> type, Hudson hudson) {
return Collections.emptyList();
}
diff --git a/hudson-core/src/main/java/hudson/Functions.java b/hudson-core/src/main/java/hudson/Functions.java
index 99feab17..ecf30dbe 100644
--- a/hudson-core/src/main/java/hudson/Functions.java
+++ b/hudson-core/src/main/java/hudson/Functions.java
@@ -74,7 +74,6 @@ import org.apache.commons.jelly.Script;
import org.apache.commons.jelly.XMLOutput;
import org.apache.commons.jexl.parser.ASTSizeFunction;
import org.apache.commons.jexl.util.Introspector;
-import org.jvnet.animal_sniffer.IgnoreJRERequirement;
import org.jvnet.tiger_types.Types;
import org.kohsuke.stapler.Ancestor;
import org.kohsuke.stapler.Stapler;
@@ -799,7 +798,6 @@ public class Functions {
return sorted;
}
- @IgnoreJRERequirement
public static ThreadInfo[] getThreadInfos() {
ThreadMXBean mbean = ManagementFactory.getThreadMXBean();
return mbean.dumpAllThreads(mbean.isObjectMonitorUsageSupported(),mbean.isSynchronizerUsageSupported());
@@ -863,7 +861,6 @@ public class Functions {
/**
* Are we running on JRE6 or above?
*/
- @IgnoreJRERequirement
public static boolean isMustangOrAbove() {
try {
System.console();
@@ -874,7 +871,6 @@ public class Functions {
}
// ThreadInfo.toString() truncates the stack trace by first 8, so needed my own version
- @IgnoreJRERequirement
public static String dumpThreadInfo(ThreadInfo ti, ThreadGroupMap map) {
String grp = map.getThreadGroup(ti);
StringBuilder sb = new StringBuilder("\"" + ti.getThreadName() + "\"" +
diff --git a/hudson-core/src/main/java/hudson/RestrictedSince.java b/hudson-core/src/main/java/hudson/RestrictedSince.java
index 86184d6a..209e3a81 100644
--- a/hudson-core/src/main/java/hudson/RestrictedSince.java
+++ b/hudson-core/src/main/java/hudson/RestrictedSince.java
@@ -16,12 +16,11 @@
package hudson;
-//import org.kohsuke.accmod.Restricted;
import java.lang.annotation.Documented;
/**
- * Accompanies {@link Restricted} annotation to indicate when the access restriction was placed.
+ * Accompanies {@link Depricated} annotation to indicate when the access restriction was placed.
*
* @author Kohsuke Kawaguchi
* @since 1.355
@@ -29,7 +28,7 @@ import java.lang.annotation.Documented;
@Documented
public @interface RestrictedSince {
/**
- * Hudson version number that this restriction has started.
+ * Hudson version number that this deprecation has started.
*/
String value();
}
diff --git a/hudson-core/src/main/java/hudson/Util.java b/hudson-core/src/main/java/hudson/Util.java
index 02db474c..6c7a1b4a 100644
--- a/hudson-core/src/main/java/hudson/Util.java
+++ b/hudson-core/src/main/java/hudson/Util.java
@@ -12,8 +12,7 @@
* Kohsuke Kawaguchi, Winston Prakash
*
*
- *******************************************************************************/
-
+ *******************************************************************************/
package hudson;
import hudson.model.TaskListener;
@@ -35,7 +34,6 @@ import org.apache.commons.lang3.time.FastDateFormat;
import org.apache.commons.io.IOUtils;
import org.kohsuke.stapler.Stapler;
-import org.jvnet.animal_sniffer.IgnoreJRERequirement;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
@@ -107,11 +105,12 @@ public class Util {
* Creates a filtered sublist.
* @since 1.176
*/
- public static <T> List<T> filter( Iterable<?> base, Class<T> type ) {
+ public static <T> List<T> filter(Iterable<?> base, Class<T> type) {
List<T> r = new ArrayList<T>();
for (Object i : base) {
- if(type.isInstance(i))
+ if (type.isInstance(i)) {
r.add(type.cast(i));
+ }
}
return r;
}
@@ -119,13 +118,12 @@ public class Util {
/**
* Creates a filtered sublist.
*/
- public static <T> List<T> filter( List<?> base, Class<T> type ) {
- return filter((Iterable)base,type);
+ public static <T> List<T> filter(List<?> base, Class<T> type) {
+ return filter((Iterable) base, type);
}
-
/**
* Pattern for capturing variables. Either $xyz or ${xyz}, while ignoring "$$"
- */
+ */
private static final Pattern VARIABLE = Pattern.compile("\\$([A-Za-z0-9_]+|\\{[A-Za-z0-9_\\.+]+\\}|\\$)");
/**
@@ -135,10 +133,10 @@ public class Util {
* Unlike shell, undefined variables are left as-is (this behavior is the same as Ant.)
*
*/
- public static String replaceMacro(String s, Map<String,String> properties) {
- return replaceMacro(s,new VariableResolver.ByMap<String>(properties));
+ public static String replaceMacro(String s, Map<String, String> properties) {
+ return replaceMacro(s, new VariableResolver.ByMap<String>(properties));
}
-
+
/**
* Replaces the occurrence of '$key' by <tt>resolver.get('key')</tt>.
*
@@ -146,30 +144,34 @@ public class Util {
* Unlike shell, undefined variables are left as-is (this behavior is the same as Ant.)
*/
public static String replaceMacro(String s, VariableResolver<String> resolver) {
- if (s == null) {
- return null;
- }
-
- int idx=0;
- while(true) {
+ if (s == null) {
+ return null;
+ }
+
+ int idx = 0;
+ while (true) {
Matcher m = VARIABLE.matcher(s);
- if(!m.find(idx)) return s;
+ if (!m.find(idx)) {
+ return s;
+ }
String key = m.group().substring(1);
// escape the dollar sign or get the key to resolve
String value;
- if(key.charAt(0)=='$') {
- value = "$";
+ if (key.charAt(0) == '$') {
+ value = "$";
} else {
- if(key.charAt(0)=='{') key = key.substring(1,key.length()-1);
- value = resolver.resolve(key);
+ if (key.charAt(0) == '{') {
+ key = key.substring(1, key.length() - 1);
+ }
+ value = resolver.resolve(key);
}
- if(value==null)
+ if (value == null) {
idx = m.end(); // skip this
- else {
- s = s.substring(0,m.start())+value+s.substring(m.end());
+ } else {
+ s = s.substring(0, m.start()) + value + s.substring(m.end());
idx = m.start() + value.length();
}
}
@@ -182,17 +184,19 @@ public class Util {
return loadFile(logfile, Charset.defaultCharset());
}
- public static String loadFile(File logfile,Charset charset) throws IOException {
- if(!logfile.exists())
+ public static String loadFile(File logfile, Charset charset) throws IOException {
+ if (!logfile.exists()) {
return "";
+ }
- StringBuilder str = new StringBuilder((int)logfile.length());
+ StringBuilder str = new StringBuilder((int) logfile.length());
- BufferedReader r = new BufferedReader(new InputStreamReader(new FileInputStream(logfile),charset));
+ BufferedReader r = new BufferedReader(new InputStreamReader(new FileInputStream(logfile), charset));
char[] buf = new char[1024];
int len;
- while((len=r.read(buf,0,buf.length))>0)
- str.append(buf,0,len);
+ while ((len = r.read(buf, 0, buf.length)) > 0) {
+ str.append(buf, 0, len);
+ }
r.close();
return str.toString();
@@ -207,10 +211,12 @@ public class Util {
*/
public static void deleteContentsRecursive(File file) throws IOException {
File[] files = file.listFiles();
- if(files==null)
+ if (files == null) {
return; // the directory didn't exist in the first place
- for (File child : files)
+ }
+ for (File child : files) {
deleteRecursive(child);
+ }
}
/**
@@ -220,35 +226,37 @@ public class Util {
*/
public static void deleteFile(File f) throws IOException {
if (!f.delete()) {
- if(!f.exists())
- // we are trying to delete a file that no longer exists, so this is not an error
+ if (!f.exists()) // we are trying to delete a file that no longer exists, so this is not an error
+ {
return;
+ }
// perhaps this file is read-only?
makeWritable(f);
/*
- on Unix both the file and the directory that contains it has to be writable
- for a file deletion to be successful. (Confirmed on Solaris 9)
-
- $ ls -la
- total 6
- dr-xr-sr-x 2 hudson hudson 512 Apr 18 14:41 .
- dr-xr-sr-x 3 hudson hudson 512 Apr 17 19:36 ..
- -r--r--r-- 1 hudson hudson 469 Apr 17 19:36 manager.xml
- -rw-r--r-- 1 hudson hudson 0 Apr 18 14:41 x
- $ rm x
- rm: x not removed: Permission denied
+ on Unix both the file and the directory that contains it has to be writable
+ for a file deletion to be successful. (Confirmed on Solaris 9)
+
+ $ ls -la
+ total 6
+ dr-xr-sr-x 2 hudson hudson 512 Apr 18 14:41 .
+ dr-xr-sr-x 3 hudson hudson 512 Apr 17 19:36 ..
+ -r--r--r-- 1 hudson hudson 469 Apr 17 19:36 manager.xml
+ -rw-r--r-- 1 hudson hudson 0 Apr 18 14:41 x
+ $ rm x
+ rm: x not removed: Permission denied
*/
makeWritable(f.getParentFile());
- if(!f.delete() && f.exists()) {
+ if (!f.delete() && f.exists()) {
// trouble-shooting.
// see http://www.nabble.com/Sometimes-can%27t-delete-files-from-hudson.scm.SubversionSCM%24CheckOutTask.invoke%28%29-tt17333292.html
// I suspect other processes putting files in this directory
File[] files = f.listFiles();
- if(files!=null && files.length>0)
- throw new IOException("Unable to delete " + f.getPath()+" - files in dir: "+Arrays.asList(files));
+ if (files != null && files.length > 0) {
+ throw new IOException("Unable to delete " + f.getPath() + " - files in dir: " + Arrays.asList(files));
+ }
throw new IOException("Unable to delete " + f.getPath());
}
}
@@ -257,7 +265,6 @@ public class Util {
/**
* Makes the given file writable by any means possible.
*/
- @IgnoreJRERequirement
private static void makeWritable(File f) {
// try chmod. this becomes no-op if this is not Unix.
try {
@@ -277,36 +284,39 @@ public class Util {
// not JDK6
}
- try {
- NativeUtils.getInstance().makeFileWritable(f);
- } catch (NativeAccessException exc) {
- LOGGER.log(Level.FINE, "Failed to chmod(2) " + f, exc);
+ if (!Functions.isWindows()) {
+ try {
+ NativeUtils.getInstance().makeFileWritable(f);
+ } catch (NativeAccessException exc) {
+ LOGGER.log(Level.FINE, "Failed to chmod(2) " + f, exc);
+ }
}
-
}
public static void deleteRecursive(File dir) throws IOException {
- if(!isSymlink(dir))
+ if (!isSymlink(dir)) {
deleteContentsRecursive(dir);
+ }
deleteFile(dir);
}
-
+
/**
* Checks if the given file represents a symlink.
*/
public static boolean isSymlink(File file) throws IOException {
String name = file.getName();
- if (name.equals(".") || name.equals(".."))
+ if (name.equals(".") || name.equals("..")) {
return false;
+ }
File fileInCanonicalParent;
File parentDir = file.getParentFile();
- if ( parentDir == null ) {
+ if (parentDir == null) {
fileInCanonicalParent = file;
} else {
- fileInCanonicalParent = new File( parentDir.getCanonicalPath(), name );
+ fileInCanonicalParent = new File(parentDir.getCanonicalPath(), name);
}
- return !fileInCanonicalParent.getCanonicalFile().equals( fileInCanonicalParent.getAbsoluteFile() );
+ return !fileInCanonicalParent.getCanonicalFile().equals(fileInCanonicalParent.getAbsoluteFile());
}
/**
@@ -314,27 +324,29 @@ public class Util {
*/
public static File createTempDir() throws IOException {
File tmp = File.createTempFile("hudson", "tmp");
- if(!tmp.delete())
- throw new IOException("Failed to delete "+tmp);
- if(!tmp.mkdirs())
- throw new IOException("Failed to create a new directory "+tmp);
+ if (!tmp.delete()) {
+ throw new IOException("Failed to delete " + tmp);
+ }
+ if (!tmp.mkdirs()) {
+ throw new IOException("Failed to create a new directory " + tmp);
+ }
return tmp;
}
-
private static final Pattern errorCodeParser = Pattern.compile(".*CreateProcess.*error=([0-9]+).*");
/**
* On Windows, error messages for IOException aren't very helpful.
* This method generates additional user-friendly error message to the listener
*/
- public static void displayIOException( IOException e, TaskListener listener ) {
+ public static void displayIOException(IOException e, TaskListener listener) {
String msg = getWin32ErrorMessage(e);
- if(msg!=null)
+ if (msg != null) {
listener.getLogger().println(msg);
+ }
}
public static String getWin32ErrorMessage(IOException e) {
- return getWin32ErrorMessage((Throwable)e);
+ return getWin32ErrorMessage((Throwable) e);
}
/**
@@ -345,20 +357,21 @@ public class Util {
*/
public static String getWin32ErrorMessage(Throwable e) {
String msg = e.getMessage();
- if(msg!=null) {
+ if (msg != null) {
Matcher m = errorCodeParser.matcher(msg);
- if(m.matches()) {
+ if (m.matches()) {
try {
ResourceBundle rb = ResourceBundle.getBundle("/hudson/win32errors");
- return rb.getString("error"+m.group(1));
+ return rb.getString("error" + m.group(1));
} catch (Exception _) {
// silently recover from resource related failures
}
}
}
- if(e.getCause()!=null)
+ if (e.getCause() != null) {
return getWin32ErrorMessage(e.getCause());
+ }
return null; // no message
}
@@ -371,9 +384,9 @@ public class Util {
public static String getWin32ErrorMessage(int n) {
try {
ResourceBundle rb = ResourceBundle.getBundle("/hudson/win32errors");
- return rb.getString("error"+n);
+ return rb.getString("error" + n);
} catch (MissingResourceException e) {
- LOGGER.log(Level.WARNING,"Failed to find resource bundle",e);
+ LOGGER.log(Level.WARNING, "Failed to find resource bundle", e);
return null;
}
}
@@ -389,32 +402,34 @@ public class Util {
}
}
- public static void copyStream(InputStream in,OutputStream out) throws IOException {
+ public static void copyStream(InputStream in, OutputStream out) throws IOException {
byte[] buf = new byte[8192];
int len;
- while((len=in.read(buf))>0)
- out.write(buf,0,len);
+ while ((len = in.read(buf)) > 0) {
+ out.write(buf, 0, len);
+ }
}
public static void copyStream(Reader in, Writer out) throws IOException {
char[] buf = new char[8192];
int len;
- while((len=in.read(buf))>0)
- out.write(buf,0,len);
+ while ((len = in.read(buf)) > 0) {
+ out.write(buf, 0, len);
+ }
}
- public static void copyStreamAndClose(InputStream in,OutputStream out) throws IOException {
+ public static void copyStreamAndClose(InputStream in, OutputStream out) throws IOException {
try {
- copyStream(in,out);
+ copyStream(in, out);
} finally {
IOUtils.closeQuietly(in);
IOUtils.closeQuietly(out);
}
}
- public static void copyStreamAndClose(Reader in,Writer out) throws IOException {
+ public static void copyStreamAndClose(Reader in, Writer out) throws IOException {
try {
- copyStream(in,out);
+ copyStream(in, out);
} finally {
IOUtils.closeQuietly(in);
IOUtils.closeQuietly(out);
@@ -431,22 +446,22 @@ public class Util {
* @since 1.145
* @see QuotedStringTokenizer
*/
- public static String[] tokenize(String s,String delimiter) {
- return QuotedStringTokenizer.tokenize(s,delimiter);
+ public static String[] tokenize(String s, String delimiter) {
+ return QuotedStringTokenizer.tokenize(s, delimiter);
}
public static String[] tokenize(String s) {
- return tokenize(s," \t\n\r\f");
+ return tokenize(s, " \t\n\r\f");
}
/**
* Converts the map format of the environment variables to the K=V format in the array.
*/
- public static String[] mapToEnv(Map<String,String> m) {
+ public static String[] mapToEnv(Map<String, String> m) {
String[] r = new String[m.size()];
- int idx=0;
+ int idx = 0;
- for (final Map.Entry<String,String> e : m.entrySet()) {
+ for (final Map.Entry<String, String> e : m.entrySet()) {
r[idx++] = e.getKey() + '=' + e.getValue();
}
return r;
@@ -454,22 +469,27 @@ public class Util {
public static int min(int x, int... values) {
for (int i : values) {
- if(i<x)
- x=i;
+ if (i < x) {
+ x = i;
+ }
}
return x;
}
public static String nullify(String v) {
- if(v!=null && v.length()==0) v=null;
+ if (v != null && v.length() == 0) {
+ v = null;
+ }
return v;
}
public static String removeTrailingSlash(String s) {
- if(s.endsWith("/")) return s.substring(0,s.length()-1);
- else return s;
+ if (s.endsWith("/")) {
+ return s.substring(0, s.length() - 1);
+ } else {
+ return s;
+ }
}
-
/**
* Write-only buffer.
*/
@@ -487,16 +507,16 @@ public class Util {
try {
MessageDigest md5 = MessageDigest.getInstance("MD5");
- DigestInputStream in =new DigestInputStream(source,md5);
+ DigestInputStream in = new DigestInputStream(source, md5);
try {
- while(in.read(garbage)>0)
+ while (in.read(garbage) > 0)
; // simply discard the input
} finally {
in.close();
}
return toHexString(md5.digest());
} catch (NoSuchAlgorithmException e) {
- throw new IOException2("MD5 not installed",e); // impossible
+ throw new IOException2("MD5 not installed", e); // impossible
}
}
@@ -520,7 +540,7 @@ public class Util {
digest.update(s.getBytes("UTF-8"));
// Due to the stupid US export restriction JDK only ships 128bit version.
- return new SecretKeySpec(digest.digest(),0,128/8, "AES");
+ return new SecretKeySpec(digest.digest(), 0, 128 / 8, "AES");
} catch (NoSuchAlgorithmException e) {
throw new Error(e);
} catch (UnsupportedEncodingException e) {
@@ -530,22 +550,25 @@ public class Util {
public static String toHexString(byte[] data, int start, int len) {
StringBuilder buf = new StringBuilder();
- for( int i=0; i<len; i++ ) {
- int b = data[start+i]&0xFF;
- if(b<16) buf.append('0');
+ for (int i = 0; i < len; i++) {
+ int b = data[start + i] & 0xFF;
+ if (b < 16) {
+ buf.append('0');
+ }
buf.append(Integer.toHexString(b));
}
return buf.toString();
}
public static String toHexString(byte[] bytes) {
- return toHexString(bytes,0,bytes.length);
+ return toHexString(bytes, 0, bytes.length);
}
public static byte[] fromHexString(String data) {
byte[] r = new byte[data.length() / 2];
- for (int i = 0; i < data.length(); i += 2)
+ for (int i = 0; i < data.length(); i += 2) {
r[i / 2] = (byte) Integer.parseInt(data.substring(i, i + 2), 16);
+ }
return r;
}
@@ -572,27 +595,27 @@ public class Util {
duration %= ONE_SECOND_MS;
long millisecs = duration;
- if (years > 0)
+ if (years > 0) {
return makeTimeSpanString(years, Messages.Util_year(years), months, Messages.Util_month(months));
- else if (months > 0)
+ } else if (months > 0) {
return makeTimeSpanString(months, Messages.Util_month(months), days, Messages.Util_day(days));
- else if (days > 0)
+ } else if (days > 0) {
return makeTimeSpanString(days, Messages.Util_day(days), hours, Messages.Util_hour(hours));
- else if (hours > 0)
+ } else if (hours > 0) {
return makeTimeSpanString(hours, Messages.Util_hour(hours), minutes, Messages.Util_minute(minutes));
- else if (minutes > 0)
+ } else if (minutes > 0) {
return makeTimeSpanString(minutes, Messages.Util_minute(minutes), seconds, Messages.Util_second(seconds));
- else if (seconds >= 10)
+ } else if (seconds >= 10) {
return Messages.Util_second(seconds);
- else if (seconds >= 1)
- return Messages.Util_second(seconds+(float)(millisecs/100)/10); // render "1.2 sec"
- else if(millisecs>=100)
- return Messages.Util_second((float)(millisecs/10)/100); // render "0.12 sec".
- else
+ } else if (seconds >= 1) {
+ return Messages.Util_second(seconds + (float) (millisecs / 100) / 10); // render "1.2 sec"
+ } else if (millisecs >= 100) {
+ return Messages.Util_second((float) (millisecs / 10) / 100); // render "0.12 sec".
+ } else {
return Messages.Util_millisecond(millisecs);
+ }
}
-
/**
* Create a string representation of a time duration. If the quantity of
* the most significant unit is big (>=10), then we use only that most
@@ -603,16 +626,16 @@ public class Util {
* and 43 seconds is "3 minutes 43 seconds".
*/
private static String makeTimeSpanString(long bigUnit,
- String bigLabel,
- long smallUnit,
- String smallLabel) {
+ String bigLabel,
+ long smallUnit,
+ String smallLabel) {
String text = bigLabel;
- if (bigUnit < 10)
+ if (bigUnit < 10) {
text += ' ' + smallLabel;
+ }
return text;
}
-
/**
* Get a human readable string representing strings like "xxx days ago",
* which should be used to point to the occurrence of an event in the past.
@@ -621,7 +644,6 @@ public class Util {
return Messages.Util_pastTime(getTimeSpanString(duration));
}
-
/**
* Combines number and unit, with a plural suffix if needed.
*
@@ -631,21 +653,23 @@ public class Util {
* Deprecated since 2009-06-24, remove method after 2009-12-24.
*/
public static String combine(long n, String suffix) {
- String s = Long.toString(n)+' '+suffix;
- if(n!=1)
- // Just adding an 's' won't work in most natural languages, even English has exception to the rule (e.g. copy/copies).
+ String s = Long.toString(n) + ' ' + suffix;
+ if (n != 1) // Just adding an 's' won't work in most natural languages, even English has exception to the rule (e.g. copy/copies).
+ {
s += "s";
+ }
return s;
}
/**
* Create a sub-list by only picking up instances of the specified type.
*/
- public static <T> List<T> createSubList( Collection<?> source, Class<T> type ) {
+ public static <T> List<T> createSubList(Collection<?> source, Class<T> type) {
List<T> r = new ArrayList<T>();
for (Object item : source) {
- if(type.isInstance(item))
+ if (type.isInstance(item)) {
r.add(type.cast(item));
+ }
}
return r;
}
@@ -666,11 +690,11 @@ public class Util {
StringBuilder out = new StringBuilder(s.length());
ByteArrayOutputStream buf = new ByteArrayOutputStream();
- OutputStreamWriter w = new OutputStreamWriter(buf,"UTF-8");
+ OutputStreamWriter w = new OutputStreamWriter(buf, "UTF-8");
for (int i = 0; i < s.length(); i++) {
int c = (int) s.charAt(i);
- if (c<128 && c!=' ') {
+ if (c < 128 && c != ' ') {
out.append((char) c);
} else {
// 1 char -> UTF8
@@ -691,18 +715,21 @@ public class Util {
throw new Error(e); // impossible
}
}
-
private static final boolean[] uriMap = new boolean[123];
+
static {
String raw =
- "! $ &'()*+,-. 0123456789 = @ABCDEFGHIJKLMNOPQRSTUVWXYZ _ abcdefghijklmnopqrstuvwxyz";
- // "# % / :;< >? [\]^ ` {|}~
- // ^--so these are encoded
+ "! $ &'()*+,-. 0123456789 = @ABCDEFGHIJKLMNOPQRSTUVWXYZ _ abcdefghijklmnopqrstuvwxyz";
+ // "# % / :;< >? [\]^ ` {|}~
+ // ^--so these are encoded
int i;
// Encode control chars and space
- for (i = 0; i < 33; i++) uriMap[i] = true;
- for (int j = 0; j < raw.length(); i++, j++)
+ for (i = 0; i < 33; i++) {
+ uriMap[i] = true;
+ }
+ for (int j = 0; j < raw.length(); i++, j++) {
uriMap[i] = (raw.charAt(j) == ' ');
+ }
// If we add encodeQuery() just add a 2nd map to encode &+=
// queryMap[38] = queryMap[43] = queryMap[61] = true;
}
@@ -732,7 +759,7 @@ public class Util {
escaped = true;
}
// 1 char -> UTF8
- buf.put(0,c);
+ buf.put(0, c);
buf.rewind();
try {
ByteBuffer bytes = enc.encode(buf);
@@ -742,7 +769,8 @@ public class Util {
out.append(toDigit((b >> 4) & 0xF));
out.append(toDigit(b & 0xF));
}
- } catch (CharacterCodingException ex) { }
+ } catch (CharacterCodingException ex) {
+ }
} else if (escaped) {
out.append(c);
}
@@ -751,63 +779,60 @@ public class Util {
}
private static char toDigit(int n) {
- return (char)(n < 10 ? '0' + n : 'A' + n - 10);
+ return (char) (n < 10 ? '0' + n : 'A' + n - 10);
}
/**
* Surrounds by a single-quote.
*/
public static String singleQuote(String s) {
- return '\''+s+'\'';
+ return '\'' + s + '\'';
}
/**
* Escapes HTML unsafe characters like &lt;, &amp; to the respective character entities.
*/
public static String escape(String text) {
- if (text==null) return null;
- StringBuilder buf = new StringBuilder(text.length()+64);
- for( int i=0; i<text.length(); i++ ) {
+ if (text == null) {
+ return null;
+ }
+ StringBuilder buf = new StringBuilder(text.length() + 64);
+ for (int i = 0; i < text.length(); i++) {
char ch = text.charAt(i);
- if(ch=='\n')
+ if (ch == '\n') {
buf.append("<br>");
- else
- if(ch=='<')
+ } else if (ch == '<') {
buf.append("&lt;");
- else
- if(ch=='&')
+ } else if (ch == '&') {
buf.append("&amp;");
- else
- if(ch=='"')
+ } else if (ch == '"') {
buf.append("&quot;");
- else
- if(ch=='\'')
+ } else if (ch == '\'') {
buf.append("&#039;");
- else
- if(ch==' ') {
+ } else if (ch == ' ') {
// All spaces in a block of consecutive spaces are converted to
// non-breaking space (&nbsp;) except for the last one. This allows
// significant whitespace to be retained without prohibiting wrapping.
- char nextCh = i+1 < text.length() ? text.charAt(i+1) : 0;
- buf.append(nextCh==' ' ? "&nbsp;" : " ");
- }
- else
+ char nextCh = i + 1 < text.length() ? text.charAt(i + 1) : 0;
+ buf.append(nextCh == ' ' ? "&nbsp;" : " ");
+ } else {
buf.append(ch);
+ }
}
return buf.toString();
}
public static String xmlEscape(String text) {
- StringBuilder buf = new StringBuilder(text.length()+64);
- for( int i=0; i<text.length(); i++ ) {
+ StringBuilder buf = new StringBuilder(text.length() + 64);
+ for (int i = 0; i < text.length(); i++) {
char ch = text.charAt(i);
- if(ch=='<')
+ if (ch == '<') {
buf.append("&lt;");
- else
- if(ch=='&')
+ } else if (ch == '&') {
buf.append("&amp;");
- else
+ } else {
buf.append(ch);
+ }
}
return buf.toString();
@@ -867,15 +892,20 @@ public class Util {
* Convert null to "".
*/
public static String fixNull(String s) {
- if(s==null) return "";
- else return s;
+ if (s == null) {
+ return "";
+ } else {
+ return s;
+ }
}
/**
* Convert empty string to null.
*/
public static String fixEmpty(String s) {
- if(s==null || s.length()==0) return null;
+ if (s == null || s.length() == 0) {
+ return null;
+ }
return s;
}
@@ -885,24 +915,26 @@ public class Util {
* @since 1.154
*/
public static String fixEmptyAndTrim(String s) {
- if(s==null) return null;
+ if (s == null) {
+ return null;
+ }
return fixEmpty(s.trim());
}
public static <T> List<T> fixNull(List<T> l) {
- return l!=null ? l : Collections.<T>emptyList();
+ return l != null ? l : Collections.<T>emptyList();
}
public static <T> Set<T> fixNull(Set<T> l) {
- return l!=null ? l : Collections.<T>emptySet();
+ return l != null ? l : Collections.<T>emptySet();
}
public static <T> Collection<T> fixNull(Collection<T> l) {
- return l!=null ? l : Collections.<T>emptySet();
+ return l != null ? l : Collections.<T>emptySet();
}
public static <T> Iterable<T> fixNull(Iterable<T> l) {
- return l!=null ? l : Collections.<T>emptySet();
+ return l != null ? l : Collections.<T>emptySet();
}
/**
@@ -910,11 +942,13 @@ public class Util {
*/
public static String getFileName(String filePath) {
int idx = filePath.lastIndexOf('\\');
- if(idx>=0)
- return getFileName(filePath.substring(idx+1));
+ if (idx >= 0) {
+ return getFileName(filePath.substring(idx + 1));
+ }
idx = filePath.lastIndexOf('/');
- if(idx>=0)
- return getFileName(filePath.substring(idx+1));
+ if (idx >= 0) {
+ return getFileName(filePath.substring(idx + 1));
+ }
return filePath;
}
@@ -923,10 +957,13 @@ public class Util {
*/
public static String join(Collection<?> strings, String separator) {
StringBuilder buf = new StringBuilder();
- boolean first=true;
+ boolean first = true;
for (Object s : strings) {
- if(first) first=false;
- else buf.append(separator);
+ if (first) {
+ first = false;
+ } else {
+ buf.append(separator);
+ }
buf.append(s);
}
return buf.toString();
@@ -937,11 +974,13 @@ public class Util {
*/
public static <T> List<T> join(Collection<? extends T>... items) {
int size = 0;
- for (Collection<? extends T> item : items)
+ for (Collection<? extends T> item : items) {
size += item.size();
+ }
List<T> r = new ArrayList<T>(size);
- for (Collection<? extends T> item : items)
+ for (Collection<? extends T> item : items) {
r.addAll(item);
+ }
return r;
}
@@ -969,14 +1008,14 @@ public class Util {
StringTokenizer tokens;
- tokens = new StringTokenizer(includes,",");
- while(tokens.hasMoreTokens()) {
+ tokens = new StringTokenizer(includes, ",");
+ while (tokens.hasMoreTokens()) {
String token = tokens.nextToken().trim();
fs.createInclude().setName(token);
}
- if(excludes!=null) {
- tokens = new StringTokenizer(excludes,",");
- while(tokens.hasMoreTokens()) {
+ if (excludes != null) {
+ tokens = new StringTokenizer(excludes, ",");
+ while (tokens.hasMoreTokens()) {
String token = tokens.nextToken().trim();
fs.createExclude().setName(token);
}
@@ -985,7 +1024,7 @@ public class Util {
}
public static FileSet createFileSet(File baseDir, String includes) {
- return createFileSet(baseDir,includes,null);
+ return createFileSet(baseDir, includes, null);
}
/**
@@ -1000,8 +1039,10 @@ public class Util {
* @param symlinkPath
* Where to create a symlink in.
*/
- public static void createSymlink(File baseDir, String targetPath, String symlinkPath, TaskListener listener) throws InterruptedException{
- if(Functions.isWindows() || NO_SYMLINK) return;
+ public static void createSymlink(File baseDir, String targetPath, String symlinkPath, TaskListener listener) throws InterruptedException {
+ if (Functions.isWindows() || NO_SYMLINK) {
+ return;
+ }
try {
String errmsg = "";
@@ -1009,9 +1050,10 @@ public class Util {
// try simple delete first (whether exists() or not, as it may be symlink pointing
// to non-existent target), but fallback to "rm -rf" to delete non-empty dir.
File symlinkFile = new File(baseDir, symlinkPath);
- if (!symlinkFile.delete() && symlinkFile.exists())
- // ignore a failure.
- new LocalProc(new String[]{"rm","-rf", symlinkPath},new String[0],listener.getLogger(), baseDir).join();
+ if (!symlinkFile.delete() && symlinkFile.exists()) // ignore a failure.
+ {
+ new LocalProc(new String[]{"rm", "-rf", symlinkPath}, new String[0], listener.getLogger(), baseDir).join();
+ }
boolean success = false;
@@ -1030,27 +1072,35 @@ public class Util {
}
} catch (IOException e) {
PrintStream log = listener.getLogger();
- log.printf("ln %s %s failed\n",targetPath, new File(baseDir, symlinkPath));
- Util.displayIOException(e,listener);
- e.printStackTrace( log );
+ log.printf("ln %s %s failed\n", targetPath, new File(baseDir, symlinkPath));
+ Util.displayIOException(e, listener);
+ e.printStackTrace(log);
}
}
-
+
/**
* Run chmod natively if we can, otherwise fall back to Ant.
*/
- public static void chmod(File f, int mask) {
+ public static void chmod(File f, int mask, boolean tryNative) {
if (Functions.isWindows()) {
return; // noop
}
- try {
- NativeUtils.getInstance().chmod(f, mask);
- } catch (NativeAccessException exc) {
- LOGGER.log(Level.WARNING, "Native function chmod failed ({0}). Using Ant''s chmod task instead.", NativeUtils.getInstance().getLastUnixError());
+ if (tryNative) {
+ try {
+ NativeUtils.getInstance().chmod(f, mask);
+ } catch (NativeAccessException exc) {
+ LOGGER.log(Level.WARNING, "Native function chmod failed ({0}). Using Ant''s chmod task instead.", NativeUtils.getInstance().getLastUnixError());
+ _chmodAnt(f, mask);
+ }
+ } else {
_chmodAnt(f, mask);
}
}
+ public static void chmod(File f, int mask) {
+ chmod(f, mask, true);
+ }
+
private static void _chmodAnt(File f, int mask) {
Chmod chmodTask = new Chmod();
chmodTask.setProject(new Project());
@@ -1099,9 +1149,9 @@ public class Util {
@Deprecated
public static String encodeRFC2396(String url) {
try {
- return new URI(null,url,null).toASCIIString();
+ return new URI(null, url, null).toASCIIString();
} catch (URISyntaxException e) {
- LOGGER.warning("Failed to encode "+url); // could this ever happen?
+ LOGGER.warning("Failed to encode " + url); // could this ever happen?
return url;
}
}
@@ -1111,12 +1161,12 @@ public class Util {
* @since 1.173
*/
public static String wrapToErrorSpan(String s) {
- s = "<span class=error><img src='"+
- Stapler.getCurrentRequest().getContextPath()+ Hudson.RESOURCE_PATH+
- "/images/none.gif' height=16 width=1>"+s+"</span>";
+ s = "<span class=error><img src='"
+ + Stapler.getCurrentRequest().getContextPath() + Hudson.RESOURCE_PATH
+ + "/images/none.gif' height=16 width=1>" + s + "</span>";
return s;
}
-
+
/**
* Returns the parsed string if parsed successful; otherwise returns the default number.
* If the string is null, empty or a ParseException is thrown then the defaultNumber
@@ -1144,7 +1194,7 @@ public class Util {
// the rewriteHudsonWar method isn't overridden.
try {
return !base.getMethod(methodName, types).equals(
- derived.getMethod(methodName,types));
+ derived.getMethod(methodName, types));
} catch (NoSuchMethodException e) {
throw new AssertionError(e);
}
@@ -1159,22 +1209,24 @@ public class Util {
public static File changeExtension(File dst, String ext) {
String p = dst.getPath();
int pos = p.lastIndexOf('.');
- if (pos<0) return new File(p+ext);
- else return new File(p.substring(0,pos)+ext);
+ if (pos < 0) {
+ return new File(p + ext);
+ } else {
+ return new File(p.substring(0, pos) + ext);
+ }
}
/**
* Null-safe String intern method.
*/
public static String intern(String s) {
- return s==null ? s : s.intern();
+ return s == null ? s : s.intern();
}
/**
* Loads a key/value pair string as {@link Properties}
* @since 1.392
*/
- @IgnoreJRERequirement
public static Properties loadProperties(String properties) throws IOException {
Properties p = new Properties();
try {
@@ -1187,19 +1239,13 @@ public class Util {
}
return p;
}
-
- public static final FastDateFormat XS_DATETIME_FORMATTER = FastDateFormat.getInstance("yyyy-MM-dd'T'HH:mm:ss'Z'",new SimpleTimeZone(0,"GMT"));
-
+ public static final FastDateFormat XS_DATETIME_FORMATTER = FastDateFormat.getInstance("yyyy-MM-dd'T'HH:mm:ss'Z'", new SimpleTimeZone(0, "GMT"));
// Note: RFC822 dates must not be localized!
- public static final FastDateFormat RFC822_DATETIME_FORMATTER
- = FastDateFormat.getInstance("EEE, dd MMM yyyy HH:mm:ss Z", Locale.US);
-
+ public static final FastDateFormat RFC822_DATETIME_FORMATTER = FastDateFormat.getInstance("EEE, dd MMM yyyy HH:mm:ss Z", Locale.US);
private static final Logger LOGGER = Logger.getLogger(Util.class.getName());
-
/**
* On Unix environment that cannot run "ln", set this to true.
*/
- public static boolean NO_SYMLINK = Boolean.getBoolean(Util.class.getName()+".noSymLink");
-
- public static boolean SYMLINK_ESCAPEHATCH = Boolean.getBoolean(Util.class.getName()+".symlinkEscapeHatch");
+ public static boolean NO_SYMLINK = Boolean.getBoolean(Util.class.getName() + ".noSymLink");
+ public static boolean SYMLINK_ESCAPEHATCH = Boolean.getBoolean(Util.class.getName() + ".symlinkEscapeHatch");
}
diff --git a/hudson-core/src/main/java/hudson/cli/ClientAuthenticationCache.java b/hudson-core/src/main/java/hudson/cli/ClientAuthenticationCache.java
index bcc046bd..8de2291c 100644
--- a/hudson-core/src/main/java/hudson/cli/ClientAuthenticationCache.java
+++ b/hudson-core/src/main/java/hudson/cli/ClientAuthenticationCache.java
@@ -135,7 +135,7 @@ public class ClientAuthenticationCache implements Serializable {
}
// try to protect this file from other users, if we can.
- Util.chmod(f, 0600);
+ Util.chmod(f, 0600, false);
return null;
}
});
diff --git a/hudson-core/src/main/java/hudson/cli/handlers/AbstractProjectOptionHandler.java b/hudson-core/src/main/java/hudson/cli/handlers/AbstractProjectOptionHandler.java
index 642745a5..c4b618cb 100644
--- a/hudson-core/src/main/java/hudson/cli/handlers/AbstractProjectOptionHandler.java
+++ b/hudson-core/src/main/java/hudson/cli/handlers/AbstractProjectOptionHandler.java
@@ -24,14 +24,12 @@ import org.kohsuke.args4j.OptionDef;
import org.kohsuke.args4j.spi.OptionHandler;
import org.kohsuke.args4j.spi.Parameters;
import org.kohsuke.args4j.spi.Setter;
-import org.kohsuke.MetaInfServices;
/**
- * Refer to {@link AbstractProject} by its name.
+ * Refer to {@link AbstractProject} by its name. Registered at META-INF/services.
*
* @author Kohsuke Kawaguchi
*/
-@MetaInfServices
public class AbstractProjectOptionHandler extends OptionHandler<AbstractProject> {
public AbstractProjectOptionHandler(CmdLineParser parser, OptionDef option, Setter<AbstractProject> setter) {
super(parser, option, setter);
diff --git a/hudson-core/src/main/java/hudson/cli/handlers/TopLevelItemOptionHandler.java b/hudson-core/src/main/java/hudson/cli/handlers/TopLevelItemOptionHandler.java
index 608d93ca..4882f892 100644
--- a/hudson-core/src/main/java/hudson/cli/handlers/TopLevelItemOptionHandler.java
+++ b/hudson-core/src/main/java/hudson/cli/handlers/TopLevelItemOptionHandler.java
@@ -17,7 +17,6 @@ package hudson.cli.handlers;
import hudson.model.AbstractProject;
import hudson.model.Hudson;
import hudson.model.TopLevelItem;
-import org.kohsuke.MetaInfServices;
import org.kohsuke.args4j.CmdLineException;
import org.kohsuke.args4j.CmdLineParser;
import org.kohsuke.args4j.OptionDef;
@@ -26,11 +25,10 @@ import org.kohsuke.args4j.spi.Parameters;
import org.kohsuke.args4j.spi.Setter;
/**
- * Refers to {@link TopLevelItem} by its name.
+ * Refers to {@link TopLevelItem} by its name. Registered at META-INF/services.
*
* @author Kohsuke Kawaguchi
*/
-@MetaInfServices
public class TopLevelItemOptionHandler extends OptionHandler<TopLevelItem> {
public TopLevelItemOptionHandler(CmdLineParser parser, OptionDef option, Setter<TopLevelItem> setter) {
super(parser, option, setter);
diff --git a/hudson-core/src/main/java/hudson/console/AnnotatedLargeText.java b/hudson-core/src/main/java/hudson/console/AnnotatedLargeText.java
index d4b80d53..cea577c1 100644
--- a/hudson-core/src/main/java/hudson/console/AnnotatedLargeText.java
+++ b/hudson-core/src/main/java/hudson/console/AnnotatedLargeText.java
@@ -16,7 +16,6 @@
package hudson.console;
-import com.trilead.ssh2.crypto.Base64;
import hudson.model.Hudson;
import hudson.remoting.ObjectInputStreamEx;
import hudson.util.IOException2;
@@ -45,6 +44,7 @@ import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
import static java.lang.Math.abs;
+import org.apache.commons.codec.binary.Base64;
/**
* Extension to {@link LargeText} that handles annotations by {@link ConsoleAnnotator}.
@@ -112,7 +112,7 @@ public class AnnotatedLargeText<T> extends LargeText {
sym.init(Cipher.DECRYPT_MODE, Hudson.getInstance().getSecretKeyAsAES128());
ObjectInputStream ois = new ObjectInputStreamEx(new GZIPInputStream(
- new CipherInputStream(new ByteArrayInputStream(Base64.decode(base64.toCharArray())),sym)),
+ new CipherInputStream(new ByteArrayInputStream(Base64.decodeBase64(base64)),sym)),
Hudson.getInstance().pluginManager.uberClassLoader);
long timestamp = ois.readLong();
if (TimeUnit2.HOURS.toMillis(1) > abs(System.currentTimeMillis()-timestamp))
@@ -156,7 +156,7 @@ public class AnnotatedLargeText<T> extends LargeText {
oos.close();
StaplerResponse rsp = Stapler.getCurrentResponse();
if (rsp!=null)
- rsp.setHeader("X-ConsoleAnnotator", new String(Base64.encode(baos.toByteArray())));
+ rsp.setHeader("X-ConsoleAnnotator", new String(Base64.encodeBase64(baos.toByteArray())));
} catch (GeneralSecurityException e) {
throw new IOException2(e);
}
diff --git a/hudson-core/src/main/java/hudson/diagnosis/HudsonHomeDiskUsageChecker.java b/hudson-core/src/main/java/hudson/diagnosis/HudsonHomeDiskUsageChecker.java
index 1706f9c9..13cf481d 100644
--- a/hudson-core/src/main/java/hudson/diagnosis/HudsonHomeDiskUsageChecker.java
+++ b/hudson-core/src/main/java/hudson/diagnosis/HudsonHomeDiskUsageChecker.java
@@ -19,7 +19,6 @@ package hudson.diagnosis;
import hudson.Extension;
import hudson.model.Hudson;
import hudson.model.PeriodicWork;
-import org.jvnet.animal_sniffer.IgnoreJRERequirement;
import java.util.logging.Logger;
@@ -35,7 +34,6 @@ public class HudsonHomeDiskUsageChecker extends PeriodicWork {
return HOUR;
}
- @IgnoreJRERequirement
protected void doRun() {
try {
long free = Hudson.getInstance().getRootDir().getUsableSpace();
diff --git a/hudson-core/src/main/java/hudson/init/InitReactorListener.java b/hudson-core/src/main/java/hudson/init/InitReactorListener.java
index 04eb7efb..b929bf74 100644
--- a/hudson-core/src/main/java/hudson/init/InitReactorListener.java
+++ b/hudson-core/src/main/java/hudson/init/InitReactorListener.java
@@ -15,7 +15,6 @@
package hudson.init;
import org.jvnet.hudson.reactor.ReactorListener;
-import org.kohsuke.MetaInfServices;
import hudson.model.Hudson;
/**
@@ -27,7 +26,7 @@ import hudson.model.Hudson;
* inside {@code WEB-INF/lib} instead.
*
* <p>
- * To register, put {@link MetaInfServices} on your implementation.
+ * Register your implementation at META-INF/services.
*
* @author Kohsuke Kawaguchi
* @see Hudson#buildReactorListener()
diff --git a/hudson-core/src/main/java/hudson/init/InitStrategy.java b/hudson-core/src/main/java/hudson/init/InitStrategy.java
index b2f65ec7..4f56493e 100644
--- a/hudson-core/src/main/java/hudson/init/InitStrategy.java
+++ b/hudson-core/src/main/java/hudson/init/InitStrategy.java
@@ -14,7 +14,6 @@
package hudson.init;
-import org.kohsuke.MetaInfServices;
import org.jvnet.hudson.reactor.Task;
import java.io.File;
@@ -37,7 +36,7 @@ import hudson.util.Service;
* inside {@code WEB-INF/lib} instead.
*
* <p>
- * To register, put {@link MetaInfServices} on your implementation.
+ * Register your implementation at META-INF/services.
*
* @author Kohsuke Kawaguchi
*/
diff --git a/hudson-core/src/main/java/hudson/lifecycle/WindowsInstallerLink.java b/hudson-core/src/main/java/hudson/lifecycle/WindowsInstallerLink.java
index fcb71209..4f515fe0 100644
--- a/hudson-core/src/main/java/hudson/lifecycle/WindowsInstallerLink.java
+++ b/hudson-core/src/main/java/hudson/lifecycle/WindowsInstallerLink.java
@@ -8,19 +8,18 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
-*
-* Kohsuke Kawaguchi, Seiji Sogabe, CloudBees, Inc.
+ *
+ * Kohsuke Kawaguchi, Seiji Sogabe, CloudBees, Inc.
*
*
- *******************************************************************************/
-
+ *******************************************************************************/
package hudson.lifecycle;
-import hudson.Functions;
import hudson.model.ManagementLink;
import hudson.model.Hudson;
import hudson.AbortException;
import hudson.Extension;
+import hudson.Functions;
import hudson.util.StreamTaskListener;
import hudson.util.jna.NativeAccessException;
import hudson.util.jna.NativeUtils;
@@ -53,7 +52,6 @@ public class WindowsInstallerLink extends ManagementLink {
* In general case, we can't determine this value, yet having this is a requirement for the installer.
*/
private final File hudsonWar;
-
/**
* If the installation is completed, this value holds the installation directory.
*/
@@ -83,20 +81,20 @@ public class WindowsInstallerLink extends ManagementLink {
* Is the installation successful?
*/
public boolean isInstalled() {
- return installationDir!=null;
+ return installationDir != null;
}
/**
* Performs installation.
*/
public void doDoInstall(StaplerRequest req, StaplerResponse rsp, @QueryParameter("dir") String _dir) throws IOException, ServletException {
- if(installationDir!=null) {
+ if (installationDir != null) {
// installation already complete
- sendError("Installation is already complete",req,rsp);
+ sendError("Installation is already complete", req, rsp);
return;
}
-
-
+
+
try {
if (!NativeUtils.getInstance().isDotNetInstalled(2, 0)) {
sendError(".NET Framework 2.0 or later is required for this feature", req, rsp);
@@ -104,14 +102,14 @@ public class WindowsInstallerLink extends ManagementLink {
} catch (NativeAccessException exc) {
sendError("Native function isDotNetInstalled() failed. " + NativeUtils.getInstance().getLastWindowsError(), req, rsp);
}
-
-
+
+
Hudson.getInstance().checkPermission(Hudson.ADMINISTER);
File dir = new File(_dir).getAbsoluteFile();
dir.mkdirs();
- if(!dir.exists()) {
- sendError("Failed to create installation directory: "+dir,req,rsp);
+ if (!dir.exists()) {
+ sendError("Failed to create installation directory: " + dir, req, rsp);
return;
}
@@ -119,8 +117,9 @@ public class WindowsInstallerLink extends ManagementLink {
// copy files over there
copy(req, rsp, dir, getClass().getResource("/windows-service/hudson.exe"), "hudson.exe");
copy(req, rsp, dir, getClass().getResource("/windows-service/hudson.xml"), "hudson.xml");
- if(!hudsonWar.getCanonicalFile().equals(new File(dir,"hudson.war").getCanonicalFile()))
+ if (!hudsonWar.getCanonicalFile().equals(new File(dir, "hudson.war").getCanonicalFile())) {
copy(req, rsp, dir, hudsonWar.toURI().toURL(), "hudson.war");
+ }
// install as a service
ByteArrayOutputStream baos = new ByteArrayOutputStream();
@@ -128,8 +127,8 @@ public class WindowsInstallerLink extends ManagementLink {
task.getLogger().println("Installing a service");
int r = WindowsSlaveInstaller.runElevated(
new File(dir, "hudson.exe"), "install", task, dir);
- if(r!=0) {
- sendError(baos.toString(),req,rsp);
+ if (r != 0) {
+ sendError(baos.toString(), req, rsp);
return;
}
@@ -148,38 +147,42 @@ public class WindowsInstallerLink extends ManagementLink {
*/
private void copy(StaplerRequest req, StaplerResponse rsp, File dir, URL src, String name) throws ServletException, IOException {
try {
- FileUtils.copyURLToFile(src,new File(dir, name));
+ FileUtils.copyURLToFile(src, new File(dir, name));
} catch (IOException e) {
- LOGGER.log(Level.SEVERE, "Failed to copy "+name,e);
- sendError("Failed to copy "+name+": "+e.getMessage(),req,rsp);
+ LOGGER.log(Level.SEVERE, "Failed to copy " + name, e);
+ sendError("Failed to copy " + name + ": " + e.getMessage(), req, rsp);
throw new AbortException();
}
}
public void doRestart(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException {
- if(installationDir==null) {
+ if (installationDir == null) {
// if the user reloads the page after Hudson has restarted,
// it comes back here. In such a case, don't let this restart Hudson.
// so just send them back to the top page
- rsp.sendRedirect(req.getContextPath()+"/");
+ rsp.sendRedirect(req.getContextPath() + "/");
return;
}
Hudson.getInstance().checkPermission(Hudson.ADMINISTER);
- rsp.forward(this,"_restart",req);
+ rsp.forward(this, "_restart", req);
final File oldRoot = Hudson.getInstance().getRootDir();
// initiate an orderly shutdown after we finished serving this request
new Thread("terminator") {
+
+ @Override
public void run() {
try {
Thread.sleep(1000);
// let the service start after we close our sockets, to avoid conflicts
Runtime.getRuntime().addShutdownHook(new Thread("service starter") {
+
+ @Override
public void run() {
try {
- if(!oldRoot.equals(installationDir)) {
+ if (!oldRoot.equals(installationDir)) {
LOGGER.info("Moving data");
Move mv = new Move();
Project p = new Project();
@@ -197,7 +200,7 @@ public class WindowsInstallerLink extends ManagementLink {
StreamTaskListener task = StreamTaskListener.fromStdout();
int r = WindowsSlaveInstaller.runElevated(
new File(installationDir, "hudson.exe"), "start", task, installationDir);
- task.getLogger().println(r==0?"Successfully started":"start service failed. Exit code="+r);
+ task.getLogger().println(r == 0 ? "Successfully started" : "start service failed. Exit code=" + r);
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
@@ -225,13 +228,13 @@ public class WindowsInstallerLink extends ManagementLink {
* Displays the error in a page.
*/
protected final void sendError(Exception e, StaplerRequest req, StaplerResponse rsp) throws ServletException, IOException {
- sendError(e.getMessage(),req,rsp);
+ sendError(e.getMessage(), req, rsp);
}
protected final void sendError(String message, StaplerRequest req, StaplerResponse rsp) throws ServletException, IOException {
- req.setAttribute("message",message);
- req.setAttribute("pre",true);
- rsp.forward(Hudson.getInstance(),"error",req);
+ req.setAttribute("message", message);
+ req.setAttribute("pre", true);
+ rsp.forward(Hudson.getInstance(), "error", req);
}
/**
@@ -242,26 +245,26 @@ public class WindowsInstallerLink extends ManagementLink {
if(!Functions.isWindows())
return null; // this is a Windows only feature
- if(Lifecycle.get() instanceof WindowsServiceLifecycle)
+ if (Lifecycle.get() instanceof WindowsServiceLifecycle) {
return null; // already installed as Windows service
-
+ }
// this system property is set by the launcher when we run "java -jar hudson.war"
// and this is how we know where is hudson.war.
String war = System.getProperty("executable-war");
- if(war!=null && new File(war).exists()) {
+ if (war != null && new File(war).exists()) {
WindowsInstallerLink link = new WindowsInstallerLink(new File(war));
// in certain situations where we know the user is just trying Hudson (like when Hudson is launched
// from JNLP from https://hudson.java.net/), also put this link on the navigation bar to increase
// visibility
- if(System.getProperty(WindowsInstallerLink.class.getName()+".prominent")!=null)
+ if (System.getProperty(WindowsInstallerLink.class.getName() + ".prominent") != null) {
Hudson.getInstance().getActions().add(link);
+ }
return link;
}
return null;
}
-
private static final Logger LOGGER = Logger.getLogger(WindowsInstallerLink.class.getName());
}
diff --git a/hudson-core/src/main/java/hudson/model/AbstractItem.java b/hudson-core/src/main/java/hudson/model/AbstractItem.java
index 0bd56c95..b387afbd 100644
--- a/hudson-core/src/main/java/hudson/model/AbstractItem.java
+++ b/hudson-core/src/main/java/hudson/model/AbstractItem.java
@@ -16,7 +16,6 @@
package hudson.model;
-import com.infradna.tool.bridge_method_injector.WithBridgeMethods;
import hudson.XmlFile;
import hudson.Util;
import hudson.Functions;
@@ -108,10 +107,6 @@ public abstract class AbstractItem extends Actionable implements Item, HttpDelet
return (parent != null ? parent.getRootDirFor(this) : Hudson.getInstance().getRootDir());
}
- /**
- * This bridge method is to maintain binary compatibility with {@link TopLevelItem#getParent()}.
- */
- @WithBridgeMethods(value=Hudson.class,castRequired=true)
public ItemGroup getParent() {
assert parent!=null;
return parent;
@@ -502,8 +497,13 @@ public abstract class AbstractItem extends Actionable implements Item, HttpDelet
public static AbstractItem resolveForCLI(
@Argument(required=true,metaVar="NAME",usage="Job name") String name) throws CmdLineException {
AbstractItem item = Hudson.getInstance().getItemByFullName(name, AbstractItem.class);
- if (item==null)
- throw new CmdLineException(null,Messages.AbstractItem_NoSuchJobExists(name,AbstractProject.findNearest(name).getFullName()));
+ if (item==null){
+ if (AbstractProject.findNearest(name) != null){
+ throw new CmdLineException(null,Messages.AbstractItem_NoSuchJobExists2(name, AbstractProject.findNearest(name).getFullName()));
+ }else{
+ throw new CmdLineException(null,Messages.AbstractItem_NoSuchJobExists(name));
+ }
+ }
return item;
}
}
diff --git a/hudson-core/src/main/java/hudson/model/AbstractProject.java b/hudson-core/src/main/java/hudson/model/AbstractProject.java
index 0ab29bf0..4c19b400 100644
--- a/hudson-core/src/main/java/hudson/model/AbstractProject.java
+++ b/hudson-core/src/main/java/hudson/model/AbstractProject.java
@@ -1,20 +1,22 @@
-/*******************************************************************************
+/**
+ * *****************************************************************************
*
* Copyright (c) 2004-2011 Oracle Corporation.
*
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
- * Contributors:
+ * Contributors:
*
- * Kohsuke Kawaguchi, Brian Westrich, Erik Ramfelt, Ertan Deniz, Jean-Baptiste Quenot, Luca Domenico Milanesio,
- * R. Tyler Ballance, Stephen Connolly, Tom Huybrechts, id:cactusman, Yahoo! Inc., Anton Kozak, Nikita Levyankov
- *
+ * Kohsuke Kawaguchi, Brian Westrich, Erik Ramfelt, Ertan Deniz, Jean-Baptiste
+ * Quenot, Luca Domenico Milanesio, R. Tyler Ballance, Stephen Connolly, Tom
+ * Huybrechts, id:cactusman, Yahoo! Inc., Anton Kozak, Nikita Levyankov
*
- *******************************************************************************/
-
+ *
+ ******************************************************************************
+ */
package hudson.model;
import antlr.ANTLRException;
@@ -117,8 +119,8 @@ import static javax.servlet.http.HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
* @author Kohsuke Kawaguchi
* @see AbstractBuild
*/
-public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends AbstractBuild<P,R>> extends Job<P,R> implements BuildableItem,
- IAbstractProject {
+public abstract class AbstractProject<P extends AbstractProject<P, R>, R extends AbstractBuild<P, R>> extends Job<P, R> implements BuildableItem,
+ IAbstractProject {
public static final String CONCURRENT_BUILD_PROPERTY_NAME = "concurrentBuild";
public static final String CLEAN_WORKSPACE_REQUIRED_PROPERTY_NAME = "cleanWorkspaceRequired";
@@ -137,167 +139,148 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
public static final String AFFINITY_CHO0SER_KEY = "affinityChooser";
public static final String SLAVE_KEY = "slave";
public static final String ASSIGNED_LABEL_KEY = "_.assignedLabelString";
-
/**
- * {@link SCM} associated with the project.
- * To allow derived classes to link {@link SCM} config to elsewhere,
- * access to this variable should always go through {@link #getScm()}.
- * @deprecated as of 2.2.0
- * don't use this field directly, logic was moved to {@link org.eclipse.hudson.api.model.IProjectProperty}.
- * Use getter/setter for accessing to this field.
+ * {@link SCM} associated with the project. To allow derived classes to link {@link SCM}
+ * config to elsewhere, access to this variable should always go through {@link #getScm()}.
+ *
+ * @deprecated as of 2.2.0 don't use this field directly, logic was moved to {@link org.eclipse.hudson.api.model.IProjectProperty}.
+ * Use getter/setter for accessing to this field.
*/
@Deprecated
private volatile SCM scm = new NullSCM();
-
/**
* State returned from {@link SCM#poll(AbstractProject, Launcher, FilePath, TaskListener, SCMRevisionState)}.
*/
private volatile transient SCMRevisionState pollingBaseline = null;
-
/**
* All the builds keyed by their build number.
*/
- protected transient /*almost final*/ RunMap<R> builds = new RunMap<R>();
-
+ protected transient /*
+ * almost final
+ */ RunMap<R> builds = new RunMap<R>();
/**
* The quiet period. Null to delegate to the system default.
- * @deprecated as of 2.2.0
- * don't use this field directly, logic was moved to {@link org.eclipse.hudson.api.model.IProjectProperty}.
- * Use getter/setter for accessing to this field.
+ *
+ * @deprecated as of 2.2.0 don't use this field directly, logic was moved to {@link org.eclipse.hudson.api.model.IProjectProperty}.
+ * Use getter/setter for accessing to this field.
*
*/
@Deprecated
private volatile Integer quietPeriod = null;
-
/**
* The retry count. Null to delegate to the system default.
- * @deprecated as of 2.2.0
- * don't use this field directly, logic was moved to {@link org.eclipse.hudson.api.model.IProjectProperty}.
- * Use getter/setter for accessing to this field.
+ *
+ * @deprecated as of 2.2.0 don't use this field directly, logic was moved to {@link org.eclipse.hudson.api.model.IProjectProperty}.
+ * Use getter/setter for accessing to this field.
*/
@Deprecated
private volatile Integer scmCheckoutRetryCount = null;
-
/**
- * If this project is configured to be only built on a certain label,
- * this value will be set to that label.
+ * If this project is configured to be only built on a certain label, this
+ * value will be set to that label.
*
- * For historical reasons, this is called 'assignedNode'. Also for
- * a historical reason, null to indicate the affinity
- * with the master node.
+ * For historical reasons, this is called 'assignedNode'. Also for a
+ * historical reason, null to indicate the affinity with the master node.
*
* @see #canRoam
*
- * @deprecated as of 2.2.0
- * don't use this field directly, logic was moved to
+ * @deprecated as of 2.2.0 don't use this field directly, logic was moved to
* {@link hudson.model.AbstractProject#getAppointedNode()#getName()}.
*/
@Deprecated
private String assignedNode;
-
/**
* Node list is dropdown or textfield
*
- * @deprecated as of 2.2.0
- * don't use this field directly, logic was moved to
+ * @deprecated as of 2.2.0 don't use this field directly, logic was moved to
* {@link hudson.model.AbstractProject#getAppointedNode()#isAdvancedAffinityChooser()}.
*/
@Deprecated
private Boolean advancedAffinityChooser;
-
/**
* True if this project can be built on any node.
*
- * <p>
- * This somewhat ugly flag combination is so that we can migrate
+ * <p> This somewhat ugly flag combination is so that we can migrate
* existing Hudson installations nicely.
*
- * @deprecated as of 2.2.0
- * don't use this field directly, logic was moved to
+ * @deprecated as of 2.2.0 don't use this field directly, logic was moved to
* {@link hudson.model.AbstractProject#getAppointedNode()#getCanRoam}.
*/
@Deprecated
private volatile boolean canRoam;
-
/**
* True to suspend new builds.
*/
protected volatile boolean disabled;
-
/**
- * True to keep builds of this project in queue when downstream projects are building.
+ * True to keep builds of this project in queue when downstream projects are
+ * building.
*
- * @deprecated as of 2.2.0. Don't use this field directly, logic was moved to {@link org.eclipse.hudson.api.model.IProjectProperty}.
- * Use getter/setter for accessing to this field.
+ * @deprecated as of 2.2.0. Don't use this field directly, logic was moved
+ * to {@link org.eclipse.hudson.api.model.IProjectProperty}. Use
+ * getter/setter for accessing to this field.
*/
@Deprecated
protected volatile boolean blockBuildWhenDownstreamBuilding;
-
/**
- * True to keep builds of this project in queue when upstream projects are building.
+ * True to keep builds of this project in queue when upstream projects are
+ * building.
*
- * @deprecated as of 2.2.0. Don't use this field directly, logic was moved to {@link org.eclipse.hudson.api.model.IProjectProperty}.
- * Use getter/setter for accessing to this field.
+ * @deprecated as of 2.2.0. Don't use this field directly, logic was moved
+ * to {@link org.eclipse.hudson.api.model.IProjectProperty}. Use
+ * getter/setter for accessing to this field.
*/
@Deprecated
protected volatile boolean blockBuildWhenUpstreamBuilding;
-
/**
- * Identifies {@link JDK} to be used.
- * Null if no explicit configuration is required.
+ * Identifies {@link JDK} to be used. Null if no explicit configuration is
+ * required.
*
- * <p>
- * Can't store {@link JDK} directly because {@link Hudson} and {@link Project}
+ * <p> Can't store {@link JDK} directly because {@link Hudson} and {@link Project}
* are saved independently.
*
* @see Hudson#getJDK(String)
- * @deprecated as of 2.2.0
- * don't use this field directly, logic was moved to {@link org.eclipse.hudson.api.model.IProjectProperty}.
- * Use getter/setter for accessing to this field.
+ * @deprecated as of 2.2.0 don't use this field directly, logic was moved to {@link org.eclipse.hudson.api.model.IProjectProperty}.
+ * Use getter/setter for accessing to this field.
*/
@Deprecated
private volatile String jdk;
-
/**
* @deprecated since 2007-01-29.
*/
@Deprecated
private transient boolean enableRemoteTrigger;
-
private volatile BuildAuthorizationToken authToken = null;
-
/**
* List of all {@link Trigger}s for this project.
*
* @deprecated as of 2.2.0
*
- * don't use this field directly, logic was moved to {@link org.eclipse.hudson.api.model.IProjectProperty}.
- * Use getter/setter for accessing to this field.
+ * don't use this field directly, logic was moved to {@link org.eclipse.hudson.api.model.IProjectProperty}.
+ * Use getter/setter for accessing to this field.
*/
protected List<Trigger<?>> triggers = new Vector<Trigger<?>>();
-
/**
* {@link Action}s contributed from subsidiary objects associated with
- * {@link AbstractProject}, such as from triggers, builders, publishers, etc.
+ * {@link AbstractProject}, such as from triggers, builders, publishers,
+ * etc.
*
- * We don't want to persist them separately, and these actions
- * come and go as configuration change, so it's kept separate.
+ * We don't want to persist them separately, and these actions come and go
+ * as configuration change, so it's kept separate.
*/
@CopyOnWrite
protected transient volatile List<Action> transientActions = new Vector<Action>();
-
/**
* @deprecated as of 2.2.0 Don't use this field directly, logic was moved to {@link org.eclipse.hudson.api.model.IProjectProperty}.
- * Use getter/setter for accessing to this field.
+ * Use getter/setter for accessing to this field.
*/
@Deprecated
private boolean concurrentBuild;
-
/**
* True to clean the workspace prior to each build.
*
* @deprecated as of 2.2.0 don't use this field directly, logic was moved to {@link org.eclipse.hudson.api.model.IProjectProperty}.
- * Use getter/setter for accessing to this field.
+ * Use getter/setter for accessing to this field.
*/
@Deprecated
private volatile boolean cleanWorkspaceRequired;
@@ -307,9 +290,9 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
//TODO: Investigate when this case happens.
//if (Hudson.getInstance() != null && !Hudson.getInstance().getNodes().isEmpty()) {
- // if a new job is configured with Hudson that already has slave nodes
- // make it roamable by default
- // canRoam = true;
+ // if a new job is configured with Hudson that already has slave nodes
+ // make it roamable by default
+ // canRoam = true;
//}
}
@@ -320,7 +303,7 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
updateTransientActions();
setCreationTime(new GregorianCalendar().getTimeInMillis());
User user = User.current();
- if (user != null){
+ if (user != null) {
setCreatedBy(user.getId());
grantProjectMatrixPermissions(user);
}
@@ -332,21 +315,25 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
this.builds = new RunMap<R>();
this.builds.load(this, new Constructor<R>() {
+
public R create(File dir) throws IOException {
return loadBuild(dir);
}
});
// boolean! Can't tell if xml file contained false..
- if (enableRemoteTrigger) OldDataMonitor.report(this, "1.77");
+ if (enableRemoteTrigger) {
+ OldDataMonitor.report(this, "1.77");
+ }
for (Trigger t : getTriggerDescribableList()) {
- t.start(this,false);
+ t.start(this, false);
}
- if(scm==null)
+ if (scm == null) {
scm = new NullSCM(); // perhaps it was pointing to a plugin that no longer exists.
-
- if(transientActions==null)
+ }
+ if (transientActions == null) {
transientActions = new Vector<Action>(); // happens when loaded from disk
+ }
updateTransientActions();
getTriggerDescribableList().setOwner(this);
}
@@ -442,23 +429,25 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
// prevent a new build while a delete operation is in progress
makeDisabled(true);
FilePath ws = getWorkspace();
- if(ws!=null) {
+ if (ws != null) {
Node on = getLastBuiltOn();
getScm().processWorkspaceBeforeDeletion(this, ws, on);
- if(on!=null)
- on.getFileSystemProvisioner().discardWorkspace(this,ws);
+ if (on != null) {
+ on.getFileSystemProvisioner().discardWorkspace(this, ws);
+ }
}
super.performDelete();
}
/**
* Does this project perform concurrent builds?
+ *
* @since 1.319
*/
@Exported
public boolean isConcurrentBuild() {
return Hudson.CONCURRENT_BUILD
- && CascadingUtil.getBooleanProjectProperty(this, CONCURRENT_BUILD_PROPERTY_NAME).getValue();
+ && CascadingUtil.getBooleanProjectProperty(this, CONCURRENT_BUILD_PROPERTY_NAME).getValue();
}
public void setConcurrentBuild(boolean b) throws IOException {
@@ -472,19 +461,20 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
public void setCleanWorkspaceRequired(boolean cleanWorkspaceRequired) {
CascadingUtil.getBooleanProjectProperty(this,
- CLEAN_WORKSPACE_REQUIRED_PROPERTY_NAME).setValue(cleanWorkspaceRequired);
+ CLEAN_WORKSPACE_REQUIRED_PROPERTY_NAME).setValue(cleanWorkspaceRequired);
}
/**
- * If this project is configured to be always built on this node,
- * return that {@link Node}. Otherwise null.
+ * If this project is configured to be always built on this node, return
+ * that {@link Node}. Otherwise null.
*/
public Label getAssignedLabel() {
return getAppointedNode() == null ? null : getAppointedNode().getAssignedLabel();
}
/**
- * Gets the textual representation of the assigned label as it was entered by the user.
+ * Gets the textual representation of the assigned label as it was entered
+ * by the user.
*/
public String getAssignedLabelString() {
return getAppointedNode() == null ? null : getAppointedNode().getAssignedLabelString();
@@ -492,13 +482,14 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
/**
* Sets the assigned label.
+ *
* @param label node label.
*
* @throws java.io.IOException exception.
*/
public void setAssignedLabel(Label label) throws IOException {
AppointedNode node = getAppointedNode();
- if(node == null){
+ if (node == null) {
node = new AppointedNode();
setAppointedNode(node);
}
@@ -535,13 +526,14 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
*/
public void setAdvancedAffinityChooser(boolean b) throws IOException {
AppointedNode node = getAppointedNode();
- if(node == null){
+ if (node == null) {
node = new AppointedNode();
setAppointedNode(node);
}
node.setAdvancedAffinityChooser(b);
save();
}
+
/**
* Sets {@link AppointedNode}.
*
@@ -558,7 +550,7 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
* @return appointedNode {@link AppointedNode}.
*/
public AppointedNode getAppointedNode() {
- return (AppointedNode)CascadingUtil.getBaseProjectProperty(this, APPOINTED_NODE_PROPERTY_NAME).getValue();
+ return (AppointedNode) CascadingUtil.getBaseProjectProperty(this, APPOINTED_NODE_PROPERTY_NAME).getValue();
}
/**
@@ -586,17 +578,17 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
/**
* Gets the directory where the module is checked out.
*
- * @return
- * null if the workspace is on a slave that's not connected.
- * @deprecated as of 1.319
- * To support concurrent builds of the same project, this method is moved to {@link AbstractBuild}.
- * For backward compatibility, this method returns the right {@link AbstractBuild#getWorkspace()} if called
- * from {@link Executor}, and otherwise the workspace of the last build.
+ * @return null if the workspace is on a slave that's not connected.
+ * @deprecated as of 1.319 To support concurrent builds of the same project,
+ * this method is moved to {@link AbstractBuild}. For backward
+ * compatibility, this method returns the right {@link AbstractBuild#getWorkspace()}
+ * if called from {@link Executor}, and otherwise the workspace of the last
+ * build.
*
- * <p>
- * If you are calling this method during a build from an executor, switch it to {@link AbstractBuild#getWorkspace()}.
- * If you are calling this method to serve a file from the workspace, doing a form validation, etc., then
- * use {@link #getSomeWorkspace()}
+ * <p> If you are calling this method during a build from an executor,
+ * switch it to {@link AbstractBuild#getWorkspace()}. If you are calling
+ * this method to serve a file from the workspace, doing a form validation,
+ * etc., then use {@link #getSomeWorkspace()}
*/
public final FilePath getWorkspace() {
AbstractBuild b = getBuildForDeprecatedMethods();
@@ -605,41 +597,43 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
}
/**
- * Various deprecated methods in this class all need the 'current' build. This method returns
- * the build suitable for that purpose.
+ * Various deprecated methods in this class all need the 'current' build.
+ * This method returns the build suitable for that purpose.
*
* @return An AbstractBuild for deprecated methods to use.
*/
private AbstractBuild getBuildForDeprecatedMethods() {
Executor e = Executor.currentExecutor();
- if(e!=null) {
+ if (e != null) {
Executable exe = e.getCurrentExecutable();
if (exe instanceof AbstractBuild) {
AbstractBuild b = (AbstractBuild) exe;
- if(b.getProject()==this)
+ if (b.getProject() == this) {
return b;
+ }
}
}
R lb = getLastBuild();
- if(lb!=null) return lb;
+ if (lb != null) {
+ return lb;
+ }
return null;
}
/**
* Gets a workspace for some build of this project.
*
- * <p>
- * This is useful for obtaining a workspace for the purpose of form field validation, where exactly
- * which build the workspace belonged is less important. The implementation makes a cursory effort
- * to find some workspace.
+ * <p> This is useful for obtaining a workspace for the purpose of form
+ * field validation, where exactly which build the workspace belonged is
+ * less important. The implementation makes a cursory effort to find some
+ * workspace.
*
- * @return
- * null if there's no available workspace.
+ * @return null if there's no available workspace.
* @since 1.319
*/
public final FilePath getSomeWorkspace() {
R b = getSomeBuildWithWorkspace();
- return b!=null ? b.getWorkspace() : null;
+ return b != null ? b.getWorkspace() : null;
}
/**
@@ -648,22 +642,22 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
* @return null if no such build exists.
*/
public final R getSomeBuildWithWorkspace() {
- int cnt=0;
- for (R b = getLastBuild(); cnt<5 && b!=null; b=b.getPreviousBuild()) {
+ int cnt = 0;
+ for (R b = getLastBuild(); cnt < 5 && b != null; b = b.getPreviousBuild()) {
FilePath ws = b.getWorkspace();
- if (ws!=null) return b;
+ if (ws != null) {
+ return b;
+ }
}
return null;
}
/**
- * Returns the root directory of the checked-out module.
- * <p>
- * This is usually where <tt>pom.xml</tt>, <tt>build.xml</tt>
- * and so on exists.
+ * Returns the root directory of the checked-out module. <p> This is usually
+ * where <tt>pom.xml</tt>, <tt>build.xml</tt> and so on exists.
*
- * @deprecated as of 1.319
- * See {@link #getWorkspace()} for a migration strategy.
+ * @deprecated as of 1.319 See {@link #getWorkspace()} for a migration
+ * strategy.
*/
public FilePath getModuleRoot() {
AbstractBuild b = getBuildForDeprecatedMethods();
@@ -671,14 +665,14 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
}
/**
- * Returns the root directories of all checked-out modules.
- * <p>
- * Some SCMs support checking out multiple modules into the same workspace.
- * In these cases, the returned array will have a length greater than one.
+ * Returns the root directories of all checked-out modules. <p> Some SCMs
+ * support checking out multiple modules into the same workspace. In these
+ * cases, the returned array will have a length greater than one.
+ *
* @return The roots of all modules checked out from the SCM.
*
- * @deprecated as of 1.319
- * See {@link #getWorkspace()} for a migration strategy.
+ * @deprecated as of 1.319 See {@link #getWorkspace()} for a migration
+ * strategy.
*/
public FilePath[] getModuleRoots() {
AbstractBuild b = getBuildForDeprecatedMethods();
@@ -692,7 +686,8 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
}
/**
- * Sets the custom quiet period of this project, or revert to the global default if null is given.
+ * Sets the custom quiet period of this project, or revert to the global
+ * default if null is given.
*
* @param seconds quiet period
* @throws IOException if any.
@@ -704,7 +699,7 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
public int getScmCheckoutRetryCount() {
IntegerProjectProperty property = CascadingUtil.getIntegerProjectProperty(this,
- SCM_CHECKOUT_RETRY_COUNT_PROPERTY_NAME);
+ SCM_CHECKOUT_RETRY_COUNT_PROPERTY_NAME);
Integer value = property.getValue();
return property.getDefaultValue().equals(value) ? Hudson.getInstance().getScmCheckoutRetryCount() : value;
}
@@ -714,8 +709,8 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
}
/**
- * Sets scmCheckoutRetryCount, Uses {@link NumberUtils#isNumber(String)} for checking retryCount param.
- * If it is not valid number, null will be set.
+ * Sets scmCheckoutRetryCount, Uses {@link NumberUtils#isNumber(String)} for
+ * checking retryCount param. If it is not valid number, null will be set.
*
* @param scmCheckoutRetryCount retry count.
* @throws IOException if any.
@@ -730,8 +725,8 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
/**
* @return true if quiet period was configured.
- * @deprecated as of 2.1.2
- * This method was used only on UI side. No longer required.
+ * @deprecated as of 2.1.2 This method was used only on UI side. No longer
+ * required.
*/
// ugly name because of EL
public boolean getHasCustomQuietPeriod() {
@@ -739,8 +734,8 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
}
/**
- * Sets quietPeriod, Uses {@link NumberUtils#isNumber(String)} for checking seconds param. If seconds is not valid
- * number, null will be set.
+ * Sets quietPeriod, Uses {@link NumberUtils#isNumber(String)} for checking
+ * seconds param. If seconds is not valid number, null will be set.
*
* @param seconds quiet period.
* @throws IOException if any.
@@ -759,7 +754,7 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
* @return true if yes, false - otherwise.
* @deprecated as of 2.1.2
*/
- public boolean hasCustomScmCheckoutRetryCount(){
+ public boolean hasCustomScmCheckoutRetryCount() {
return null != CascadingUtil.getIntegerProjectProperty(this, SCM_CHECKOUT_RETRY_COUNT_PROPERTY_NAME).getValue();
}
@@ -769,8 +764,8 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
}
/**
- * Used in <tt>sidepanel.jelly</tt> to decide whether to display
- * the config/delete/build links.
+ * Used in <tt>sidepanel.jelly</tt> to decide whether to display the
+ * config/delete/build links.
*/
public boolean isConfigurable() {
return true;
@@ -778,7 +773,7 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
public boolean blockBuildWhenDownstreamBuilding() {
return CascadingUtil.getBooleanProjectProperty(this,
- BLOCK_BUILD_WHEN_DOWNSTREAM_BUILDING_PROPERTY_NAME).getValue();
+ BLOCK_BUILD_WHEN_DOWNSTREAM_BUILDING_PROPERTY_NAME).getValue();
}
public void setBlockBuildWhenDownstreamBuilding(boolean b) throws IOException {
@@ -788,7 +783,7 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
public boolean blockBuildWhenUpstreamBuilding() {
return CascadingUtil.getBooleanProjectProperty(this,
- BLOCK_BUILD_WHEN_UPSTREAM_BUILDING_PROPERTY_NAME).getValue();
+ BLOCK_BUILD_WHEN_UPSTREAM_BUILDING_PROPERTY_NAME).getValue();
}
public void setBlockBuildWhenUpstreamBuilding(boolean b) throws IOException {
@@ -803,10 +798,11 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
/**
* Validates the retry count Regex
*/
- public FormValidation doCheckRetryCount(@QueryParameter String value)throws IOException,ServletException{
+ public FormValidation doCheckRetryCount(@QueryParameter String value) throws IOException, ServletException {
// retry count is optional so this is ok
- if(value == null || value.trim().equals(""))
+ if (value == null || value.trim().equals("")) {
return FormValidation.ok();
+ }
if (!value.matches("[0-9]*")) {
return FormValidation.error("Invalid retry count");
}
@@ -817,10 +813,13 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
* Marks the build as disabled.
*/
public void makeDisabled(boolean b) throws IOException {
- if(disabled==b) return; // noop
+ if (disabled == b) {
+ return; // noop
+ }
this.disabled = b;
- if(b)
+ if (b) {
Hudson.getInstance().getQueue().cancel(this);
+ }
save();
}
@@ -834,18 +833,19 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
@Override
public BallColor getIconColor() {
- if(isDisabled())
+ if (isDisabled()) {
return BallColor.DISABLED;
- else
+ } else {
return super.getIconColor();
+ }
}
/**
* effectively deprecated. Since using updateTransientActions correctly
- * under concurrent environment requires a lock that can too easily cause deadlocks.
+ * under concurrent environment requires a lock that can too easily cause
+ * deadlocks.
*
- * <p>
- * Override {@link #createTransientActions()} instead.
+ * <p> Override {@link #createTransientActions()} instead.
*/
protected void updateTransientActions() {
transientActions = createTransientActions();
@@ -854,22 +854,24 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
protected List<Action> createTransientActions() {
Vector<Action> ta = new Vector<Action>();
- for (JobProperty<? super P> p : getAllProperties())
- ta.addAll(p.getJobActions((P)this));
+ for (JobProperty<? super P> p : getAllProperties()) {
+ ta.addAll(p.getJobActions((P) this));
+ }
- for (TransientProjectActionFactory tpaf : TransientProjectActionFactory.all())
+ for (TransientProjectActionFactory tpaf : TransientProjectActionFactory.all()) {
ta.addAll(Util.fixNull(tpaf.createFor(this))); // be defensive against null
+ }
return ta;
}
/**
- * Returns the live list of all {@link Publisher}s configured for this project.
+ * Returns the live list of all {@link Publisher}s configured for this
+ * project.
*
- * <p>
- * This method couldn't be called <tt>getPublishers()</tt> because existing methods
- * in sub-classes return different inconsistent types.
+ * <p> This method couldn't be called <tt>getPublishers()</tt> because
+ * existing methods in sub-classes return different inconsistent types.
*/
- public abstract DescribableList<Publisher,Descriptor<Publisher>> getPublishersList();
+ public abstract DescribableList<Publisher, Descriptor<Publisher>> getPublishersList();
@Override
public void addProperty(JobProperty<? super P> jobProp) throws IOException {
@@ -881,21 +883,22 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
List<Action> a = getActions();
List<ProminentProjectAction> pa = new Vector<ProminentProjectAction>();
for (Action action : a) {
- if(action instanceof ProminentProjectAction)
+ if (action instanceof ProminentProjectAction) {
pa.add((ProminentProjectAction) action);
+ }
}
return pa;
}
@Override
- public void doConfigSubmit( StaplerRequest req, StaplerResponse rsp ) throws IOException, ServletException, FormException {
- super.doConfigSubmit(req,rsp);
+ public void doConfigSubmit(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException, FormException {
+ super.doConfigSubmit(req, rsp);
updateTransientActions();
Set<AbstractProject> upstream = Collections.emptySet();
- if(req.getParameter("pseudoUpstreamTrigger")!=null) {
- upstream = new HashSet<AbstractProject>(Items.fromNameList(req.getParameter("upstreamProjects"),AbstractProject.class));
+ if (req.getParameter("pseudoUpstreamTrigger") != null) {
+ upstream = new HashSet<AbstractProject>(Items.fromNameList(req.getParameter("upstreamProjects"), AbstractProject.class));
}
// dependency setting might have been changed by the user, so rebuild.
@@ -905,23 +908,26 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
// this needs to be done after we release the lock on 'this',
// or otherwise we could dead-lock
- for (AbstractProject<?,?> p : Hudson.getInstance().getAllItems(AbstractProject.class)) {
+ for (AbstractProject<?, ?> p : Hudson.getInstance().getAllItems(AbstractProject.class)) {
// Don't consider child projects such as MatrixConfiguration:
- if (!p.isConfigurable()) continue;
+ if (!p.isConfigurable()) {
+ continue;
+ }
boolean isUpstream = upstream.contains(p);
- synchronized(p) {
+ synchronized (p) {
// does 'p' include us in its BuildTrigger?
- DescribableList<Publisher,Descriptor<Publisher>> pl = p.getPublishersList();
+ DescribableList<Publisher, Descriptor<Publisher>> pl = p.getPublishersList();
BuildTrigger trigger = pl.get(BuildTrigger.class);
- List<AbstractProject> newChildProjects = trigger == null ? new ArrayList<AbstractProject>():trigger.getChildProjects();
- if(isUpstream) {
- if(!newChildProjects.contains(this))
+ List<AbstractProject> newChildProjects = trigger == null ? new ArrayList<AbstractProject>() : trigger.getChildProjects();
+ if (isUpstream) {
+ if (!newChildProjects.contains(this)) {
newChildProjects.add(this);
+ }
} else {
newChildProjects.remove(this);
}
- if(newChildProjects.isEmpty()) {
+ if (newChildProjects.isEmpty()) {
pl.remove(BuildTrigger.class);
} else {
// here, we just need to replace the old one with the new one,
@@ -931,26 +937,28 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
List<BuildTrigger> existingList = pl.getAll(BuildTrigger.class);
BuildTrigger existing;
switch (existingList.size()) {
- case 0:
- existing = null;
- break;
- case 1:
- existing = existingList.get(0);
- break;
- default:
- pl.removeAll(BuildTrigger.class);
- Set<AbstractProject> combinedChildren = new HashSet<AbstractProject>();
- for (BuildTrigger bt : existingList)
- combinedChildren.addAll(bt.getChildProjects());
- existing = new BuildTrigger(new ArrayList<AbstractProject>(combinedChildren),existingList.get(0).getThreshold());
- pl.add(existing);
- break;
+ case 0:
+ existing = null;
+ break;
+ case 1:
+ existing = existingList.get(0);
+ break;
+ default:
+ pl.removeAll(BuildTrigger.class);
+ Set<AbstractProject> combinedChildren = new HashSet<AbstractProject>();
+ for (BuildTrigger bt : existingList) {
+ combinedChildren.addAll(bt.getChildProjects());
+ }
+ existing = new BuildTrigger(new ArrayList<AbstractProject>(combinedChildren), existingList.get(0).getThreshold());
+ pl.add(existing);
+ break;
}
- if(existing!=null && existing.hasSame(newChildProjects))
+ if (existing != null && existing.hasSame(newChildProjects)) {
continue; // no need to touch
+ }
pl.replace(new BuildTrigger(newChildProjects,
- existing==null?Result.SUCCESS:existing.getThreshold()));
+ existing == null ? Result.SUCCESS : existing.getThreshold()));
}
BuildTrigger buildTrigger = pl.get(BuildTrigger.class);
CascadingUtil.getExternalProjectProperty(p, BUILD_TRIGGER_PROPERTY_NAME).setValue(buildTrigger);
@@ -964,29 +972,25 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
Hudson.getInstance().rebuildDependencyGraph();
}
- /**
- * @deprecated
- * Use {@link #scheduleBuild(Cause)}. Since 1.283
- */
+ /**
+ * @deprecated Use {@link #scheduleBuild(Cause)}. Since 1.283
+ */
public boolean scheduleBuild() {
- return scheduleBuild(new LegacyCodeCause());
+ return scheduleBuild(new LegacyCodeCause());
}
- /**
- * @deprecated
- * Use {@link #scheduleBuild(int, Cause)}. Since 1.283
- */
+ /**
+ * @deprecated Use {@link #scheduleBuild(int, Cause)}. Since 1.283
+ */
public boolean scheduleBuild(int quietPeriod) {
- return scheduleBuild(quietPeriod, new LegacyCodeCause());
+ return scheduleBuild(quietPeriod, new LegacyCodeCause());
}
/**
* Schedules a build of this project.
*
- * @return
- * true if the project is actually added to the queue.
- * false if the queue contained it and therefore the add()
- * was noop
+ * @return true if the project is actually added to the queue. false if the
+ * queue contained it and therefore the add() was noop
*/
public boolean scheduleBuild(Cause c) {
return scheduleBuild(getQuietPeriod(), c);
@@ -999,9 +1003,11 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
/**
* Schedules a build.
*
- * Important: the actions should be persistable without outside references (e.g. don't store
- * references to this project). To provide parameters for a parameterized project, add a ParametersAction. If
- * no ParametersAction is provided for such a project, one will be created with the default parameter values.
+ * Important: the actions should be persistable without outside references
+ * (e.g. don't store references to this project). To provide parameters for
+ * a parameterized project, add a ParametersAction. If no ParametersAction
+ * is provided for such a project, one will be created with the default
+ * parameter values.
*
* @param quietPeriod the quiet period to observer
* @param c the cause for this build which should be recorded
@@ -1009,31 +1015,32 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
* @return whether the build was actually scheduled
*/
public boolean scheduleBuild(int quietPeriod, Cause c, Action... actions) {
- return scheduleBuild2(quietPeriod,c,actions)!=null;
+ return scheduleBuild2(quietPeriod, c, actions) != null;
}
/**
- * Schedules a build of this project, and returns a {@link Future} object
- * to wait for the completion of the build.
+ * Schedules a build of this project, and returns a {@link Future} object to
+ * wait for the completion of the build.
*
- * @param actions
- * For the convenience of the caller, this array can contain null, and those will be silently ignored.
+ * @param actions For the convenience of the caller, this array can contain
+ * null, and those will be silently ignored.
*/
public Future<R> scheduleBuild2(int quietPeriod, Cause c, Action... actions) {
- return scheduleBuild2(quietPeriod,c,Arrays.asList(actions));
+ return scheduleBuild2(quietPeriod, c, Arrays.asList(actions));
}
/**
- * Schedules a build of this project, and returns a {@link Future} object
- * to wait for the completion of the build.
+ * Schedules a build of this project, and returns a {@link Future} object to
+ * wait for the completion of the build.
*
- * @param actions
- * For the convenience of the caller, this collection can contain null, and those will be silently ignored.
+ * @param actions For the convenience of the caller, this collection can
+ * contain null, and those will be silently ignored.
* @since 1.383
*/
public Future<R> scheduleBuild2(int quietPeriod, Cause c, Collection<? extends Action> actions) {
- if (!isBuildable())
+ if (!isBuildable()) {
return null;
+ }
List<Action> queueActions = new ArrayList<Action>(actions);
if (isParameterized() && Util.filter(queueActions, ParametersAction.class).isEmpty()) {
@@ -1045,8 +1052,9 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
}
WaitingItem i = Hudson.getInstance().getQueue().schedule(this, quietPeriod, queueActions);
- if(i!=null)
- return (Future)i.getFuture();
+ if (i != null) {
+ return (Future) i.getFuture();
+ }
return null;
}
@@ -1055,38 +1063,41 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
ArrayList<ParameterValue> defValues = new ArrayList<ParameterValue>();
/*
- * This check is made ONLY if someone will call this method even if isParametrized() is false.
+ * This check is made ONLY if someone will call this method even if
+ * isParametrized() is false.
*/
- if(paramDefProp == null)
+ if (paramDefProp == null) {
return defValues;
+ }
- /* Scan for all parameter with an associated default values */
- for(ParameterDefinition paramDefinition : paramDefProp.getParameterDefinitions())
- {
- ParameterValue defaultValue = paramDefinition.getDefaultParameterValue();
+ /*
+ * Scan for all parameter with an associated default values
+ */
+ for (ParameterDefinition paramDefinition : paramDefProp.getParameterDefinitions()) {
+ ParameterValue defaultValue = paramDefinition.getDefaultParameterValue();
- if(defaultValue != null)
+ if (defaultValue != null) {
defValues.add(defaultValue);
+ }
}
return defValues;
}
/**
- * Schedules a build, and returns a {@link Future} object
- * to wait for the completion of the build.
+ * Schedules a build, and returns a {@link Future} object to wait for the
+ * completion of the build.
*
- * <p>
- * Production code shouldn't be using this, but for tests this is very convenient, so this isn't marked
- * as deprecated.
+ * <p> Production code shouldn't be using this, but for tests this is very
+ * convenient, so this isn't marked as deprecated.
*/
public Future<R> scheduleBuild2(int quietPeriod) {
return scheduleBuild2(quietPeriod, new LegacyCodeCause());
}
/**
- * Schedules a build of this project, and returns a {@link Future} object
- * to wait for the completion of the build.
+ * Schedules a build of this project, and returns a {@link Future} object to
+ * wait for the completion of the build.
*/
public Future<R> scheduleBuild2(int quietPeriod, Cause c) {
return scheduleBuild2(quietPeriod, c, new Action[0]);
@@ -1096,9 +1107,13 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
* Schedules a polling of this project.
*/
public boolean schedulePolling() {
- if(isDisabled()) return false;
+ if (isDisabled()) {
+ return false;
+ }
SCMTrigger scmt = getTrigger(SCMTrigger.class);
- if(scmt==null) return false;
+ if (scmt == null) {
+ return false;
+ }
scmt.run();
return true;
}
@@ -1160,7 +1175,6 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
* Determines Class&lt;R>.
*/
protected abstract Class<R> getBuildClass();
-
// keep track of the previous time we started a build
private transient long lastBuildStartTime;
@@ -1168,16 +1182,16 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
* Creates a new build of this project for immediate execution.
*/
protected synchronized R newBuild() throws IOException {
- // make sure we don't start two builds in the same second
- // so the build directories will be different too
- long timeSinceLast = System.currentTimeMillis() - lastBuildStartTime;
- if (timeSinceLast < 1000) {
- try {
- Thread.sleep(1000 - timeSinceLast);
- } catch (InterruptedException e) {
- }
- }
- lastBuildStartTime = System.currentTimeMillis();
+ // make sure we don't start two builds in the same second
+ // so the build directories will be different too
+ long timeSinceLast = System.currentTimeMillis() - lastBuildStartTime;
+ if (timeSinceLast < 1000) {
+ try {
+ Thread.sleep(1000 - timeSinceLast);
+ } catch (InterruptedException e) {
+ }
+ }
+ lastBuildStartTime = System.currentTimeMillis();
try {
R lastBuild = getBuildClass().getConstructor(getClass()).newInstance(this);
builds.put(lastBuild);
@@ -1195,9 +1209,15 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
private IOException handleInvocationTargetException(InvocationTargetException e) {
Throwable t = e.getTargetException();
- if(t instanceof Error) throw (Error)t;
- if(t instanceof RuntimeException) throw (RuntimeException)t;
- if(t instanceof IOException) return (IOException)t;
+ if (t instanceof Error) {
+ throw (Error) t;
+ }
+ if (t instanceof RuntimeException) {
+ throw (RuntimeException) t;
+ }
+ if (t instanceof IOException) {
+ return (IOException) t;
+ }
throw new Error(t);
}
@@ -1206,7 +1226,7 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
*/
protected R loadBuild(File dir) throws IOException {
try {
- return getBuildClass().getConstructor(getClass(),File.class).newInstance(this,dir);
+ return getBuildClass().getConstructor(getClass(), File.class).newInstance(this, dir);
} catch (InstantiationException e) {
throw new Error(e);
} catch (IllegalAccessException e) {
@@ -1221,10 +1241,9 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
/**
* {@inheritDoc}
*
- * <p>
- * Note that this method returns a read-only view of {@link Action}s.
- * {@link BuildStep}s and others who want to add a project action
- * should do so by implementing {@link BuildStep#getProjectActions(AbstractProject)}.
+ * <p> Note that this method returns a read-only view of {@link Action}s.
+ * {@link BuildStep}s and others who want to add a project action should do
+ * so by implementing {@link BuildStep#getProjectActions(AbstractProject)}.
*
* @see TransientProjectActionFactory
*/
@@ -1240,17 +1259,17 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
/**
* Gets the {@link Node} where this project was last built on.
*
- * @return
- * null if no information is available (for example,
- * if no build was done yet.)
+ * @return null if no information is available (for example, if no build was
+ * done yet.)
*/
public Node getLastBuiltOn() {
// where was it built on?
AbstractBuild b = getLastBuild();
- if(b==null)
+ if (b == null) {
return null;
- else
+ } else {
return b.getBuiltOn();
+ }
}
public Object getSameNodeConstraint() {
@@ -1264,25 +1283,25 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
/**
* {@inheritDoc}
*
- * <p>
- * A project must be blocked if its own previous build is in progress,
+ * <p> A project must be blocked if its own previous build is in progress,
* or if the blockBuildWhenUpstreamBuilding option is true and an upstream
* project is building, but derived classes can also check other conditions.
*/
public boolean isBuildBlocked() {
- return getCauseOfBlockage()!=null;
+ return getCauseOfBlockage() != null;
}
public String getWhyBlocked() {
CauseOfBlockage cb = getCauseOfBlockage();
- return cb!=null ? cb.getShortDescription() : null;
+ return cb != null ? cb.getShortDescription() : null;
}
/**
* Blocked because the previous build is already in progress.
*/
public static class BecauseOfBuildInProgress extends CauseOfBlockage {
- private final AbstractBuild<?,?> build;
+
+ private final AbstractBuild<?, ?> build;
public BecauseOfBuildInProgress(AbstractBuild<?, ?> build) {
this.build = build;
@@ -1292,25 +1311,28 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
public String getShortDescription() {
Executor e = build.getExecutor();
String eta = "";
- if (e != null)
+ if (e != null) {
eta = Messages.AbstractProject_ETA(e.getEstimatedRemainingTime());
+ }
int lbn = build.getNumber();
return Messages.AbstractProject_BuildInProgress(lbn, eta);
}
}
/**
- * Because the downstream build is in progress, and we are configured to wait for that.
+ * Because the downstream build is in progress, and we are configured to
+ * wait for that.
*/
public static class BecauseOfDownstreamBuildInProgress extends CauseOfBlockage {
//TODO: review and check whether we can do it private
- public final AbstractProject<?,?> up;
+
+ public final AbstractProject<?, ?> up;
public AbstractProject getUp() {
return up;
}
- public BecauseOfDownstreamBuildInProgress(AbstractProject<?,?> up) {
+ public BecauseOfDownstreamBuildInProgress(AbstractProject<?, ?> up) {
this.up = up;
}
@@ -1321,13 +1343,15 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
}
/**
- * Because the upstream build is in progress, and we are configured to wait for that.
+ * Because the upstream build is in progress, and we are configured to wait
+ * for that.
*/
public static class BecauseOfUpstreamBuildInProgress extends CauseOfBlockage {
//TODO: review and check whether we can do it private
- public final AbstractProject<?,?> up;
- public BecauseOfUpstreamBuildInProgress(AbstractProject<?,?> up) {
+ public final AbstractProject<?, ?> up;
+
+ public BecauseOfUpstreamBuildInProgress(AbstractProject<?, ?> up) {
this.up = up;
}
@@ -1342,57 +1366,60 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
}
public CauseOfBlockage getCauseOfBlockage() {
- if (isBuilding() && !isConcurrentBuild())
+ if (isBuilding() && !isConcurrentBuild()) {
return new BecauseOfBuildInProgress(getLastBuild());
+ }
if (blockBuildWhenDownstreamBuilding()) {
- AbstractProject<?,?> bup = getBuildingDownstream();
- if (bup!=null)
+ AbstractProject<?, ?> bup = getBuildingDownstream();
+ if (bup != null) {
return new BecauseOfDownstreamBuildInProgress(bup);
+ }
}
if (blockBuildWhenUpstreamBuilding()) {
- AbstractProject<?,?> bup = getBuildingUpstream();
- if (bup!=null)
+ AbstractProject<?, ?> bup = getBuildingUpstream();
+ if (bup != null) {
return new BecauseOfUpstreamBuildInProgress(bup);
+ }
}
return null;
}
/**
- * Returns the project if any of the downstream project (or itself) is either
- * building or is in the unblocked queue.
- * <p>
- * This means eventually there will be an automatic triggering of
- * the given project (provided that all builds went smoothly.)
+ * Returns the project if any of the downstream project (or itself) is
+ * either building or is in the unblocked queue. <p> This means eventually
+ * there will be an automatic triggering of the given project (provided that
+ * all builds went smoothly.)
*/
protected AbstractProject getBuildingDownstream() {
- DependencyGraph graph = Hudson.getInstance().getDependencyGraph();
+ DependencyGraph graph = Hudson.getInstance().getDependencyGraph();
Set<AbstractProject> tups = graph.getTransitiveDownstream(this);
tups.add(this);
for (AbstractProject tup : tups) {
- if(tup!=this && (tup.isBuilding() || tup.isInUnblockedQueue()))
+ if (tup != this && (tup.isBuilding() || tup.isInUnblockedQueue())) {
return tup;
+ }
}
return null;
}
/**
* Returns the project if any of the upstream project (or itself) is either
- * building or is in the unblocked queue.
- * <p>
- * This means eventually there will be an automatic triggering of
- * the given project (provided that all builds went smoothly.)
+ * building or is in the unblocked queue. <p> This means eventually there
+ * will be an automatic triggering of the given project (provided that all
+ * builds went smoothly.)
*/
protected AbstractProject getBuildingUpstream() {
- DependencyGraph graph = Hudson.getInstance().getDependencyGraph();
+ DependencyGraph graph = Hudson.getInstance().getDependencyGraph();
Set<AbstractProject> tups = graph.getTransitiveUpstream(this);
tups.add(this);
for (AbstractProject tup : tups) {
- if(tup!=this && (tup.isBuilding() || tup.isInUnblockedQueue()))
+ if (tup != this && (tup.isBuilding() || tup.isInUnblockedQueue())) {
return tup;
+ }
}
return null;
}
-
+
private boolean isInUnblockedQueue() {
return Hudson.getInstance().getQueue().getUnblockedQueuedTasks().contains(this);
}
@@ -1400,15 +1427,19 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
public List<SubTask> getSubTasks() {
List<SubTask> r = new ArrayList<SubTask>();
r.add(this);
- for (SubTaskContributor euc : SubTaskContributor.all())
+ for (SubTaskContributor euc : SubTaskContributor.all()) {
r.addAll(euc.forProject(this));
- for (JobProperty<? super P> p : getAllProperties())
+ }
+ for (JobProperty<? super P> p : getAllProperties()) {
r.addAll(p.getSubTasks());
+ }
return r;
}
public R createExecutable() throws IOException {
- if(isDisabled()) return null;
+ if (isDisabled()) {
+ return null;
+ }
return newBuild();
}
@@ -1424,17 +1455,19 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
* Gets the {@link Resource} that represents the workspace of this project.
* Useful for locking and mutual exclusion control.
*
- * @deprecated as of 1.319
- * Projects no longer have a fixed workspace, ands builds will find an available workspace via
- * {@link WorkspaceList} for each build (furthermore, that happens after a build is started.)
- * So a {@link Resource} representation for a workspace at the project level no longer makes sense.
+ * @deprecated as of 1.319 Projects no longer have a fixed workspace, ands
+ * builds will find an available workspace via
+ * {@link WorkspaceList} for each build (furthermore, that happens after a
+ * build is started.) So a {@link Resource} representation for a workspace
+ * at the project level no longer makes sense.
*
- * <p>
- * If you need to lock a workspace while you do some computation, see the source code of
- * {@link #pollSCMChanges(TaskListener)} for how to obtain a lock of a workspace through {@link WorkspaceList}.
+ * <p> If you need to lock a workspace while you do some computation, see
+ * the source code of
+ * {@link #pollSCMChanges(TaskListener)} for how to obtain a lock of a
+ * workspace through {@link WorkspaceList}.
*/
public Resource getWorkspaceResource() {
- return new Resource(getFullDisplayName()+" workspace");
+ return new Resource(getFullDisplayName() + " workspace");
}
/**
@@ -1453,8 +1486,11 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
}
/**
- * Set of child resource activities of the build of this project (override in child projects).
- * @return The set of child resource activities of the build of this project.
+ * Set of child resource activities of the build of this project (override
+ * in child projects).
+ *
+ * @return The set of child resource activities of the build of this
+ * project.
*/
protected Set<ResourceActivity> getResourceActivities() {
return Collections.emptySet();
@@ -1462,9 +1498,9 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
public boolean checkout(AbstractBuild build, Launcher launcher, BuildListener listener, File changelogFile) throws IOException, InterruptedException {
SCM scm = getScm();
- if(scm==null)
+ if (scm == null) {
return true; // no SCM
-
+ }
FilePath workspace = build.getWorkspace();
workspace.mkdirs();
@@ -1478,20 +1514,22 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
*/
private void calcPollingBaseline(AbstractBuild build, Launcher launcher, TaskListener listener) throws IOException, InterruptedException {
SCMRevisionState baseline = build.getAction(SCMRevisionState.class);
- if (baseline==null) {
+ if (baseline == null) {
try {
baseline = getScm()._calcRevisionsFromBuild(build, launcher, listener);
} catch (AbstractMethodError e) {
baseline = SCMRevisionState.NONE; // pre-1.345 SCM implementations, which doesn't use the baseline in polling
}
- if (baseline!=null)
+ if (baseline != null) {
build.addAction(baseline);
+ }
}
pollingBaseline = baseline;
}
/**
- * For reasons I don't understand, if I inline this method, AbstractMethodError escapes try/catch block.
+ * For reasons I don't understand, if I inline this method,
+ * AbstractMethodError escapes try/catch block.
*/
private SCMRevisionState safeCalcRevisionsFromBuild(AbstractBuild build, Launcher launcher, TaskListener listener) throws IOException, InterruptedException {
return getScm()._calcRevisionsFromBuild(build, launcher, listener);
@@ -1500,25 +1538,23 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
/**
* Checks if there's any update in SCM, and returns true if any is found.
*
- * @deprecated as of 1.346
- * Use {@link #poll(TaskListener)} instead.
+ * @deprecated as of 1.346 Use {@link #poll(TaskListener)} instead.
*/
- public boolean pollSCMChanges( TaskListener listener ) {
+ public boolean pollSCMChanges(TaskListener listener) {
return poll(listener).hasChanges();
}
/**
* Checks if there's any update in SCM, and returns true if any is found.
*
- * <p>
- * The implementation is responsible for ensuring mutual exclusion between polling and builds
- * if necessary.
+ * <p> The implementation is responsible for ensuring mutual exclusion
+ * between polling and builds if necessary.
*
* @since 1.345
*/
- public PollingResult poll( TaskListener listener ) {
+ public PollingResult poll(TaskListener listener) {
SCM scm = getScm();
- if (scm==null) {
+ if (scm == null) {
listener.getLogger().println(Messages.AbstractProject_NoSCM());
return NO_CHANGES;
}
@@ -1528,20 +1564,22 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
}
R lb = getLastBuild();
- if (lb==null) {
+ if (lb == null) {
listener.getLogger().println(Messages.AbstractProject_NoBuilds());
return isInQueue() ? NO_CHANGES : BUILD_NOW;
}
- if (pollingBaseline==null) {
+ if (pollingBaseline == null) {
R success = getLastSuccessfulBuild(); // if we have a persisted baseline, we'll find it by this
- for (R r=lb; r!=null; r=r.getPreviousBuild()) {
+ for (R r = lb; r != null; r = r.getPreviousBuild()) {
SCMRevisionState s = r.getAction(SCMRevisionState.class);
- if (s!=null) {
+ if (s != null) {
pollingBaseline = s;
break;
}
- if (r==success) break; // searched far enough
+ if (r == success) {
+ break; // searched far enough
+ }
}
// NOTE-NO-BASELINE:
// if we don't have baseline yet, it means the data is built by old Hudson that doesn't set the baseline
@@ -1551,9 +1589,9 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
try {
if (scm.requiresWorkspaceForPolling()) {
// lock the workspace of the last build
- FilePath ws=lb.getWorkspace();
+ FilePath ws = lb.getWorkspace();
- if (ws==null || !ws.exists()) {
+ if (ws == null || !ws.exists()) {
// workspace offline. build now, or nothing will ever be built
Label label = getAssignedLabel();
if (label != null && label.isSelfLabel()) {
@@ -1562,9 +1600,9 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
listener.getLogger().println(Messages.AbstractProject_NoWorkspace());
return NO_CHANGES;
}
- listener.getLogger().println( ws==null
- ? Messages.AbstractProject_WorkspaceOffline()
- : Messages.AbstractProject_NoWorkspace());
+ listener.getLogger().println(ws == null
+ ? Messages.AbstractProject_WorkspaceOffline()
+ : Messages.AbstractProject_NoWorkspace());
if (isInQueue()) {
listener.getLogger().println(Messages.AbstractProject_AwaitingBuildForWorkspace());
return NO_CHANGES;
@@ -1589,8 +1627,10 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
Launcher launcher = ws.createLauncher(listener);
try {
LOGGER.fine("Polling SCM changes of " + getName());
- if (pollingBaseline==null) // see NOTE-NO-BASELINE above
- calcPollingBaseline(lb,launcher,listener);
+ if (pollingBaseline == null) // see NOTE-NO-BASELINE above
+ {
+ calcPollingBaseline(lb, launcher, listener);
+ }
PollingResult r = scm.poll(this, launcher, ws, listener, pollingBaseline);
pollingBaseline = r.remote;
return r;
@@ -1602,8 +1642,10 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
// polling without workspace
LOGGER.fine("Polling SCM changes of " + getName());
- if (pollingBaseline==null) // see NOTE-NO-BASELINE above
- calcPollingBaseline(lb,null,listener);
+ if (pollingBaseline == null) // see NOTE-NO-BASELINE above
+ {
+ calcPollingBaseline(lb, null, listener);
+ }
PollingResult r = scm.poll(this, null, null, listener, pollingBaseline);
pollingBaseline = r.remote;
return r;
@@ -1611,7 +1653,7 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
} catch (AbortException e) {
listener.getLogger().println(e.getMessage());
listener.fatalError(Messages.AbstractProject_Aborted());
- LOGGER.log(Level.FINE, "Polling "+this+" aborted",e);
+ LOGGER.log(Level.FINE, "Polling " + this + " aborted", e);
return NO_CHANGES;
} catch (IOException e) {
e.printStackTrace(listener.fatalError(e.getMessage()));
@@ -1628,9 +1670,11 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
* @since 1.191
*/
public boolean hasParticipant(User user) {
- for( R build = getLastBuild(); build!=null; build=build.getPreviousBuild())
- if(build.hasParticipant(user))
+ for (R build = getLastBuild(); build != null; build = build.getPreviousBuild()) {
+ if (build.hasParticipant(user)) {
return true;
+ }
+ }
return false;
}
@@ -1662,10 +1706,9 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
updateTransientActions();
}
- protected final synchronized <T extends Describable<T>>
- void addToList( T item, List<T> collection ) throws IOException {
- for( int i=0; i<collection.size(); i++ ) {
- if(collection.get(i).getDescriptor()==item.getDescriptor()) {
+ protected final synchronized <T extends Describable<T>> void addToList(T item, List<T> collection) throws IOException {
+ for (int i = 0; i < collection.size(); i++) {
+ if (collection.get(i).getDescriptor() == item.getDescriptor()) {
// replace
collection.set(i, item);
save();
@@ -1678,10 +1721,9 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
updateTransientActions();
}
- protected final synchronized <T extends Describable<T>>
- void removeFromList(Descriptor<T> item, List<T> collection) throws IOException {
- for( int i=0; i< collection.size(); i++ ) {
- if(collection.get(i).getDescriptor()==item) {
+ protected final synchronized <T extends Describable<T>> void removeFromList(Descriptor<T> item, List<T> collection) throws IOException {
+ for (int i = 0; i < collection.size(); i++) {
+ if (collection.get(i).getDescriptor() == item) {
// found it
collection.remove(i);
save();
@@ -1691,8 +1733,8 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
}
}
- public synchronized Map<TriggerDescriptor,Trigger> getTriggers() {
- return (Map)Descriptor.toMap(getTriggerDescribableList());
+ public synchronized Map<TriggerDescriptor, Trigger> getTriggers() {
+ return (Map) Descriptor.toMap(getTriggerDescribableList());
}
/**
@@ -1710,12 +1752,14 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
}
/**
- * Gets the specific trigger, or null if the propert is not configured for this job.
+ * Gets the specific trigger, or null if the propert is not configured for
+ * this job.
*/
public <T extends Trigger> T getTrigger(Class<T> clazz) {
for (Trigger p : getTriggersList()) {
- if(clazz.isInstance(p))
+ if (clazz.isInstance(p)) {
return clazz.cast(p);
+ }
}
return null;
}
@@ -1737,8 +1781,8 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
public abstract boolean isFingerprintConfigured();
/**
- * Gets the other {@link AbstractProject}s that should be built
- * when a build of this project is completed.
+ * Gets the other {@link AbstractProject}s that should be built when a build
+ * of this project is completed.
*/
@Exported
public final List<AbstractProject> getDownstreamProjects() {
@@ -1751,18 +1795,21 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
}
/**
- * Returns only those upstream projects that defines {@link BuildTrigger} to this project.
- * This is a subset of {@link #getUpstreamProjects()}
+ * Returns only those upstream projects that defines {@link BuildTrigger} to
+ * this project. This is a subset of {@link #getUpstreamProjects()}
*
- * @return A List of upstream projects that has a {@link BuildTrigger} to this project.
+ * @return A List of upstream projects that has a {@link BuildTrigger} to
+ * this project.
*/
public final List<AbstractProject> getBuildTriggerUpstreamProjects() {
ArrayList<AbstractProject> result = new ArrayList<AbstractProject>();
- for (AbstractProject<?,?> ap : getUpstreamProjects()) {
+ for (AbstractProject<?, ?> ap : getUpstreamProjects()) {
BuildTrigger buildTrigger = ap.getPublishersList().get(BuildTrigger.class);
- if (buildTrigger != null)
- if (buildTrigger.getChildProjects().contains(this))
+ if (buildTrigger != null) {
+ if (buildTrigger.getChildProjects().contains(this)) {
result.add(ap);
+ }
+ }
}
return result;
}
@@ -1777,7 +1824,8 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
}
/**
- * Gets all the downstream projects including transitive downstream projects.
+ * Gets all the downstream projects including transitive downstream
+ * projects.
*
* @since 1.138
*/
@@ -1789,12 +1837,11 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
* Gets the dependency relationship map between this project (as the source)
* and that project (as the sink.)
*
- * @return
- * can be empty but not null. build number of this project to the build
- * numbers of that project.
+ * @return can be empty but not null. build number of this project to the
+ * build numbers of that project.
*/
public SortedMap<Integer, RangeSet> getRelationship(AbstractProject that) {
- TreeMap<Integer,RangeSet> r = new TreeMap<Integer,RangeSet>(REVERSE_INTEGER_COMPARATOR);
+ TreeMap<Integer, RangeSet> r = new TreeMap<Integer, RangeSet>(REVERSE_INTEGER_COMPARATOR);
checkAndRecord(that, r, this.getBuilds());
// checkAndRecord(that, r, that.getBuilds());
@@ -1805,26 +1852,30 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
/**
* Helper method for getDownstreamRelationship.
*
- * For each given build, find the build number range of the given project and put that into the map.
+ * For each given build, find the build number range of the given project
+ * and put that into the map.
*/
private void checkAndRecord(AbstractProject that, TreeMap<Integer, RangeSet> r, Collection<R> builds) {
for (R build : builds) {
RangeSet rs = build.getDownstreamRelationship(that);
- if(rs==null || rs.isEmpty())
+ if (rs == null || rs.isEmpty()) {
continue;
+ }
int n = build.getNumber();
RangeSet value = r.get(n);
- if(value==null)
- r.put(n,rs);
- else
+ if (value == null) {
+ r.put(n, rs);
+ } else {
value.add(rs);
+ }
}
}
/**
* Builds the dependency graph.
+ *
* @see DependencyGraph
*/
protected abstract void buildDependencyGraph(DependencyGraph graph);
@@ -1832,14 +1883,15 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
@Override
protected SearchIndexBuilder makeSearchIndex() {
SearchIndexBuilder sib = super.makeSearchIndex();
- if(isBuildable() && hasPermission(Hudson.ADMINISTER))
- sib.add("build","build");
+ if (isBuildable() && hasPermission(Hudson.ADMINISTER)) {
+ sib.add("build", "build");
+ }
return sib;
}
@Override
protected HistoryWidget createHistoryWidget() {
- return new BuildHistoryWidget<R>(this,getBuilds(),HISTORY_ADAPTER);
+ return new BuildHistoryWidget<R>(this, getBuilds(), HISTORY_ADAPTER);
}
public boolean isParameterized() {
@@ -1854,18 +1906,19 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
/**
* Schedules a new build command.
*/
- public void doBuild( StaplerRequest req, StaplerResponse rsp ) throws IOException, ServletException {
+ public void doBuild(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException {
BuildAuthorizationToken.checkPermission(this, authToken, req, rsp);
// if a build is parameterized, let that take over
ParametersDefinitionProperty pp = getProperty(ParametersDefinitionProperty.class);
if (pp != null) {
- pp._doBuild(req,rsp);
+ pp._doBuild(req, rsp);
return;
}
- if (!isBuildable())
- throw HttpResponses.error(SC_INTERNAL_SERVER_ERROR,new IOException(getFullName()+" is not buildable"));
+ if (!isBuildable()) {
+ throw HttpResponses.error(SC_INTERNAL_SERVER_ERROR, new IOException(getFullName() + " is not buildable"));
+ }
Hudson.getInstance().getQueue().schedule(this, getDelay(req), getBuildCause(req));
rsp.forwardToPreviousPage(req);
@@ -1874,7 +1927,9 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
/**
* Computes the build cause, using RemoteCause or UserCause as appropriate.
*/
- /*package*/ CauseAction getBuildCause(StaplerRequest req) {
+ /*
+ * package
+ */ CauseAction getBuildCause(StaplerRequest req) {
Cause cause;
if (authToken != null && authToken.getToken() != null && req.getParameter("token") != null) {
// Optional additional cause text when starting via token
@@ -1887,34 +1942,41 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
}
/**
- * Computes the delay by taking the default value and the override in the request parameter into the account.
+ * Computes the delay by taking the default value and the override in the
+ * request parameter into the account.
*/
public int getDelay(StaplerRequest req) throws ServletException {
String delay = req.getParameter("delay");
- if (delay==null) return getQuietPeriod();
+ if (delay == null) {
+ return getQuietPeriod();
+ }
try {
// TODO: more unit handling
- if(delay.endsWith("sec")) delay=delay.substring(0,delay.length()-3);
- if(delay.endsWith("secs")) delay=delay.substring(0,delay.length()-4);
+ if (delay.endsWith("sec")) {
+ delay = delay.substring(0, delay.length() - 3);
+ }
+ if (delay.endsWith("secs")) {
+ delay = delay.substring(0, delay.length() - 4);
+ }
return Integer.parseInt(delay);
} catch (NumberFormatException e) {
- throw new ServletException("Invalid delay parameter value: "+delay);
+ throw new ServletException("Invalid delay parameter value: " + delay);
}
}
/**
- * Supports build trigger with parameters via an HTTP GET or POST.
- * Currently only String parameters are supported.
+ * Supports build trigger with parameters via an HTTP GET or POST. Currently
+ * only String parameters are supported.
*/
public void doBuildWithParameters(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException {
BuildAuthorizationToken.checkPermission(this, authToken, req, rsp);
ParametersDefinitionProperty pp = getProperty(ParametersDefinitionProperty.class);
if (pp != null) {
- pp.buildWithParameters(req,rsp);
+ pp.buildWithParameters(req, rsp);
} else {
- throw new IllegalStateException("This build is not parameterized!");
+ throw new IllegalStateException("This build is not parameterized!");
}
}
@@ -1922,7 +1984,7 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
/**
* Schedules a new SCM polling command.
*/
- public void doPolling( StaplerRequest req, StaplerResponse rsp ) throws IOException, ServletException {
+ public void doPolling(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException {
BuildAuthorizationToken.checkPermission(this, authToken, req, rsp);
schedulePolling();
rsp.forwardToPreviousPage(req);
@@ -1931,7 +1993,7 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
/**
* Cancels a scheduled build.
*/
- public void doCancelQueue( StaplerRequest req, StaplerResponse rsp ) throws IOException, ServletException {
+ public void doCancelQueue(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException {
checkPermission(BUILD);
Hudson.getInstance().getQueue().cancel(this);
@@ -1940,14 +2002,14 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
@Override
protected void submit(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException, FormException {
- super.submit(req,rsp);
+ super.submit(req, rsp);
makeDisabled(null != req.getParameter("disable"));
setJDK(req.getParameter("jdk"));
setQuietPeriod(null != req.getParameter(HAS_QUIET_PERIOD_PROPERTY_NAME)
- ? req.getParameter("quiet_period") : null);
+ ? req.getParameter("quiet_period") : null);
setScmCheckoutRetryCount(null != req.getParameter(HAS_SCM_CHECKOUT_RETRY_COUNT_PROPERTY_NAME)
- ? req.getParameter("scmCheckoutRetryCount") : null);
+ ? req.getParameter("scmCheckoutRetryCount") : null);
setBlockBuildWhenDownstreamBuilding(null != req.getParameter("blockBuildWhenDownstreamBuilding"));
setBlockBuildWhenUpstreamBuilding(null != req.getParameter("blockBuildWhenUpstreamBuilding"));
@@ -1955,10 +2017,10 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
// New logic for handling whether this choice came from the dropdown or textfield.
if (BASIC_KEY.equals(req.getParameter(AFFINITY_CHO0SER_KEY))) {
setAppointedNode(
- new AppointedNode(Util.fixEmptyAndTrim(req.getParameter(SLAVE_KEY)), false));
+ new AppointedNode(Util.fixEmptyAndTrim(req.getParameter(SLAVE_KEY)), false));
} else {
setAppointedNode(
- new AppointedNode(Util.fixEmptyAndTrim(req.getParameter(ASSIGNED_LABEL_KEY)), true));
+ new AppointedNode(Util.fixEmptyAndTrim(req.getParameter(ASSIGNED_LABEL_KEY)), true));
}
} else {
@@ -1971,22 +2033,21 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
authToken = BuildAuthorizationToken.create(req);
- setScm(SCMS.parseSCM(req,this));
+ setScm(SCMS.parseSCM(req, this));
buildTriggers(req, req.getSubmittedForm(), Trigger.for_(this));
}
-
/**
- * @deprecated
- * As of 1.261. Use {@link #buildDescribable(StaplerRequest, List)} instead.
+ * @deprecated As of 1.261. Use {@link #buildDescribable(StaplerRequest, List)}
+ * instead.
*/
protected final <T extends Describable<T>> List<T> buildDescribable(StaplerRequest req, List<? extends Descriptor<T>> descriptors, String prefix) throws FormException, ServletException {
- return buildDescribable(req,descriptors);
+ return buildDescribable(req, descriptors);
}
protected final <T extends Describable<T>> List<T> buildDescribable(StaplerRequest req, List<? extends Descriptor<T>> descriptors)
- throws FormException, ServletException {
+ throws FormException, ServletException {
JSONObject data = req.getSubmittedForm();
List<T> r = new Vector<T>();
@@ -2001,7 +2062,7 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
}
protected void buildTriggers(StaplerRequest req, JSONObject json, List<TriggerDescriptor> descriptors)
- throws FormException {
+ throws FormException {
for (TriggerDescriptor d : descriptors) {
String propertyName = d.getJsonSafeClassName();
CascadingUtil.setChildrenTrigger(this, d, propertyName, req, json);
@@ -2011,16 +2072,16 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
/**
* Serves the workspace files.
*/
- public DirectoryBrowserSupport doWs( StaplerRequest req, StaplerResponse rsp ) throws IOException, ServletException, InterruptedException {
+ public DirectoryBrowserSupport doWs(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException, InterruptedException {
checkPermission(AbstractProject.WORKSPACE);
FilePath ws = getSomeWorkspace();
if ((ws == null) || (!ws.exists())) {
// if there's no workspace, report a nice error message
rsp.setStatus(HttpServletResponse.SC_NOT_FOUND);
- req.getView(this,"noWorkspace.jelly").forward(req,rsp);
+ req.getView(this, "noWorkspace.jelly").forward(req, rsp);
return null;
} else {
- return new DirectoryBrowserSupport(this, ws, getDisplayName()+" workspace", "folder.png", true);
+ return new DirectoryBrowserSupport(this, ws, getDisplayName() + " workspace", "folder.png", true);
}
}
@@ -2033,31 +2094,36 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
if (cleanWorkspace()) {
return new HttpRedirect(".");
} else {
- return new ForwardToView(this,"wipeOutWorkspaceBlocked.jelly");
+ return new ForwardToView(this, "wipeOutWorkspaceBlocked.jelly");
}
- } catch (IOException e) {
- ForwardToView resp = new ForwardToView(this, "error.jelly");
- resp.with("message", Messages._AbstractProject_UnableWipeOut());
- resp.with("pre", false);
- resp.with("exception", e);
+ } catch (final IOException e) {
+ ForwardToView resp = new ForwardToView(this, "error.jelly") {
+ @Override
+ public void generateResponse(StaplerRequest req, StaplerResponse rsp, Object node) throws IOException, ServletException {
+ req.setAttribute("message", Messages._AbstractProject_UnableWipeOut());
+ req.setAttribute("pre", false);
+ req.setAttribute("exception", e);
+ super.generateResponse(req, rsp, node);
+ }
+ };
return resp;
}
}
- public boolean cleanWorkspace() throws IOException, InterruptedException{
+ public boolean cleanWorkspace() throws IOException, InterruptedException {
checkPermission(BUILD);
R b = getSomeBuildWithWorkspace();
FilePath ws = b != null ? b.getWorkspace() : null;
if (ws != null && getScm().processWorkspaceBeforeDeletion(this, ws, b.getBuiltOn())) {
ws.deleteRecursive();
return true;
- } else{
+ } else {
// If we get here, that means the SCM blocked the workspace deletion.
return false;
}
}
- @CLIMethod(name="disable-job")
+ @CLIMethod(name = "disable-job")
public HttpResponse doDisable() throws IOException, ServletException {
requirePOST();
checkPermission(CONFIGURE);
@@ -2065,7 +2131,7 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
return new HttpRedirect(".");
}
- @CLIMethod(name="enable-job")
+ @CLIMethod(name = "enable-job")
public HttpResponse doEnable() throws IOException, ServletException {
requirePOST();
checkPermission(CONFIGURE);
@@ -2076,8 +2142,9 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
/**
* RSS feed for changes in this project.
*/
- public void doRssChangelog( StaplerRequest req, StaplerResponse rsp ) throws IOException, ServletException {
+ public void doRssChangelog(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException {
class FeedItem {
+
ChangeLogSet.Entry e;
int idx;
@@ -2086,74 +2153,78 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
this.idx = idx;
}
- AbstractBuild<?,?> getBuild() {
+ AbstractBuild<?, ?> getBuild() {
return e.getParent().build;
}
}
List<FeedItem> entries = new ArrayList<FeedItem>();
- for(R r=getLastBuild(); r!=null; r=r.getPreviousBuild()) {
- int idx=0;
- for( ChangeLogSet.Entry e : r.getChangeSet())
- entries.add(new FeedItem(e,idx++));
+ for (R r = getLastBuild(); r != null; r = r.getPreviousBuild()) {
+ int idx = 0;
+ for (ChangeLogSet.Entry e : r.getChangeSet()) {
+ entries.add(new FeedItem(e, idx++));
+ }
}
RSS.forwardToRss(
- getDisplayName()+' '+getScm().getDescriptor().getDisplayName()+" changes",
- getUrl()+"changes",
- entries, new FeedAdapter<FeedItem>() {
- public String getEntryTitle(FeedItem item) {
- return "#"+item.getBuild().number+' '+item.e.getMsg()+" ("+item.e.getAuthor()+")";
- }
+ getDisplayName() + ' ' + getScm().getDescriptor().getDisplayName() + " changes",
+ getUrl() + "changes",
+ entries, new FeedAdapter<FeedItem>() {
- public String getEntryUrl(FeedItem item) {
- return item.getBuild().getUrl()+"changes#detail"+item.idx;
- }
+ public String getEntryTitle(FeedItem item) {
+ return "#" + item.getBuild().number + ' ' + item.e.getMsg() + " (" + item.e.getAuthor() + ")";
+ }
- public String getEntryID(FeedItem item) {
- return getEntryUrl(item);
- }
+ public String getEntryUrl(FeedItem item) {
+ return item.getBuild().getUrl() + "changes#detail" + item.idx;
+ }
- public String getEntryDescription(FeedItem item) {
- StringBuilder buf = new StringBuilder();
- for(String path : item.e.getAffectedPaths())
- buf.append(path).append('\n');
- return buf.toString();
- }
+ public String getEntryID(FeedItem item) {
+ return getEntryUrl(item);
+ }
- public Calendar getEntryTimestamp(FeedItem item) {
- return item.getBuild().getTimestamp();
+ public String getEntryDescription(FeedItem item) {
+ StringBuilder buf = new StringBuilder();
+ for (String path : item.e.getAffectedPaths()) {
+ buf.append(path).append('\n');
}
+ return buf.toString();
+ }
- public String getEntryAuthor(FeedItem entry) {
- return Mailer.descriptor().getAdminAddress();
- }
- },
- req, rsp );
+ public Calendar getEntryTimestamp(FeedItem item) {
+ return item.getBuild().getTimestamp();
+ }
+
+ public String getEntryAuthor(FeedItem entry) {
+ return Mailer.descriptor().getAdminAddress();
+ }
+ },
+ req, rsp);
}
/**
- * {@link AbstractProject} subtypes should implement this base class as a descriptor.
+ * {@link AbstractProject} subtypes should implement this base class as a
+ * descriptor.
*
* @since 1.294
*/
public static abstract class AbstractProjectDescriptor extends TopLevelItemDescriptor {
+
/**
- * {@link AbstractProject} subtypes can override this method to veto some {@link Descriptor}s
- * from showing up on their configuration screen. This is often useful when you are building
- * a workflow/company specific project type, where you want to limit the number of choices
+ * {@link AbstractProject} subtypes can override this method to veto
+ * some {@link Descriptor}s from showing up on their configuration
+ * screen. This is often useful when you are building a workflow/company
+ * specific project type, where you want to limit the number of choices
* given to the users.
*
- * <p>
- * Some {@link Descriptor}s define their own schemes for controlling applicability
- * (such as {@link BuildStepDescriptor#isApplicable(Class)}),
- * This method works like AND in conjunction with them;
- * Both this method and that method need to return true in order for a given {@link Descriptor}
+ * <p> Some {@link Descriptor}s define their own schemes for controlling
+ * applicability (such as {@link BuildStepDescriptor#isApplicable(Class)}),
+ * This method works like AND in conjunction with them; Both this method
+ * and that method need to return true in order for a given {@link Descriptor}
* to show up for the given {@link Project}.
*
- * <p>
- * The default implementation returns true for everything.
+ * <p> The default implementation returns true for everything.
*
* @see BuildStepDescriptor#isApplicable(Class)
* @see BuildWrapperDescriptor#isApplicable(AbstractProject)
@@ -2165,8 +2236,9 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
}
public FormValidation doCheckAssignedLabelString(@QueryParameter String value) {
- if (Util.fixEmpty(value)==null)
+ if (Util.fixEmpty(value) == null) {
return FormValidation.ok(); // nothing typed yet
+ }
try {
Label.parseExpression(value);
} catch (ANTLRException e) {
@@ -2174,12 +2246,13 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
Messages.AbstractProject_AssignedLabelString_InvalidBooleanExpression(e.getMessage()));
}
// TODO: if there's an atom in the expression that is empty, report it
- if (Hudson.getInstance().getLabel(value).isEmpty())
+ if (Hudson.getInstance().getLabel(value).isEmpty()) {
return FormValidation.warning(Messages.AbstractProject_AssignedLabelString_NoMatch());
+ }
return FormValidation.ok();
}
- public AutoCompletionCandidates doAutoCompleteAssignedLabelString(@QueryParameter String value) {
+ public AutoCompletionCandidates doAutoCompleteAssignedLabelString(@QueryParameter String value) {
AutoCompletionCandidates c = new AutoCompletionCandidates();
Set<Label> labels = Hudson.getInstance().getLabels();
List<String> queries = new AutoCompleteSeeder(value).getSeeds();
@@ -2196,26 +2269,26 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
}
/**
- * Finds a {@link AbstractProject} that has the name closest to the given name.
+ * Finds a {@link AbstractProject} that has the name closest to the given
+ * name.
*/
public static AbstractProject findNearest(String name) {
List<AbstractProject> projects = Hudson.getInstance().getItems(AbstractProject.class);
String[] names = new String[projects.size()];
- for( int i=0; i<projects.size(); i++ )
+ for (int i = 0; i < projects.size(); i++) {
names[i] = projects.get(i).getName();
+ }
String nearest = EditDistance.findNearest(name, names);
- return (AbstractProject)Hudson.getInstance().getItem(nearest);
+ return (AbstractProject) Hudson.getInstance().getItem(nearest);
}
-
private static final Comparator<Integer> REVERSE_INTEGER_COMPARATOR = new Comparator<Integer>() {
+
public int compare(Integer o1, Integer o2) {
- return o2-o1;
+ return o2 - o1;
}
};
-
private static final Logger LOGGER = Logger.getLogger(AbstractProject.class.getName());
-
/**
* Permission to abort a build. For now, let's make it the same as {@link #BUILD}
*/
@@ -2226,10 +2299,15 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
*/
@CLIResolver
public static AbstractProject resolveForCLI(
- @Argument(required=true,metaVar="NAME",usage="Job name") String name) throws CmdLineException {
+ @Argument(required = true, metaVar = "NAME", usage = "Job name") String name) throws CmdLineException {
AbstractProject item = Hudson.getInstance().getItemByFullName(name, AbstractProject.class);
- if (item==null)
- throw new CmdLineException(null,Messages.AbstractItem_NoSuchJobExists(name,AbstractProject.findNearest(name).getFullName()));
+ if (item == null) {
+ if (AbstractProject.findNearest(name) != null) {
+ throw new CmdLineException(null, Messages.AbstractItem_NoSuchJobExists2(name, AbstractProject.findNearest(name).getFullName()));
+ } else {
+ throw new CmdLineException(null, Messages.AbstractItem_NoSuchJobExists(name));
+ }
+ }
return item;
}
}
diff --git a/hudson-core/src/main/java/hudson/model/ExternalRun.java b/hudson-core/src/main/java/hudson/model/ExternalRun.java
index 5a7de94f..975a8890 100644
--- a/hudson-core/src/main/java/hudson/model/ExternalRun.java
+++ b/hudson-core/src/main/java/hudson/model/ExternalRun.java
@@ -19,7 +19,6 @@ package hudson.model;
import hudson.Proc;
import hudson.util.DecodingStream;
import hudson.util.DualOutputStream;
-import org.jvnet.animal_sniffer.IgnoreJRERequirement;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
@@ -87,7 +86,6 @@ public class ExternalRun extends Run<ExternalJob,ExternalRun> {
* </xmp></pre>
*/
@SuppressWarnings({"Since15"})
- @IgnoreJRERequirement
public void acceptRemoteSubmission(final Reader in) throws IOException {
final long[] duration = new long[1];
run(new Runner() {
diff --git a/hudson-core/src/main/java/hudson/model/Job.java b/hudson-core/src/main/java/hudson/model/Job.java
index a3282f91..f0cbba2c 100644
--- a/hudson-core/src/main/java/hudson/model/Job.java
+++ b/hudson-core/src/main/java/hudson/model/Job.java
@@ -28,7 +28,6 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import org.apache.commons.lang3.StringUtils;
import com.google.common.collect.Sets;
-import com.infradna.tool.bridge_method_injector.WithBridgeMethods;
import hudson.Extension;
import hudson.ExtensionPoint;
import hudson.PermalinkList;
@@ -944,7 +943,6 @@ public abstract class Job<JobT extends Job<JobT, RunT>, RunT extends Run<JobT, R
* @return never null. The first entry is the latest build.
*/
@Exported
- @WithBridgeMethods(List.class)
public RunList<RunT> getBuilds() {
return RunList.fromRuns(_getRuns().values());
}
@@ -1002,7 +1000,6 @@ public abstract class Job<JobT extends Job<JobT, RunT>, RunT extends Run<JobT, R
* @deprecated
* as of 1.372. Should just do {@code getBuilds().byTimestamp(s,e)} to avoid code bloat in {@link Job}.
*/
- @WithBridgeMethods(List.class)
public RunList<RunT> getBuildsByTimestamp(long start, long end) {
return getBuilds().byTimestamp(start, end);
}
diff --git a/hudson-core/src/main/java/hudson/model/Node.java b/hudson-core/src/main/java/hudson/model/Node.java
index 65aa12ad..a3745425 100644
--- a/hudson-core/src/main/java/hudson/model/Node.java
+++ b/hudson-core/src/main/java/hudson/model/Node.java
@@ -16,7 +16,6 @@
package hudson.model;
-import com.infradna.tool.bridge_method_injector.WithBridgeMethods;
import hudson.Extension;
import hudson.ExtensionPoint;
import hudson.FilePath;
@@ -256,7 +255,6 @@ public abstract class Node extends AbstractModelObject implements Describable<No
/**
* Gets the special label that represents this node itself.
*/
- @WithBridgeMethods(Label.class)
public LabelAtom getSelfLabel() {
return LabelAtom.get(getNodeName());
}
diff --git a/hudson-core/src/main/java/hudson/model/UpdateSite.java b/hudson-core/src/main/java/hudson/model/UpdateSite.java
index 73e6847a..1fc3bdbd 100644
--- a/hudson-core/src/main/java/hudson/model/UpdateSite.java
+++ b/hudson-core/src/main/java/hudson/model/UpdateSite.java
@@ -24,14 +24,14 @@ import hudson.util.IOUtils;
import hudson.util.JSONCanonicalUtils;
import hudson.util.TextFile;
import hudson.util.VersionNumber;
+import hudson.util.CertificateUtil;
+import hudson.util.SignatureOutputStream;
import static hudson.util.TimeUnit2.DAYS;
import net.sf.json.JSONObject;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.StaplerResponse;
-import org.jvnet.hudson.crypto.CertificateUtil;
-import org.jvnet.hudson.crypto.SignatureOutputStream;
import org.apache.commons.io.output.NullOutputStream;
import org.apache.commons.io.output.TeeOutputStream;
@@ -57,9 +57,8 @@ import java.security.cert.X509Certificate;
import java.security.cert.CertificateFactory;
import java.security.cert.TrustAnchor;
-import com.trilead.ssh2.crypto.Base64;
-
import javax.servlet.ServletContext;
+import org.apache.commons.codec.binary.Base64;
/**
@@ -160,7 +159,7 @@ public class UpdateSite {
{// load and verify certificates
CertificateFactory cf = CertificateFactory.getInstance("X509");
for (Object cert : o.getJSONArray("certificates")) {
- X509Certificate c = (X509Certificate) cf.generateCertificate(new ByteArrayInputStream(Base64.decode(cert.toString().toCharArray())));
+ X509Certificate c = (X509Certificate) cf.generateCertificate(new ByteArrayInputStream(Base64.decodeBase64(cert.toString())));
c.checkValidity();
certs.add(c);
}
@@ -188,14 +187,14 @@ public class UpdateSite {
// did the digest match? this is not a part of the signature validation, but if we have a bug in the c14n
// (which is more likely than someone tampering with update center), we can tell
- String computedDigest = new String(Base64.encode(sha1.digest()));
+ String computedDigest = new String(Base64.encodeBase64(sha1.digest()));
String providedDigest = signature.getString("digest");
if (!computedDigest.equalsIgnoreCase(providedDigest)) {
LOGGER.severe("Digest mismatch: "+computedDigest+" vs "+providedDigest);
return false;
}
- if (!sig.verify(Base64.decode(signature.getString("signature").toCharArray()))) {
+ if (!sig.verify(Base64.decodeBase64(signature.getString("signature")))) {
LOGGER.severe("Signature in the update center doesn't match with the certificate");
return false;
}
diff --git a/hudson-core/src/main/java/hudson/model/UsageStatistics.java b/hudson-core/src/main/java/hudson/model/UsageStatistics.java
index 0fae9b00..3d87163b 100644
--- a/hudson-core/src/main/java/hudson/model/UsageStatistics.java
+++ b/hudson-core/src/main/java/hudson/model/UsageStatistics.java
@@ -16,7 +16,6 @@
package hudson.model;
-import com.trilead.ssh2.crypto.Base64;
import hudson.PluginWrapper;
import hudson.Util;
import hudson.Extension;
@@ -46,6 +45,7 @@ import java.security.spec.X509EncodedKeySpec;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.GZIPOutputStream;
+import org.apache.commons.codec.binary.Base64;
/**
* @author Kohsuke Kawaguchi
@@ -172,7 +172,7 @@ public class UsageStatistics extends PageDecorator {
o.write(w);
w.close();
- return new String(Base64.encode(baos.toByteArray()));
+ return new String(Base64.encodeBase64(baos.toByteArray()));
} catch (GeneralSecurityException e) {
throw new Error(e); // impossible
}
diff --git a/hudson-core/src/main/java/hudson/model/User.java b/hudson-core/src/main/java/hudson/model/User.java
index 170da20d..eebb17ef 100644
--- a/hudson-core/src/main/java/hudson/model/User.java
+++ b/hudson-core/src/main/java/hudson/model/User.java
@@ -16,7 +16,6 @@
package hudson.model;
-import com.infradna.tool.bridge_method_injector.WithBridgeMethods;
import com.thoughtworks.xstream.XStream;
import hudson.CopyOnWrite;
import hudson.FeedAdapter;
@@ -353,7 +352,6 @@ public class User extends AbstractModelObject implements AccessControlled, Savea
*
* TODO: do we need some index for this?
*/
- @WithBridgeMethods(List.class)
public RunList getBuilds() {
List<AbstractBuild> r = new ArrayList<AbstractBuild>();
for (AbstractProject<?,?> p : Hudson.getInstance().getAllItems(AbstractProject.class))
diff --git a/hudson-core/src/main/java/hudson/node_monitors/DiskSpaceMonitorDescriptor.java b/hudson-core/src/main/java/hudson/node_monitors/DiskSpaceMonitorDescriptor.java
index f408fe95..0a661229 100644
--- a/hudson-core/src/main/java/hudson/node_monitors/DiskSpaceMonitorDescriptor.java
+++ b/hudson-core/src/main/java/hudson/node_monitors/DiskSpaceMonitorDescriptor.java
@@ -22,7 +22,6 @@ import hudson.remoting.VirtualChannel;
import hudson.Util;
import hudson.slaves.OfflineCause;
import hudson.node_monitors.DiskSpaceMonitorDescriptor.DiskSpace;
-import org.jvnet.animal_sniffer.IgnoreJRERequirement;
import java.io.File;
import java.io.IOException;
@@ -134,7 +133,6 @@ import org.kohsuke.stapler.export.Exported;
protected abstract DiskSpace getFreeSpace(Computer c) throws IOException, InterruptedException;
protected static final class GetUsableSpace implements FileCallable<DiskSpace> {
- @IgnoreJRERequirement
public DiskSpace invoke(File f, VirtualChannel channel) throws IOException {
try {
long s = f.getUsableSpace();
diff --git a/hudson-core/src/main/java/hudson/node_monitors/TemporarySpaceMonitor.java b/hudson-core/src/main/java/hudson/node_monitors/TemporarySpaceMonitor.java
index 14e70ffb..2f337118 100644
--- a/hudson-core/src/main/java/hudson/node_monitors/TemporarySpaceMonitor.java
+++ b/hudson-core/src/main/java/hudson/node_monitors/TemporarySpaceMonitor.java
@@ -24,7 +24,6 @@ import hudson.model.Computer;
import hudson.model.Hudson;
import hudson.node_monitors.DiskSpaceMonitorDescriptor.DiskSpace;
import hudson.remoting.VirtualChannel;
-import org.jvnet.animal_sniffer.IgnoreJRERequirement;
import org.kohsuke.stapler.DataBoundConstructor;
import java.io.File;
@@ -74,7 +73,6 @@ public class TemporarySpaceMonitor extends AbstractDiskSpaceMonitor {
}
protected static final class GetTempSpace implements FileCallable<DiskSpace> {
- @IgnoreJRERequirement
public DiskSpace invoke(File f, VirtualChannel channel) throws IOException {
try {
// if the disk is really filled up we can't even create a single file,
diff --git a/hudson-core/src/main/java/hudson/os/EmbeddedSu.java b/hudson-core/src/main/java/hudson/os/EmbeddedSu.java
new file mode 100644
index 00000000..c0a39247
--- /dev/null
+++ b/hudson-core/src/main/java/hudson/os/EmbeddedSu.java
@@ -0,0 +1,180 @@
+/*******************************************************************************
+ *
+ * Copyright (c) 2004-2009 Oracle Corporation.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *
+ * Kohsuke Kawaguchi
+ *
+ *******************************************************************************/
+
+package hudson.os;
+
+import java.io.ByteArrayOutputStream;
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintWriter;
+import java.util.Arrays;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.logging.Logger;
+
+/**
+ * Encapsulates the process launch through <tt>su</tt> (embedded_su(1M) to be exact)
+ *
+ * @author Kohsuke Kawaguchi
+ */
+public class EmbeddedSu {
+ /**
+ * Not meant to be instantiated.
+ */
+ private EmbeddedSu() {
+ }
+
+ /**
+ * Launches a process as configured by {@link ProcessBuilder}, but under
+ * a separate user priviledge by using <tt>su</tt> functionality.
+ *
+ * @param user
+ * The user name in which the new process runs.
+ * @param pwd
+ * The password of the user.
+ */
+ public static Process startWithSu(String user, String pwd, ProcessBuilder pb) throws IOException {
+ if (user==null || pwd==null)
+ throw new IllegalArgumentException();
+
+ // su only invokes a shell, so the argument has to be packed into the -c option
+ StringBuilder buf = new StringBuilder("exec ");
+ for( String cmd : pb.command() ) {
+ buf.append(' ');
+ // to prevent shell from interfering with characters like '$' and '`',
+ // put everything in single-quotes. When we do this, single-quotes in
+ // arguments have to be escaped.
+ buf.append('\'').append(cmd.replaceAll("\'","'\''")).append('\'');
+ }
+
+ List<String> cmds = pb.command();
+ cmds.clear();
+ cmds.addAll(Arrays.asList("/usr/lib/embedded_su",user,"-c",buf.toString()));
+
+ // now the command line massage is ready. start a process
+ Process proc = pb.start();
+
+ PrintWriter out = new PrintWriter(proc.getOutputStream(),true);
+ InputStream in = proc.getInputStream();
+ // send initialization block
+ LOGGER.fine("Initiating embedded_su conversation");
+ out.println(".");
+
+ /*
+ embedded_su often sends us PAM_ERROR_MSG that's useful, so capture them.
+ alice@opensolaris:~$ /usr/lib/embedded_su root
+ .
+ CONV 1
+ PAM_PROMPT_ECHO_OFF
+ Password:
+ .
+ root
+ CONV 1
+ PAM_ERROR_MSG
+ Roles can only be assumed by authorized users
+ .
+ ERROR
+ embedded_su: Sorry
+ .
+ */
+ List<String> errorMessages = new ArrayList<String>();
+
+ while(true) {
+ String line = readLine(in);
+ if(line.startsWith("CONV")) {
+ // how many blocks do we expect?
+ int n = Integer.parseInt(line.substring(5));
+ for( int i=0; i<n; i++) {
+ String header = readLine(in);
+ String textBlock = readTextBlock(in);
+ LOGGER.fine("Got "+header+" : "+textBlock);
+ if(header.startsWith("PAM_PROMPT_ECHO_OFF")) {
+ // this is where we want to send the password
+ // if we are asked the password for the 2nd time, it's rather unlikely that
+ // the same value is expected --- instead, its' probably a retry.
+ out.println(pwd);
+ pwd = null;
+ }
+ if(header.startsWith("PAM_PROMPT_ECHO_ON")) {
+ // embedded_su expects some value but this is probably not where we want to send the password
+ out.println();
+ }
+ if(header.startsWith("PAM_ERROR_MSG")) {
+ errorMessages.add(textBlock);
+ }
+ // ignore the rest
+ }
+ continue;
+ }
+ if(line.startsWith("SUCCESS")) {
+ LOGGER.fine("Authentication successful: "+line);
+ return proc;
+ }
+ if(line.startsWith("ERROR")) {
+ LOGGER.fine("Authentication faied: "+line);
+ throw new SuAuthenticationFailureException(readTextBlock(in)+join(errorMessages));
+ }
+
+ LOGGER.fine("Unrecognized response: "+line);
+ throw new IOException("Unrecognized response from embedded_su "+line);
+ }
+ }
+
+ private static String join(Collection<String> col) {
+ StringBuilder buf = new StringBuilder();
+ for (String a : col)
+ buf.append(a);
+ return buf.toString();
+ }
+
+ /**
+ * Reads a line from the given input stream, without any read ahead.
+ *
+ * Line end is '\n', as this is for Solaris.
+ */
+ private static String readLine(InputStream in) throws IOException {
+ ByteArrayOutputStream buf = new ByteArrayOutputStream();
+ int ch;
+
+ while((ch=in.read())!=-1) {
+ if(ch=='\n') return buf.toString();
+ buf.write(ch);
+ }
+ throw new EOFException();
+ }
+
+ /**
+ * Reads the text block.
+ */
+ private static String readTextBlock(InputStream in) throws IOException {
+ StringBuilder buf = new StringBuilder();
+
+ while(true) {
+ String line = readLine(in);
+ if(line.equals("."))
+ return buf.toString(); // end of it
+
+ if(line.startsWith(".."))
+ buf.append(line.substring(1));
+ else
+ buf.append(line);
+ buf.append('\n');
+ }
+ }
+
+ private static final Logger LOGGER = Logger.getLogger(EmbeddedSu.class.getName());
+}
diff --git a/hudson-core/src/main/java/hudson/os/SU.java b/hudson-core/src/main/java/hudson/os/SU.java
index 821cde18..bf8d6bea 100644
--- a/hudson-core/src/main/java/hudson/os/SU.java
+++ b/hudson-core/src/main/java/hudson/os/SU.java
@@ -8,15 +8,14 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
-*
-* Kohsuke Kawaguchi
+ *
+ * Kohsuke Kawaguchi
*
*
*******************************************************************************/
package hudson.os;
-import com.sun.solaris.EmbeddedSu;
import hudson.Launcher.LocalLauncher;
import hudson.Util;
import hudson.model.Computer;
diff --git a/hudson-core/src/main/java/hudson/os/SuAuthenticationFailureException.java b/hudson-core/src/main/java/hudson/os/SuAuthenticationFailureException.java
new file mode 100644
index 00000000..ec85b935
--- /dev/null
+++ b/hudson-core/src/main/java/hudson/os/SuAuthenticationFailureException.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ *
+ * Copyright (c) 2004-2009 Oracle Corporation.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *
+ * Kohsuke Kawaguchi
+ *
+ *******************************************************************************/
+
+package hudson.os;
+
+import java.io.IOException;
+
+/**
+ * 'su' failed to authenticate the given credential.
+ *
+ * <p>
+ * Wrong password, invalid user name, that sort of things.
+ *
+ * @author Kohsuke Kawaguchi
+ */
+public class SuAuthenticationFailureException extends IOException {
+ public SuAuthenticationFailureException(String message) {
+ super(message);
+ }
+}
diff --git a/hudson-core/src/main/java/hudson/tasks/Mailer.java b/hudson-core/src/main/java/hudson/tasks/Mailer.java
index e271271e..4dc420c7 100644
--- a/hudson-core/src/main/java/hudson/tasks/Mailer.java
+++ b/hudson-core/src/main/java/hudson/tasks/Mailer.java
@@ -51,8 +51,6 @@ import javax.mail.internet.MimeMessage;
import javax.servlet.ServletException;
import net.sf.json.JSONObject;
import org.apache.commons.lang3.StringUtils;
-import org.kohsuke.accmod.Restricted;
-import org.kohsuke.accmod.restrictions.NoExternalUse;
import org.kohsuke.stapler.QueryParameter;
import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.export.Exported;
@@ -129,7 +127,7 @@ public class Mailer extends Notifier {
* @deprecated as of 1.286
* Use {@link #descriptor()} to obtain the current instance.
*/
- @Restricted(NoExternalUse.class)
+ @Deprecated
@RestrictedSince("1.355")
public static DescriptorImpl DESCRIPTOR;
diff --git a/hudson-core/src/main/java/hudson/tools/ZipExtractionInstaller.java b/hudson-core/src/main/java/hudson/tools/ZipExtractionInstaller.java
index aba6896d..dd534999 100644
--- a/hudson-core/src/main/java/hudson/tools/ZipExtractionInstaller.java
+++ b/hudson-core/src/main/java/hudson/tools/ZipExtractionInstaller.java
@@ -35,7 +35,6 @@ import java.net.URL;
import java.net.URLConnection;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.QueryParameter;
-import org.jvnet.animal_sniffer.IgnoreJRERequirement;
/**
* Installs a tool into the Hudson working area by downloading and unpacking a ZIP file.
@@ -116,7 +115,6 @@ public class ZipExtractionInstaller extends ToolInstaller {
process(d);
return null;
}
- @IgnoreJRERequirement
private void process(File f) {
if (f.isFile()) {
if (Functions.isMustangOrAbove()) {
diff --git a/hudson-core/src/main/java/hudson/util/CertificateUtil.java b/hudson-core/src/main/java/hudson/util/CertificateUtil.java
new file mode 100644
index 00000000..b4ae3166
--- /dev/null
+++ b/hudson-core/src/main/java/hudson/util/CertificateUtil.java
@@ -0,0 +1,87 @@
+/*******************************************************************************
+ *
+ * Copyright (c) 2004-2009 Oracle Corporation.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *
+ * Kohsuke Kawaguchi
+ *
+ *******************************************************************************/
+
+package hudson.util;
+
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.TrustManagerFactory;
+import javax.net.ssl.X509TrustManager;
+import java.security.GeneralSecurityException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.CertPath;
+import java.security.cert.CertPathValidator;
+import java.security.cert.CertificateFactory;
+import java.security.cert.PKIXCertPathValidatorResult;
+import java.security.cert.PKIXParameters;
+import java.security.cert.TrustAnchor;
+import java.security.cert.X509Certificate;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Utility code to work around horrible Java Crypto API.
+ *
+ * @author Kohsuke Kawaguchi
+ */
+public class CertificateUtil {
+ /**
+ * Obtains the list of default root CAs installed in the JRE.
+ */
+ public static Set<TrustAnchor> getDefaultRootCAs() throws NoSuchAlgorithmException, KeyStoreException {
+ X509TrustManager x509tm = getDefaultX509TrustManager();
+
+ Set<TrustAnchor> rootCAs = new HashSet<TrustAnchor>();
+ for (X509Certificate c : x509tm.getAcceptedIssuers()) {
+ rootCAs.add(new TrustAnchor(c,null));
+ }
+ return rootCAs;
+ }
+
+ /**
+ * Loads the system default {@link X509TrustManager}.
+ */
+ public static X509TrustManager getDefaultX509TrustManager() throws NoSuchAlgorithmException, KeyStoreException {
+ TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
+ tmf.init((KeyStore)null);
+
+ for (TrustManager tm : tmf.getTrustManagers()) {
+ if (tm instanceof X509TrustManager) {
+ return (X509TrustManager) tm;
+ }
+ }
+ throw new IllegalStateException("X509TrustManager is not found");
+ }
+
+ /**
+ * Validate a certificate chain. Normal return indicates a successful validation.
+ */
+ public static PKIXCertPathValidatorResult validatePath(List<X509Certificate> certs) throws GeneralSecurityException {
+ return validatePath(certs,getDefaultRootCAs());
+ }
+
+ public static PKIXCertPathValidatorResult validatePath(List<X509Certificate> certs, Set<TrustAnchor> trustAnchors) throws GeneralSecurityException {
+ CertPathValidator cpv = CertPathValidator.getInstance("PKIX");
+ PKIXParameters params = new PKIXParameters(trustAnchors);
+ params.setRevocationEnabled(false);
+
+ CertificateFactory cf = CertificateFactory.getInstance("X509");
+ CertPath path = cf.generateCertPath(certs);
+
+ return (PKIXCertPathValidatorResult) cpv.validate(path, params);
+ }
+}
diff --git a/hudson-core/src/main/java/hudson/util/ConsistentHash.java b/hudson-core/src/main/java/hudson/util/ConsistentHash.java
index 2cb2456e..59b64978 100644
--- a/hudson-core/src/main/java/hudson/util/ConsistentHash.java
+++ b/hudson-core/src/main/java/hudson/util/ConsistentHash.java
@@ -16,8 +16,7 @@
package hudson.util;
-import com.trilead.ssh2.crypto.digest.MD5;
-
+import ch.ethz.ssh2.crypto.digest.MD5;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
diff --git a/hudson-core/src/main/java/hudson/util/Digester2.java b/hudson-core/src/main/java/hudson/util/Digester2.java
index e68efc30..97cb543d 100644
--- a/hudson-core/src/main/java/hudson/util/Digester2.java
+++ b/hudson-core/src/main/java/hudson/util/Digester2.java
@@ -19,8 +19,6 @@ package hudson.util;
import hudson.RestrictedSince;
import org.apache.commons.digester.Digester;
import org.apache.commons.digester.Rule;
-import org.kohsuke.accmod.Restricted;
-import org.kohsuke.accmod.restrictions.NoExternalUse;
import org.xml.sax.Attributes;
/**
@@ -31,7 +29,7 @@ import org.xml.sax.Attributes;
* @deprecated use {@link org.apache.commons.digester3.Digester} instead
* @since 2.1.2
*/
-@Restricted(NoExternalUse.class)
+@Deprecated
@RestrictedSince("2.1.2")
public class Digester2 extends Digester {
@Override
diff --git a/hudson-core/src/main/java/hudson/util/FormFieldValidator.java b/hudson-core/src/main/java/hudson/util/FormFieldValidator.java
index 7005f5b7..b62d79ab 100644
--- a/hudson-core/src/main/java/hudson/util/FormFieldValidator.java
+++ b/hudson-core/src/main/java/hudson/util/FormFieldValidator.java
@@ -606,7 +606,7 @@ public abstract class FormFieldValidator {
return;
}
- com.trilead.ssh2.crypto.Base64.decode(v.toCharArray());
+ org.apache.commons.codec.binary.Base64.decodeBase64(v);
ok();
} catch (IOException e) {
fail();
diff --git a/hudson-core/src/main/java/hudson/util/FormValidation.java b/hudson-core/src/main/java/hudson/util/FormValidation.java
index ff60bd6a..e3c953eb 100644
--- a/hudson-core/src/main/java/hudson/util/FormValidation.java
+++ b/hudson-core/src/main/java/hudson/util/FormValidation.java
@@ -36,6 +36,7 @@ import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.util.Locale;
+import org.apache.commons.codec.binary.Base64;
/**
* Represents the result of the form field validation.
@@ -369,21 +370,19 @@ public abstract class FormValidation extends IOException implements HttpResponse
* @since 1.305
*/
public static FormValidation validateBase64(String value, boolean allowWhitespace, boolean allowEmpty, String errorMessage) {
- try {
- String v = value;
- if(!allowWhitespace) {
- if(v.indexOf(' ')>=0 || v.indexOf('\n')>=0)
- return error(errorMessage);
- }
- v=v.trim();
- if(!allowEmpty && v.length()==0)
+ String v = value;
+ if (!allowWhitespace) {
+ if (v.indexOf(' ') >= 0 || v.indexOf('\n') >= 0) {
return error(errorMessage);
-
- com.trilead.ssh2.crypto.Base64.decode(v.toCharArray());
- return ok();
- } catch (IOException e) {
+ }
+ }
+ v = v.trim();
+ if (!allowEmpty && v.length() == 0) {
return error(errorMessage);
}
+
+ Base64.decodeBase64(v);
+ return ok();
}
/**
diff --git a/hudson-core/src/main/java/hudson/util/Protector.java b/hudson-core/src/main/java/hudson/util/Protector.java
index 13f3d31a..ffc96ac4 100644
--- a/hudson-core/src/main/java/hudson/util/Protector.java
+++ b/hudson-core/src/main/java/hudson/util/Protector.java
@@ -23,8 +23,7 @@ import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.GeneralSecurityException;
import java.security.NoSuchAlgorithmException;
-
-import com.trilead.ssh2.crypto.Base64;
+import org.apache.commons.codec.binary.Base64;
/**
* Encrypt/decrypt data by using a "session" key that only lasts for
@@ -42,7 +41,7 @@ public class Protector {
try {
Cipher cipher = Secret.getCipher(ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, DES_KEY);
- return new String(Base64.encode(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) {
@@ -58,7 +57,7 @@ public class Protector {
try {
Cipher cipher = Secret.getCipher(ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, DES_KEY);
- String plainText = new String(cipher.doFinal(Base64.decode(data.toCharArray())), "UTF-8");
+ String plainText = new String(cipher.doFinal(Base64.decodeBase64(data)), "UTF-8");
if(plainText.endsWith(MAGIC))
return plainText.substring(0,plainText.length()-3);
return null;
diff --git a/hudson-core/src/main/java/hudson/util/Scrambler.java b/hudson-core/src/main/java/hudson/util/Scrambler.java
index e1505fa9..0148bd00 100644
--- a/hudson-core/src/main/java/hudson/util/Scrambler.java
+++ b/hudson-core/src/main/java/hudson/util/Scrambler.java
@@ -16,10 +16,9 @@
package hudson.util;
-import com.trilead.ssh2.crypto.Base64;
-
import java.io.IOException;
import java.io.UnsupportedEncodingException;
+import org.apache.commons.codec.binary.Base64;
/**
* Used when storing passwords in configuration files.
@@ -36,7 +35,7 @@ public class Scrambler {
public static String scramble(String secret) {
if(secret==null) return null;
try {
- return new String(Base64.encode(secret.getBytes("UTF-8")));
+ return new String(Base64.encodeBase64(secret.getBytes("UTF-8")));
} catch (UnsupportedEncodingException e) {
throw new Error(e); // impossible
}
@@ -45,7 +44,7 @@ public class Scrambler {
public static String descramble(String scrambled) {
if(scrambled==null) return null;
try {
- return new String(Base64.decode(scrambled.toCharArray()),"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 71860c51..fe0ead08 100644
--- a/hudson-core/src/main/java/hudson/util/Secret.java
+++ b/hudson-core/src/main/java/hudson/util/Secret.java
@@ -21,7 +21,6 @@ import com.thoughtworks.xstream.converters.MarshallingContext;
import com.thoughtworks.xstream.converters.UnmarshallingContext;
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
-import com.trilead.ssh2.crypto.Base64;
import hudson.model.Hudson;
import hudson.Util;
import org.kohsuke.stapler.Stapler;
@@ -32,6 +31,7 @@ import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.io.IOException;
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.
@@ -107,7 +107,7 @@ public final class Secret implements Serializable {
Cipher cipher = getCipher("AES");
cipher.init(Cipher.ENCRYPT_MODE, getKey());
// add the magic suffix which works like a check sum.
- return new String(Base64.encode(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) {
@@ -124,7 +124,7 @@ public final class Secret implements Serializable {
try {
Cipher cipher = getCipher("AES");
cipher.init(Cipher.DECRYPT_MODE, getKey());
- String plainText = new String(cipher.doFinal(Base64.decode(data.toCharArray())), "UTF-8");
+ 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()));
return null;
diff --git a/hudson-core/src/main/java/hudson/util/SignatureOutputStream.java b/hudson-core/src/main/java/hudson/util/SignatureOutputStream.java
new file mode 100644
index 00000000..42231f08
--- /dev/null
+++ b/hudson-core/src/main/java/hudson/util/SignatureOutputStream.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ *
+ * Copyright (c) 2004-2009 Oracle Corporation.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *
+ * Kohsuke Kawaguchi
+ *
+ *******************************************************************************/
+
+package hudson.util;
+
+import org.apache.commons.io.output.NullOutputStream;
+
+import java.security.Signature;
+import java.security.SignatureException;
+import java.io.FilterOutputStream;
+import java.io.OutputStream;
+import java.io.IOException;
+
+/**
+ * @author Kohsuke Kawaguchi
+ */
+public class SignatureOutputStream extends FilterOutputStream {
+ private final Signature sig;
+
+ public SignatureOutputStream(OutputStream out, Signature sig) {
+ super(out);
+ this.sig = sig;
+ }
+
+ public SignatureOutputStream(Signature sig) {
+ this(new NullOutputStream(),sig);
+ }
+
+ @Override
+ public void write(int b) throws IOException {
+ try {
+ sig.update((byte)b);
+ out.write(b);
+ } catch (SignatureException 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);
+ } catch (SignatureException e) {
+ throw (IOException)new IOException(e.getMessage()).initCause(e);
+ }
+ }
+}
diff --git a/hudson-core/src/main/java/hudson/util/jna/NativeUtils.java b/hudson-core/src/main/java/hudson/util/jna/NativeUtils.java
index 968bc774..13c768d6 100644
--- a/hudson-core/src/main/java/hudson/util/jna/NativeUtils.java
+++ b/hudson-core/src/main/java/hudson/util/jna/NativeUtils.java
@@ -12,8 +12,7 @@
* Winston Prakash
*
*
- *******************************************************************************/
-
+ *******************************************************************************/
package hudson.util.jna;
import hudson.DescriptorExtensionList;
@@ -49,31 +48,27 @@ public class NativeUtils implements Serializable {
private NativeUtils() {
try {
- DescriptorExtensionList<NativeUnixSupport, Descriptor<NativeUnixSupport>> unixSupportDescriptors
- = NativeUnixSupport.all();
+ DescriptorExtensionList<NativeUnixSupport, Descriptor<NativeUnixSupport>> unixSupportDescriptors = NativeUnixSupport.all();
if (null != unixSupportDescriptors && !unixSupportDescriptors.isEmpty()) {
nativeUnixSupport = unixSupportDescriptors.get(0).newInstance(null, null);
}
- DescriptorExtensionList<NativeWindowsSupport, Descriptor<NativeWindowsSupport>> windowsSupportDescriptors
- = NativeWindowsSupport.all();
+ DescriptorExtensionList<NativeWindowsSupport, Descriptor<NativeWindowsSupport>> windowsSupportDescriptors = NativeWindowsSupport.all();
if (null != windowsSupportDescriptors && !windowsSupportDescriptors.isEmpty()) {
nativeWindowsSupport = windowsSupportDescriptors.get(0).newInstance(null, null);
}
- DescriptorExtensionList<NativeMacSupport, Descriptor<NativeMacSupport>> macSupportDescriptors
- = NativeMacSupport.all();
+ DescriptorExtensionList<NativeMacSupport, Descriptor<NativeMacSupport>> macSupportDescriptors = NativeMacSupport.all();
if (null != macSupportDescriptors && !macSupportDescriptors.isEmpty()) {
nativeMacSupport = macSupportDescriptors.get(0).newInstance(null, null);
}
- DescriptorExtensionList<NativeZfsSupport, Descriptor<NativeZfsSupport>> zfsSupportDescriptors
- = NativeZfsSupport.all();
+ DescriptorExtensionList<NativeZfsSupport, Descriptor<NativeZfsSupport>> zfsSupportDescriptors = NativeZfsSupport.all();
if (null != zfsSupportDescriptors && !zfsSupportDescriptors.isEmpty()) {
nativeZfsSupport = zfsSupportDescriptors.get(0).newInstance(null, null);
}
} catch (Exception ex) {
- LOGGER.log(Level.SEVERE, null, ex);
+ LOGGER.log(Level.FINE, null, ex);
}
}
@@ -388,7 +383,7 @@ public class NativeUtils implements Serializable {
ensureWindowsSupport(NativeFunction.WINDOWS_FILE_MOVE);
nativeWindowsSupport.windowsMoveFile(fromFile, toFile);
}
-
+
/**
* Get the error associated with the last Native Unix Operation
* @return String error message
@@ -409,7 +404,7 @@ public class NativeUtils implements Serializable {
ensureMacSupport(NativeFunction.WINDOWS_FILE_MOVE);
return nativeMacSupport.getMacProcesses();
}
-
+
/**
* Get the error associated with the last Native Unix Operation
* @return String error message
@@ -473,7 +468,7 @@ public class NativeUtils implements Serializable {
ensureZfsSupport(NativeFunction.ZFS);
return nativeZfsSupport.zfsExists(zfsName);
}
-
+
/**
* Get the error associated with the last Native Unix Operation
* @return String error message
diff --git a/hudson-core/src/main/java/hudson/util/ssh/DEREncoder.java b/hudson-core/src/main/java/hudson/util/ssh/DEREncoder.java
new file mode 100644
index 00000000..b04bebdd
--- /dev/null
+++ b/hudson-core/src/main/java/hudson/util/ssh/DEREncoder.java
@@ -0,0 +1,117 @@
+/*******************************************************************************
+ *
+ * Copyright (c) 2004-2010 Oracle Corporation.
+ *
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *
+ * Kohsuke Kawaguchi
+ *
+ *******************************************************************************/
+
+package hudson.util.ssh;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.ByteArrayOutputStream;
+import java.math.BigInteger;
+import org.apache.commons.codec.binary.Base64;
+
+/**
+ * ASN.1 DER encoder.
+ *
+ * This is the binary packaging format used by OpenSSH key.
+ *
+ * @author Kohsuke Kawaguchi
+ */
+final class DEREncoder {
+
+ private final DataOutputStream out;
+ private final ByteArrayOutputStream baos = new ByteArrayOutputStream();
+
+ public DEREncoder() {
+ this.out = new DataOutputStream(baos);
+ }
+
+ public void reset() {
+ baos.reset();
+ }
+
+ public byte[] toByteArray() {
+ return baos.toByteArray();
+ }
+
+ /**
+ * Converts that to base64 with new lines to make it 64-chars per line.
+ */
+ public String toBase64() {
+ byte[] r = Base64.encodeBase64(toByteArray());
+
+ StringBuilder buf = new StringBuilder();
+ for (int i = 0; i < r.length; i++) {
+ buf.append(r[i]);
+ if (i % 64 == 63) {
+ buf.append('\n');
+ }
+ }
+ if (r.length % 64 != 0) {
+ buf.append('\n');
+ }
+ return buf.toString();
+ }
+
+ public DEREncoder writeSequence(byte[] data, int offset, int length) throws IOException {
+ out.write(0x30);
+ writeLength(length);
+ out.write(data, offset, length);
+ return this;
+ }
+
+ public DEREncoder writeSequence(byte[] data) throws IOException {
+ return writeSequence(data, 0, data.length);
+ }
+
+ public void writeLength(int len) throws IOException {
+ if (len < 0x80) {
+ // short form
+ out.write(len);
+ return;
+ }
+
+ // how many bytes do we need to store this length?
+ int bytes = countByteLen(len);
+
+ out.write(0x80 | bytes);
+ for (int i = bytes - 1; i >= 0; i--) {
+ out.write((len >> (8 * i)) & 0xFF);
+ }
+ }
+
+ private int countByteLen(int len) {
+ int bytes = 0;
+ while (len > 0) {
+ bytes++;
+ len >>= 8;
+ }
+ return bytes;
+ }
+
+ public DEREncoder write(BigInteger i) throws IOException {
+ out.write(0x02);
+ byte[] bytes = i.toByteArray();
+ writeLength(bytes.length);
+ out.write(bytes);
+ return this;
+ }
+
+ public DEREncoder write(BigInteger... ints) throws IOException {
+ for (BigInteger i : ints) {
+ write(i);
+ }
+ return this;
+ }
+}
diff --git a/hudson-core/src/main/java/hudson/util/ssh/KeyReader.java b/hudson-core/src/main/java/hudson/util/ssh/KeyReader.java
new file mode 100644
index 00000000..b8d971fa
--- /dev/null
+++ b/hudson-core/src/main/java/hudson/util/ssh/KeyReader.java
@@ -0,0 +1,65 @@
+/********************************************************************************
+ *
+ * Copyright (c) 2004-2010 Oracle Corporation.
+ *
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *
+ * Kohsuke Kawaguchi
+ *
+ *******************************************************************************/
+
+package hudson.util.ssh;
+
+import java.io.DataInput;
+import java.io.DataInputStream;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.math.BigInteger;
+
+/**
+ * Parses the putty key bit vector, which is an encoded sequence of {@link BigInteger}s.
+ *
+ * @author Kohsuke Kawaguchi
+ */
+class KeyReader {
+
+ private final DataInput di;
+
+ KeyReader(byte[] key) {
+ this.di = new DataInputStream(new ByteArrayInputStream(key));
+ }
+
+ /**
+ * Skips an integer without reading it.
+ */
+ public void skip() {
+ try {
+ di.skipBytes(di.readInt());
+ } catch (IOException e) {
+ throw new AssertionError(e);
+ }
+ }
+
+ private byte[] read() {
+ try {
+ int len = di.readInt();
+ byte[] r = new byte[len];
+ di.readFully(r);
+ return r;
+ } catch (IOException e) {
+ throw new AssertionError(e);
+ }
+ }
+
+ /**
+ * Reads the next integer.
+ */
+ public BigInteger readInt() {
+ return new BigInteger(read());
+ }
+}
diff --git a/hudson-core/src/main/java/hudson/util/ssh/PuTTYKey.java b/hudson-core/src/main/java/hudson/util/ssh/PuTTYKey.java
new file mode 100644
index 00000000..ddfa2d4a
--- /dev/null
+++ b/hudson-core/src/main/java/hudson/util/ssh/PuTTYKey.java
@@ -0,0 +1,276 @@
+/**
+ * *****************************************************************************
+ *
+ * Copyright (c) 2004-2010 Oracle Corporation.
+ *
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *
+ * Kohsuke Kawaguchi
+ *
+ ******************************************************************************
+ */
+package hudson.util.ssh;
+
+import ch.ethz.ssh2.crypto.cipher.AES;
+import ch.ethz.ssh2.crypto.cipher.CBCMode;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.io.FileWriter;
+import java.math.BigInteger;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.HashMap;
+import java.util.Map;
+import org.apache.commons.codec.binary.Base64;
+
+/**
+ * Interprets PuTTY's ".ppk" file.
+ *
+ * <h2>Notes</h2> <ol> <li> The file appears to be a text file but it doesn't
+ * have the fixed encoding. So we just use the platform default encoding, which
+ * is what PuTTY seems to use. Fortunately, the important part is all ASCII, so
+ * this shouldn't really hurt the interpretation of the key. </ol>
+ *
+ * <h2>Sample PuTTY file format</h2>
+ * <pre>
+ * PuTTY-User-Key-File-2: ssh-rsa
+ * Encryption: none
+ * Comment: rsa-key-20080514
+ * Public-Lines: 4
+ * AAAAB3NzaC1yc2EAAAABJQAAAIEAiPVUpONjGeVrwgRPOqy3Ym6kF/f8bltnmjA2
+ * BMdAtaOpiD8A2ooqtLS5zWYuc0xkW0ogoKvORN+RF4JI+uNUlkxWxnzJM9JLpnvA
+ * HrMoVFaQ0cgDMIHtE1Ob1cGAhlNInPCRnGNJpBNcJ/OJye3yt7WqHP4SPCCLb6nL
+ * nmBUrLM=
+ * Private-Lines: 8
+ * AAAAgGtYgJzpktzyFjBIkSAmgeVdozVhgKmF6WsDMUID9HKwtU8cn83h6h7ug8qA
+ * hUWcvVxO201/vViTjWVz9ALph3uMnpJiuQaaNYIGztGJBRsBwmQW9738pUXcsUXZ
+ * 79KJP01oHn6Wkrgk26DIOsz04QOBI6C8RumBO4+F1WdfueM9AAAAQQDmA4hcK8Bx
+ * nVtEpcF310mKD3nsbJqARdw5NV9kCxPnEsmy7Sy1L4Ob/nTIrynbc3MA9HQVJkUz
+ * 7V0va5Pjm/T7AAAAQQCYbnG0UEekwk0LG1Hkxh1OrKMxCw2KWMN8ac3L0LVBg/Tk
+ * 8EnB2oT45GGeJaw7KzdoOMFZz0iXLsVLNUjNn2mpAAAAQQCN6SEfWqiNzyc/w5n/
+ * lFVDHExfVUJp0wXv+kzZzylnw4fs00lC3k4PZDSsb+jYCMesnfJjhDgkUA0XPyo8
+ * Emdk
+ * Private-MAC: 50c45751d18d74c00fca395deb7b7695e3ed6f77
+ * </pre>
+ *
+ * @author Kohsuke Kawaguchi
+ */
+public class PuTTYKey {
+
+ private static final String PUTTY_SIGNATURE = "PuTTY-User-Key-File-";
+ private final byte[] privateKey;
+ private final byte[] publicKey;
+ /**
+ * For each line that looks like "Xyz: vvv", it will be stored in this map.
+ */
+ private final Map<String, String> headers = new HashMap<String, String>();
+
+ public PuTTYKey(File ppkFile, String passphrase) throws IOException {
+ this(new FileReader(ppkFile), passphrase);
+ }
+
+ public PuTTYKey(InputStream in, String passphrase) throws IOException {
+ this(new InputStreamReader(in), passphrase);
+ }
+
+ public PuTTYKey(Reader in, String passphrase) throws IOException {
+ BufferedReader r = new BufferedReader(in);
+
+ Map<String, String> payload = new HashMap<String, String>();
+
+ // parse the text into headers and payloads
+ try {
+ String headerName = null;
+ String line;
+ while ((line = r.readLine()) != null) {
+ int idx = line.indexOf(": ");
+ if (idx > 0) {
+ headerName = line.substring(0, idx);
+ headers.put(headerName, line.substring(idx + 2));
+ } else {
+ String s = payload.get(headerName);
+ if (s == null) {
+ s = line;
+ } else {
+ s += line;
+ }
+ payload.put(headerName, s);
+ }
+ }
+ } finally {
+ r.close();
+ }
+
+ boolean encrypted = "aes256-cbc".equals(headers.get("Encryption"));
+
+ publicKey = decodeBase64(payload.get("Public-Lines"));
+ byte[] privateLines = decodeBase64(payload.get("Private-Lines"));
+
+ if (encrypted) {
+ AES aes = new AES();
+ byte[] key = toKey(passphrase);
+ aes.init(false, key);
+ CBCMode cbc = new CBCMode(aes, new byte[16], false); // initial vector=0
+
+ byte[] out = new byte[privateLines.length];
+ for (int i = 0; i < privateLines.length / cbc.getBlockSize(); i++) {
+ cbc.transformBlock(privateLines, i * cbc.getBlockSize(), out, i * cbc.getBlockSize());
+ }
+ privateLines = out;
+ }
+
+ this.privateKey = privateLines;
+ }
+
+ /**
+ * Key type. Either "ssh-rsa" for RSA key, or "ssh-dss" for DSA key.
+ */
+ public String getAlgorithm() {
+ return headers.get("PuTTY-User-Key-File-2");
+ }
+
+ /**
+ * Converts a passphrase into a key, by following the convention that PuTTY
+ * uses.
+ *
+ * <p> This is used to decrypt the private key when it's encrypted.
+ */
+ private byte[] toKey(String passphrase) {
+ try {
+ MessageDigest digest = MessageDigest.getInstance("SHA-1");
+
+ digest.update(new byte[]{0, 0, 0, 0});
+ digest.update(passphrase.getBytes());
+ byte[] key1 = digest.digest();
+
+ digest.update(new byte[]{0, 0, 0, 1});
+ digest.update(passphrase.getBytes());
+ byte[] key2 = digest.digest();
+
+ byte[] r = new byte[32];
+ System.arraycopy(key1, 0, r, 0, 20);
+ System.arraycopy(key2, 0, r, 20, 12);
+
+ return r;
+ } catch (NoSuchAlgorithmException e) {
+ throw new AssertionError(e); // impossible
+ }
+ }
+
+ private static byte[] decodeBase64(String s) throws IOException {
+ return Base64.decodeBase64(s);
+ }
+
+ /**
+ * Converts this key into OpenSSH format.
+ *
+ * @return A multi-line string that can be written back to a file.
+ */
+ public String toOpenSSH() throws IOException {
+ if (getAlgorithm().equals("ssh-rsa")) {
+ KeyReader r = new KeyReader(publicKey);
+ r.skip(); // skip this
+ BigInteger e = r.readInt();
+ BigInteger n = r.readInt();
+
+ r = new KeyReader(privateKey);
+ BigInteger d = r.readInt();
+ BigInteger p = r.readInt();
+ BigInteger q = r.readInt();
+ BigInteger iqmp = r.readInt();
+
+ BigInteger dmp1 = d.mod(p.subtract(BigInteger.ONE));
+ BigInteger dmq1 = d.mod(q.subtract(BigInteger.ONE));
+
+
+ DEREncoder payload = new DEREncoder().writeSequence(
+ new DEREncoder().write(BigInteger.ZERO, n, e, d, p, q, dmp1, dmq1, iqmp).toByteArray());
+
+ StringBuilder buf = new StringBuilder();
+ buf.append("-----BEGIN RSA PRIVATE KEY-----\n");
+ buf.append(payload.toBase64());
+ buf.append("-----END RSA PRIVATE KEY-----\n");
+
+ // debug assist
+ // Object o = PEMDecoder.decode(buf.toString().toCharArray(), null);
+
+ return buf.toString();
+ }
+
+ if (getAlgorithm().equals("ssh-dss")) {
+ KeyReader r = new KeyReader(publicKey);
+ r.skip(); // skip this
+ BigInteger p = r.readInt();
+ BigInteger q = r.readInt();
+ BigInteger g = r.readInt();
+ BigInteger y = r.readInt();
+
+ r = new KeyReader(privateKey);
+ BigInteger x = r.readInt();
+
+ DEREncoder payload = new DEREncoder().writeSequence(
+ new DEREncoder().write(BigInteger.ZERO, p, q, g, y, x).toByteArray());
+
+ StringBuilder buf = new StringBuilder();
+ buf.append("-----BEGIN DSA PRIVATE KEY-----\n");
+ buf.append(payload.toBase64());
+ buf.append("-----END DSA PRIVATE KEY-----\n");
+
+ // debug assist
+ // Object o = PEMDecoder.decode(buf.toString().toCharArray(), null);
+
+ return buf.toString();
+ }
+
+ throw new IllegalArgumentException("Unrecognized key type: " + getAlgorithm());
+ }
+
+ /**
+ * Converts the key to OpenSSH format, then write it to a file.
+ */
+ public void toOpenSSH(File f) throws IOException {
+ FileWriter w = new FileWriter(f);
+ try {
+ w.write(toOpenSSH());
+ } finally {
+ w.close();
+ }
+ }
+
+ /**
+ * Checks if the given file is a PuTTY's ".ppk" file, by looking at the file
+ * contents.
+ */
+ public static boolean isPuTTYKeyFile(File ppkFile) throws IOException {
+ return isPuTTYKeyFile(new FileReader(ppkFile));
+ }
+
+ public static boolean isPuTTYKeyFile(InputStream in) throws IOException {
+ return isPuTTYKeyFile(new InputStreamReader(in));
+ }
+
+ public static boolean isPuTTYKeyFile(Reader _reader) throws IOException {
+ BufferedReader r = new BufferedReader(_reader);
+ try {
+ String line;
+ while ((line = r.readLine()) != null) {
+ if (line.startsWith(PUTTY_SIGNATURE)) {
+ return true;
+ }
+ }
+ return false;
+ } finally {
+ r.close();
+ }
+ }
+}
diff --git a/hudson-core/src/main/java/hudson/util/ssh/SFTPClient.java b/hudson-core/src/main/java/hudson/util/ssh/SFTPClient.java
index cba04c29..22a2072c 100644
--- a/hudson-core/src/main/java/hudson/util/ssh/SFTPClient.java
+++ b/hudson-core/src/main/java/hudson/util/ssh/SFTPClient.java
@@ -8,18 +8,15 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
- *
- *
+ *
+ * Kohsuke Kawaguchi
+ *
*******************************************************************************/
package hudson.util.ssh;
-import com.trilead.ssh2.Connection;
-import com.trilead.ssh2.SFTPException;
-import com.trilead.ssh2.SFTPv3Client;
-import com.trilead.ssh2.SFTPv3FileAttributes;
-import com.trilead.ssh2.SFTPv3FileHandle;
-import com.trilead.ssh2.sftp.ErrorCodes;
+import ch.ethz.ssh2.*;
+import ch.ethz.ssh2.sftp.ErrorCodes;
import hudson.util.IOException2;
import java.io.IOException;
diff --git a/hudson-core/src/main/java/org/eclipse/hudson/util/plugin/PluginMarker.java b/hudson-core/src/main/java/org/eclipse/hudson/util/plugin/PluginMarker.java
deleted file mode 100644
index 6b0b9d8b..00000000
--- a/hudson-core/src/main/java/org/eclipse/hudson/util/plugin/PluginMarker.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*******************************************************************************
- *
- * Copyright (c) 2011 Oracle Corporation.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *
- * Anton Kozak
- *
- *******************************************************************************/
-package org.eclipse.hudson.util.plugin;
-
-import javax.tools.Diagnostic;
-import org.kohsuke.MetaInfServices;
-
-import javax.annotation.processing.AbstractProcessor;
-import javax.annotation.processing.Processor;
-import javax.annotation.processing.RoundEnvironment;
-import javax.annotation.processing.SupportedAnnotationTypes;
-import javax.annotation.processing.SupportedSourceVersion;
-import javax.lang.model.SourceVersion;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.Modifier;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.util.ElementScanner6;
-import javax.tools.FileObject;
-import javax.tools.StandardLocation;
-import java.io.IOException;
-import java.io.OutputStreamWriter;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.io.Writer;
-import java.util.Set;
-
-/**
- *
- * Discovers the type of {@link hudson.Plugin} and generates "META-INF/services/hudson.Plugin".
- * It's used for manifest creation (Plugin-Class section) and the plugin loading.
- * Custom {@link hudson.Plugin} implementation is required for the -plugin initialization, for example XStream aliases, etc
- */
-@SupportedSourceVersion(SourceVersion.RELEASE_6)
-@SupportedAnnotationTypes("*")
-@MetaInfServices(Processor.class)
-@SuppressWarnings({"Since15"})
-public class PluginMarker extends AbstractProcessor {
-
- protected static final String HUDSON_PLUGIN_QUAFIFIER = "hudson.Plugin";
- protected static final String META_INF_SERVICES_LOCATION = "META-INF/services/hudson.Plugin";
-
- /**
- * {@inheritDoc}
- */
- @Override
- public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
- ElementScanner6<Void,Void> scanner = new ElementScanner6<Void, Void>() {
- @Override
- public Void visitType(TypeElement e, Void aVoid) {
- if(!e.getModifiers().contains(Modifier.ABSTRACT)) {
- Element sc = processingEnv.getTypeUtils().asElement(e.getSuperclass());
- if (sc!=null && ((TypeElement)sc).getQualifiedName().contentEquals(HUDSON_PLUGIN_QUAFIFIER)) {
- try {
- write(e);
- } catch (IOException x) {
- StringWriter sw = new StringWriter();
- x.printStackTrace(new PrintWriter(sw));
- processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR,sw.toString(),e);
- }
- }
- }
-
- return super.visitType(e, aVoid);
- }
- };
-
- for( Element e : roundEnv.getRootElements() )
- scanner.scan(e,null);
-
- return false;
- }
-
- /**
- * Writes plugin class name to the defined location.
- *
- * @param typeElement detected element.
- * @throws IOException exception.
- */
- private void write(TypeElement typeElement) throws IOException {
- FileObject f = processingEnv.getFiler().createResource(StandardLocation.CLASS_OUTPUT,
- "", META_INF_SERVICES_LOCATION);
- Writer w = new OutputStreamWriter(f.openOutputStream(),"UTF-8");
- try {
- w.write(typeElement.getQualifiedName().toString());
- } finally {
- w.close();
- }
- }
-}
diff --git a/hudson-core/src/main/resources/META-INF/services/org.kohsuke.args4j.spi.OptionHandler b/hudson-core/src/main/resources/META-INF/services/org.kohsuke.args4j.spi.OptionHandler
new file mode 100644
index 00000000..21d3e856
--- /dev/null
+++ b/hudson-core/src/main/resources/META-INF/services/org.kohsuke.args4j.spi.OptionHandler
@@ -0,0 +1,2 @@
+hudson.cli.handlers.AbstractProjectOptionHandler
+hudson.cli.handlers.TopLevelItemOptionHandler
diff --git a/hudson-core/src/main/resources/hudson/model/BuildTimelineWidget/control.jelly b/hudson-core/src/main/resources/hudson/model/BuildTimelineWidget/control.jelly
index b59f5886..99bae19c 100644
--- a/hudson-core/src/main/resources/hudson/model/BuildTimelineWidget/control.jelly
+++ b/hudson-core/src/main/resources/hudson/model/BuildTimelineWidget/control.jelly
@@ -56,7 +56,7 @@
<j:invokeStatic var="tz" className="java.util.TimeZone" method="getDefault"/>
- <div id="tl" style="height:250px; border:1px solid black;" />
+ <div id="tl" class="timeline" />
<div id="status" />
<script type="text/javascript">
diff --git a/hudson-core/src/main/resources/hudson/model/Messages.properties b/hudson-core/src/main/resources/hudson/model/Messages.properties
index 49efb39c..17cc7df0 100644
--- a/hudson-core/src/main/resources/hudson/model/Messages.properties
+++ b/hudson-core/src/main/resources/hudson/model/Messages.properties
@@ -18,7 +18,8 @@ AbstractBuild.BuildingRemotely=Building remotely on {0}
AbstractBuild.BuildingOnMaster=Building on master
AbstractBuild.KeptBecause=kept because of {0}
-AbstractItem.NoSuchJobExists=No such job ''{0}'' exists. Perhaps you meant ''{1}''?
+AbstractItem.NoSuchJobExists=No such job ''{0}'' exists.
+AbstractItem.NoSuchJobExists2=No such job ''{0}'' exists. Perhaps you meant ''{1}''?
AbstractItem.Pronoun=Job
AbstractProject.NewBuildForWorkspace=Scheduling a new build to get a workspace.
AbstractProject.AwaitingBuildForWorkspace=Awaiting build to get a workspace.
diff --git a/hudson-core/src/main/resources/hudson/security/SecurityRealm/loginDialog.jelly b/hudson-core/src/main/resources/hudson/security/SecurityRealm/loginDialog.jelly
index 1970a49f..eef2528c 100644
--- a/hudson-core/src/main/resources/hudson/security/SecurityRealm/loginDialog.jelly
+++ b/hudson-core/src/main/resources/hudson/security/SecurityRealm/loginDialog.jelly
@@ -54,21 +54,6 @@
<input style="margin-left:10px; width:75px" type="button" id="cancelButton" value="${%Cancel}" />
</form>
- <style type="text/css">
- #loginError, #loginMsg {
- opacity:0;
- -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
- filter: alpha(opacity=0);
- text-align:center;
- font-weight:bold;
- }
- #loginError {
- color: red;
- }
- #loginMsg {
- color: black;
- }
- </style>
<div id="loginError">
${%Invalid login information. Please try again.}
diff --git a/hudson-core/src/main/resources/hudson/security/SecurityRealm/loginLink.jelly b/hudson-core/src/main/resources/hudson/security/SecurityRealm/loginLink.jelly
index e8505c29..206efa23 100644
--- a/hudson-core/src/main/resources/hudson/security/SecurityRealm/loginLink.jelly
+++ b/hudson-core/src/main/resources/hudson/security/SecurityRealm/loginLink.jelly
@@ -40,8 +40,8 @@
}
function submitForm(){
- jQuery('#loginMsg').css({ opacity: 1.0 });
- jQuery('#loginError').css({ opacity: 0.0 });
+ jQuery('#loginMsg').show();
+ jQuery('#loginError').hide();
var dataString = jQuery("#loginForm").serialize();
jQuery.ajax({
type: 'POST',
@@ -51,8 +51,8 @@
window.location.href="${from}";
},
error: function(){
- jQuery('#loginError').css({ opacity: 1.0 });
- jQuery('#loginMsg').css({ opacity: 0.0 });
+ jQuery('#loginError').show();
+ jQuery('#loginMsg').hide();
},
dataType: "html"
});
@@ -82,8 +82,8 @@
jQuery.unblockUI();
jQuery('#j_username').attr({value:""});
jQuery('#j_password').attr({value:""});
- jQuery('#loginError').css({ opacity: 0.0 });
- jQuery('#loginMsg').css({ opacity: 0.0 });
+ jQuery('#loginError').hide();
+ jQuery('#loginMsg').hide();
return false;
});
diff --git a/hudson-core/src/main/resources/lib/layout/layout.jelly b/hudson-core/src/main/resources/lib/layout/layout.jelly
index 3c487310..1cd09871 100644
--- a/hudson-core/src/main/resources/lib/layout/layout.jelly
+++ b/hudson-core/src/main/resources/lib/layout/layout.jelly
@@ -253,7 +253,7 @@
<div style=" height:100%">
<img src="${imagesURL}/top-left-round.png" style="float:left"/>
<div style="margin-left:25; height:25; background-image:url(${imagesURL}/spacer.png); background-repeat:repeat-x" />
- <div id="main-panel-container" style=" background-color:#FFF; padding-left: 10px; height:100%">
+ <div id="main-panel-container" style=" background-color:#FFFFFF; padding-left: 10px; height:100%">
<table width="95%" height="100%" border="0">
<tr>
<td id="global-messages" width="100%">

Back to the top