KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > hudson > tasks > Maven


1 package hudson.tasks;
2
3 import hudson.CopyOnWrite;
4 import hudson.FilePath.FileCallable;
5 import hudson.Functions;
6 import hudson.Launcher;
7 import hudson.Util;
8 import hudson.model.Build;
9 import hudson.model.BuildListener;
10 import hudson.model.Descriptor;
11 import hudson.model.Project;
12 import hudson.remoting.VirtualChannel;
13 import hudson.util.ArgumentListBuilder;
14 import hudson.util.FormFieldValidator;
15 import org.kohsuke.stapler.StaplerRequest;
16 import org.kohsuke.stapler.StaplerResponse;
17
18 import javax.servlet.ServletException JavaDoc;
19 import java.io.File JavaDoc;
20 import java.io.IOException JavaDoc;
21 import java.util.Map JavaDoc;
22 import java.util.StringTokenizer JavaDoc;
23
24 /**
25  * Build by using Maven.
26  *
27  * @author Kohsuke Kawaguchi
28  */

29 public class Maven extends Builder {
30     /**
31      * The targets and other maven options.
32      * Can be separated by SP or NL.
33      */

34     private final String JavaDoc targets;
35
36     /**
37      * Identifies {@link MavenInstallation} to be used.
38      */

39     private final String JavaDoc mavenName;
40
41     public Maven(String JavaDoc targets,String JavaDoc mavenName) {
42         this.targets = targets;
43         this.mavenName = mavenName;
44     }
45
46     public String JavaDoc getTargets() {
47         return targets;
48     }
49
50     /**
51      * Gets the Maven to invoke,
52      * or null to invoke the default one.
53      */

54     public MavenInstallation getMaven() {
55         for( MavenInstallation i : DESCRIPTOR.getInstallations() ) {
56             if(mavenName !=null && i.getName().equals(mavenName))
57                 return i;
58         }
59         return null;
60     }
61
62     /**
63      * Looks for <tt>pom.xlm</tt> or <tt>project.xml</tt> to determine the maven executable
64      * name.
65      */

66     private static final class DecideDefaultMavenCommand implements FileCallable<String JavaDoc> {
67         // command line arguments.
68
private final String JavaDoc arguments;
69
70         public DecideDefaultMavenCommand(String JavaDoc arguments) {
71             this.arguments = arguments;
72         }
73
74         public String JavaDoc invoke(File JavaDoc ws, VirtualChannel channel) throws IOException JavaDoc {
75             String JavaDoc seed=null;
76
77             // check for the -f option
78
StringTokenizer JavaDoc tokens = new StringTokenizer JavaDoc(arguments);
79             while(tokens.hasMoreTokens()) {
80                 String JavaDoc t = tokens.nextToken();
81                 if(t.equals("-f") && tokens.hasMoreTokens()) {
82                     File JavaDoc file = new File JavaDoc(ws,tokens.nextToken());
83                     if(!file.exists())
84                         continue; // looks like an error, but let the execution fail later
85
if(file.isDirectory())
86                         // in M1, you specify a directory in -f
87
seed = "maven";
88                     else
89                         // in M2, you specify a POM file name.
90
seed = "mvn";
91                     break;
92                 }
93             }
94
95             if(seed==null) {
96                 if(new File JavaDoc(ws,"pom.xml").exists())
97                     seed = "mvn";
98                 else
99                     // err on Maven 1 to be closer to the behavior in < 1.81
100
seed = "maven";
101             }
102
103             if(Functions.isWindows())
104                 seed += ".bat";
105             return seed;
106         }
107     }
108
109     public boolean perform(Build build, Launcher launcher, BuildListener listener) throws IOException JavaDoc, InterruptedException JavaDoc {
110         Project proj = build.getProject();
111
112         String JavaDoc normalizedTarget = targets.replaceAll("[\t\r\n]+"," ");
113
114         ArgumentListBuilder args = new ArgumentListBuilder();
115         MavenInstallation ai = getMaven();
116         if(ai==null) {
117             String JavaDoc execName = proj.getWorkspace().act(new DecideDefaultMavenCommand(normalizedTarget));
118             args.add(execName).addTokenized(normalizedTarget);
119         } else {
120             File JavaDoc exec = ai.getExecutable();
121             if(exec==null) {
122                 listener.fatalError("Couldn't find any executable in "+ai.getMavenHome());
123                 return false;
124             }
125             if(!exec.exists()) {
126                 listener.fatalError(exec+" doesn't exist");
127                 return false;
128             }
129             args.add(exec.getPath()).addTokenized(normalizedTarget);
130         }
131
132         Map JavaDoc<String JavaDoc,String JavaDoc> env = build.getEnvVars();
133         if(ai!=null)
134             env.put("MAVEN_HOME",ai.getMavenHome());
135         // just as a precaution
136
// see http://maven.apache.org/continuum/faqs.html#how-does-continuum-detect-a-successful-build
137
env.put("MAVEN_TERMINATE_CMD","on");
138
139         try {
140             int r = launcher.launch(args.toCommandArray(),env,listener.getLogger(),proj.getModuleRoot()).join();
141             return r==0;
142         } catch (IOException JavaDoc e) {
143             Util.displayIOException(e,listener);
144             e.printStackTrace( listener.fatalError("command execution failed") );
145             return false;
146         }
147     }
148
149     public Descriptor<Builder> getDescriptor() {
150         return DESCRIPTOR;
151     }
152
153     public static final DescriptorImpl DESCRIPTOR = new DescriptorImpl();
154
155     public static final class DescriptorImpl extends Descriptor<Builder> {
156         @CopyOnWrite
157         private volatile MavenInstallation[] installations = new MavenInstallation[0];
158
159         private DescriptorImpl() {
160             super(Maven.class);
161             load();
162         }
163
164
165         protected void convert(Map JavaDoc<String JavaDoc, Object JavaDoc> oldPropertyBag) {
166             if(oldPropertyBag.containsKey("installations"))
167                 installations = (MavenInstallation[]) oldPropertyBag.get("installations");
168         }
169
170         public String JavaDoc getHelpFile() {
171             return "/help/project-config/maven.html";
172         }
173
174         public String JavaDoc getDisplayName() {
175             return "Invoke top-level Maven targets";
176         }
177
178         public MavenInstallation[] getInstallations() {
179             return installations;
180         }
181
182         public boolean configure(StaplerRequest req) {
183             boolean r = true;
184
185             int i;
186             String JavaDoc[] names = req.getParameterValues("maven_name");
187             String JavaDoc[] homes = req.getParameterValues("maven_home");
188             int len;
189             if(names!=null && homes!=null)
190                 len = Math.min(names.length,homes.length);
191             else
192                 len = 0;
193             MavenInstallation[] insts = new MavenInstallation[len];
194
195             for( i=0; i<len; i++ ) {
196                 if(Util.nullify(names[i])==null) continue;
197                 if(Util.nullify(homes[i])==null) continue;
198                 insts[i] = new MavenInstallation(names[i],homes[i]);
199             }
200
201             this.installations = insts;
202
203             save();
204
205             return r;
206         }
207
208         public Builder newInstance(StaplerRequest req) {
209             return new Maven(req.getParameter("maven_targets"),req.getParameter("maven_version"));
210         }
211
212
213     //
214
// web methods
215
//
216
/**
217          * Checks if the MAVEN_HOME is valid.
218          */

219         public void doCheckMavenHome( StaplerRequest req, StaplerResponse rsp ) throws IOException JavaDoc, ServletException JavaDoc {
220             // this can be used to check the existence of a file on the server, so needs to be protected
221
new FormFieldValidator(req,rsp,true) {
222                 public void check() throws IOException JavaDoc, ServletException JavaDoc {
223                     File JavaDoc f = getFileParameter("value");
224                     if(!f.isDirectory()) {
225                         error(f+" is not a directory");
226                         return;
227                     }
228
229                     // I couldn't come up with a simple logic to test for a maven installation
230
// there seems to be just too much difference between m1 and m2.
231

232                     ok();
233                 }
234             }.process();
235         }
236     }
237
238     public static final class MavenInstallation {
239         private final String JavaDoc name;
240         private final String JavaDoc mavenHome;
241
242         public MavenInstallation(String JavaDoc name, String JavaDoc mavenHome) {
243             this.name = name;
244             this.mavenHome = mavenHome;
245         }
246
247         /**
248          * install directory.
249          */

250         public String JavaDoc getMavenHome() {
251             return mavenHome;
252         }
253
254         public File JavaDoc getHomeDir() {
255             return new File JavaDoc(mavenHome);
256         }
257
258         /**
259          * Human readable display name.
260          */

261         public String JavaDoc getName() {
262             return name;
263         }
264
265         public File JavaDoc getExecutable() {
266             File JavaDoc exe = getExeFile("maven");
267             if(exe.exists())
268                 return exe;
269             exe = getExeFile("mvn");
270             if(exe.exists())
271                 return exe;
272             return null;
273         }
274
275         private File JavaDoc getExeFile(String JavaDoc execName) {
276             if(File.separatorChar=='\\')
277                 execName += ".bat";
278             return new File JavaDoc(getMavenHome(), "bin/" + execName);
279         }
280
281         /**
282          * Returns true if the executable exists.
283          */

284         public boolean getExists() {
285             return getExecutable()!=null;
286         }
287     }
288 }
289
Popular Tags