aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHenrik Lynggaard Hansen2012-07-17 15:55:51 (EDT)
committerHenrik Lynggaard Hansen2012-07-17 15:55:51 (EDT)
commitbbaac1367e66ef1a4a698664cabecd29abbb6fe4 (patch)
treed6da12fb4f3256f434b71202f5878fa0f548f6b7
parent825e47b2ae6a94d7be58a9f180e10928c8d62613 (diff)
downloadorg.eclipse.hudson.core-bbaac1367e66ef1a4a698664cabecd29abbb6fe4.zip
org.eclipse.hudson.core-bbaac1367e66ef1a4a698664cabecd29abbb6fe4.tar.gz
org.eclipse.hudson.core-bbaac1367e66ef1a4a698664cabecd29abbb6fe4.tar.bz2
Reformat hudson.os and hudson.schedulerrefs/changes/27/6827/1
Change-Id: If5f3ff060effd6a250969abf44d42ad34a3d6ec9 Signed-off-by: Henrik Lynggaard Hansen <henrik@hlyh.dk>
-rw-r--r--hudson-core/src/main/java/hudson/os/EmbeddedSu.java110
-rw-r--r--hudson-core/src/main/java/hudson/os/SU.java69
-rw-r--r--hudson-core/src/main/java/hudson/os/SuAuthenticationFailureException.java23
-rw-r--r--hudson-core/src/main/java/hudson/os/solaris/ZFSInstaller.java150
-rw-r--r--hudson-core/src/main/java/hudson/os/solaris/ZFSProvisioner.java27
-rw-r--r--hudson-core/src/main/java/hudson/os/solaris/package-info.java14
-rw-r--r--hudson-core/src/main/java/hudson/scheduler/BaseParser.java109
-rw-r--r--hudson-core/src/main/java/hudson/scheduler/CronTab.java285
-rw-r--r--hudson-core/src/main/java/hudson/scheduler/CronTabList.java20
-rw-r--r--hudson-core/src/main/java/hudson/scheduler/package.html4
10 files changed, 429 insertions, 382 deletions
diff --git a/hudson-core/src/main/java/hudson/os/EmbeddedSu.java b/hudson-core/src/main/java/hudson/os/EmbeddedSu.java
index c0a3924..7f2b73a 100644
--- a/hudson-core/src/main/java/hudson/os/EmbeddedSu.java
+++ b/hudson-core/src/main/java/hudson/os/EmbeddedSu.java
@@ -7,10 +7,10 @@
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
- * Contributors:
+ * Contributors:
*
* Kohsuke Kawaguchi
- *
+ *
*******************************************************************************/
package hudson.os;
@@ -27,11 +27,13 @@ import java.util.Collection;
import java.util.logging.Logger;
/**
- * Encapsulates the process launch through <tt>su</tt> (embedded_su(1M) to be exact)
+ * 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.
*/
@@ -39,105 +41,105 @@ public class EmbeddedSu {
}
/**
- * Launches a process as configured by {@link ProcessBuilder}, but under
- * a separate user priviledge by using <tt>su</tt> functionality.
+ * 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.
+ * @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)
+ 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() ) {
+ 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('\'');
+ 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()));
+ 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);
+ 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
- .
+ 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) {
+ while (true) {
String line = readLine(in);
- if(line.startsWith("CONV")) {
+ if (line.startsWith("CONV")) {
// how many blocks do we expect?
int n = Integer.parseInt(line.substring(5));
- for( int i=0; i<n; i++) {
+ 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")) {
+ 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")) {
+ 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")) {
+ if (header.startsWith("PAM_ERROR_MSG")) {
errorMessages.add(textBlock);
}
// ignore the rest
}
continue;
}
- if(line.startsWith("SUCCESS")) {
- LOGGER.fine("Authentication successful: "+line);
+ 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));
+ 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);
+ 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)
+ for (String a : col) {
buf.append(a);
+ }
return buf.toString();
}
@@ -150,8 +152,10 @@ public class EmbeddedSu {
ByteArrayOutputStream buf = new ByteArrayOutputStream();
int ch;
- while((ch=in.read())!=-1) {
- if(ch=='\n') return buf.toString();
+ while ((ch = in.read()) != -1) {
+ if (ch == '\n') {
+ return buf.toString();
+ }
buf.write(ch);
}
throw new EOFException();
@@ -163,18 +167,18 @@ public class EmbeddedSu {
private static String readTextBlock(InputStream in) throws IOException {
StringBuilder buf = new StringBuilder();
- while(true) {
+ while (true) {
String line = readLine(in);
- if(line.equals("."))
+ if (line.equals(".")) {
return buf.toString(); // end of it
-
- if(line.startsWith(".."))
+ }
+ if (line.startsWith("..")) {
buf.append(line.substring(1));
- else
+ } 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 cb6b2c6..cce4d9d 100644
--- a/hudson-core/src/main/java/hudson/os/SU.java
+++ b/hudson-core/src/main/java/hudson/os/SU.java
@@ -7,10 +7,10 @@
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
- * Contributors:
+ * Contributors:
*
* Kohsuke Kawaguchi
- *
+ *
*
*******************************************************************************/
@@ -36,43 +36,45 @@ import java.io.PrintStream;
import java.util.Collections;
/**
- * Executes {@link Callable} as the super user, by forking a new process and executing the closure in there
- * if necessary.
+ * Executes {@link Callable} as the super user, by forking a new process and
+ * executing the closure in there if necessary.
*
- * <p>
- * A best effort is made to execute the closure as root, but we may still end up exeucting the closure
- * in the non-root privilege, so the closure should expect that and handle it gracefully.
+ * <p> A best effort is made to execute the closure as root, but we may still
+ * end up exeucting the closure in the non-root privilege, so the closure should
+ * expect that and handle it gracefully.
*
- * <p>
- * Still very much experimental. Subject to change. <b>Don't use it.</b>
+ * <p> Still very much experimental. Subject to change. <b>Don't use it.</b>
*
* @author Kohsuke Kawaguchi
*/
public abstract class SU {
+
private SU() { // not meant to be instantiated
}
/**
- * Returns a {@link VirtualChannel} that's connected to the priviledge-escalated environment.
+ * Returns a {@link VirtualChannel} that's connected to the
+ * priviledge-escalated environment.
*
- * @return
- * Never null. This may represent a channel to a separate JVM, or just {@link LocalChannel}.
- * Close this channel and the SU environment will be shut down.
+ * @return Never null. This may represent a channel to a separate JVM, or
+ * just {@link LocalChannel}. Close this channel and the SU environment will
+ * be shut down.
*/
public static VirtualChannel start(final TaskListener listener, final String rootUsername, final String rootPassword) throws IOException, InterruptedException {
- if(File.pathSeparatorChar==';') // on Windows
+ if (File.pathSeparatorChar == ';') // on Windows
+ {
return newLocalChannel(); // TODO: perhaps use RunAs to run as an Administrator?
-
+ }
String os = Util.fixNull(System.getProperty("os.name"));
- if(os.equals("Linux"))
+ if (os.equals("Linux")) {
return new UnixSu() {
protected String sudoExe() {
return "sudo";
}
protected Process sudoWithPass(ArgumentListBuilder args) throws IOException {
- args.prepend(sudoExe(),"-S");
- listener.getLogger().println("$ "+Util.join(args.toList()," "));
+ args.prepend(sudoExe(), "-S");
+ listener.getLogger().println("$ " + Util.join(args.toList(), " "));
ProcessBuilder pb = new ProcessBuilder(args.toCommandArray());
Process p = pb.start();
// TODO: use -p to detect prompt
@@ -83,9 +85,10 @@ public abstract class SU {
ps.println(rootPassword);
return p;
}
- }.start(listener,rootPassword);
+ }.start(listener, rootPassword);
+ }
- if(os.equals("SunOS"))
+ if (os.equals("SunOS")) {
return new UnixSu() {
protected String sudoExe() {
return "/usr/bin/pfexec";
@@ -96,9 +99,10 @@ public abstract class SU {
ProcessBuilder pb = new ProcessBuilder(args.prepend(sudoExe()).toCommandArray());
return EmbeddedSu.startWithSu(rootUsername, rootPassword, pb);
}
- // in solaris, pfexec never asks for a password, so username==null means
- // we won't be using password. this helps disambiguate empty password
- }.start(listener,rootUsername==null?null:rootPassword);
+ // in solaris, pfexec never asks for a password, so username==null means
+ // we won't be using password. this helps disambiguate empty password
+ }.start(listener, rootUsername == null ? null : rootPassword);
+ }
// TODO: Mac?
@@ -111,9 +115,10 @@ public abstract class SU {
}
/**
- * Starts a new priviledge-escalated environment, execute a closure, and shut it down.
+ * Starts a new priviledge-escalated environment, execute a closure, and
+ * shut it down.
*/
- public static <V,T extends Throwable> V execute(TaskListener listener, String rootUsername, String rootPassword, final Callable<V, T> closure) throws T, IOException, InterruptedException {
+ public static <V, T extends Throwable> V execute(TaskListener listener, String rootUsername, String rootPassword, final Callable<V, T> closure) throws T, IOException, InterruptedException {
VirtualChannel ch = start(listener, rootUsername, rootPassword);
try {
return ch.call(closure);
@@ -138,19 +143,23 @@ public abstract class SU {
throw new IOException(exc);
}
- if(uid==0) // already running as root
+ if (uid == 0) // already running as root
+ {
return newLocalChannel();
+ }
String javaExe = System.getProperty("java.home") + "/bin/java";
File slaveJar = Which.jarFile(Launcher.class);
ArgumentListBuilder args = new ArgumentListBuilder().add(javaExe);
- if(slaveJar.isFile())
+ if (slaveJar.isFile()) {
args.add("-jar").add(slaveJar);
- else // in production code this never happens, but during debugging this is convenientud
+ } else // in production code this never happens, but during debugging this is convenientud
+ {
args.add("-cp").add(slaveJar).add(hudson.remoting.Launcher.class.getName());
+ }
- if(rootPassword==null) {
+ if (rootPassword == null) {
// try sudo, in the hope that the user has the permission to do so without password
return new LocalLauncher(listener).launchChannel(
args.prepend(sudoExe()).toCommandArray(),
@@ -159,7 +168,7 @@ public abstract class SU {
// try sudo with the given password. Also run in pfexec so that we can elevate the privileges
Process proc = sudoWithPass(args);
return Channels.forProcess(args.toStringWithQuote(), Computer.threadPoolForRemoting, proc,
- listener.getLogger() );
+ listener.getLogger());
}
}
}
diff --git a/hudson-core/src/main/java/hudson/os/SuAuthenticationFailureException.java b/hudson-core/src/main/java/hudson/os/SuAuthenticationFailureException.java
index ec85b93..e736086 100644
--- a/hudson-core/src/main/java/hudson/os/SuAuthenticationFailureException.java
+++ b/hudson-core/src/main/java/hudson/os/SuAuthenticationFailureException.java
@@ -1,18 +1,19 @@
-/*******************************************************************************
+/**
+ * *****************************************************************************
*
* 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
+ * 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
- *
- *******************************************************************************/
-
+ * Kohsuke Kawaguchi
+ *
+ ******************************************************************************
+ */
package hudson.os;
import java.io.IOException;
@@ -20,12 +21,12 @@ import java.io.IOException;
/**
* 'su' failed to authenticate the given credential.
*
- * <p>
- * Wrong password, invalid user name, that sort of things.
+ * <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/os/solaris/ZFSInstaller.java b/hudson-core/src/main/java/hudson/os/solaris/ZFSInstaller.java
index fca6905..e8ad794 100644
--- a/hudson-core/src/main/java/hudson/os/solaris/ZFSInstaller.java
+++ b/hudson-core/src/main/java/hudson/os/solaris/ZFSInstaller.java
@@ -7,10 +7,10 @@
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
- * Contributors:
+ * Contributors:
+ *
+ *
*
- *
- *
*
*******************************************************************************/
@@ -51,22 +51,21 @@ import java.util.logging.Level;
import java.util.logging.Logger;
/**
- * Encourages the user to migrate HUDSON_HOME on a ZFS file system.
+ * Encourages the user to migrate HUDSON_HOME on a ZFS file system.
*
* @author Kohsuke Kawaguchi
* @since 1.283
*/
public class ZFSInstaller extends AdministrativeMonitor implements Serializable {
+
/**
* True if $HUDSON_HOME is a ZFS file system by itself.
*/
private final boolean active = shouldBeActive();
-
/**
* This will be the file system name that we'll create.
*/
private String prospectiveZfsFileSystemName;
-
private NativeUtils nativeUtils = NativeUtils.getInstance();
public boolean isActivated() {
@@ -87,33 +86,34 @@ public class ZFSInstaller extends AdministrativeMonitor implements Serializable
}
private boolean shouldBeActive() {
- if(!System.getProperty("os.name").equals("SunOS") || disabled)
- // on systems that don't have ZFS, we don't need this monitor
+ if (!System.getProperty("os.name").equals("SunOS") || disabled) // on systems that don't have ZFS, we don't need this monitor
+ {
return false;
+ }
try {
List<NativeZfsFileSystem> roots = nativeUtils.getZfsRoots();
-
- if(roots.isEmpty())
- return false; // no active ZFS pool
+ if (roots.isEmpty()) {
+ return false; // no active ZFS pool
+ }
// if we don't run on a ZFS file system, activate
NativeZfsFileSystem hudsonZfs = nativeUtils.getZfsByMountPoint(Hudson.getInstance().getRootDir());
- if(hudsonZfs!=null)
+ if (hudsonZfs != null) {
return false; // already on ZFS
-
+ }
// decide what file system we'll create
NativeZfsFileSystem pool = roots.get(0);
-
+
prospectiveZfsFileSystemName = computeHudsonFileSystemName(pool);
return true;
} catch (Exception e) {
- LOGGER.log(Level.WARNING, "Failed to detect whether Hudson is on ZFS",e);
+ LOGGER.log(Level.WARNING, "Failed to detect whether Hudson is on ZFS", e);
return false;
} catch (LinkageError e) {
LOGGER.info("No ZFS available. If you believe this is an error, increase the logging level to get the stack trace");
- LOGGER.log(Level.FINE,"Stack trace of failed ZFS load",e);
+ LOGGER.log(Level.FINE, "Stack trace of failed ZFS load", e);
return false;
}
}
@@ -125,7 +125,7 @@ public class ZFSInstaller extends AdministrativeMonitor implements Serializable
requirePOST();
Hudson.getInstance().checkPermission(Hudson.ADMINISTER);
- if(req.hasParameter("n")) {
+ if (req.hasParameter("n")) {
// we'll shut up
disable(true);
return HttpResponses.redirectViaContextPath("/manage");
@@ -137,25 +137,23 @@ public class ZFSInstaller extends AdministrativeMonitor implements Serializable
/**
* Creates a ZFS file system to migrate the data to.
*
- * <p>
- * This has to be done while we still have an interactive access with the user, since it involves the password.
+ * <p> This has to be done while we still have an interactive access with
+ * the user, since it involves the password.
*
- * <p>
- * An exception will be thrown if the operation fails. A normal completion means a success.
+ * <p> An exception will be thrown if the operation fails. A normal
+ * completion means a success.
*
- * @return
- * The ZFS dataset name to migrate the data to.
+ * @return The ZFS dataset name to migrate the data to.
*/
private String createZfsFileSystem(final TaskListener listener, String rootUsername, String rootPassword) throws IOException, InterruptedException {
// capture the UID that Hudson runs under
// so that we can allow this user to do everything on this new partition
-
+
final File home = Hudson.getInstance().getRootDir();
// this is the actual creation of the file system.
// return true indicating a success
return SU.execute(listener, rootUsername, rootPassword, new Callable<String, IOException>() {
-
public String call() throws IOException {
NativeZfsFileSystem hudson = null;
try {
@@ -194,7 +192,7 @@ public class ZFSInstaller extends AdministrativeMonitor implements Serializable
return hudson.getName();
} catch (NativeAccessException ex) {
Logger.getLogger(ZFSInstaller.class.getName()).log(Level.SEVERE, null, ex);
- if (hudson != null){
+ if (hudson != null) {
hudson.destory();
}
throw new IOException();
@@ -207,7 +205,7 @@ public class ZFSInstaller extends AdministrativeMonitor implements Serializable
* Called from the confirmation screen to actually initiate the migration.
*/
public void doStart(StaplerRequest req, StaplerResponse rsp, @QueryParameter String username, @QueryParameter String password) throws ServletException, IOException {
- requirePOST();
+ requirePOST();
Hudson hudson = Hudson.getInstance();
hudson.checkPermission(Hudson.ADMINISTER);
@@ -215,23 +213,23 @@ public class ZFSInstaller extends AdministrativeMonitor implements Serializable
ByteArrayOutputStream log = new ByteArrayOutputStream();
StreamTaskListener listener = new StreamTaskListener(log);
try {
- datasetName = createZfsFileSystem(listener,username,password);
+ datasetName = createZfsFileSystem(listener, username, password);
} catch (Exception e) {
e.printStackTrace(listener.error(e.getMessage()));
if (e.getCause() instanceof NativeAccessException) {
NativeAccessException ze = (NativeAccessException) e;
- if(ze.getCode() == NativeAccessException.PERMISSION) {
+ if (ze.getCode() == NativeAccessException.PERMISSION) {
// permission problem. ask the user to give us the root password
- req.setAttribute("message",log.toString());
- rsp.forward(this,"askRootPassword",req);
+ req.setAttribute("message", log.toString());
+ rsp.forward(this, "askRootPassword", req);
return;
}
}
// for other kinds of problems, report and bail out
- req.setAttribute("pre",true);
- sendError(log.toString(),req,rsp);
+ req.setAttribute("pre", true);
+ sendError(log.toString(), req, rsp);
return;
}
@@ -239,7 +237,7 @@ public class ZFSInstaller extends AdministrativeMonitor implements Serializable
WebAppController.get().install(new HudsonIsRestarting());
// redirect the user to the manage page
- rsp.sendRedirect2(req.getContextPath()+"/manage");
+ rsp.sendRedirect2(req.getContextPath() + "/manage");
// asynchronously restart, so that we can give a bit of time to the browser to load "restarting..." screen.
new Thread("restart thread") {
@@ -247,15 +245,15 @@ public class ZFSInstaller extends AdministrativeMonitor implements Serializable
public void run() {
try {
Thread.sleep(5000);
-
+
Map<String, String> properties = new HashMap<String, String>();
properties.put("ZFSInstaller.migrate", datasetName);
nativeUtils.restartJavaProcess(properties, true);
} catch (NativeAccessException ex) {
- LOGGER.log(Level.SEVERE, "Restart failed", ex);
+ LOGGER.log(Level.SEVERE, "Restart failed", ex);
} catch (InterruptedException e) {
- LOGGER.log(Level.SEVERE, "Restart failed",e);
+ LOGGER.log(Level.SEVERE, "Restart failed", e);
}
}
}.start();
@@ -264,11 +262,11 @@ public class ZFSInstaller extends AdministrativeMonitor implements Serializable
@Extension
public static AdministrativeMonitor init() {
String migrationTarget = System.getProperty(ZFSInstaller.class.getName() + ".migrate");
- if(migrationTarget!=null) {
+ if (migrationTarget != null) {
ByteArrayOutputStream out = new ByteArrayOutputStream();
StreamTaskListener listener = new StreamTaskListener(new ForkOutputStream(System.out, out));
try {
- if(migrate(listener,migrationTarget)) {
+ if (migrate(listener, migrationTarget)) {
// completed successfully
return new MigrationCompleteNotice();
}
@@ -282,8 +280,9 @@ public class ZFSInstaller extends AdministrativeMonitor implements Serializable
// install the monitor if applicable
ZFSInstaller zi = new ZFSInstaller();
- if(zi.isActivated())
+ if (zi.isActivated()) {
return zi;
+ }
return null;
}
@@ -293,62 +292,61 @@ public class ZFSInstaller extends AdministrativeMonitor implements Serializable
*
* TODO: do this in a separate JVM to elevate the privilege.
*
- * @param listener
- * Log of migration goes here.
- * @param target
- * Dataset to move the data to.
- * @return
- * false if a migration failed.
+ * @param listener Log of migration goes here.
+ * @param target Dataset to move the data to.
+ * @return false if a migration failed.
*/
private static boolean migrate(TaskListener listener, String target) throws IOException, InterruptedException {
try {
NativeUtils nativeUtils = NativeUtils.getInstance();
-
+
PrintStream out = listener.getLogger();
File home = Hudson.getInstance().getRootDir();
// do the migration
NativeZfsFileSystem existing = nativeUtils.getZfsByMountPoint(home);
- if(existing!=null) {
- out.println(home+" is already on ZFS. Doing nothing");
+ if (existing != null) {
+ out.println(home + " is already on ZFS. Doing nothing");
return true;
}
File tmpDir = Util.createTempDir();
// mount a new file system to a temporary location
- out.println("Opening "+target);
+ out.println("Opening " + target);
NativeZfsFileSystem hudson = nativeUtils.openZfs(target);
hudson.setMountPoint(tmpDir);
- hudson.setProperty("hudson:managed-by","hudson"); // mark this file system as "managed by Hudson"
+ hudson.setProperty("hudson:managed-by", "hudson"); // mark this file system as "managed by Hudson"
hudson.mount();
// copy all the files
out.println("Copying all existing data files");
- if(system(home,listener, "/usr/bin/cp","-pR",".", tmpDir.getAbsolutePath())!=0) {
- out.println("Failed to copy "+home+" to "+tmpDir);
+ if (system(home, listener, "/usr/bin/cp", "-pR", ".", tmpDir.getAbsolutePath()) != 0) {
+ out.println("Failed to copy " + home + " to " + tmpDir);
return false;
}
// unmount
- out.println("Unmounting "+target);
+ out.println("Unmounting " + target);
hudson.unmount(NativeZfsFileSystem.MS_FORCE);
// move the original directory to the side
- File backup = new File(home.getPath()+".backup");
- out.println("Moving "+home+" to "+backup);
- if(backup.exists())
+ File backup = new File(home.getPath() + ".backup");
+ out.println("Moving " + home + " to " + backup);
+ if (backup.exists()) {
Util.deleteRecursive(backup);
- if(!home.renameTo(backup)) {
- out.println("Failed to move your current data "+home+" out of the way");
+ }
+ if (!home.renameTo(backup)) {
+ out.println("Failed to move your current data " + home + " out of the way");
}
// update the mount point
- out.println("Creating a new mount point at "+home);
- if(!home.mkdir())
- throw new IOException("Failed to create mount point "+home);
+ out.println("Creating a new mount point at " + home);
+ if (!home.mkdir()) {
+ throw new IOException("Failed to create mount point " + home);
+ }
- out.println("Mounting "+target);
+ out.println("Mounting " + target);
hudson.setMountPoint(home);
hudson.mount();
@@ -359,9 +357,9 @@ public class ZFSInstaller extends AdministrativeMonitor implements Serializable
hudson.share();
// delete back up
- out.println("Deleting "+backup);
- if(system(new File("/"),listener,"/usr/bin/rm","-rf",backup.getAbsolutePath())!=0) {
- out.println("Failed to delete "+backup.getAbsolutePath());
+ out.println("Deleting " + backup);
+ if (system(new File("/"), listener, "/usr/bin/rm", "-rf", backup.getAbsolutePath()) != 0) {
+ out.println("Failed to delete " + backup.getAbsolutePath());
return false;
}
@@ -380,13 +378,15 @@ public class ZFSInstaller extends AdministrativeMonitor implements Serializable
private static String computeHudsonFileSystemName(NativeZfsFileSystem top) {
try {
NativeUtils nativeUtils = NativeUtils.getInstance();
-
- if(!nativeUtils.zfsExists(top.getName()+"/hudson"))
- return top.getName()+"/hudson";
- for( int i = 2; ; i++ ) {
+
+ if (!nativeUtils.zfsExists(top.getName() + "/hudson")) {
+ return top.getName() + "/hudson";
+ }
+ for (int i = 2;; i++) {
String name = top.getName() + "/hudson" + i;
- if(!nativeUtils.zfsExists(name))
+ if (!nativeUtils.zfsExists(name)) {
return name;
+ }
}
} catch (NativeAccessException ex) {
Logger.getLogger(ZFSInstaller.class.getName()).log(Level.SEVERE, null, ex);
@@ -398,6 +398,7 @@ public class ZFSInstaller extends AdministrativeMonitor implements Serializable
* Used to indicate that the migration was completed successfully.
*/
public static final class MigrationCompleteNotice extends AdministrativeMonitor {
+
public boolean isActivated() {
return true;
}
@@ -407,6 +408,7 @@ public class ZFSInstaller extends AdministrativeMonitor implements Serializable
* Used to indicate a failure in the migration.
*/
public static final class MigrationFailedNotice extends AdministrativeMonitor {
+
ByteArrayOutputStream record;
MigrationFailedNotice(ByteArrayOutputStream record) {
@@ -416,16 +418,14 @@ public class ZFSInstaller extends AdministrativeMonitor implements Serializable
public boolean isActivated() {
return true;
}
-
+
public String getLog() {
return record.toString();
}
}
-
private static final Logger LOGGER = Logger.getLogger(ZFSInstaller.class.getName());
-
/**
* Escape hatch in case JNI calls fatally crash, like in HUDSON-3733.
*/
- public static boolean disabled = Boolean.getBoolean(ZFSInstaller.class.getName()+".disabled");
+ public static boolean disabled = Boolean.getBoolean(ZFSInstaller.class.getName() + ".disabled");
}
diff --git a/hudson-core/src/main/java/hudson/os/solaris/ZFSProvisioner.java b/hudson-core/src/main/java/hudson/os/solaris/ZFSProvisioner.java
index ce20ba8..8db67aa 100644
--- a/hudson-core/src/main/java/hudson/os/solaris/ZFSProvisioner.java
+++ b/hudson-core/src/main/java/hudson/os/solaris/ZFSProvisioner.java
@@ -7,10 +7,10 @@
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
- * Contributors:
+ * Contributors:
+ *
+ *
*
- *
- *
*
*******************************************************************************/
@@ -43,7 +43,7 @@ import java.util.logging.Logger;
* @author Kohsuke Kawaguchi
*/
public class ZFSProvisioner extends FileSystemProvisioner implements Serializable {
-
+
private NativeUtils nativeUtils = NativeUtils.getInstance();
private final Node node;
private final String rootDataset;
@@ -54,22 +54,23 @@ public class ZFSProvisioner extends FileSystemProvisioner implements Serializabl
public String invoke(File f, VirtualChannel channel) throws IOException {
try {
NativeZfsFileSystem fs = nativeUtils.getZfsByMountPoint(f);
- if(fs != null) return fs.getName();
+ if (fs != null) {
+ return fs.getName();
+ }
} catch (NativeAccessException ex) {
Logger.getLogger(ZFSProvisioner.class.getName()).log(Level.SEVERE, null, ex);
}
-
+
// TODO: for now, only support slaves that are already on ZFS.
throw new IOException("Not on ZFS");
}
});
}
- public void prepareWorkspace(AbstractBuild<?,?> build, FilePath ws, final TaskListener listener) throws IOException, InterruptedException {
+ public void prepareWorkspace(AbstractBuild<?, ?> build, FilePath ws, final TaskListener listener) throws IOException, InterruptedException {
final String name = build.getProject().getFullName();
-
- ws.act(new FileCallable<Void>() {
+ ws.act(new FileCallable<Void>() {
public Void invoke(File f, VirtualChannel channel) throws IOException {
try {
NativeZfsFileSystem fs = nativeUtils.getZfsByMountPoint(f);
@@ -96,13 +97,13 @@ public class ZFSProvisioner extends FileSystemProvisioner implements Serializabl
public Void invoke(File f, VirtualChannel channel) throws IOException {
try {
NativeZfsFileSystem fs = nativeUtils.getZfsByMountPoint(f);
- if(fs != null){
- fs.destory(true);
+ if (fs != null) {
+ fs.destory(true);
}
} catch (NativeAccessException ex) {
Logger.getLogger(ZFSProvisioner.class.getName()).log(Level.SEVERE, null, ex);
}
-
+
return null;
}
});
@@ -121,6 +122,7 @@ public class ZFSProvisioner extends FileSystemProvisioner implements Serializabl
@Extension
public static final class DescriptorImpl extends FileSystemProvisionerDescriptor {
+
public boolean discard(FilePath ws, TaskListener listener) throws IOException, InterruptedException {
// TODO
return false;
@@ -130,6 +132,5 @@ public class ZFSProvisioner extends FileSystemProvisioner implements Serializabl
return "ZFS";
}
}
-
private static final long serialVersionUID = 1L;
}
diff --git a/hudson-core/src/main/java/hudson/os/solaris/package-info.java b/hudson-core/src/main/java/hudson/os/solaris/package-info.java
index 065099e..aa20300 100644
--- a/hudson-core/src/main/java/hudson/os/solaris/package-info.java
+++ b/hudson-core/src/main/java/hudson/os/solaris/package-info.java
@@ -1,16 +1,18 @@
-/*******************************************************************************
+/**
+ * *****************************************************************************
*
* 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:
- *
*
- *******************************************************************************/
+ *
+ ******************************************************************************
+ */
/**
* Solaris specific features of Hudson.
*/
diff --git a/hudson-core/src/main/java/hudson/scheduler/BaseParser.java b/hudson-core/src/main/java/hudson/scheduler/BaseParser.java
index 364c263..823c435 100644
--- a/hudson-core/src/main/java/hudson/scheduler/BaseParser.java
+++ b/hudson-core/src/main/java/hudson/scheduler/BaseParser.java
@@ -7,11 +7,11 @@
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
- * Contributors:
-*
+ * Contributors:
+ *
* Kohsuke Kawaguchi
-*
- *
+ *
+ *
*
*******************************************************************************/
@@ -23,30 +23,31 @@ import org.antlr.runtime.RecognizerSharedState;
import org.antlr.runtime.Token;
import org.antlr.runtime.TokenStream;
-
-
/**
* @author Kohsuke Kawaguchi
*/
abstract class BaseParser extends Parser {
- private static final int[] LOWER_BOUNDS = new int[] {0,0,1,0,0};
- private static final int[] UPPER_BOUNDS = new int[] {59,23,31,12,7};
+
+ private static final int[] LOWER_BOUNDS = new int[]{0, 0, 1, 0, 0};
+ private static final int[] UPPER_BOUNDS = new int[]{59, 23, 31, 12, 7};
protected BaseParser(TokenStream tokenStream) {
super(tokenStream);
}
-
+
protected BaseParser(TokenStream stream, RecognizerSharedState sharedState) {
- super(stream, sharedState);
+ super(stream, sharedState);
}
protected long doRange(int start, int end, int step, int field) throws RecognitionException {
rangeCheck(start, field);
rangeCheck(end, field);
- if (step <= 0)
+ if (step <= 0) {
error(Messages.BaseParser_MustBePositive(step));
- if (start>end)
- error(Messages.BaseParser_StartEndReversed(end,start));
+ }
+ if (start > end) {
+ error(Messages.BaseParser_StartEndReversed(end, start));
+ }
long bits = 0;
for (int i = start; i <= end; i += step) {
@@ -55,56 +56,58 @@ abstract class BaseParser extends Parser {
return bits;
}
- protected long doRange( int step, int field ) throws RecognitionException {
- return doRange( LOWER_BOUNDS[field], UPPER_BOUNDS[field], step, field );
+ protected long doRange(int step, int field) throws RecognitionException {
+ return doRange(LOWER_BOUNDS[field], UPPER_BOUNDS[field], step, field);
}
protected void rangeCheck(int value, int field) throws RecognitionException {
- if( value<LOWER_BOUNDS[field] || UPPER_BOUNDS[field]<value ) {
- error(Messages.BaseParser_OutOfRange(value,LOWER_BOUNDS[field],UPPER_BOUNDS[field]));
+ if (value < LOWER_BOUNDS[field] || UPPER_BOUNDS[field] < value) {
+ error(Messages.BaseParser_OutOfRange(value, LOWER_BOUNDS[field], UPPER_BOUNDS[field]));
}
}
private void error(String msg) throws RecognitionException {
Token token = getTokenStream().LT(0);
throw new SemanticException(
- msg,
- token.getLine(),
- token.getCharPositionInLine()
- );
+ msg,
+ token.getLine(),
+ token.getCharPositionInLine());
}
-
+
public static class SemanticException extends RecognitionException {
- String msg;
- Throwable throwable;
-
- public SemanticException(String msg, int line, int charPositionInLine) {
- super();
- this.msg = msg;
- this.line = line;
- this.charPositionInLine = charPositionInLine;
- }
-
- public SemanticException(String msg, Throwable e) {
- super();
- this.msg = msg;
- this.throwable = e;
- }
-
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder("SemanticException: ");
- sb.append(msg);
- if (line > 0 || charPositionInLine > 0)
- sb.append(" at [").append(line).append(',').append(charPositionInLine);
- if (throwable != null)
- sb.append(" from ").append(throwable.toString());
- return sb.toString();
- }
-
- @Override
- public String getMessage() {
- return msg;
- }
+
+ String msg;
+ Throwable throwable;
+
+ public SemanticException(String msg, int line, int charPositionInLine) {
+ super();
+ this.msg = msg;
+ this.line = line;
+ this.charPositionInLine = charPositionInLine;
+ }
+
+ public SemanticException(String msg, Throwable e) {
+ super();
+ this.msg = msg;
+ this.throwable = e;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder("SemanticException: ");
+ sb.append(msg);
+ if (line > 0 || charPositionInLine > 0) {
+ sb.append(" at [").append(line).append(',').append(charPositionInLine);
+ }
+ if (throwable != null) {
+ sb.append(" from ").append(throwable.toString());
+ }
+ return sb.toString();
+ }
+
+ @Override
+ public String getMessage() {
+ return msg;
+ }
}
}
diff --git a/hudson-core/src/main/java/hudson/scheduler/CronTab.java b/hudson-core/src/main/java/hudson/scheduler/CronTab.java
index 503e341..35cfea5 100644
--- a/hudson-core/src/main/java/hudson/scheduler/CronTab.java
+++ b/hudson-core/src/main/java/hudson/scheduler/CronTab.java
@@ -7,10 +7,10 @@
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
- * Contributors:
-*
-* Kohsuke Kawaguchi, InfraDNA, Inc.
- *
+ * Contributors:
+ *
+ * Kohsuke Kawaguchi, InfraDNA, Inc.
+ *
*
*******************************************************************************/
@@ -32,25 +32,21 @@ import org.antlr.runtime.RecognitionException;
* @author Kohsuke Kawaguchi
*/
public final class CronTab {
+
/**
- * bits[0]: minutes
- * bits[1]: hours
- * bits[2]: days
- * bits[3]: months
+ * bits[0]: minutes bits[1]: hours bits[2]: days bits[3]: months
*
* false:not scheduled &lt;-> true scheduled
*/
final long[] bits = new long[4];
-
int dayOfWeek;
-
/**
* Textual representation.
*/
private String spec;
public CronTab(String format) throws RecognitionException {
- this(format,1);
+ this(format, 1);
}
public CronTab(String format, int line) throws RecognitionException {
@@ -65,56 +61,64 @@ public final class CronTab {
spec = format;
parser.startRule(this);
- if((dayOfWeek&(1<<7))!=0)
+ if ((dayOfWeek & (1 << 7)) != 0) {
dayOfWeek |= 1; // copy bit 7 over to bit 0
+ }
}
-
/**
* Returns true if the given calendar matches
*/
boolean check(Calendar cal) {
- if(!checkBits(bits[0],cal.get(MINUTE)))
+ if (!checkBits(bits[0], cal.get(MINUTE))) {
return false;
- if(!checkBits(bits[1],cal.get(HOUR_OF_DAY)))
+ }
+ if (!checkBits(bits[1], cal.get(HOUR_OF_DAY))) {
return false;
- if(!checkBits(bits[2],cal.get(DAY_OF_MONTH)))
+ }
+ if (!checkBits(bits[2], cal.get(DAY_OF_MONTH))) {
return false;
- if(!checkBits(bits[3],cal.get(MONTH)+1))
+ }
+ if (!checkBits(bits[3], cal.get(MONTH) + 1)) {
return false;
- if(!checkBits(dayOfWeek,cal.get(Calendar.DAY_OF_WEEK)-1))
+ }
+ if (!checkBits(dayOfWeek, cal.get(Calendar.DAY_OF_WEEK) - 1)) {
return false;
+ }
return true;
}
private static abstract class CalendarField {
+
/**
* {@link Calendar} field ID.
*/
final int field;
/**
- * Lower field is a calendar field whose value needs to be reset when we change the value in this field.
- * For example, if we modify the value in HOUR, MINUTES must be reset.
+ * Lower field is a calendar field whose value needs to be reset when we
+ * change the value in this field. For example, if we modify the value
+ * in HOUR, MINUTES must be reset.
*/
final CalendarField lowerField;
/**
- * Whether this field is 0-origin or 1-origin differs between Crontab and {@link Calendar},
- * so this field adjusts that. If crontab is 1 origin and calendar is 0 origin, this field is 1
- * that is the value is {@code (cronOrigin-calendarOrigin)}
+ * Whether this field is 0-origin or 1-origin differs between Crontab
+ * and {@link Calendar}, so this field adjusts that. If crontab is 1
+ * origin and calendar is 0 origin, this field is 1 that is the value is
+ * {@code (cronOrigin-calendarOrigin)}
*/
final int offset;
/**
- * When we reset this field, we set the field to this value.
- * For example, resetting {@link Calendar#DAY_OF_MONTH} means setting it to 1.
+ * When we reset this field, we set the field to this value. For
+ * example, resetting {@link Calendar#DAY_OF_MONTH} means setting it to
+ * 1.
*/
final int min;
/**
- * If this calendar field has other aliases such that a change in this field
- * modifies other field values, then true.
+ * If this calendar field has other aliases such that a change in this
+ * field modifies other field values, then true.
*/
final boolean redoAdjustmentIfModified;
-
/**
* What is this field? Useful for debugging
*/
@@ -124,7 +128,7 @@ public final class CronTab {
this.displayName = displayName;
this.field = field;
this.min = min;
- this.redoAdjustmentIfModified= redoAdjustmentIfModified;
+ this.redoAdjustmentIfModified = redoAdjustmentIfModified;
this.lowerField = lowerField;
this.offset = offset;
}
@@ -133,15 +137,15 @@ public final class CronTab {
* Gets the current value of this field in the given calendar.
*/
int valueOf(Calendar c) {
- return c.get(field)+offset;
+ return c.get(field) + offset;
}
void addTo(Calendar c, int i) {
- c.add(field,i);
+ c.add(field, i);
}
void setTo(Calendar c, int i) {
- c.set(field,i-offset);
+ c.set(field, i - offset);
}
void clear(Calendar c) {
@@ -149,43 +153,50 @@ public final class CronTab {
}
/**
- * Given the value 'n' (which represents the current value), finds the smallest x such that:
- * 1) x matches the specified {@link CronTab} (as far as this field is concerned.)
- * 2) x>=n (inclusive)
+ * Given the value 'n' (which represents the current value), finds the
+ * smallest x such that: 1) x matches the specified {@link CronTab} (as
+ * far as this field is concerned.) 2) x>=n (inclusive)
*
- * If there's no such bit, return -1. Note that if 'n' already matches the crontab, the same n will be returned.
+ * If there's no such bit, return -1. Note that if 'n' already matches
+ * the crontab, the same n will be returned.
*/
private int ceil(CronTab c, int n) {
long bits = bits(c);
- while ((bits|(1L<<n))!=bits) {
- if (n>60) return -1;
+ while ((bits | (1L << n)) != bits) {
+ if (n > 60) {
+ return -1;
+ }
n++;
}
return n;
}
/**
- * Given a bit mask, finds the first bit that's on, and return its index.
+ * Given a bit mask, finds the first bit that's on, and return its
+ * index.
*/
private int first(CronTab c) {
- return ceil(c,0);
+ return ceil(c, 0);
}
private int floor(CronTab c, int n) {
long bits = bits(c);
- while ((bits|(1L<<n))!=bits) {
- if (n==0) return -1;
+ while ((bits | (1L << n)) != bits) {
+ if (n == 0) {
+ return -1;
+ }
n--;
}
return n;
}
private int last(CronTab c) {
- return floor(c,63);
+ return floor(c, 63);
}
/**
- * Extracts the bit masks from the given {@link CronTab} that matches this field.
+ * Extracts the bit masks from the given {@link CronTab} that matches
+ * this field.
*/
abstract long bits(CronTab c);
@@ -193,60 +204,76 @@ public final class CronTab {
* Increment the next field.
*/
abstract void rollUp(Calendar cal, int i);
+ private static final CalendarField MINUTE = new CalendarField("minute", Calendar.MINUTE, 0, 0, false, null) {
+ long bits(CronTab c) {
+ return c.bits[0];
+ }
- private static final CalendarField MINUTE = new CalendarField("minute", Calendar.MINUTE, 0, 0, false, null) {
- long bits(CronTab c) { return c.bits[0]; }
- void rollUp(Calendar cal, int i) { cal.add(Calendar.HOUR_OF_DAY,i); }
+ void rollUp(Calendar cal, int i) {
+ cal.add(Calendar.HOUR_OF_DAY, i);
+ }
};
- private static final CalendarField HOUR = new CalendarField("hour", Calendar.HOUR_OF_DAY, 0, 0, false, MINUTE) {
- long bits(CronTab c) { return c.bits[1]; }
- void rollUp(Calendar cal, int i) { cal.add(Calendar.DAY_OF_MONTH,i); }
+ private static final CalendarField HOUR = new CalendarField("hour", Calendar.HOUR_OF_DAY, 0, 0, false, MINUTE) {
+ long bits(CronTab c) {
+ return c.bits[1];
+ }
+
+ void rollUp(Calendar cal, int i) {
+ cal.add(Calendar.DAY_OF_MONTH, i);
+ }
};
- private static final CalendarField DAY_OF_MONTH = new CalendarField("day", Calendar.DAY_OF_MONTH, 1, 0, true, HOUR) {
- long bits(CronTab c) { return c.bits[2]; }
- void rollUp(Calendar cal, int i) { cal.add(Calendar.MONTH,i); }
+ private static final CalendarField DAY_OF_MONTH = new CalendarField("day", Calendar.DAY_OF_MONTH, 1, 0, true, HOUR) {
+ long bits(CronTab c) {
+ return c.bits[2];
+ }
+
+ void rollUp(Calendar cal, int i) {
+ cal.add(Calendar.MONTH, i);
+ }
};
- private static final CalendarField MONTH = new CalendarField("month", Calendar.MONTH, 1, 1, false, DAY_OF_MONTH) {
- long bits(CronTab c) { return c.bits[3]; }
- void rollUp(Calendar cal, int i) { cal.add(Calendar.YEAR,i); }
+ private static final CalendarField MONTH = new CalendarField("month", Calendar.MONTH, 1, 1, false, DAY_OF_MONTH) {
+ long bits(CronTab c) {
+ return c.bits[3];
+ }
+
+ void rollUp(Calendar cal, int i) {
+ cal.add(Calendar.YEAR, i);
+ }
};
- private static final CalendarField DAY_OF_WEEK = new CalendarField("dow", Calendar.DAY_OF_WEEK, 1,-1, true, HOUR) {
- long bits(CronTab c) { return c.dayOfWeek; }
+ private static final CalendarField DAY_OF_WEEK = new CalendarField("dow", Calendar.DAY_OF_WEEK, 1, -1, true, HOUR) {
+ long bits(CronTab c) {
+ return c.dayOfWeek;
+ }
+
void rollUp(Calendar cal, int i) {
- cal.add(Calendar.DAY_OF_WEEK,7);
+ cal.add(Calendar.DAY_OF_WEEK, 7);
}
@Override
void setTo(Calendar c, int i) {
- int v = i-offset;
- c.set(field,v);
- if (v<c.getFirstDayOfWeek()) {
+ int v = i - offset;
+ c.set(field, v);
+ if (v < c.getFirstDayOfWeek()) {
// in crontab, the first DoW is always Sunday, but in Java, it can be Monday or in theory arbitrary other days.
// When first DoW is 1/2 Monday, calendar points to 1/2 Monday, setting the DoW to Sunday makes
// the calendar moves forward to 1/8 Sunday, instead of 1/1 Sunday. So we need to compensate that effect here.
- addTo(c,-7);
+ addTo(c, -7);
}
}
};
-
private static final CalendarField[] ADJUST_ORDER = {
MONTH, DAY_OF_MONTH, DAY_OF_WEEK, HOUR, MINUTE
};
}
-
/**
- * Computes the nearest future timestamp that matches this cron tab.
- * <p>
- * More precisely, given the time 't', computes another smallest time x such that:
+ * Computes the nearest future timestamp that matches this cron tab. <p>
+ * More precisely, given the time 't', computes another smallest time x such
+ * that:
*
- * <ul>
- * <li>x >= t (inclusive)
- * <li>x matches this crontab
- * </ul>
+ * <ul> <li>x >= t (inclusive) <li>x matches this crontab </ul>
*
- * <p>
- * Note that if t already matches this cron, it's returned as is.
+ * <p> Note that if t already matches this cron, it's returned as is.
*/
public Calendar ceil(long t) {
Calendar cal = new GregorianCalendar(Locale.US);
@@ -264,23 +291,26 @@ public final class CronTab {
while (true) {
for (CalendarField f : CalendarField.ADJUST_ORDER) {
int cur = f.valueOf(cal);
- int next = f.ceil(this,cur);
- if (cur==next) continue; // this field is already in a good shape. move on to next
-
+ int next = f.ceil(this, cur);
+ if (cur == next) {
+ continue; // this field is already in a good shape. move on to next
+ }
// we are modifying this field, so clear all the lower level fields
- for (CalendarField l=f.lowerField; l!=null; l=l.lowerField)
+ for (CalendarField l = f.lowerField; l != null; l = l.lowerField) {
l.clear(cal);
+ }
- if (next<0) {
+ if (next < 0) {
// we need to roll over to the next field.
f.rollUp(cal, 1);
- f.setTo(cal,f.first(this));
+ f.setTo(cal, f.first(this));
// since higher order field is affected by this, we need to restart from all over
continue OUTER;
} else {
- f.setTo(cal,next);
- if (f.redoAdjustmentIfModified)
+ f.setTo(cal, next);
+ if (f.redoAdjustmentIfModified) {
continue OUTER; // when we modify DAY_OF_MONTH and DAY_OF_WEEK, do it all over from the top
+ }
}
}
return cal; // all fields adjusted
@@ -288,17 +318,13 @@ public final class CronTab {
}
/**
- * Computes the nearest past timestamp that matched this cron tab.
- * <p>
- * More precisely, given the time 't', computes another smallest time x such that:
+ * Computes the nearest past timestamp that matched this cron tab. <p> More
+ * precisely, given the time 't', computes another smallest time x such
+ * that:
*
- * <ul>
- * <li>x &lt;= t (inclusive)
- * <li>x matches this crontab
- * </ul>
+ * <ul> <li>x &lt;= t (inclusive) <li>x matches this crontab </ul>
*
- * <p>
- * Note that if t already matches this cron, it's returned as is.
+ * <p> Note that if t already matches this cron, it's returned as is.
*/
public Calendar floor(long t) {
Calendar cal = new GregorianCalendar(Locale.US);
@@ -316,32 +342,35 @@ public final class CronTab {
while (true) {
for (CalendarField f : CalendarField.ADJUST_ORDER) {
int cur = f.valueOf(cal);
- int next = f.floor(this,cur);
- if (cur==next) continue; // this field is already in a good shape. move on to next
-
+ int next = f.floor(this, cur);
+ if (cur == next) {
+ continue; // this field is already in a good shape. move on to next
+ }
// we are modifying this field, so clear all the lower level fields
- for (CalendarField l=f.lowerField; l!=null; l=l.lowerField)
+ for (CalendarField l = f.lowerField; l != null; l = l.lowerField) {
l.clear(cal);
+ }
- if (next<0) {
+ if (next < 0) {
// we need to borrow from the next field.
- f.rollUp(cal,-1);
+ f.rollUp(cal, -1);
// the problem here, in contrast with the ceil method, is that
// the maximum value of the field is not always a fixed value (that is, day of month)
// so we zero-clear all the lower fields, set the desired value +1,
- f.setTo(cal,f.last(this));
- f.addTo(cal,1);
+ f.setTo(cal, f.last(this));
+ f.addTo(cal, 1);
// then subtract a minute to achieve maximum values on all the lower fields,
// with the desired value in 'f'
- CalendarField.MINUTE.addTo(cal,-1);
+ CalendarField.MINUTE.addTo(cal, -1);
// since higher order field is affected by this, we need to restart from all over
continue OUTER;
} else {
- f.setTo(cal,next);
- f.addTo(cal,1);
- CalendarField.MINUTE.addTo(cal,-1);
- if (f.redoAdjustmentIfModified)
+ f.setTo(cal, next);
+ f.addTo(cal, 1);
+ CalendarField.MINUTE.addTo(cal, -1);
+ if (f.redoAdjustmentIfModified) {
continue OUTER; // when we modify DAY_OF_MONTH and DAY_OF_WEEK, do it all over from the top
+ }
}
}
return cal; // all fields adjusted
@@ -349,48 +378,47 @@ public final class CronTab {
}
void set(String format) throws RecognitionException {
- set(format,1);
+ set(format, 1);
}
/**
* Returns true if n-th bit is on.
*/
private boolean checkBits(long bitMask, int n) {
- return (bitMask|(1L<<n))==bitMask;
+ return (bitMask | (1L << n)) == bitMask;
}
public String toString() {
- return super.toString()+"["+
- toString("minute",bits[0])+','+
- toString("hour",bits[1])+','+
- toString("dayOfMonth",bits[2])+','+
- toString("month",bits[3])+','+
- toString("dayOfWeek",dayOfWeek)+']';
+ return super.toString() + "["
+ + toString("minute", bits[0]) + ','
+ + toString("hour", bits[1]) + ','
+ + toString("dayOfMonth", bits[2]) + ','
+ + toString("month", bits[3]) + ','
+ + toString("dayOfWeek", dayOfWeek) + ']';
}
private String toString(String key, long bit) {
- return key+'='+Long.toHexString(bit);
+ return key + '=' + Long.toHexString(bit);
}
/**
- * Checks if this crontab entry looks reasonable,
- * and if not, return an warning message.
+ * Checks if this crontab entry looks reasonable, and if not, return an
+ * warning message.
*
- * <p>
- * The point of this method is to catch syntactically correct
- * but semantically suspicious combinations, like
- * "* 0 * * *"
+ * <p> The point of this method is to catch syntactically correct but
+ * semantically suspicious combinations, like "* 0 * * *"
*/
public String checkSanity() {
- for( int i=0; i<5; i++ ) {
- long bitMask = (i<4)?bits[i]:(long)dayOfWeek;
- for( int j=LOWER_BOUNDS[i]; j<=UPPER_BOUNDS[i]; j++ ) {
- if(!checkBits(bitMask,j)) {
+ for (int i = 0; i < 5; i++) {
+ long bitMask = (i < 4) ? bits[i] : (long) dayOfWeek;
+ for (int j = LOWER_BOUNDS[i]; j <= UPPER_BOUNDS[i]; j++) {
+ if (!checkBits(bitMask, j)) {
// this rank has a sparse entry.
// if we have a sparse rank, one of them better be the left-most.
- if(i>0)
- return "Do you really mean \"every minute\" when you say \""+spec+"\"? "+
- "Perhaps you meant \"0 "+spec.substring(spec.indexOf(' ')+1)+"\"";
+ if (i > 0) {
+ return "Do you really mean \"every minute\" when you say \"" + spec + "\"? "
+ + "Perhaps you meant \"0 " + spec.substring(spec.indexOf(' ') + 1) + "\"";
+ }
// once we find a sparse rank, upper ranks don't matter
return null;
}
@@ -399,8 +427,7 @@ public final class CronTab {
return null;
}
-
// lower/uppser bounds of fields
- private static final int[] LOWER_BOUNDS = new int[] {0,0,1,0,0};
- private static final int[] UPPER_BOUNDS = new int[] {59,23,31,12,7};
+ private static final int[] LOWER_BOUNDS = new int[]{0, 0, 1, 0, 0};
+ private static final int[] UPPER_BOUNDS = new int[]{59, 23, 31, 12, 7};
}
diff --git a/hudson-core/src/main/java/hudson/scheduler/CronTabList.java b/hudson-core/src/main/java/hudson/scheduler/CronTabList.java
index 2e3ea5d..d879364 100644
--- a/hudson-core/src/main/java/hudson/scheduler/CronTabList.java
+++ b/hudson-core/src/main/java/hudson/scheduler/CronTabList.java
@@ -7,10 +7,10 @@
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
- * Contributors:
-*
+ * Contributors:
+ *
* Kohsuke Kawaguchi
- *
+ *
*
*******************************************************************************/
@@ -28,6 +28,7 @@ import org.antlr.runtime.RecognitionException;
* @author Kohsuke Kawaguchi
*/
public final class CronTabList {
+
private final List<CronTab> tabs;
public CronTabList(Collection<CronTab> tabs) {
@@ -47,13 +48,11 @@ public final class CronTabList {
}
/**
- * Checks if this crontab entry looks reasonable,
- * and if not, return an warning message.
+ * Checks if this crontab entry looks reasonable, and if not, return an
+ * warning message.
*
- * <p>
- * The point of this method is to catch syntactically correct
- * but semantically suspicious combinations, like
- * "* 0 * * *"
+ * <p> The point of this method is to catch syntactically correct but
+ * semantically suspicious combinations, like "* 0 * * *"
*/
public String checkSanity() {
for (CronTab tab : tabs) {
@@ -71,8 +70,9 @@ public final class CronTabList {
for (String line : format.split("\\r?\\n")) {
lineNumber++;
line = line.trim();
- if (line.length() == 0 || line.startsWith("#"))
+ if (line.length() == 0 || line.startsWith("#")) {
continue; // ignorable line
+ }
try {
r.add(new CronTab(line, lineNumber));
} catch (RecognitionException e) {
diff --git a/hudson-core/src/main/java/hudson/scheduler/package.html b/hudson-core/src/main/java/hudson/scheduler/package.html
index 22025cc..4106d33 100644
--- a/hudson-core/src/main/java/hudson/scheduler/package.html
+++ b/hudson-core/src/main/java/hudson/scheduler/package.html
@@ -16,5 +16,5 @@
-->
<html><head/><body>
-Classes that implement cron-like features
-</body></html> \ No newline at end of file
+ Classes that implement cron-like features
+ </body></html> \ No newline at end of file