提交 4b9d924c 编写于 作者: K kohsuke

fixed a bug around setting up the parent pointer.

Modified so that the root directory of the children is determined by the parent.


git-svn-id: https://hudson.dev.java.net/svn/hudson/trunk/hudson/main@1861 71c3de6d-444a-0410-be80-ed276b4c234a
上级 460d7b95
package hudson.maven;
import hudson.FilePath;
import hudson.model.AbstractProject;
import hudson.model.Descriptor;
import hudson.model.Descriptor.FormException;
import hudson.model.Hudson;
import hudson.model.Items;
import hudson.model.Job;
import hudson.model.Item;
import hudson.model.ItemGroup;
import hudson.util.DescribableList;
import hudson.FilePath;
import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.StaplerResponse;
import org.apache.maven.project.MavenProject;
import javax.servlet.ServletException;
import java.io.File;
......@@ -26,13 +27,19 @@ public final class MavenModule extends AbstractProject<MavenModule,MavenBuild> i
private DescribableList<MavenReporter,Descriptor<MavenReporter>> reporters =
new DescribableList<MavenReporter,Descriptor<MavenReporter>>(this);
public MavenModule(Hudson parent, String name) {
super(parent, name);
/**
* Name taken from {@link MavenProject#getName()}.
*/
private String displayName;
/*package*/ MavenModule(MavenModuleSet parent, PomInfo pom) {
super(parent, pom.name.toString());
displayName = pom.displayName;
}
@Override
public void onLoad(String name) throws IOException {
super.onLoad(name);
public void onLoad(ItemGroup<? extends Item> parent, String name) throws IOException {
super.onLoad(parent, name);
if(reporters==null)
reporters = new DescribableList<MavenReporter, Descriptor<MavenReporter>>(this);
reporters.setOwner(this);
......@@ -44,6 +51,10 @@ public final class MavenModule extends AbstractProject<MavenModule,MavenBuild> i
throw new UnsupportedOperationException();
}
@Override
public String getDisplayName() {
return displayName;
}
public MavenModuleSet getParent() {
return (MavenModuleSet)super.getParent();
......
package hudson.maven;
import hudson.FilePath;
import hudson.FilePath.FileCallable;
import hudson.Launcher;
import hudson.Util;
import hudson.model.AbstractItem;
......@@ -9,24 +10,36 @@ import hudson.model.Hudson;
import hudson.model.ItemGroup;
import hudson.model.Items;
import hudson.model.JDK;
import hudson.model.Node;
import hudson.model.Project;
import hudson.model.TaskListener;
import hudson.model.TopLevelItem;
import hudson.model.TopLevelItemDescriptor;
import hudson.model.Node;
import hudson.model.LargeText;
import hudson.model.Item;
import hudson.remoting.VirtualChannel;
import hudson.scm.NullSCM;
import hudson.scm.SCM;
import hudson.scm.SCMS;
import hudson.util.ByteBuffer;
import hudson.util.CopyOnWriteMap;
import hudson.util.IOException2;
import hudson.util.StreamTaskListener;
import org.apache.maven.embedder.MavenEmbedderException;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.ProjectBuildingException;
import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.StaplerResponse;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.util.Collection;
import java.util.Map;
import java.util.List;
import java.util.ArrayList;
/**
* Group of {@link MavenModule}s.
......@@ -40,7 +53,7 @@ import java.util.Map;
*/
public class MavenModuleSet extends AbstractItem implements TopLevelItem, ItemGroup<MavenModule> {
/**
* All {@link MavenModule}s.
* All {@link MavenModule}s, keyed by their {@link MavenModule#getName() name}s.
*/
transient /*final*/ Map<String,MavenModule> modules = new CopyOnWriteMap.Tree<String,MavenModule>();
......@@ -87,11 +100,13 @@ public class MavenModuleSet extends AbstractItem implements TopLevelItem, ItemGr
* return that {@link Node}. Otherwise null.
*/
public Node getAssignedNode() {
if(assignedNode==null)
return null;
if(assignedNode.equals(""))
return Hudson.getInstance();
return Hudson.getInstance().getSlave(assignedNode);
return Hudson.getInstance();
// TODO
//if(assignedNode==null)
// return null;
//if(assignedNode.equals(""))
// return Hudson.getInstance();
//return Hudson.getInstance().getSlave(assignedNode);
}
public SCM getScm() {
......@@ -118,6 +133,10 @@ public class MavenModuleSet extends AbstractItem implements TopLevelItem, ItemGr
return modules.get(name);
}
public File getRootDirFor(MavenModule child) {
return new File(new File(getRootDir(),"modules"),child.getName());
}
public Collection<MavenModule> getAllJobs() {
return getItems();
}
......@@ -130,11 +149,10 @@ public class MavenModuleSet extends AbstractItem implements TopLevelItem, ItemGr
return Hudson.getInstance().getWorkspaceFor(this);
}
public void onLoad(ItemGroup<? extends Item> parent, String name) throws IOException {
super.onLoad(parent, name);
public void onLoad(String name) throws IOException {
super.onLoad(name);
File modulesDir = new File(root,"modules");
File modulesDir = new File(getRootDir(),"modules");
modulesDir.mkdirs(); // make sure it exists
File[] subdirs = modulesDir.listFiles(new FileFilter() {
......@@ -145,7 +163,7 @@ public class MavenModuleSet extends AbstractItem implements TopLevelItem, ItemGr
modules = new CopyOnWriteMap.Tree<String,MavenModule>();
for (File subdir : subdirs) {
try {
MavenModule item = (MavenModule) Items.load(subdir);
MavenModule item = (MavenModule) Items.load(this,subdir);
modules.put(item.getName(), item);
} catch (IOException e) {
e.printStackTrace(); // TODO: logging
......@@ -167,6 +185,92 @@ public class MavenModuleSet extends AbstractItem implements TopLevelItem, ItemGr
}
}
private transient LargeText parsePomBuffer;
public void parsePOMs() {
ByteBuffer buf = new ByteBuffer();
parsePomBuffer = new LargeText(buf,false);
final StreamTaskListener listener = new StreamTaskListener(buf);
try {
// TODO: shall checkout do updates as well?
Launcher launcher = getAssignedNode().createLauncher(listener);
if(!checkout(launcher,listener))
return;
// TODO: this needs to be moved to its own class since MavenModuleSet is not serializable
List<PomInfo> poms = getWorkspace().act(new FileCallable<List<PomInfo>>() {
public List<PomInfo> invoke(File ws, VirtualChannel channel) throws IOException {
// TODO: this logic needs to be smarter
File pom = new File(ws,"pom.xml");
try {
MavenEmbedder embedder = MavenUtil.createEmbedder(listener);
MavenProject mp = embedder.readProject(pom);
MavenUtil.resolveModules(embedder,mp);
List<PomInfo> infos = new ArrayList<PomInfo>();
toPomInfo(mp,infos);
return infos;
} catch (MavenEmbedderException e) {
// TODO: better error handling needed
throw new IOException2(e);
} catch (ProjectBuildingException e) {
throw new IOException2(e);
}
}
private void toPomInfo(MavenProject mp, List<PomInfo> infos) {
infos.add(new PomInfo(mp));
for (MavenProject child : (List<MavenProject>)mp.getCollectedProjects())
toPomInfo(child,infos);
}
});
synchronized(modules) {
modules.clear();
for (PomInfo pom : poms) {
MavenModule mm = new MavenModule(this,pom);
mm.save();
modules.put(mm.getName(),mm);
}
}
} catch (IOException e) {
e.printStackTrace(listener.error("Failed to parse POMs"));
} catch (InterruptedException e) {
e.printStackTrace(listener.error("Aborted"));
} catch (RuntimeException e) {
// bug in the code.
e.printStackTrace(listener.error("Processing failed due to a bug in the code. Please report thus to users@hudson.dev.java.net"));
throw e;
}
parsePomBuffer.markAsComplete();
}
//
//
// Web methods
//
//
public void doStartParsePOM(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException {
new Thread(new Runnable() {
public void run() {
parsePOMs();
}
}).start();
rsp.sendRedirect("parsePOM");
}
/**
* Handles incremental log output.
*/
public void doProgressiveParsePOMLog( StaplerRequest req, StaplerResponse rsp) throws IOException {
if(parsePomBuffer==null)
rsp.setStatus(HttpServletResponse.SC_OK);
else
parsePomBuffer.doProgressText(req,rsp);
}
public synchronized void doConfigSubmit(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException {
if(!Hudson.adminCheck(req,rsp))
......
package hudson.maven;
import org.apache.maven.project.MavenProject;
import java.io.Serializable;
/**
* @author Kohsuke Kawaguchi
*/
final class PomInfo implements Serializable {
public final ModuleName name;
/**
* This is a human readable name of the POM. Not necessarily unique
* or file system safe.
*
* @see MavenProject#getName()
*/
public final String displayName;
public PomInfo(MavenProject project) {
this.name = new ModuleName(project.getGroupId(),project.getArtifactId());
this.displayName = project.getName();
}
private static final long serialVersionUID = 1L;
}
......@@ -30,16 +30,11 @@ public abstract class AbstractItem extends Actionable implements Item {
*/
protected String description;
/**
* Root directory for this view item on the file system.
*/
protected transient File root;
private ItemGroup parent;
protected AbstractItem(ItemGroup parent, String name) {
doSetName(name);
this.parent = parent;
doSetName(name);
}
public String getName() {
......@@ -51,7 +46,7 @@ public abstract class AbstractItem extends Actionable implements Item {
}
public File getRootDir() {
return root;
return parent.getRootDirFor(this);
}
public ItemGroup getParent() {
......@@ -74,12 +69,12 @@ public abstract class AbstractItem extends Actionable implements Item {
}
/**
* Just update {@link #name} and {@link #root}, since they are linked.
* Just update {@link #name} without performing the rename operation,
* which would involve copying files and etc.
*/
protected void doSetName(String name) {
this.name = name;
this.root = new File(new File(Hudson.getInstance().getRootDir(),"jobs"),name);
this.root.mkdirs();
getRootDir().mkdirs();
}
/**
......@@ -97,7 +92,8 @@ public abstract class AbstractItem extends Actionable implements Item {
* Called right after when a {@link Item} is loaded from disk.
* This is an opporunity to do a post load processing.
*/
public void onLoad(String name) throws IOException {
public void onLoad(ItemGroup<? extends Item> parent, String name) throws IOException {
this.parent = parent;
doSetName(name);
}
......@@ -144,7 +140,7 @@ public abstract class AbstractItem extends Actionable implements Item {
public synchronized void doDoDelete( StaplerRequest req, StaplerResponse rsp ) throws IOException {
if(!Hudson.adminCheck(req,rsp))
return;
Util.deleteRecursive(root);
Util.deleteRecursive(getRootDir());
if(this instanceof TopLevelItem)
Hudson.getInstance().deleteJob((TopLevelItem)this);
......
......@@ -105,8 +105,8 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
}
@Override
public void onLoad(String name) throws IOException {
super.onLoad(name);
public void onLoad(ItemGroup<? extends Item> parent, String name) throws IOException {
super.onLoad(parent, name);
this.builds = new RunMap<R>();
this.builds.load(this,new Constructor<R>() {
......
......@@ -625,6 +625,10 @@ public final class Hudson extends View implements ItemGroup<TopLevelItem>, Node
return items.get(name);
}
public File getRootDirFor(TopLevelItem child) {
return new File(new File(getRootDir(),"jobs"),child.getName());
}
/**
* Gets the {@link Item} object by its full name.
* Full names are like path names, where each name of {@link Item} is
......@@ -784,7 +788,7 @@ public final class Hudson extends View implements ItemGroup<TopLevelItem>, Node
items.clear();
for (File subdir : subdirs) {
try {
TopLevelItem item = (TopLevelItem)Items.load(subdir);
TopLevelItem item = (TopLevelItem)Items.load(this,subdir);
items.put(item.getName(), item);
} catch (IOException e) {
e.printStackTrace(); // TODO: logging
......@@ -973,7 +977,7 @@ public final class Hudson extends View implements ItemGroup<TopLevelItem>, Node
Util.copyFile(Items.getConfigFile(src).getFile(),Items.getConfigFile(result).getFile());
// reload from the new config
result = (TopLevelItem)Items.load(result.getRootDir());
result = (TopLevelItem)Items.load(this,result.getRootDir());
result.onCopiedFrom(src);
items.put(name,result);
}
......
......@@ -79,7 +79,7 @@ public interface Item extends PersistenceRoot {
* Called right after when a {@link Item} is loaded from disk.
* This is an opporunity to do a post load processing.
*/
void onLoad(String name) throws IOException;
void onLoad(ItemGroup<? extends Item> parent, String name) throws IOException;
/**
* When a {@link Item} is copied from existing one,
......
package hudson.model;
import java.util.Collection;
import java.io.File;
/**
* Represents a grouping inherent to a kind of {@link Item}s.
......@@ -36,4 +37,9 @@ public interface ItemGroup<T extends Item> extends PersistenceRoot, ModelObject
* Gets the {@link Item} inside this group that has a given name.
*/
T getItem(String name);
/**
* Assigns the {@link Item#getRootDir() root directory} for children.
*/
File getRootDirFor(T child);
}
......@@ -71,9 +71,9 @@ public class Items {
* @param dir
* The directory that contains the config file, not the config file itself.
*/
public static Item load(File dir) throws IOException {
public static Item load(ItemGroup parent, File dir) throws IOException {
Item item = (Item)getConfigFile(dir).read();
item.onLoad(dir.getName());
item.onLoad(parent,dir.getName());
return item;
}
......
......@@ -77,8 +77,8 @@ public abstract class Job<JobT extends Job<JobT,RunT>, RunT extends Run<JobT,Run
getBuildDir().mkdirs();
}
public void onLoad(String name) throws IOException {
super.onLoad(name);
public void onLoad(ItemGroup<? extends Item> parent, String name) throws IOException {
super.onLoad(parent, name);
TextFile f = getNextBuildNumberFile();
if(f.exists()) {
......@@ -107,7 +107,7 @@ public abstract class Job<JobT extends Job<JobT,RunT>, RunT extends Run<JobT,Run
}
private TextFile getNextBuildNumberFile() {
return new TextFile(new File(this.root,"nextBuildNumber"));
return new TextFile(new File(this.getRootDir(),"nextBuildNumber"));
}
private void saveNextBuildNumber() throws IOException {
......@@ -202,10 +202,10 @@ public abstract class Job<JobT extends Job<JobT,RunT>, RunT extends Run<JobT,Run
String oldName = this.name;
File oldRoot = this.root;
File oldRoot = this.getRootDir();
doSetName(newName);
File newRoot = this.root;
File newRoot = this.getRootDir();
{// rename data files
boolean interrupted=false;
......@@ -335,7 +335,7 @@ public abstract class Job<JobT extends Job<JobT,RunT>, RunT extends Run<JobT,Run
* @see RunMap
*/
protected File getBuildDir() {
return new File(root,"builds");
return new File(getRootDir(),"builds");
}
/**
......
......@@ -62,8 +62,8 @@ public class Project extends AbstractProject<Project,Build> implements TopLevelI
super(parent,name);
}
public void onLoad(String name) throws IOException {
super.onLoad(name);
public void onLoad(ItemGroup<? extends Item> parent, String name) throws IOException {
super.onLoad(parent, name);
if(buildWrappers==null)
// it didn't exist in < 1.64
......
......@@ -60,8 +60,8 @@ public abstract class ViewJob<JobT extends ViewJob<JobT,RunT>, RunT extends Run<
}
public void onLoad(String name) throws IOException {
super.onLoad(name);
public void onLoad(ItemGroup<? extends Item> parent, String name) throws IOException {
super.onLoad(parent, name);
notLoaded = true;
}
......
......@@ -96,7 +96,7 @@ public class SCMTrigger extends Trigger {
* Start polling if it's scheduled.
*/
public synchronized void startPolling() {
AbstractBuild b = project.getLastBuild();
AbstractBuild b = (AbstractBuild)project.getLastBuild();
if(b!=null && b.isBuilding())
return; // build in progress
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册