001: /*
002: * Copyright 2003-2004 The Apache Software Foundation
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: *
016: */
017: package org.tp23.antinstaller.antmod;
018:
019: import java.io.File;
020: import java.net.MalformedURLException;
021: import java.net.URL;
022: import java.net.URLClassLoader;
023: import java.util.ArrayList;
024: import java.util.Iterator;
025: import java.util.List;
026: import java.util.Map;
027: import java.util.Properties;
028: import java.util.StringTokenizer;
029:
030: import org.apache.tools.ant.launch.LaunchException;
031: import org.apache.tools.ant.launch.Locator;
032: import org.tp23.antinstaller.InstallerContext;
033:
034: /**
035: * This is a launcher for Ant.
036: *
037: * This file has been modified by Paul Hinds for Antinstaller and is not the same
038: * as the one delivered with Ant 1.6
039: *
040: * @since Ant 1.6
041: * @version $Id: Launcher.java,v 1.1.1.1 2005/10/18 18:20:54 teknopaul Exp $
042: */
043: public class Launcher {
044: /** The Ant Home property */
045: public static final String ANTHOME_PROPERTY = "ant.home";
046:
047: /** The Ant Library Directory property */
048: public static final String ANTLIBDIR_PROPERTY = "ant.library.dir";
049:
050: /** The location of a per-user library directory */
051: public static final String USER_LIBDIR = ".ant/lib";
052:
053: /** The startup class that is to be run */
054: public static final String MAIN_CLASS = "org.apache.tools.ant.Main";
055:
056: private final Map allProperties;
057:
058: /**
059: * Addtional Constructor to pass password properties to Ant
060: * without saving them to a file.
061: * Added by Paul Hinds
062: * @param allProperties Properties
063: */
064: public Launcher(Map allProperties) {
065: this .allProperties = allProperties;
066: }
067:
068: /**
069: * Run the launcher to launch Ant
070: *
071: * @param args the command line arguments (hardcoded in AI)
072: *
073: * @exception MalformedURLException if the URLs required for the classloader
074: * cannot be created.
075: */
076: public int run(String[] args, InstallerContext cxt)
077: throws LaunchException, MalformedURLException {
078:
079: try {
080:
081: String antHomeProperty = System
082: .getProperty(ANTHOME_PROPERTY);
083: File antHome = null;
084:
085: File jarDir = null;
086:
087: File sourceJar = Locator.getClassSource(getClass());
088: jarDir = sourceJar.getParentFile();
089:
090: if (antHomeProperty != null) {
091: antHome = new File(antHomeProperty);
092: }
093:
094: if (antHome == null || !antHome.exists()) {
095: antHome = jarDir.getParentFile();
096: System.setProperty(ANTHOME_PROPERTY, antHome
097: .getAbsolutePath());
098: }
099:
100: if (!antHome.exists()) {
101: throw new LaunchException(
102: "Ant home is set incorrectly or ant could not be located");
103: }
104:
105: List libPaths = new ArrayList();
106: List argList = new ArrayList();
107: String[] newArgs;
108:
109: for (int i = 0; i < args.length; ++i) {
110: if (args[i].equals("-lib")) {
111: if (i == args.length - 1) {
112: throw new LaunchException(
113: "The -lib argument must be followed by a library location");
114: }
115: libPaths.add(args[++i]);
116: } else {
117: argList.add(args[i]);
118: }
119: }
120:
121: if (libPaths.size() == 0) {
122: newArgs = args;
123: } else {
124: newArgs = (String[]) argList.toArray(new String[0]);
125: }
126:
127: List libPathURLs = new ArrayList();
128: for (Iterator i = libPaths.iterator(); i.hasNext();) {
129: String libPath = (String) i.next();
130: StringTokenizer myTokenizer = new StringTokenizer(
131: libPath, System.getProperty("path.separator"));
132: while (myTokenizer.hasMoreElements()) {
133: String elementName = myTokenizer.nextToken();
134: File element = new File(elementName);
135: if (elementName.indexOf("%") != -1
136: && !element.exists()) {
137: continue;
138: }
139: if (element.isDirectory()) {
140: // add any jars in the directory
141: URL[] dirURLs = Locator
142: .getLocationURLs(element);
143: for (int j = 0; j < dirURLs.length; ++j) {
144: libPathURLs.add(dirURLs[j]);
145: }
146: }
147:
148: libPathURLs.add(element.toURL());
149: }
150: }
151:
152: URL[] libJars = (URL[]) libPathURLs.toArray(new URL[0]);
153:
154: // Now try and find JAVA_HOME
155: File toolsJar = Locator.getToolsJar();
156:
157: // determine ant library directory for system jars: use property
158: // or default using location of ant-launcher.jar
159: File antLibDir = null;
160: String antLibDirProperty = System
161: .getProperty(ANTLIBDIR_PROPERTY);
162: if (antLibDirProperty != null) {
163: antLibDir = new File(antLibDirProperty);
164: }
165: if ((antLibDir == null) || !antLibDir.exists()) {
166: antLibDir = jarDir;
167: System.setProperty(ANTLIBDIR_PROPERTY, antLibDir
168: .getAbsolutePath());
169: }
170: URL[] systemJars = Locator.getLocationURLs(antLibDir);
171:
172: File userLibDir = new File(System.getProperty("user.home"),
173: USER_LIBDIR);
174: URL[] userJars = Locator.getLocationURLs(userLibDir);
175:
176: int numJars = libJars.length + userJars.length
177: + systemJars.length;
178: if (toolsJar != null) {
179: numJars++;
180: }
181: URL[] jars = new URL[numJars];
182: System.arraycopy(libJars, 0, jars, 0, libJars.length);
183: System.arraycopy(userJars, 0, jars, libJars.length,
184: userJars.length);
185: System.arraycopy(systemJars, 0, jars, userJars.length
186: + libJars.length, systemJars.length);
187:
188: if (toolsJar != null) {
189: jars[jars.length - 1] = toolsJar.toURL();
190: }
191:
192: // now update the class.path property
193: StringBuffer baseClassPath = new StringBuffer(System
194: .getProperty("java.class.path"));
195: if (baseClassPath.charAt(baseClassPath.length() - 1) == File.pathSeparatorChar) {
196: baseClassPath.setLength(baseClassPath.length() - 1);
197: }
198:
199: for (int i = 0; i < jars.length; ++i) {
200: baseClassPath.append(File.pathSeparatorChar);
201: baseClassPath.append(Locator
202: .fromURI(jars[i].toString()));
203: }
204:
205: System.setProperty("java.class.path", baseClassPath
206: .toString());
207:
208: URLClassLoader loader = new URLClassLoader(jars);
209: Thread.currentThread().setContextClassLoader(loader);
210: try {
211: Main main = new Main();
212: Properties props = new Properties();
213: props.putAll(allProperties);
214: return main.startAnt(newArgs, props, null, cxt);
215: } catch (Throwable t) {
216: t.printStackTrace();
217: return 1;
218: }
219: } catch (Throwable ex) {
220: // Essentially all of the above is nice to have as far as AntInstaller is concerned
221: // ant.home may not be available when installing and application on a client that does not
222: // have and never will have Ant. However the code is left since sometimes AntInstaller can be used
223: // for a general gui for Ant builds and features such and ANT_HOME/lib are useful
224: try {
225: System.setProperty(ANTHOME_PROPERTY, new File(".")
226: .getAbsolutePath());
227: Main main = new Main();
228: // fix for bug:1177191
229: // remove the -lib as discovered by Mark Anderson
230: String[] newArgs = new String[args.length - 2];
231: for (int i = 0, n = 0; i < args.length; i++) {
232: if (args[i].equals("-lib")) {
233: i++;
234: continue;
235: }
236: newArgs[n++] = args[i];
237: }
238: Properties props = new Properties();
239: props.putAll(allProperties);
240: return main.startAnt(newArgs, props, null, cxt);
241: } catch (Throwable t) {
242: t.printStackTrace();
243: return 1;
244: }
245: }
246: }
247: }
|