KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > tools > ant > launch > Launcher


1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */

18 package org.apache.tools.ant.launch;
19
20 import java.net.URL JavaDoc;
21 import java.net.URLClassLoader JavaDoc;
22 import java.net.MalformedURLException JavaDoc;
23 import java.io.File JavaDoc;
24 import java.util.StringTokenizer JavaDoc;
25 import java.util.List JavaDoc;
26 import java.util.ArrayList JavaDoc;
27 import java.util.Iterator JavaDoc;
28
29
30
31 /**
32  * This is a launcher for Ant.
33  *
34  * @since Ant 1.6
35  */

36 public class Launcher {
37
38     /**
39      * The Ant Home (installation) Directory property.
40      * {@value}
41      */

42     public static final String JavaDoc ANTHOME_PROPERTY = "ant.home";
43
44     /**
45      * The Ant Library Directory property.
46      * {@value}
47      */

48     public static final String JavaDoc ANTLIBDIR_PROPERTY = "ant.library.dir";
49
50     /**
51      * The directory name of the per-user ant directory.
52      * {@value}
53      */

54     public static final String JavaDoc ANT_PRIVATEDIR = ".ant";
55
56     /**
57      * The name of a per-user library directory.
58      * {@value}
59      */

60     public static final String JavaDoc ANT_PRIVATELIB = "lib";
61
62     /**
63      * The location of a per-user library directory.
64      * <p>
65      * It's value is the concatenation of {@link #ANT_PRIVATEDIR}
66      * with {@link #ANT_PRIVATELIB}, with an appropriate file separator
67      * in between. For example, on Unix, it's <code>.ant/lib</code>.
68      */

69     public static final String JavaDoc USER_LIBDIR =
70         ANT_PRIVATEDIR + File.separatorChar + ANT_PRIVATELIB;
71
72     /**
73      * The startup class that is to be run.
74      * {@value}
75      */

76     public static final String JavaDoc MAIN_CLASS = "org.apache.tools.ant.Main";
77
78     /**
79      * System property with user home directory.
80      * {@value}
81      */

82     public static final String JavaDoc USER_HOMEDIR = "user.home";
83
84     /**
85      * System property with application classpath.
86      * {@value}
87      */

88     private static final String JavaDoc JAVA_CLASS_PATH = "java.class.path";
89
90     /**
91      * Exit code on trouble
92      */

93     protected static final int EXIT_CODE_ERROR = 2;
94
95     /**
96      * Entry point for starting command line Ant.
97      *
98      * @param args commandline arguments
99      */

100     public static void main(String JavaDoc[] args) {
101         int exitCode;
102         try {
103             Launcher launcher = new Launcher();
104             exitCode = launcher.run(args);
105         } catch (LaunchException e) {
106             exitCode = EXIT_CODE_ERROR;
107             System.err.println(e.getMessage());
108         } catch (Throwable JavaDoc t) {
109             exitCode = EXIT_CODE_ERROR;
110             t.printStackTrace(System.err);
111         }
112         if (exitCode != 0) {
113             System.exit(exitCode);
114         }
115     }
116
117
118     /**
119      * Add a CLASSPATH or -lib to lib path urls.
120      *
121      * @param path the classpath or lib path to add to the libPathULRLs
122      * @param getJars if true and a path is a directory, add the jars in
123      * the directory to the path urls
124      * @param libPathURLs the list of paths to add to
125      */

126     private void addPath(String JavaDoc path, boolean getJars, List JavaDoc libPathURLs)
127             throws MalformedURLException JavaDoc {
128         StringTokenizer JavaDoc tokenizer = new StringTokenizer JavaDoc(path, File.pathSeparator);
129         while (tokenizer.hasMoreElements()) {
130             String JavaDoc elementName = tokenizer.nextToken();
131             File JavaDoc element = new File JavaDoc(elementName);
132             if (elementName.indexOf("%") != -1 && !element.exists()) {
133                 continue;
134             }
135             if (getJars && element.isDirectory()) {
136                 // add any jars in the directory
137
URL JavaDoc[] dirURLs = Locator.getLocationURLs(element);
138                 for (int j = 0; j < dirURLs.length; ++j) {
139                     libPathURLs.add(dirURLs[j]);
140                 }
141             }
142
143             libPathURLs.add(Locator.fileToURL(element));
144         }
145     }
146
147     /**
148      * Run the launcher to launch Ant.
149      *
150      * @param args the command line arguments
151      * @return an exit code. As the normal ant main calls exit when it ends,
152      * this is for handling failures at bind-time
153      * @exception MalformedURLException if the URLs required for the classloader
154      * cannot be created.
155      */

156     private int run(String JavaDoc[] args)
157             throws LaunchException, MalformedURLException JavaDoc {
158         String JavaDoc antHomeProperty = System.getProperty(ANTHOME_PROPERTY);
159         File JavaDoc antHome = null;
160
161         File JavaDoc sourceJar = Locator.getClassSource(getClass());
162         File JavaDoc jarDir = sourceJar.getParentFile();
163         String JavaDoc mainClassname = MAIN_CLASS;
164
165         if (antHomeProperty != null) {
166             antHome = new File JavaDoc(antHomeProperty);
167         }
168
169         if (antHome == null || !antHome.exists()) {
170             antHome = jarDir.getParentFile();
171             System.setProperty(ANTHOME_PROPERTY, antHome.getAbsolutePath());
172         }
173
174         if (!antHome.exists()) {
175             throw new LaunchException("Ant home is set incorrectly or "
176                 + "ant could not be located");
177         }
178
179         List JavaDoc libPaths = new ArrayList JavaDoc();
180         String JavaDoc cpString = null;
181         List JavaDoc argList = new ArrayList JavaDoc();
182         String JavaDoc[] newArgs;
183         boolean noUserLib = false;
184         boolean noClassPath = false;
185
186         for (int i = 0; i < args.length; ++i) {
187             if (args[i].equals("-lib")) {
188                 if (i == args.length - 1) {
189                     throw new LaunchException("The -lib argument must "
190                         + "be followed by a library location");
191                 }
192                 libPaths.add(args[++i]);
193             } else if (args[i].equals("-cp")) {
194                 if (i == args.length - 1) {
195                     throw new LaunchException("The -cp argument must "
196                         + "be followed by a classpath expression");
197                 }
198                 if (cpString != null) {
199                     throw new LaunchException("The -cp argument must "
200                         + "not be repeated");
201                 }
202                 cpString = args[++i];
203             } else if (args[i].equals("--nouserlib") || args[i].equals("-nouserlib")) {
204                 noUserLib = true;
205             } else if (args[i].equals("--noclasspath") || args[i].equals("-noclasspath")) {
206                 noClassPath = true;
207             } else if (args[i].equals("-main")) {
208                 if (i == args.length - 1) {
209                     throw new LaunchException("The -main argument must "
210                             + "be followed by a library location");
211                 }
212                 mainClassname = args[++i];
213             } else {
214                 argList.add(args[i]);
215             }
216         }
217
218         //decide whether to copy the existing arg set, or
219
//build a new one from the list of all args excluding the special
220
//operations that only we handle
221
if (argList.size() == args.length) {
222             newArgs = args;
223         } else {
224             newArgs = (String JavaDoc[]) argList.toArray(new String JavaDoc[argList.size()]);
225         }
226
227         URL JavaDoc[] libURLs = getLibPathURLs(
228             noClassPath ? null : cpString, libPaths);
229         URL JavaDoc[] systemURLs = getSystemURLs(jarDir);
230         URL JavaDoc[] userURLs = noUserLib ? new URL JavaDoc[0] : getUserURLs();
231
232         URL JavaDoc[] jars = getJarArray(
233             libURLs, userURLs, systemURLs, Locator.getToolsJar());
234
235         // now update the class.path property
236
StringBuffer JavaDoc baseClassPath
237             = new StringBuffer JavaDoc(System.getProperty(JAVA_CLASS_PATH));
238         if (baseClassPath.charAt(baseClassPath.length() - 1)
239                 == File.pathSeparatorChar) {
240             baseClassPath.setLength(baseClassPath.length() - 1);
241         }
242
243         for (int i = 0; i < jars.length; ++i) {
244             baseClassPath.append(File.pathSeparatorChar);
245             baseClassPath.append(Locator.fromURI(jars[i].toString()));
246         }
247
248         System.setProperty(JAVA_CLASS_PATH, baseClassPath.toString());
249
250         URLClassLoader JavaDoc loader = new URLClassLoader JavaDoc(jars);
251         Thread.currentThread().setContextClassLoader(loader);
252         Class JavaDoc mainClass = null;
253         int exitCode = 0;
254         try {
255             mainClass = loader.loadClass(mainClassname);
256             AntMain main = (AntMain) mainClass.newInstance();
257             main.startAnt(newArgs, null, null);
258         } catch (InstantiationException JavaDoc ex) {
259             System.err.println(
260                 "Incompatible version of " + mainClassname + " detected");
261             File JavaDoc mainJar = Locator.getClassSource(mainClass);
262             System.err.println(
263                 "Location of this class " + mainJar);
264             exitCode = EXIT_CODE_ERROR;
265         } catch (Throwable JavaDoc t) {
266             t.printStackTrace(System.err);
267             exitCode = EXIT_CODE_ERROR;
268         }
269         return exitCode;
270     }
271
272     /**
273      * Get the list of -lib enties and -cp entry into
274      * a URL array.
275      * @param cpString the classpath string
276      * @param libPaths the list of -lib entries.
277      * @return an array of URLs.
278      */

279     private URL JavaDoc[] getLibPathURLs(String JavaDoc cpString, List JavaDoc libPaths)
280         throws MalformedURLException JavaDoc {
281         List JavaDoc libPathURLs = new ArrayList JavaDoc();
282
283         if (cpString != null) {
284             addPath(cpString, false, libPathURLs);
285         }
286
287         for (Iterator JavaDoc i = libPaths.iterator(); i.hasNext();) {
288             String JavaDoc libPath = (String JavaDoc) i.next();
289             addPath(libPath, true, libPathURLs);
290         }
291
292         return (URL JavaDoc[]) libPathURLs.toArray(new URL JavaDoc[libPathURLs.size()]);
293     }
294
295     /**
296      * Get the jar files in ANT_HOME/lib.
297      * determine ant library directory for system jars: use property
298      * or default using location of ant-launcher.jar
299      */

300     private URL JavaDoc[] getSystemURLs(File JavaDoc antLauncherDir) throws MalformedURLException JavaDoc {
301         File JavaDoc antLibDir = null;
302         String JavaDoc antLibDirProperty = System.getProperty(ANTLIBDIR_PROPERTY);
303         if (antLibDirProperty != null) {
304             antLibDir = new File JavaDoc(antLibDirProperty);
305         }
306         if ((antLibDir == null) || !antLibDir.exists()) {
307             antLibDir = antLauncherDir;
308             System.setProperty(ANTLIBDIR_PROPERTY, antLibDir.getAbsolutePath());
309         }
310         return Locator.getLocationURLs(antLibDir);
311     }
312
313     /**
314      * Get the jar files in user.home/.ant/lib
315      */

316     private URL JavaDoc[] getUserURLs() throws MalformedURLException JavaDoc {
317         File JavaDoc userLibDir
318             = new File JavaDoc(System.getProperty(USER_HOMEDIR), USER_LIBDIR);
319
320         return Locator.getLocationURLs(userLibDir);
321     }
322
323     /**
324      * Combine the various jar sources into a single array of jars.
325      * @param libJars the jars specified in -lib command line options
326      * @param userJars the jars in ~/.ant/lib
327      * @param systemJars the jars in $ANT_HOME/lib
328      * @param toolsJar the tools.jar file
329      * @return a combined array
330      * @throws MalformedURLException if there is a problem.
331      */

332     private URL JavaDoc[] getJarArray (
333         URL JavaDoc[] libJars, URL JavaDoc[] userJars, URL JavaDoc[] systemJars, File JavaDoc toolsJar)
334         throws MalformedURLException JavaDoc {
335         int numJars = libJars.length + userJars.length + systemJars.length;
336         if (toolsJar != null) {
337             numJars++;
338         }
339         URL JavaDoc[] jars = new URL JavaDoc[numJars];
340         System.arraycopy(libJars, 0, jars, 0, libJars.length);
341         System.arraycopy(userJars, 0, jars, libJars.length, userJars.length);
342         System.arraycopy(systemJars, 0, jars, userJars.length + libJars.length,
343             systemJars.length);
344
345         if (toolsJar != null) {
346             jars[jars.length - 1] = Locator.fileToURL(toolsJar);
347         }
348         return jars;
349     }
350 }
351
Popular Tags