KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > hudson > maven > MavenModuleSetBuild


1 package hudson.maven;
2
3 import hudson.FilePath.FileCallable;
4 import hudson.model.AbstractBuild;
5 import hudson.model.Build;
6 import hudson.model.BuildListener;
7 import hudson.model.Hudson;
8 import hudson.model.Result;
9 import hudson.remoting.VirtualChannel;
10 import hudson.util.IOException2;
11 import hudson.tasks.test.AbstractTestResultAction;
12 import org.apache.maven.embedder.MavenEmbedderException;
13 import org.apache.maven.project.MavenProject;
14 import org.apache.maven.project.ProjectBuildingException;
15
16 import java.io.File JavaDoc;
17 import java.io.IOException JavaDoc;
18 import java.util.ArrayList JavaDoc;
19 import java.util.HashMap JavaDoc;
20 import java.util.List JavaDoc;
21 import java.util.Map JavaDoc;
22 import java.util.Collection JavaDoc;
23 import java.util.LinkedHashMap JavaDoc;
24
25 /**
26  * {@link Build} for {@link MavenModuleSet}.
27  *
28  * <p>
29  * A "build" of {@link MavenModuleSet} consists of:
30  *
31  * <ol>
32  * <li>Update the workspace.
33  * <li>Parse POMs
34  * <li>Trigger module builds.
35  * </ol>
36  *
37  * This object remembers the changelog and what {@link MavenBuild}s are done
38  * on this.
39  *
40  * @author Kohsuke Kawaguchi
41  */

42 public final class MavenModuleSetBuild extends AbstractBuild<MavenModuleSet,MavenModuleSetBuild> {
43
44     public MavenModuleSetBuild(MavenModuleSet job) throws IOException JavaDoc {
45         super(job);
46     }
47
48     MavenModuleSetBuild(MavenModuleSet project, File JavaDoc buildDir) throws IOException JavaDoc {
49         super(project, buildDir);
50     }
51
52     @Override JavaDoc
53     public AbstractTestResultAction getTestResultAction() {
54         // TODO
55
return null;
56     }
57
58     /**
59      * Computes the module builds that correspond to this build.
60      * <p>
61      * A module may be built multiple times (by the user action),
62      * so the value is a list.
63      */

64     public Map JavaDoc<MavenModule,List JavaDoc<MavenBuild>> getModuleBuilds() {
65         Collection JavaDoc<MavenModule> mods = getParent().getModules();
66
67         // identify the build number range. [start,end)
68
int start = getNumber();
69         int end;
70         MavenModuleSetBuild nb = getNextBuild();
71         end = nb!=null ? nb.getNumber() : Integer.MAX_VALUE;
72
73         // preserve the order by using LinkedHashMap
74
Map JavaDoc<MavenModule,List JavaDoc<MavenBuild>> r = new LinkedHashMap JavaDoc<MavenModule,List JavaDoc<MavenBuild>>(mods.size());
75
76         for (MavenModule m : mods) {
77             List JavaDoc<MavenBuild> builds = new ArrayList JavaDoc<MavenBuild>();
78             MavenBuild b = m.getNearestBuild(start);
79             while(b!=null && b.getNumber()<end) {
80                 builds.add(b);
81                 b = b.getNextBuild();
82             }
83             r.put(m,builds);
84         }
85
86         return r;
87     }
88
89     public void run() {
90         run(new RunnerImpl());
91     }
92
93     /**
94      * The sole job of the {@link MavenModuleSet} build is to update SCM
95      * and triggers module builds.
96      */

97     private class RunnerImpl extends AbstractRunner {
98         protected Result doRun(final BuildListener listener) throws Exception JavaDoc {
99             try {
100                 listener.getLogger().println("Parsing POMs");
101                 List JavaDoc<PomInfo> poms = project.getModuleRoot().act(new PomParser(listener,project.getRootPOM()));
102
103                 // update the module list
104
Map JavaDoc<ModuleName,MavenModule> modules = project.modules;
105                 synchronized(modules) {
106                     Map JavaDoc<ModuleName,MavenModule> old = new HashMap JavaDoc<ModuleName, MavenModule>(modules);
107
108                     modules.clear();
109                     project.reconfigure(poms.get(0));
110                     for (PomInfo pom : poms) {
111                         MavenModule mm = old.get(pom.name);
112                         if(mm!=null) {// found an existing matching module
113
mm.reconfigure(pom);
114                             modules.put(pom.name,mm);
115                         } else {// this looks like a new module
116
listener.getLogger().println("Discovered a new module "+pom.name+" "+pom.displayName);
117                             mm = new MavenModule(project,pom,getNumber());
118                             modules.put(mm.getModuleName(),mm);
119                         }
120                         mm.save();
121                     }
122
123                     // remaining modules are no longer active.
124
old.keySet().removeAll(modules.keySet());
125                     for (MavenModule om : old.values())
126                         om.disable();
127                     modules.putAll(old);
128                 }
129
130                 // we might have added new modules
131
Hudson.getInstance().rebuildDependencyGraph();
132
133                 // start the build
134
listener.getLogger().println("Triggering "+project.getRootModule().getModuleName());
135                 project.getRootModule().scheduleBuild();
136                 
137                 return null;
138             } catch (AbortException e) {
139                 // error should have been already reported.
140
return Result.FAILURE;
141             } catch (IOException JavaDoc e) {
142                 e.printStackTrace(listener.error("Failed to parse POMs"));
143                 return Result.FAILURE;
144             } catch (InterruptedException JavaDoc e) {
145                 e.printStackTrace(listener.error("Aborted"));
146                 return Result.FAILURE;
147             } catch (RuntimeException JavaDoc e) {
148                 // bug in the code.
149
e.printStackTrace(listener.error("Processing failed due to a bug in the code. Please report thus to users@hudson.dev.java.net"));
150                 throw e;
151             }
152         }
153
154         public void post(BuildListener listener) {
155         }
156     }
157
158     private static final class PomParser implements FileCallable<List JavaDoc<PomInfo>> {
159         private final BuildListener listener;
160         private final String JavaDoc rootPOM;
161
162         public PomParser(BuildListener listener, String JavaDoc rootPOM) {
163             this.listener = listener;
164             this.rootPOM = rootPOM;
165         }
166
167         /**
168          * Computes the path of {@link #rootPOM}.
169          *
170          * Returns "abc" if rootPOM="abc/pom.xml"
171          * If rootPOM="pom.xml", this method returns "".
172          */

173         private String JavaDoc getRootPath() {
174             int idx = Math.max(rootPOM.lastIndexOf('/'), rootPOM.lastIndexOf('\\'));
175             if(idx==-1) return "";
176             return rootPOM.substring(0,idx);
177         }
178
179         public List JavaDoc<PomInfo> invoke(File JavaDoc ws, VirtualChannel channel) throws IOException JavaDoc {
180             File JavaDoc pom = new File JavaDoc(ws,rootPOM);
181
182             if(!pom.exists()) {
183                 listener.getLogger().println("No such file "+pom);
184                 listener.getLogger().println("Perhaps you need to specify the correct POM file path in the project configuration?");
185                 throw new AbortException();
186             }
187
188             try {
189                 MavenEmbedder embedder = MavenUtil.createEmbedder(listener);
190                 MavenProject mp = embedder.readProject(pom);
191                 Map JavaDoc<MavenProject,String JavaDoc> relPath = new HashMap JavaDoc<MavenProject,String JavaDoc>();
192                 MavenUtil.resolveModules(embedder,mp,getRootPath(),relPath);
193
194                 List JavaDoc<PomInfo> infos = new ArrayList JavaDoc<PomInfo>();
195                 toPomInfo(mp,relPath,infos);
196                 return infos;
197             } catch (MavenEmbedderException e) {
198                 // TODO: better error handling needed
199
throw new IOException2(e);
200             } catch (ProjectBuildingException e) {
201                 throw new IOException2(e);
202             }
203         }
204
205         private void toPomInfo(MavenProject mp, Map JavaDoc<MavenProject,String JavaDoc> relPath, List JavaDoc<PomInfo> infos) {
206             infos.add(new PomInfo(mp,relPath.get(mp)));
207             for (MavenProject child : (List JavaDoc<MavenProject>)mp.getCollectedProjects())
208                 toPomInfo(child,relPath,infos);
209         }
210
211         private static final long serialVersionUID = 1L;
212     }
213
214     private static class AbortException extends IOException JavaDoc {
215         private static final long serialVersionUID = 1L;
216     }
217 }
218
Popular Tags