提交 7c19d793 编写于 作者: K Kohsuke Kawaguchi

added a new method to interpret the path with relative names

上级 1bdecb46
......@@ -627,7 +627,7 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
Set<AbstractProject> upstream = Collections.emptySet();
if(req.getParameter("pseudoUpstreamTrigger")!=null) {
upstream = new HashSet<AbstractProject>(Items.fromNameList(req.getParameter("upstreamProjects"),AbstractProject.class));
upstream = new HashSet<AbstractProject>(Items.fromNameList(getParent(),req.getParameter("upstreamProjects"),AbstractProject.class));
}
// dependency setting might have been changed by the user, so rebuild.
......@@ -645,7 +645,7 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
// does 'p' include us in its BuildTrigger?
DescribableList<Publisher,Descriptor<Publisher>> pl = p.getPublishersList();
BuildTrigger trigger = pl.get(BuildTrigger.class);
List<AbstractProject> newChildProjects = trigger == null ? new ArrayList<AbstractProject>():trigger.getChildProjects();
List<AbstractProject> newChildProjects = trigger == null ? new ArrayList<AbstractProject>():trigger.getChildProjects(p);
if(isUpstream) {
if(!newChildProjects.contains(this))
newChildProjects.add(this);
......@@ -673,13 +673,13 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
pl.removeAll(BuildTrigger.class);
Set<AbstractProject> combinedChildren = new HashSet<AbstractProject>();
for (BuildTrigger bt : existingList)
combinedChildren.addAll(bt.getChildProjects());
combinedChildren.addAll(bt.getChildProjects(p));
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(p,newChildProjects))
continue; // no need to touch
pl.replace(new BuildTrigger(newChildProjects,
existing==null?Result.SUCCESS:existing.getThreshold()));
......@@ -1432,7 +1432,7 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
for (AbstractProject<?,?> ap : getUpstreamProjects()) {
BuildTrigger buildTrigger = ap.getPublishersList().get(BuildTrigger.class);
if (buildTrigger != null)
if (buildTrigger.getChildProjects().contains(this))
if (buildTrigger.getChildProjects(ap).contains(this))
result.add(ap);
}
return result;
......
......@@ -2060,6 +2060,76 @@ public final class Hudson extends Node implements ItemGroup<TopLevelItem>, Stapl
return item;
}
/**
* Gets the item by its relative name from the given context
*
* <h2>Relative Names</h2>
* <p>
* If the name starts from '/', like "/foo/bar/zot", then it's interpreted as absolute.
* Otherwise, the name should be something like "../foo/bar" and it's interpreted like
* relative path name is, against the given context.
*
* @param context
* null is interpreted as {@link Hudson}. Base 'directory' of the interpretation.
* @since 1.406
*/
public Item getItem(String relativeName, ItemGroup context) {
if (context==null) context = this;
if (relativeName.startsWith("/")) // absolute
return getItemByFullName(relativeName);
Object/*Item|ItemGroup*/ ctx = context;
StringTokenizer tokens = new StringTokenizer(relativeName,"/");
while (tokens.hasMoreTokens()) {
String s = tokens.nextToken();
if (s.equals("..")) {
if (ctx instanceof Item) {
ctx = ((Item)ctx).getParent();
continue;
}
ctx=null; // can't go up further
break;
}
if (s.equals(".")) {
continue;
}
if (ctx instanceof ItemGroup) {
ItemGroup g = (ItemGroup) ctx;
Item i = g.getItem(s);
if (i==null || !i.hasPermission(Item.READ)) {
ctx=null; // can't go up further
break;
}
ctx=i;
}
}
if (ctx instanceof Item)
return (Item)ctx;
// fall back to the classic interpretation
return getItemByFullName(relativeName);
}
public final Item getItem(String relativeName, Item context) {
return getItem(relativeName,context!=null?context.getParent():null);
}
public final <T extends Item> T getItem(String relativeName, ItemGroup context, Class<T> type) {
Item r = getItem(relativeName, context);
if (type.isInstance(r))
return type.cast(r);
return null;
}
public final <T extends Item> T getItem(String relativeName, Item context, Class<T> type) {
return getItem(relativeName,context!=null?context.getParent():null,type);
}
public File getRootDirFor(TopLevelItem child) {
return getRootDirFor(child.getName());
}
......
......@@ -79,16 +79,24 @@ public class Items {
}
/**
* Does the opposite of {@link #toNameList(Collection)}.
* @deprecated as of 1.406
* Use {@link #fromNameList(ItemGroup, String, Class)}
*/
public static <T extends Item> List<T> fromNameList(String list, Class<T> type) {
return fromNameList(null,list,type);
}
/**
* Does the opposite of {@link #toNameList(Collection)}.
*/
public static <T extends Item> List<T> fromNameList(ItemGroup context, String list, Class<T> type) {
Hudson hudson = Hudson.getInstance();
List<T> r = new ArrayList<T>();
StringTokenizer tokens = new StringTokenizer(list,",");
while(tokens.hasMoreTokens()) {
String fullName = tokens.nextToken().trim();
T item = hudson.getItemByFullName(fullName,type);
T item = hudson.getItem(fullName, context, type);
if(item!=null)
r.add(item);
}
......
......@@ -37,6 +37,7 @@ import hudson.model.DependencyGraph;
import hudson.model.DependencyGraph.Dependency;
import hudson.model.Hudson;
import hudson.model.Item;
import hudson.model.ItemGroup;
import hudson.model.Items;
import hudson.model.Job;
import hudson.model.Project;
......@@ -125,8 +126,20 @@ public class BuildTrigger extends Recorder implements DependecyDeclarer {
return threshold;
}
/**
* @deprecated as of 1.406
* Use {@link #getChildProjects(ItemGroup)}
*/
public List<AbstractProject> getChildProjects() {
return Items.fromNameList(childProjects,AbstractProject.class);
return getChildProjects(Hudson.getInstance());
}
public List<AbstractProject> getChildProjects(AbstractProject owner) {
return getChildProjects(owner==null?null:owner.getParent());
}
public List<AbstractProject> getChildProjects(ItemGroup base) {
return Items.fromNameList(base,childProjects,AbstractProject.class);
}
public BuildStepMonitor getRequiredMonitorService() {
......@@ -136,11 +149,19 @@ public class BuildTrigger extends Recorder implements DependecyDeclarer {
/**
* Checks if this trigger has the exact same set of children as the given list.
*/
public boolean hasSame(Collection<? extends AbstractProject> projects) {
List<AbstractProject> children = getChildProjects();
public boolean hasSame(AbstractProject owner, Collection<? extends AbstractProject> projects) {
List<AbstractProject> children = getChildProjects(owner);
return children.size()==projects.size() && children.containsAll(projects);
}
/**
* @deprecated as of 1.406
* Use {@link #hasSame(AbstractProject, Collection)}
*/
public boolean hasSame(Collection<? extends AbstractProject> projects) {
return hasSame(null,projects);
}
@Override
public boolean perform(AbstractBuild build, Launcher launcher, BuildListener listener) {
return true;
......@@ -200,7 +221,7 @@ public class BuildTrigger extends Recorder implements DependecyDeclarer {
}
public void buildDependencyGraph(AbstractProject owner, DependencyGraph graph) {
for (AbstractProject p : getChildProjects())
for (AbstractProject p : getChildProjects(owner))
graph.addDependency(new Dependency(owner, p) {
@Override
public boolean shouldTriggerBuild(AbstractBuild build, TaskListener listener,
......@@ -292,16 +313,16 @@ public class BuildTrigger extends Recorder implements DependecyDeclarer {
/**
* Form validation method.
*/
public FormValidation doCheck(@AncestorInPath AccessControlled subject, @QueryParameter String value ) {
public FormValidation doCheck(@AncestorInPath Item project, @QueryParameter String value ) {
// Require CONFIGURE permission on this project
if(!subject.hasPermission(Item.CONFIGURE)) return FormValidation.ok();
if(!project.hasPermission(Item.CONFIGURE)) return FormValidation.ok();
StringTokenizer tokens = new StringTokenizer(Util.fixNull(value),",");
boolean hasProjects = false;
while(tokens.hasMoreTokens()) {
String projectName = tokens.nextToken().trim();
if (StringUtils.isNotBlank(projectName)) {
Item item = Hudson.getInstance().getItemByFullName(projectName,Item.class);
Item item = Hudson.getInstance().getItem(projectName,project,Item.class);
if(item==null)
return FormValidation.error(Messages.BuildTrigger_NoSuchProject(projectName,AbstractProject.findNearest(projectName).getName()));
if(!(item instanceof AbstractProject))
......
......@@ -315,7 +315,7 @@ public class MailSender {
if(address.startsWith("upstream-individuals:")) {
// people who made a change in the upstream
String projectName = address.substring("upstream-individuals:".length());
AbstractProject up = Hudson.getInstance().getItemByFullName(projectName,AbstractProject.class);
AbstractProject up = Hudson.getInstance().getItem(projectName,build.getProject(),AbstractProject.class);
if(up==null) {
listener.getLogger().println("No such project exist: "+projectName);
continue;
......
......@@ -335,7 +335,7 @@ public class AggregatedTestResultPublisher extends Recorder {
for (String name : Util.tokenize(fixNull(value), ",")) {
name = name.trim();
if(Hudson.getInstance().getItemByFullName(name)==null)
if(Hudson.getInstance().getItem(name,project)==null)
return FormValidation.error(hudson.tasks.Messages.BuildTrigger_NoSuchProject(name,AbstractProject.findNearest(name).getName()));
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册