1 /*
2  * Copyright  2003-2004 The Apache Software Foundation
3  *
4  *  Licensed under the Apache License, Version 2.0 (the "License");
5  *  you may not use this file except in compliance with the License.
6  *  You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10 *  Unless required by applicable law or agreed to in writing, software
11 *  distributed under the License is distributed on an "AS IS" BASIS,
12 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 *  See the License for the specific language governing permissions and
14 *  limitations under the License.
15 *
16 */
17package org.tp23.antinstaller.antmod;
18
19import java.io.File;
20import java.net.MalformedURLException;
21import java.net.URL;
22import java.net.URLClassLoader;
23import java.util.ArrayList;
24import java.util.Iterator;
25import java.util.List;
26import java.util.Map;
27import java.util.Properties;
28import java.util.StringTokenizer;
29
30import org.apache.tools.ant.launch.LaunchException;
31import org.apache.tools.ant.launch.Locator;
32import org.tp23.antinstaller.InstallerContext;
33
34
35
36/**
37 *  This is a launcher for Ant.
38 *
39 * This file has been modified by Paul Hinds for Antinstaller and is not the same
40 * as the one delivered with Ant 1.6
41 *
42 * @since Ant 1.6
43 * @version $Id: Launcher.java,v 1.1.1.1 2005/10/18 18:20:54 teknopaul Exp $
44 */
45public class Launcher {
46    /** The Ant Home property */
47    public static final String ANTHOME_PROPERTY = "ant.home";
48
49
50    /** The Ant Library Directory property */
51    public static final String ANTLIBDIR_PROPERTY = "ant.library.dir";
52
53
54    /** The location of a per-user library directory */
55    public static final String USER_LIBDIR = ".ant/lib";
56
57
58    /** The startup class that is to be run */
59    public static final String MAIN_CLASS = "org.apache.tools.ant.Main";
60
61    private final Map allProperties;
62
63
64
65/**
66     * Addtional Constructor to pass password properties to Ant
67     * without saving them to a file.
68     * Added by Paul Hinds
69     * @param allProperties Properties
70     */
71    public Launcher(Map allProperties) {
72        this.allProperties = allProperties;
73    }
74
75
76
77/**
78     * Run the launcher to launch Ant
79     *
80     * @param args the command line arguments
81     *
82     * @exception MalformedURLException if the URLs required for the classloader
83     *            cannot be created.
84     */
85    public int run(String[] args, InstallerContext cxt) throws LaunchException, MalformedURLException {
86
87        try {
88
89            String antHomeProperty = System.getProperty(ANTHOME_PROPERTY);
90            File antHome = null;
91
92            File jarDir = null;
93
94            File sourceJar = Locator.getClassSource(getClass());
95            jarDir = sourceJar.getParentFile();
96
97            if (antHomeProperty != null) {
98                antHome = new File(antHomeProperty);
99            }
00
01            if (antHome == null || !antHome.exists()) {
02                antHome = jarDir.getParentFile();
03                System.setProperty(ANTHOME_PROPERTY, antHome.getAbsolutePath());
04            }
05
06            if (!antHome.exists()) {
07                throw new LaunchException("Ant home is set incorrectly or ant could not be located");
08            }
09
10            List libPaths = new ArrayList();
11            List argList = new ArrayList();
12            String[] newArgs;
13
14            for (int i = 0; i < args.length; ++i) {
15                if (args[i].equals("-lib")) {
16                    if (i == args.length - 1) {
17                        throw new LaunchException("The -lib argument must be followed by a library location");
18                    }
19                    libPaths.add(args[++i]);
20                }
21                else {
22                    argList.add(args[i]);
23                }
24            }
25
26            if (libPaths.size() == 0) {
27                newArgs = args;
28            }
29            else {
30                newArgs = (String[]) argList.toArray(new String[0]);
31            }
32
33            List libPathURLs = new ArrayList();
34            for (Iterator i = libPaths.iterator(); i.hasNext(); ) {
35                String libPath = (String) i.next();
36                StringTokenizer myTokenizer
37                    = new StringTokenizer(libPath, System.getProperty("path.separator"));
38                while (myTokenizer.hasMoreElements()) {
39                    String elementName = myTokenizer.nextToken();
40                    File element = new File(elementName);
41                    if (elementName.indexOf("%") != -1 && !element.exists()) {
42                        continue;
43                    }
44                    if (element.isDirectory()) {
45                        // add any jars in the directory
46                        URL[] dirURLs = Locator.getLocationURLs(element);
47                        for (int j = 0; j < dirURLs.length; ++j) {
48                            libPathURLs.add(dirURLs[j]);
49                        }
50                    }
51
52                    libPathURLs.add(element.toURL());
53                }
54            }
55
56            URL[] libJars = (URL[]) libPathURLs.toArray(new URL[0]);
57
58            // Now try and find JAVA_HOME
59            File toolsJar = Locator.getToolsJar();
60
61            // determine ant library directory for system jars: use property
62            // or default using location of ant-launcher.jar
63            File antLibDir = null;
64            String antLibDirProperty = System.getProperty(ANTLIBDIR_PROPERTY);
65            if (antLibDirProperty != null) {
66                antLibDir = new File(antLibDirProperty);
67            }
68            if ( (antLibDir == null) || !antLibDir.exists()) {
69                antLibDir = jarDir;
70                System.setProperty(ANTLIBDIR_PROPERTY, antLibDir.getAbsolutePath());
71            }
72            URL[] systemJars = Locator.getLocationURLs(antLibDir);
73
74            File userLibDir
75                = new File(System.getProperty("user.home"), USER_LIBDIR);
76            URL[] userJars = Locator.getLocationURLs(userLibDir);
77
78
79            int numJars = libJars.length + userJars.length + systemJars.length;
80            if (toolsJar != null) {
81                numJars++;
82            }
83            URL[] jars = new URL[numJars];
84            System.arraycopy(libJars, 0, jars, 0, libJars.length);
85            System.arraycopy(userJars, 0, jars, libJars.length, userJars.length);
86            System.arraycopy(systemJars, 0, jars, userJars.length + libJars.length,
87                             systemJars.length);
88
89            if (toolsJar != null) {
90                jars[jars.length - 1] = toolsJar.toURL();
91            }
92
93
94            // now update the class.path property
95            StringBuffer baseClassPath
96                = new StringBuffer(System.getProperty("java.class.path"));
97            if (baseClassPath.charAt(baseClassPath.length() - 1)
98                == File.pathSeparatorChar) {
99                baseClassPath.setLength(baseClassPath.length() - 1);
00            }
01
02            for (int i = 0; i < jars.length; ++i) {
03                baseClassPath.append(File.pathSeparatorChar);
04                baseClassPath.append(Locator.fromURI(jars[i].toString()));
05            }
06
07            System.setProperty("java.class.path", baseClassPath.toString());
08
09            URLClassLoader loader = new URLClassLoader(jars);
10            Thread.currentThread().setContextClassLoader(loader);
11            try {
12                Main main = new Main();
13                Properties props = new Properties();
14                props.putAll(allProperties);
15                return main.startAnt(newArgs, props, null, cxt);
16            }
17            catch (Throwable t) {
18                t.printStackTrace();
19                return 1;
20            }
21        }
22        catch (Throwable ex) {
23            // Essentially all of the above is nice to have as far as AntInstaller is concerned
24            // ant.home may not be available when installing and application on a client that does not
25            // have and never will have Ant.  However the code is left since sometimes AntInstaller can be used
26            // for a general gui for Ant builds and features such and ANT_HOME/lib are useful
27            try {
28                System.setProperty(ANTHOME_PROPERTY, new File(".").getAbsolutePath());
29                Main main = new Main();
30                // fix for bug:1177191
31                // remove the -lib as discovered by Mark Anderson
32                String[] newArgs = new String[args.length-2];
33                for(int i=0,n=0;i<args.length;i++){
34                    if(args[i].equals("-lib")){
35                        i++;
36                        continue;
37                    }
38                    newArgs[n++]=args[i];
39                }
40                Properties props = new Properties();
41                props.putAll(allProperties);
42                return main.startAnt(newArgs, props, null, cxt);
43            }
44            catch (Throwable t) {
45                t.printStackTrace();
46                return 1;
47            }
48        }
49    }
50}
51