KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > uk > ac > roe > antigen > builder > Installer


1 /*
2  * Created on 22-Oct-2004
3  */

4 package uk.ac.roe.antigen.builder;
5
6 import java.io.BufferedInputStream JavaDoc;
7 import java.io.File JavaDoc;
8 import java.io.FileInputStream JavaDoc;
9 import java.io.FileNotFoundException JavaDoc;
10 import java.io.IOException JavaDoc;
11 import java.io.InputStream JavaDoc;
12 import java.net.MalformedURLException JavaDoc;
13 import java.net.URL JavaDoc;
14 import java.net.URLDecoder JavaDoc;
15 import java.util.Enumeration JavaDoc;
16 import java.util.Hashtable JavaDoc;
17 import java.util.Iterator JavaDoc;
18 import java.util.List JavaDoc;
19 import java.util.Properties JavaDoc;
20 import java.util.logging.Handler JavaDoc;
21 import java.util.logging.Level JavaDoc;
22 import java.util.logging.Logger JavaDoc;
23
24 import org.apache.commons.cli.CommandLine;
25 import org.apache.commons.cli.HelpFormatter;
26 import org.apache.commons.cli.Option;
27 import org.apache.commons.cli.OptionBuilder;
28 import org.apache.commons.cli.Options;
29 import org.apache.commons.cli.ParseException;
30 import org.apache.commons.cli.Parser;
31 import org.apache.commons.cli.PosixParser;
32 import org.apache.tools.ant.BuildException;
33 import org.apache.tools.ant.BuildLogger;
34 import org.apache.tools.ant.DefaultLogger;
35 import org.apache.tools.ant.Project;
36 import org.apache.tools.ant.ProjectHelper;
37 import org.apache.tools.ant.Target;
38 import org.apache.tools.ant.input.InputHandler;
39 import org.apache.velocity.exception.MethodInvocationException;
40 import org.apache.velocity.exception.ParseErrorException;
41 import org.apache.velocity.exception.ResourceNotFoundException;
42
43 import uk.ac.roe.antigen.ant.BuildGrabber;
44 import uk.ac.roe.antigen.ant.GeneralInputHandler;
45 import uk.ac.roe.antigen.ant.TaskTreeCalcuator;
46 import uk.ac.roe.antigen.dialogs.AbortDialog;
47 import uk.ac.roe.antigen.dialogs.BuildLoggerFrame;
48 import uk.ac.roe.antigen.dialogs.InfoFrame;
49 import uk.ac.roe.antigen.dialogs.SplashScreen;
50 import uk.ac.roe.antigen.dialogs.TargetChoiceFrame;
51 import uk.ac.roe.antigen.textcomponents.DefaultPromptingInputHandler;
52 import uk.ac.roe.antigen.textcomponents.TextInfoDisplay;
53 import uk.ac.roe.antigen.textcomponents.TextTargetChooser;
54 import uk.ac.roe.antigen.utils.Config;
55 import uk.ac.roe.antigen.utils.CopyableFile;
56
57 /**
58  * Main controller, loads up the build file, and fires it at Ant, setting up our
59  * Custom loggers and inputhandlers.
60  *
61  * @todo refactor and make it less embarrassing
62  *
63  * @author jdt
64  */

65 public class Installer {
66
67     private static final String JavaDoc ANTIGEN_HOME = "antigen.home";
68
69     private static final String JavaDoc ANTIGEN_JARFILE = "antigen.jarfile";
70
71     /**
72      * Logger for this class
73      */

74     private static final Logger JavaDoc logger = Logger.getLogger(Installer.class.getName());
75
76     private static final String JavaDoc PROPERTY_OPTION = "D";
77     
78     private static final String JavaDoc PROXY_OPTION="p";
79     
80     private static final String JavaDoc PROPERTYFILE_OPTION = "f";
81
82     private static final String JavaDoc CMDLINE_OPTION = "c";
83
84     private static final String JavaDoc HELP_OPTION = "h";
85
86     private static final String JavaDoc DEBUG_OPTION = "d";
87
88     private static final String JavaDoc PROXYUSER_OPTION = "u";
89
90     private static final String JavaDoc PROPERTY_ANTIGEN_OPTION = "A";
91
92     public static void main(String JavaDoc[] args) throws Throwable JavaDoc {
93
94         
95         CommandLine line = parseCommandLine(args);
96         
97         Config.load("/config.properties");
98
99         //Override Antigen properties if requested
100
if (line.hasOption(PROPERTY_ANTIGEN_OPTION)) {
101             String JavaDoc[] keyValuePairs=line.getOptionValues(PROPERTY_ANTIGEN_OPTION);
102             logger.fine("Found "+keyValuePairs.length/2+" antigen properties");
103             for (int i=0;i<keyValuePairs.length/2;++i) {
104                     String JavaDoc key=keyValuePairs[2*i];
105                     String JavaDoc value=keyValuePairs[2*i+1];
106                     logger.fine("Overriding property "+key+"="+value);
107                     Config.setProperty(key,value);
108             }
109         }
110         
111         String JavaDoc levelString = Config.getProperty("antigen.loglevel","SEVERE");
112         boolean debug = line.hasOption(DEBUG_OPTION);
113         if (debug) {
114             levelString = line.getOptionValue(DEBUG_OPTION);
115         }
116         Level JavaDoc logLevel = Level.parse(levelString);
117
118         // Crank up the logging level, and that of the (assumed only)
119
// handler
120
Logger JavaDoc rootLogger = Logger.getLogger("");
121         rootLogger.setLevel(logLevel);
122         Handler JavaDoc[] handlers = rootLogger.getHandlers();
123         assert handlers.length != 0;
124         Handler JavaDoc handler = handlers[0];
125         handler.setLevel(logLevel);
126         logger.info("Debug mode: "+levelString);
127         
128         boolean textOnly = line.hasOption(CMDLINE_OPTION);
129         logger.info("Text only mode: " + textOnly);
130
131         Properties JavaDoc sysprops = System.getProperties();
132         if (line.hasOption(PROXY_OPTION)) {
133             logger.fine("Setting proxy");
134             String JavaDoc hostAndPort = line.getOptionValue(PROXY_OPTION);
135             String JavaDoc[] hostAndPortSplit = hostAndPort.split(":");
136             String JavaDoc host = hostAndPortSplit[0];
137             String JavaDoc port = hostAndPortSplit.length>1 ? hostAndPortSplit[1] : "80";
138             logger.fine("Proxying through "+host+" on port "+port);
139
140            // sysprops.put("proxySet", "true");
141
sysprops.put("http.proxyHost", host);
142             sysprops.put("http.proxyPort", port);
143             if (line.hasOption(PROXYUSER_OPTION)) {
144                 String JavaDoc userAndPass = line.getOptionValue(PROXYUSER_OPTION);
145                 String JavaDoc[] userAndPassSplit = userAndPass.split(":");
146                 String JavaDoc proxyUser = userAndPassSplit[0];
147                 String JavaDoc proxyPassword = userAndPassSplit.length>1 ? userAndPassSplit[1] : "";
148                 sysprops.put("http.proxyUser", proxyUser);
149                 sysprops.put("http.proxyPassword", proxyPassword);
150             }
151         }
152
153         File JavaDoc thisJar;
154         logger.fine("Getting this jar");
155         try {
156             thisJar = new Installer().getEnclosingJar(); //yuck
157
} catch (FileNotFoundException JavaDoc fe) {
158             logger.warning(fe.getMessage());
159             logger.warning("Unable to set property "+ANTIGEN_JARFILE);
160             thisJar = new File JavaDoc("Unknown");
161         }
162         
163         //Show a dialog, if necessary
164
if ((Config.getProperty("antigen.splash.logo")!=null || Config.getProperty("antigen.splash.text")!=null) && !textOnly) {
165             new SplashScreen().show();
166         }
167         
168         
169         
170         
171
172
173         // Grab all the build files, and place them in a temporary directory
174
String JavaDoc buildSrcType = Config.getProperty("build.src.type");
175         String JavaDoc buildSrcLoc = Config.getProperty("build.src.location");
176         assert buildSrcLoc != null;
177         CopyableFile tmpDir = null;
178         
179         String JavaDoc buildDir = Config.getProperty("antigen.tmp.dir");
180         try {
181             BuildGrabber buildGrabber;
182             if (buildDir!=null) {
183                 buildGrabber= new BuildGrabber(new File JavaDoc(buildDir));
184             } else {
185                 buildGrabber= new BuildGrabber();
186             }
187             if ("dir".equals(buildSrcType)) {
188                 //useful for testing
189
logger.fine("Grabbing from directory " + buildSrcLoc);
190                 tmpDir = buildGrabber.grab(new File JavaDoc(buildSrcLoc));
191             } else if ("classpath".equals(buildSrcType)) {
192                 //grab a jar file off the classpath - useful if everything's
193
// bundled in one big jar
194
logger.fine("Grabbing from the classpath off " + buildSrcLoc);
195                 tmpDir = buildGrabber.grab(buildSrcLoc);
196             } else if ("self".equals(buildSrcType)) {
197                 logger.fine("Grabbing from self");
198                 tmpDir = buildGrabber.grab(thisJar.toURL());
199             } else {
200                 //default to URL
201
tmpDir = buildGrabber.grab(new URL JavaDoc(buildSrcLoc));
202             }
203         } catch (MalformedURLException JavaDoc e1) {
204             logger.severe("Unable to load build script from " + buildSrcType + " " + buildSrcLoc);
205             logger.severe("Sorry, but I can't continue");
206             logger.fine(e1.getMessage());
207             throw e1;
208         } catch (IOException JavaDoc e1) {
209             logger.severe("Unable to load build script from " + buildSrcType + " " + buildSrcLoc);
210             logger.severe("Sorry, but I can't continue");
211             logger.fine(e1.getMessage());
212             throw e1;
213         }
214
215         BuildLoggerFrame builddialog = null;
216         if (!textOnly) {
217             builddialog = new BuildLoggerFrame();
218         }
219         showInfoDialog(builddialog, sysprops, "antigen.intro.text", "antigen.intro.template", textOnly);
220
221         File JavaDoc buildFile = new File JavaDoc(tmpDir, "build.xml");
222
223         Project project = new Project();
224         project.init();
225         ProjectHelper.configureProject(project, buildFile);
226
227         //Add in some properties that might be useful to a script
228

229         project.setProperty(ANTIGEN_HOME, System.getProperty("user.dir")); //where we're running
230
project.setProperty(ANTIGEN_JARFILE, thisJar.getAbsolutePath());
231
232         //Add in some properties if requested
233
//Single properties
234
if (line.hasOption(PROPERTY_OPTION)) {
235             String JavaDoc[] keyValuePairs=line.getOptionValues(PROPERTY_OPTION);
236             logger.fine("Found "+keyValuePairs.length/2+" command line properties");
237             for (int i=0;i<keyValuePairs.length/2;++i) {
238                     String JavaDoc key=keyValuePairs[2*i];
239                     String JavaDoc value=keyValuePairs[2*i+1];
240                     logger.fine("Setting property "+key+"="+value);
241                     project.setProperty(key, value);
242             }
243         }
244         
245         //property files
246
if (line.hasOption(PROPERTYFILE_OPTION)) {
247             logger.fine("Attempting to load properties from a file");
248             File JavaDoc inputFile = new File JavaDoc(line.getOptionValue(PROPERTYFILE_OPTION));
249             //Really ought to be a utility method somewhere to do this kind of
250
// shit
251
Properties JavaDoc props = new Properties JavaDoc();
252             InputStream JavaDoc is = null;
253             try {
254                 is = new BufferedInputStream JavaDoc(new FileInputStream JavaDoc(inputFile));
255                 props.load(is);
256             } catch (IOException JavaDoc ie) {
257                 logger.warning("Was unable to load properties file " + ie.getMessage() + "...continuing");
258             } finally {
259                 if (is != null)
260                     try {
261                         is.close();
262                     } catch (IOException JavaDoc swallow) {
263                         // Well, I tried
264
}
265             }
266             Enumeration JavaDoc enumer = props.keys();
267             while (enumer.hasMoreElements()) {
268                 String JavaDoc key = (String JavaDoc) enumer.nextElement();
269                 logger.fine("Putting property " + key + "=" + props.getProperty(key));
270                 project.setProperty(key, props.getProperty(key));
271             }
272         }
273
274         // Select which targets to run
275
String JavaDoc targetName = project.getDefaultTarget();
276
277         String JavaDoc anyChosenTargets = Config.getProperty(TargetChoiceFrame.ANTIGEN_TARGETS);
278         if (anyChosenTargets != null) {
279             if (anyChosenTargets.split(",").length == 1) {
280                 //only one choice
281
targetName = anyChosenTargets; //@TODO need to check this
282
// exists
283
} else {
284                 TargetChooser targetChoiceFrame;
285                 if (textOnly) {
286                     targetChoiceFrame = new TextTargetChooser(project);
287                 } else {
288                     targetChoiceFrame = new TargetChoiceFrame(project);
289                 }
290                 List JavaDoc targetNames = targetChoiceFrame.showAndWaitForResponse();
291                 Target master = new Target();
292
293                 //master.
294
Iterator JavaDoc it = targetNames.iterator();
295                 while (it.hasNext()) {
296                     String JavaDoc next = (String JavaDoc) it.next();
297                     logger.fine("Adding target " + next);
298                     master.addDependency(next);
299                 }
300                 final String JavaDoc masterTargetName = "master";
301                 master.setName(masterTargetName);
302                 master.setDescription("One project to rule them all");
303                 // master.setProject(project);
304
project.addTarget(masterTargetName, master);
305                 targetName = masterTargetName;
306                 project.init();
307             }
308         }
309
310         //Get total number of tasks to be run
311

312         int numberOfTasks = new TaskTreeCalcuator(project).getNumberOfTasksToRun(targetName);
313         logger.fine("main(String[])" + numberOfTasks);
314
315         InputHandler inputHandler;
316         BuildLogger buildLogger;
317         if (!textOnly) {
318             builddialog.setVisible(true);
319             builddialog.setNumberOfTasks(numberOfTasks); //used to callibrate
320
// progress bar
321
BuildLogger dialogBuildLogger = builddialog.getBuildLogger();
322
323             inputHandler = new GeneralInputHandler(builddialog);
324             buildLogger = dialogBuildLogger;
325
326         } else {
327             inputHandler = new DefaultPromptingInputHandler();
328             DefaultLogger defaultListener = new DefaultLogger();
329             buildLogger = defaultListener;
330             buildLogger.setOutputPrintStream(System.out);
331             buildLogger.setErrorPrintStream(System.err);
332         }
333         
334         int antOutputLevel = Integer.parseInt(Config.getProperty("antigen.antoutput","2"));
335         buildLogger.setMessageOutputLevel(antOutputLevel);
336         project.addBuildListener(buildLogger);
337         project.setInputHandler(inputHandler);
338
339         try {
340             project.executeTarget(targetName);
341             if (!textOnly) {
342                 builddialog.setFinished();
343             }
344
345             showInfoDialog(builddialog, project.getProperties(), "antigen.outro.text", "antigen.outro.template",
346                     textOnly);
347
348         } catch (BuildException e) {
349             logger.info("There was an error in the build process");
350             logger.info("e.getClass()");
351             logger.info("e");
352             if (textOnly) {
353                 System.out.println(e.getMessage());
354             } else {
355                 new AbortDialog(builddialog, e.getMessage()).show();
356             }
357         } finally {
358             //Only delete the builddir if it's a temporary one.
359
if (buildDir==null) {
360                 tmpDir.recursivelyDelete();
361             }
362         }
363
364     }
365
366     /**
367      * @param args
368      */

369     private static CommandLine parseCommandLine(String JavaDoc[] args) {
370         Parser parser = new PosixParser();
371         Options options = new Options();
372         options.addOption(HELP_OPTION, "help", false, "Display this help.")
373                 .addOption(CMDLINE_OPTION, "commandline", false, "Execute on the command line (without a GUI)")
374                 .addOption(DEBUG_OPTION, "debug", true,"Set the commandline debug output level - see java doc for java/util/logging/Level for values, defaults to SEVERE")
375                 .addOption(PROPERTYFILE_OPTION, "properties", true,"Supply a .property file")
376              // .addOption(PROPERTY_OPTION, "property",true,"Supply a single property (foo.bar=value)")
377
.addOption(PROXY_OPTION,"proxy",true,"Supply a web proxy host (host:port)")
378                 .addOption(PROXYUSER_OPTION,"user",true, "Supply a user name for the proxy (user:password)");
379         Option propertyOpt = OptionBuilder.withArgName( "property=value" )
380                 .withLongOpt("antproperty")
381                 .hasArg()
382                 .withValueSeparator()
383                 .withDescription( "use value for given property in the Ant build" )
384                 .create( PROPERTY_OPTION );
385         options.addOption(propertyOpt);
386         propertyOpt.setArgs(Option.UNLIMITED_VALUES);
387         
388         Option antigenPropertyOpt = OptionBuilder.withArgName( "property=value" )
389             .withLongOpt("antigenproperty")
390             .hasArg()
391             .withValueSeparator()
392             .withDescription( "use value for given property, overriding the value in the Antigen config.properties file" )
393             .create( PROPERTY_ANTIGEN_OPTION );
394         options.addOption(antigenPropertyOpt);
395         antigenPropertyOpt.setArgs(Option.UNLIMITED_VALUES);
396
397         CommandLine line = null;
398         try {
399             line = parser.parse(options, args);
400         } catch (ParseException e) {
401             logger.severe("Error parsing command line " + e.getMessage());
402             displayHelp(options);
403             System.exit(1); //@TODO this has to be done better - this is crap
404
}
405         if (line.hasOption(HELP_OPTION)) {
406             displayHelp(options);
407             System.exit(0); //@TODO this has to be done better - this is crap
408
}
409         return line;
410     }
411
412     /**
413      * @param options
414      *
415      */

416     private static void displayHelp(Options options) {
417         new HelpFormatter().printHelp("java -jar (jarname) option", options);
418     }
419
420     /**
421      * @param builddialog
422      * @param properties
423      * @param textKey
424      * @param templateKey
425      * @param textOnly
426      * @throws Exception
427      * @throws ResourceNotFoundException
428      * @throws ParseErrorException
429      * @throws MethodInvocationException
430      */

431     private static void showInfoDialog(BuildLoggerFrame builddialog, Hashtable JavaDoc properties, String JavaDoc textKey,
432             String JavaDoc templateKey, boolean textOnly) throws Exception JavaDoc {
433         String JavaDoc text = Config.getProperty(textKey);
434         String JavaDoc template = Config.getProperty(templateKey);
435         String JavaDoc message = template != null ? MessageProcessor.processMessage(properties, template) : text;
436
437         if (message == null) {
438             logger.fine("No information text");
439             return;
440         }
441
442         InfoDisplay display;
443         if (textOnly) {
444             display = new TextInfoDisplay(message);
445         } else {
446             display = new InfoFrame(message);
447         }
448
449         display.showAndWaitForResponse();
450     }
451
452     /**
453      * Get the File that this jar is being run from. Lifted from antinstaller's
454      * SelfExtractor http://antinstaller.sourceforge.net and modified a bit
455      *
456      * @return
457      * @throws FileNotFoundException
458      */

459
460     private File JavaDoc getEnclosingJar() throws FileNotFoundException JavaDoc {
461         logger.fine("Attempting to get enclosing jar name");
462         String JavaDoc thisClass = "/" + getClass().getName().replace('.', '/') + ".class";
463         logger.finer("This class " + thisClass);
464         URL JavaDoc jarUrl = this.getClass().getResource(thisClass);
465         String JavaDoc stringForm = jarUrl.toString();
466         logger.finer("Jar URL " + stringForm);
467         String JavaDoc fileForm = jarUrl.getFile();
468
469         int endIdx = stringForm.indexOf("!/");
470         if (endIdx == -1) {
471             throw new FileNotFoundException JavaDoc("Could not locate enclosing jar: !/ not found in URL");
472         }
473         
474         String JavaDoc fileNamePart = stringForm.substring("jar:file:".length(), endIdx);
475         logger.finer("Extracted file name: " + fileNamePart);
476         String JavaDoc unescaped = URLDecoder.decode(fileNamePart);
477         logger.finer("Unescaped Extracted file name: " + unescaped);
478         File JavaDoc file = new File JavaDoc(unescaped);
479         if (!file.exists()) {
480             throw new FileNotFoundException JavaDoc("Could not locate enclosing jar: file "+file+" not found");
481         }
482         return file;
483     }
484
485 }
Popular Tags