All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.tools.ant.Diagnostics Maven / Gradle / Ivy

There is a newer version: 1.0-rc5
Show newest version
/*
 * Copyright  2002-2004 The Apache Software Foundation
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 */
package org.apache.tools.ant;

import org.apache.tools.ant.util.LoaderUtils;

import javax.xml.parsers.SAXParserFactory;
import javax.xml.parsers.SAXParser;
import java.io.File;
import java.io.FilenameFilter;
import java.io.PrintStream;
import java.io.InputStream;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Properties;
import java.lang.reflect.Method;
import java.lang.reflect.InvocationTargetException;

/**
 * A little diagnostic helper that output some information that may help
 * in support. It should quickly give correct information about the
 * jar existing in ant.home/lib and the jar versions...
 *
 * @since Ant 1.5
 */
public final class Diagnostics {

    private static final String TEST_CLASS
        = "org.apache.tools.ant.taskdefs.optional.Test";

    /** utility class */
    private Diagnostics() {
    }

    /**
     * Check if optional tasks are available. Not that it does not check
     * for implementation version. Use validateVersion() for this.
     * @return true if optional tasks are available.
     */
    public static boolean isOptionalAvailable() {
        try {
            Class.forName(TEST_CLASS);
        } catch (ClassNotFoundException e) {
            return false;
        }
        return true;
    }

    /**
     * Check if core and optional implementation version do match.
     * @throws BuildException if the implementation version of optional tasks
     * does not match the core implementation version.
     */
    public static void validateVersion() throws BuildException {
        try {
            Class optional
                = Class.forName("org.apache.tools.ant.taskdefs.optional.Test");
            String coreVersion = getImplementationVersion(Main.class);
            String optionalVersion = getImplementationVersion(optional);

            if (coreVersion != null && !coreVersion.equals(optionalVersion)) {
                throw new BuildException("Invalid implementation version "
                    + "between Ant core and Ant optional tasks.\n"
                    + " core    : " + coreVersion + "\n"
                    + " optional: " + optionalVersion);
            }
        } catch (ClassNotFoundException e) {
            // ignore
        }
    }

    /**
     * return the list of jar files existing in ANT_HOME/lib
     * and that must have been picked up by Ant script.
     * @return the list of jar files existing in ant.home/lib or
     * null if an error occurs.
     */
    public static File[] listLibraries() {
        String home = System.getProperty("ant.home");
        if (home == null) {
            return null;
        }
        File libDir = new File(home, "lib");
        FilenameFilter filter = new FilenameFilter() {
            public boolean accept(File dir, String name) {
                return name.endsWith(".jar");
            }
        };
        // listFiles is JDK 1.2+ method...
        String[] filenames = libDir.list(filter);
        if (filenames == null) {
            return null;
        }
        File[] files = new File[filenames.length];
        for (int i = 0; i < filenames.length; i++) {
            files[i] = new File(libDir, filenames[i]);
        }
        return files;
    }

    /**
     * main entry point for command line
     * @param args command line arguments.
     */
    public static void main(String[] args) {
        doReport(System.out);
    }


    /**
     * Helper method to get the implementation version.
     * @param clazz the class to get the information from.
     * @return null if there is no package or implementation version.
     * '?.?' for JDK 1.0 or 1.1.
     */
    private static String getImplementationVersion(Class clazz) {
        try {
          // Package pkg = clazz.getPackage();
          Method method = Class.class.getMethod("getPackage", new Class[0]);
          Object pkg = method.invoke(clazz, null);
          if (pkg != null) {
              // pkg.getImplementationVersion();
              method = pkg.getClass().getMethod("getImplementationVersion", new Class[0]);
              Object version = method.invoke(pkg, null);
              return (String) version;
          }
        } catch (Exception e) {
          // JDK < 1.2 should land here because the methods above don't exist.
          return "?.?";
        }
        return null;
    }

    /**
     * what parser are we using.
     * @return the classname of the parser
     */
    private static String getXmlParserName() {
        SAXParser saxParser = getSAXParser();
        if (saxParser == null) {
            return "Could not create an XML Parser";
        }

        // check to what is in the classname
        String saxParserName = saxParser.getClass().getName();
        return saxParserName;
    }

    /**
     * Create a JAXP SAXParser
     * @return parser or null for trouble
     */
    private static SAXParser getSAXParser() {
        SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
        if (saxParserFactory == null) {
            return null;
        }
        SAXParser saxParser = null;
        try {
            saxParser = saxParserFactory.newSAXParser();
        } catch (Exception e) {
            // ignore
        }
        return saxParser;
    }

    /**
     * get the location of the parser
     * @return path or null for trouble in tracking it down
     */

    private static String getXMLParserLocation() {
        SAXParser saxParser = getSAXParser();
        if (saxParser == null) {
            return null;
        }
        String location = getClassLocation(saxParser.getClass());
        return location;
    }

    /**
     * get the location of a class. Stolen from axis/webapps/happyaxis.jsp
     * @param clazz
     * @return the jar file or path where a class was found, or null
     */

    private static String getClassLocation(Class clazz) {
        File f = LoaderUtils.getClassSource(clazz);
        return f == null ? null : f.getAbsolutePath();
    }


    /**
     * Print a report to the given stream.
     * @param out the stream to print the report to.
     */
    public static void doReport(PrintStream out) {
        out.println("------- Ant diagnostics report -------");
        out.println(Main.getAntVersion());
        out.println();
        out.println("-------------------------------------------");
        out.println(" Implementation Version (JDK1.2+ only)");
        out.println("-------------------------------------------");
        out.println("core tasks     : " + getImplementationVersion(Main.class));

        Class optional = null;
        try {
            optional = Class.forName(
                    "org.apache.tools.ant.taskdefs.optional.Test");
            out.println("optional tasks : "
                + getImplementationVersion(optional));
        } catch (ClassNotFoundException e) {
            out.println("optional tasks : not available");
        }

        out.println();
        out.println("-------------------------------------------");
        out.println(" ANT_HOME/lib jar listing");
        out.println("-------------------------------------------");
        doReportLibraries(out);

        out.println();
        out.println("-------------------------------------------");
        out.println(" Tasks availability");
        out.println("-------------------------------------------");
        doReportTasksAvailability(out);

        out.println();
        out.println("-------------------------------------------");
        out.println(" org.apache.env.Which diagnostics");
        out.println("-------------------------------------------");
        doReportWhich(out);


        out.println();
        out.println("-------------------------------------------");
        out.println(" XML Parser information");
        out.println("-------------------------------------------");
        doReportParserInfo(out);

        out.println();
        out.println("-------------------------------------------");
        out.println(" System properties");
        out.println("-------------------------------------------");
        doReportSystemProperties(out);

        out.println();
    }

    /**
     * Report a listing of system properties existing in the current vm.
     * @param out the stream to print the properties to.
     */
    private static void doReportSystemProperties(PrintStream out) {
        for (Enumeration keys = System.getProperties().propertyNames();
            keys.hasMoreElements();) {
            String key = (String) keys.nextElement();
            out.println(key + " : " + System.getProperty(key));
        }
    }


    /**
     * Report the content of ANT_HOME/lib directory
     * @param out the stream to print the content to
     */
    private static void doReportLibraries(PrintStream out) {
        out.println("ant.home: " + System.getProperty("ant.home"));
        File[] libs = listLibraries();
        if (libs == null) {
            out.println("Unable to list libraries.");
            return;
        }
        for (int i = 0; i < libs.length; i++) {
            out.println(libs[i].getName()
                    + " (" + libs[i].length() + " bytes)");
        }
    }


    /**
     * Call org.apache.env.Which if available
     * @param out the stream to print the content to.
     */
    private static void doReportWhich(PrintStream out) {
        Throwable error = null;
        try {
            Class which = Class.forName("org.apache.env.Which");
            Method method
                = which.getMethod("main", new Class[]{String[].class});
            method.invoke(null, new Object[]{new String[]{}});
        } catch (ClassNotFoundException e) {
            out.println("Not available.");
            out.println("Download it at http://xml.apache.org/commons/");
        } catch (InvocationTargetException e) {
            error = e.getTargetException() == null ? e : e.getTargetException();
        } catch (Throwable e) {
            error = e;
        }
        // report error if something weird happens...this is diagnostic.
        if (error != null) {
            out.println("Error while running org.apache.env.Which");
            error.printStackTrace();
        }
    }

    /**
     * Create a report about non-available tasks that are defined in the
     * mapping but could not be found via lookup. It might generally happen
     * because Ant requires multiple libraries to compile and one of them
     * was missing when compiling Ant.
     * @param out the stream to print the tasks report to
     * null for a missing stream (ie mapping).
     */
    private static void doReportTasksAvailability(PrintStream out) {
        InputStream is = Main.class.getResourceAsStream(
                "/org/apache/tools/ant/taskdefs/defaults.properties");
        if (is == null) {
            out.println("None available");
        } else {
            Properties props = new Properties();
            try {
                props.load(is);
                for (Enumeration keys = props.keys(); keys.hasMoreElements();) {
                    String key = (String) keys.nextElement();
                    String classname = props.getProperty(key);
                    try {
                        Class.forName(classname);
                        props.remove(key);
                    } catch (ClassNotFoundException e) {
                        out.println(key + " : Not Available");
                    } catch (NoClassDefFoundError e) {
                        String pkg = e.getMessage().replace('/', '.');
                        out.println(key + " : Missing dependency " + pkg);
                    } catch (Error e) {
                        out.println(key + " : Initialization error");
                    }
                }
                if (props.size() == 0) {
                    out.println("All defined tasks are available");
                }
            } catch (IOException e) {
                out.println(e.getMessage());
            }
        }
    }

    /**
     * tell the user about the XML parser
     * @param out
     */
    private static void doReportParserInfo(PrintStream out) {
        String parserName = getXmlParserName();
        String parserLocation = getXMLParserLocation();
        if (parserName == null) {
            parserName = "unknown";
        }
        if (parserLocation == null) {
            parserLocation = "unknown";
        }
        out.println("XML Parser : " + parserName);
        out.println("XML Parser Location: " + parserLocation);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy