提交 e86b3a34 编写于 作者: K kohsuke

pulled up rename to Item and onRenamed to ItemGroup

git-svn-id: https://hudson.dev.java.net/svn/hudson/trunk/hudson/main@36009 71c3de6d-444a-0410-be80-ed276b4c234a
上级 be5ab549
......@@ -456,6 +456,10 @@ public class MatrixProject extends AbstractProject<MatrixProject,MatrixBuild> im
return getRootDirFor(child.getCombination());
}
public void onRenamed(MatrixConfiguration item, String oldName, String newName) throws IOException {
throw new UnsupportedOperationException();
}
public File getRootDirFor(Combination combination) {
File f = getConfigurationsDir();
for (Entry<String, String> e : combination.entrySet())
......
......@@ -30,10 +30,13 @@ import hudson.Functions;
import hudson.BulkChange;
import hudson.cli.declarative.CLIMethod;
import hudson.cli.declarative.CLIResolver;
import hudson.model.listeners.ItemListener;
import hudson.model.listeners.SaveableListener;
import hudson.security.AccessControlled;
import hudson.security.Permission;
import hudson.security.ACL;
import org.apache.tools.ant.taskdefs.Copy;
import org.apache.tools.ant.types.FileSet;
import org.kohsuke.stapler.export.Exported;
import org.kohsuke.stapler.export.ExportedBean;
......@@ -123,6 +126,121 @@ public abstract class AbstractItem extends Actionable implements Item, HttpDelet
this.name = name;
}
/**
* Renames this item.
* Not all the Items need to support this operation, but if you decide to do so,
* you can use this method.
*/
protected void renameTo(String newName) throws IOException {
// always synchronize from bigger objects first
final ItemGroup parent = getParent();
synchronized (parent) {
synchronized (this) {
// sanity check
if (newName == null)
throw new IllegalArgumentException("New name is not given");
// noop?
if (this.name.equals(newName))
return;
Item existing = parent.getItem(newName);
if (existing != null && existing!=this)
// the look up is case insensitive, so we need "existing!=this"
// to allow people to rename "Foo" to "foo", for example.
// see http://www.nabble.com/error-on-renaming-project-tt18061629.html
throw new IllegalArgumentException("Job " + newName
+ " already exists");
String oldName = this.name;
File oldRoot = this.getRootDir();
doSetName(newName);
File newRoot = this.getRootDir();
boolean success = false;
try {// rename data files
boolean interrupted = false;
boolean renamed = false;
// try to rename the job directory.
// this may fail on Windows due to some other processes
// accessing a file.
// so retry few times before we fall back to copy.
for (int retry = 0; retry < 5; retry++) {
if (oldRoot.renameTo(newRoot)) {
renamed = true;
break; // succeeded
}
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// process the interruption later
interrupted = true;
}
}
if (interrupted)
Thread.currentThread().interrupt();
if (!renamed) {
// failed to rename. it must be that some lengthy
// process is going on
// to prevent a rename operation. So do a copy. Ideally
// we'd like to
// later delete the old copy, but we can't reliably do
// so, as before the VM
// shuts down there might be a new job created under the
// old name.
Copy cp = new Copy();
cp.setProject(new org.apache.tools.ant.Project());
cp.setTodir(newRoot);
FileSet src = new FileSet();
src.setDir(getRootDir());
cp.addFileset(src);
cp.setOverwrite(true);
cp.setPreserveLastModified(true);
cp.setFailOnError(false); // keep going even if
// there's an error
cp.execute();
// try to delete as much as possible
try {
Util.deleteRecursive(oldRoot);
} catch (IOException e) {
// but ignore the error, since we expect that
e.printStackTrace();
}
}
success = true;
} finally {
// if failed, back out the rename.
if (!success)
doSetName(oldName);
}
callOnRenamed(newName, parent, oldName);
for (ItemListener l : ItemListener.all())
l.onRenamed(this, oldName, newName);
}
}
}
/**
* A pointless function to work around what appears to be a HotSpot problem. See HUDSON-5756 and bug 6933067
* on BugParade for more details.
*/
private void callOnRenamed(String newName, ItemGroup parent, String oldName) throws IOException {
try {
parent.onRenamed(this, oldName, newName);
} catch (AbstractMethodError _) {
// ignore
}
}
/**
* Gets all the jobs that this {@link Item} contains as descendants.
*/
......
......@@ -59,7 +59,6 @@ import hudson.cli.declarative.CLIMethod;
import hudson.cli.declarative.CLIResolver;
import static hudson.init.InitMilestone.JOB_LOADED;
import static hudson.init.InitMilestone.PLUGINS_STARTED;
import hudson.init.InitializerFinder;
import hudson.init.InitMilestone;
import hudson.init.InitReactorListener;
import hudson.init.InitStrategy;
......@@ -2095,7 +2094,7 @@ public final class Hudson extends Node implements ItemGroup<TopLevelItem>, Stapl
* Called by {@link Job#renameTo(String)} to update relevant data structure.
* assumed to be synchronized on Hudson by the caller.
*/
/*package*/ void onRenamed(TopLevelItem job, String oldName, String newName) throws IOException {
public void onRenamed(TopLevelItem job, String oldName, String newName) throws IOException {
items.remove(oldName);
items.put(newName,job);
......
......@@ -23,6 +23,7 @@
*/
package hudson.model;
import java.io.IOException;
import java.util.Collection;
import java.io.File;
......@@ -71,4 +72,9 @@ public interface ItemGroup<T extends Item> extends PersistenceRoot, ModelObject
* Assigns the {@link Item#getRootDir() root directory} for children.
*/
File getRootDirFor(T child);
/**
* Internal method. Called by {@link Item}s when they are renamed by users.
*/
void onRenamed(T item, String oldName, String newName) throws IOException;
}
......@@ -470,107 +470,9 @@ public abstract class Job<JobT extends Job<JobT, RunT>, RunT extends Run<JobT, R
/**
* Renames a job.
*
* <p>
* This method is defined on {@link Job} but really only applicable for
* {@link Job}s that are top-level items.
*/
public void renameTo(String newName) throws IOException {
// always synchronize from bigger objects first
final Hudson parent = Hudson.getInstance();
assert this instanceof TopLevelItem;
synchronized (parent) {
synchronized (this) {
// sanity check
if (newName == null)
throw new IllegalArgumentException("New name is not given");
TopLevelItem existing = parent.getItem(newName);
if (existing != null && existing!=this)
// the look up is case insensitive, so we need "existing!=this"
// to allow people to rename "Foo" to "foo", for example.
// see http://www.nabble.com/error-on-renaming-project-tt18061629.html
throw new IllegalArgumentException("Job " + newName
+ " already exists");
// noop?
if (this.name.equals(newName))
return;
String oldName = this.name;
File oldRoot = this.getRootDir();
doSetName(newName);
File newRoot = this.getRootDir();
boolean success = false;
try {// rename data files
boolean interrupted = false;
boolean renamed = false;
// try to rename the job directory.
// this may fail on Windows due to some other processes
// accessing a file.
// so retry few times before we fall back to copy.
for (int retry = 0; retry < 5; retry++) {
if (oldRoot.renameTo(newRoot)) {
renamed = true;
break; // succeeded
}
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// process the interruption later
interrupted = true;
}
}
if (interrupted)
Thread.currentThread().interrupt();
if (!renamed) {
// failed to rename. it must be that some lengthy
// process is going on
// to prevent a rename operation. So do a copy. Ideally
// we'd like to
// later delete the old copy, but we can't reliably do
// so, as before the VM
// shuts down there might be a new job created under the
// old name.
Copy cp = new Copy();
cp.setProject(new org.apache.tools.ant.Project());
cp.setTodir(newRoot);
FileSet src = new FileSet();
src.setDir(getRootDir());
cp.addFileset(src);
cp.setOverwrite(true);
cp.setPreserveLastModified(true);
cp.setFailOnError(false); // keep going even if
// there's an error
cp.execute();
// try to delete as much as possible
try {
Util.deleteRecursive(oldRoot);
} catch (IOException e) {
// but ignore the error, since we expect that
e.printStackTrace();
}
}
success = true;
} finally {
// if failed, back out the rename.
if (!success)
doSetName(oldName);
}
parent.onRenamed((TopLevelItem) this, oldName, newName);
for (ItemListener l : ItemListener.all())
l.onRenamed(this, oldName, newName);
}
}
super.renameTo(newName);
}
/**
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册