提交 2bb355c9 编写于 作者: K kohsuke

moving various pieces around to make room for better m2 integration.


git-svn-id: https://hudson.dev.java.net/svn/hudson/trunk/hudson/main@1806 71c3de6d-444a-0410-be80-ed276b4c234a
上级 d85f2ec0
...@@ -4,7 +4,8 @@ import hudson.model.AbstractProject; ...@@ -4,7 +4,8 @@ import hudson.model.AbstractProject;
import hudson.model.Descriptor; import hudson.model.Descriptor;
import hudson.model.Hudson; import hudson.model.Hudson;
import hudson.model.Job; import hudson.model.Job;
import hudson.model.JobDescriptor; import hudson.model.TopLevelItemDescriptor;
import hudson.model.ItemLoader;
import hudson.model.Descriptor.FormException; import hudson.model.Descriptor.FormException;
import hudson.util.DescribableList; import hudson.util.DescribableList;
import org.kohsuke.stapler.StaplerRequest; import org.kohsuke.stapler.StaplerRequest;
...@@ -19,17 +20,17 @@ import java.io.IOException; ...@@ -19,17 +20,17 @@ import java.io.IOException;
* *
* @author Kohsuke Kawaguchi * @author Kohsuke Kawaguchi
*/ */
public final class MavenJob extends AbstractProject<MavenJob,MavenBuild> implements DescribableList.Owner { public final class MavenModule extends AbstractProject<MavenModule,MavenBuild> implements DescribableList.Owner {
private DescribableList<MavenReporter,Descriptor<MavenReporter>> reporters = private DescribableList<MavenReporter,Descriptor<MavenReporter>> reporters =
new DescribableList<MavenReporter,Descriptor<MavenReporter>>(this); new DescribableList<MavenReporter,Descriptor<MavenReporter>>(this);
public MavenJob(Hudson parent, String name) { public MavenModule(Hudson parent, String name) {
super(parent, name); super(parent, name);
} }
@Override @Override
protected void onLoad(Hudson root, String name) throws IOException { public void onLoad(String name) throws IOException {
super.onLoad(root, name); super.onLoad(name);
if(reporters==null) if(reporters==null)
reporters = new DescribableList<MavenReporter, Descriptor<MavenReporter>>(this); reporters = new DescribableList<MavenReporter, Descriptor<MavenReporter>>(this);
reporters.setOwner(this); reporters.setOwner(this);
...@@ -66,21 +67,7 @@ public final class MavenJob extends AbstractProject<MavenJob,MavenBuild> impleme ...@@ -66,21 +67,7 @@ public final class MavenJob extends AbstractProject<MavenJob,MavenBuild> impleme
save(); save();
} }
public JobDescriptor<MavenJob,MavenBuild> getDescriptor() {
return DESCRIPTOR;
}
public static final JobDescriptor<MavenJob,MavenBuild> DESCRIPTOR = new JobDescriptor<MavenJob,MavenBuild>(MavenJob.class) {
public String getDisplayName() {
return "Building Maven2 project (alpha)";
}
public MavenJob newInstance(String name) {
return new MavenJob(Hudson.getInstance(),name);
}
};
static { static {
XSTREAM.alias("maven2", MavenJob.class); ItemLoader.XSTREAM.alias("maven2", MavenModule.class);
} }
} }
package hudson.maven;
import hudson.model.AbstractItem;
import hudson.model.Hudson;
import hudson.model.ItemGroup;
import hudson.model.ItemLoader;
import hudson.model.TopLevelItem;
import hudson.model.TopLevelItemDescriptor;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;
import java.util.TreeMap;
/**
* Group of {@link MavenModule}s.
*
* <p>
* This corresponds to the group of Maven POMs that constitute a single
* tree of projects. This group serves as the grouping of those related
* modules.
*
* @author Kohsuke Kawaguchi
*/
public class MavenModuleSet extends AbstractItem implements TopLevelItem, ItemGroup<MavenModule> {
private final String name;
/**
* All {@link MavenModule}s.
*/
transient final Map<String,MavenModule> modules = new TreeMap<String,MavenModule>();
public MavenModuleSet(String name) {
this.name = name;
}
public String getDisplayName() {
return name;
}
public String getName() {
return name;
}
public String getUrlChildPrefix() {
return "module";
}
public Hudson getParent() {
return Hudson.getInstance();
}
public synchronized Collection<MavenModule> getItems() {
return new ArrayList<MavenModule>(modules.values());
}
public synchronized boolean contains(MavenModule item) {
return modules.containsKey(item.getName());
}
public Collection<MavenModule> getAllJobs() {
return getItems();
}
public void onLoad(String name) throws IOException {
super.onLoad(name);
File modulesDir = new File(root,"modules");
modulesDir.mkdirs(); // make sure it exists
File[] subdirs = modulesDir.listFiles(new FileFilter() {
public boolean accept(File child) {
return child.isDirectory();
}
});
modules.clear();
for (File subdir : subdirs) {
try {
MavenModule item = (MavenModule)ItemLoader.load(subdir);
modules.put(item.getName(), item);
} catch (IOException e) {
e.printStackTrace(); // TODO: logging
}
}
}
public TopLevelItemDescriptor getDescriptor() {
return DESCRIPTOR;
}
public static final TopLevelItemDescriptor DESCRIPTOR = new TopLevelItemDescriptor(MavenModuleSet.class) {
public String getDisplayName() {
return "Building a maven2 project";
}
public MavenModuleSet newInstance(String name) {
return new MavenModuleSet(name);
}
};
static {
ItemLoader.XSTREAM.alias("maven2-module-set", MavenModule.class);
}
}
package hudson.maven;
/**
* Version independent name of a Maven project.
*
* @author Kohsuke Kawaguchi
*/
public class ModuleName {
public final String groupId;
public final String artifactId;
public ModuleName(String groupId, String artifactId) {
this.groupId = groupId;
this.artifactId = artifactId;
}
/**
* Returns the "groupId:artifactId" form.
*/
public String toString() {
return groupId+':'+artifactId;
}
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
PluginName that = (PluginName) o;
return artifactId.equals(that.artifactId)
&& groupId.equals(that.groupId);
}
public int hashCode() {
int result;
result = groupId.hashCode();
result = 31 * result + artifactId.hashCode();
return result;
}
}
...@@ -3,24 +3,23 @@ package hudson.maven; ...@@ -3,24 +3,23 @@ package hudson.maven;
import org.apache.maven.plugin.descriptor.PluginDescriptor; import org.apache.maven.plugin.descriptor.PluginDescriptor;
/** /**
* Identifier of an artifact (like jar) in Maven, * Identifier of a specific version of a Maven plugin
* that consists of groupId, artifactId, and version. * that consists of groupId, artifactId, and version.
* *
*
* @author Kohsuke Kawaguchi * @author Kohsuke Kawaguchi
*/ */
public final class Name { public final class PluginName {
public final String groupId; public final String groupId;
public final String artifactId; public final String artifactId;
public final String version; public final String version;
public Name(String groupId, String artifactId, String version) { public PluginName(String groupId, String artifactId, String version) {
this.groupId = groupId; this.groupId = groupId;
this.artifactId = artifactId; this.artifactId = artifactId;
this.version = version; this.version = version;
} }
public Name(PluginDescriptor pd) { public PluginName(PluginDescriptor pd) {
this(pd.getGroupId(), pd.getArtifactId(), pd.getVersion()); this(pd.getGroupId(), pd.getArtifactId(), pd.getVersion());
} }
...@@ -35,7 +34,7 @@ public final class Name { ...@@ -35,7 +34,7 @@ public final class Name {
if (this == o) return true; if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false; if (o == null || getClass() != o.getClass()) return false;
Name that = (Name) o; PluginName that = (PluginName) o;
return artifactId.equals(that.artifactId) return artifactId.equals(that.artifactId)
&& groupId.equals(that.groupId) && groupId.equals(that.groupId)
......
package hudson.model;
import hudson.XmlFile;
import java.io.File;
import java.io.IOException;
import java.util.Collection;
/**
* Partial default implementation of {@link Item}.
*
* @author Kohsuke Kawaguchi
*/
// Item doesn't necessarily have to be Actionable, but
// Java doesn't let multiple inheritance.
public abstract class AbstractItem extends Actionable implements Item {
/**
* Root directory for this view item on the file system.
*/
protected transient File root;
public File getRootDir() {
return root;
}
/**
* Gets all the jobs that this {@link Item} contains as descendants.
*/
public abstract Collection<? extends Job> getAllJobs();
/**
* Gets the name of the view item.
*
* <p>
* The name must be unique among all {@link Item}s in this Hudson,
* because we allow a single {@link Item} to show up in multiple
* {@link View}s.
*/
public abstract String getName();
/**
* 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 {
}
/**
* When a {@link Item} is copied from existing one,
* the files are first copied on the file system,
* then it will be loaded, then this method will be invoked
* to perform any implementation-specific work.
*/
public void onCopiedFrom(Item src) {
}
public final String getUrl() {
return getParent().getUrl()+getParent().getUrlChildPrefix()+'/'+getName()+'/';
}
/**
* Save the settings to a file.
*/
public synchronized void save() throws IOException {
getConfigFile().write(this);
}
protected final XmlFile getConfigFile() {
return ItemLoader.getConfigFile(this);
}
}
package hudson.model;
import java.io.IOException;
import java.util.Collection;
/**
* Object that can be displayed in a {@link ListView}.
*
* {@link Item}s are allowed to show up in multiple {@link View}s,
* so they need to have unique names among all {@link Item}s.
* This uniqueness is also used for allocating file system storage
* for each {@link Item}.
*
*
* TODO: rename to something else.
* @author Kohsuke Kawaguchi
*/
public interface Item extends PersistenceRoot {
/**
* Gets the parent that contains this item.
*/
ItemGroup<? extends Item> getParent();
/**
* Gets all the jobs that this {@link Item} contains as descendants.
*
* TODO: revisit
*/
abstract Collection<? extends Job> getAllJobs();
/**
* Gets the name of the item.
*
* <p>
* The name must be unique among all {@link Item}s in this Hudson,
* because we allow a single {@link Item} to show up in multiple
* {@link View}s.
*/
String getName();
/**
* Returns the URL of this project relative to the context root of the application.
*
* @see AbstractItem#getUrl() for how to implement this
*/
String getUrl();
/**
* 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;
/**
* When a {@link Item} is copied from existing one,
* the files are first copied on the file system,
* then it will be loaded, then this method will be invoked
* to perform any implementation-specific work.
*/
void onCopiedFrom(Item src);
/**
* Save the settings to a file.
*
* Use {@link ItemLoader#getConfigFile(Item)}
* or {@link AbstractItem#getConfigFile()} to obtain the file
* to save the data.
*/
public void save() throws IOException;
}
package hudson.model;
import java.util.Collection;
/**
* Represents a grouping inherent to a kind of {@link Item}s.
*
* @author Kohsuke Kawaguchi
*/
public interface ItemGroup<T extends Item> extends PersistenceRoot, ModelObject {
/**
* Gets all the items in this collection in a read-only view.
*
* TODO: check if this is really needed
*/
Collection<T> getItems();
/**
* Checks if the job is in this collection.
*
* TODO: check if this is really needed
*/
boolean contains(T item);
/**
* Returns the path relative to the context root,
* like "foo/bar/zot/". Note no leading slash but trailing slash.
*/
String getUrl();
/**
* Gets the URL token that prefixes the URLs for child {@link Item}s.
* Like "job", "item", etc.
*/
String getUrlChildPrefix();
}
package hudson.model;
import com.thoughtworks.xstream.XStream;
import hudson.util.XStream2;
import hudson.XmlFile;
import java.io.File;
import java.io.IOException;
/**
* Used to load {@link Item} implementation.
*
*
* TODO: move this to {@link ItemGroup}?
*
* @author Kohsuke Kawaguchi
*/
public final class ItemLoader {
/**
* Loads a {@link Item} from a config file.
*
* @param dir
* The directory that contains the config file, not the config file itself.
*/
public static Item load(File dir) throws IOException {
Item item = (Item)getConfigFile(dir).read();
item.onLoad(dir.getName());
return item;
}
/**
* The file we save our configuration.
*/
static XmlFile getConfigFile(File dir) {
return new XmlFile(XSTREAM,new File(dir,"config.xml"));
}
/**
* The file we save our configuration.
*/
public static XmlFile getConfigFile(Item item) {
return getConfigFile(item.getRootDir());
}
/**
* Used to load/save job configuration.
*
* When you extend {@link Job} in a plugin, try to put the alias so
* that it produces a reasonable XML.
*/
public static final XStream XSTREAM = new XStream2();
static {
XSTREAM.alias("project",Project.class);
}
}
package hudson.model;
import java.io.File;
/**
* Root object of a persisted object tree
* that gets its own file system directory.
*
* @author Kohsuke Kawaguchi
*/
public interface PersistenceRoot {
/**
* Gets the root directory on the file system that this
* {@link Item} can use freely fore storing the configuration data.
*
* <p>
* This parameter is given by the {@link ItemGroup} when
* {@link Item} is loaded from memory.
*/
File getRootDir();
}
package hudson.model;
import hudson.ExtensionPoint;
/**
* {@link Item} that can be directly displayed under {@link Hudson}.
*
* <p>
* To register a custom {@link TopLevelItem} class from a plugin, add it to
* {@link TopLevelItems#LIST}. Also see {@link ItemLoader#XSTREAM}.
*
* @author Kohsuke Kawaguchi
*/
public interface TopLevelItem extends Item, ExtensionPoint, Describable<TopLevelItem> {
/**
* By definition the parent of the top-level item is always {@link Hudson}.
*/
Hudson getParent();
/**
*
* @see Describable#getDescriptor()
*/
TopLevelItemDescriptor getDescriptor();
}
...@@ -6,12 +6,12 @@ import java.util.List; ...@@ -6,12 +6,12 @@ import java.util.List;
import java.util.ArrayList; import java.util.ArrayList;
/** /**
* {@link Descriptor} for {@link Job}s. * {@link Descriptor} for {@link TopLevelItem}s.
* *
* @author Kohsuke Kawaguchi * @author Kohsuke Kawaguchi
*/ */
public abstract class JobDescriptor<J extends Job<J,R>,R extends Run<J,R>> extends Descriptor<Job<J,R>> { public abstract class TopLevelItemDescriptor extends Descriptor<TopLevelItem> {
protected JobDescriptor(Class<? extends Job<J,R>> clazz) { protected TopLevelItemDescriptor(Class<? extends TopLevelItem> clazz) {
super(clazz); super(clazz);
} }
...@@ -20,23 +20,12 @@ public abstract class JobDescriptor<J extends Job<J,R>,R extends Run<J,R>> exten ...@@ -20,23 +20,12 @@ public abstract class JobDescriptor<J extends Job<J,R>,R extends Run<J,R>> exten
* This is not a valid operation for {@link Job}s. * This is not a valid operation for {@link Job}s.
*/ */
@Deprecated @Deprecated
public Job<J,R> newInstance(StaplerRequest req) throws FormException { public TopLevelItem newInstance(StaplerRequest req) throws FormException {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
/** /**
* Creates a new {@link Job}. * Creates a new {@link Job}.
*/ */
public abstract Job<J,R> newInstance(String name); public abstract TopLevelItem newInstance(String name);
/**
* Gets the {@link JobPropertyDescriptor}s applicable for this job type.
*/
public List<JobPropertyDescriptor> getPropertyDescriptors() {
List<JobPropertyDescriptor> r = new ArrayList<JobPropertyDescriptor>();
for (JobPropertyDescriptor p : Jobs.PROPERTIES)
if(p.isApplicable(clazz))
r.add(p);
return r;
}
} }
package hudson.model;
import hudson.maven.MavenModuleSet;
import java.util.List;
/**
* @author Kohsuke Kawaguchi
*/
public class TopLevelItems {
/**
* List of all installed job types.
*/
public static final List<TopLevelItemDescriptor> LIST = (List)Descriptor.toList(
Project.DESCRIPTOR,
ExternalJob.DESCRIPTOR
);
public static TopLevelItemDescriptor getDescriptor(String displayName) {
for (TopLevelItemDescriptor job : LIST) {
if(job.getDisplayName().equals(displayName))
return job;
}
return null;
}
static {
if(Boolean.getBoolean("hudson.maven"))
LIST.add(MavenModuleSet.DESCRIPTOR);
}
}
package hudson.model;
import java.util.Collection;
/**
* Object that can be displayed in a {@link View}.
*
* @author Kohsuke Kawaguchi
*/
public interface ViewItem {
/**
* Gets all the jobs that this {@link ViewItem} contains as descendants.
*/
Collection<Job> getAllJobs();
/**
* Gets the name of the view item.
*
* <p>
* The name must be unique among all {@link ViewItem}s in this Hudson,
* because we allow a single {@link ViewItem} to show up in multiple
* {@link View}s.
*/
String getName();
}
package hudson.model.listeners;
import hudson.ExtensionPoint;
import hudson.model.Hudson;
import hudson.model.Item;
/**
* @since 1.74
* @author Kohsuke Kawaguchi
*/
public class ItemListener implements ExtensionPoint {
/**
* Called after a new job is created and added to {@link Hudson}.
*/
public void onCreated(Item item) {
}
/**
* Called after all the jobs are loaded from disk into {@link Hudson}
* object.
*/
public void onLoaded() {
}
/**
* Called right before a job is going to be deleted.
*
* At this point the data files of the job is already gone.
*/
public void onDeleted(Item item) {
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册