Clover coverage report - Ant Coverage
Coverage timestamp: Tue Apr 8 2003 20:43:55 EST
file stats: LOC: 409   Methods: 17
NCLOC: 234   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
Diagnostics.java 5.9% 8.6% 11.8% 8.4%
 1   
 /*
 2   
  * The Apache Software License, Version 1.1
 3   
  *
 4   
  * Copyright (c) 2002-2003 The Apache Software Foundation.  All rights
 5   
  * reserved.
 6   
  *
 7   
  * Redistribution and use in source and binary forms, with or without
 8   
  * modification, are permitted provided that the following conditions
 9   
  * are met:
 10   
  *
 11   
  * 1. Redistributions of source code must retain the above copyright
 12   
  *    notice, this list of conditions and the following disclaimer.
 13   
  *
 14   
  * 2. Redistributions in binary form must reproduce the above copyright
 15   
  *    notice, this list of conditions and the following disclaimer in
 16   
  *    the documentation and/or other materials provided with the
 17   
  *    distribution.
 18   
  *
 19   
  * 3. The end-user documentation included with the redistribution, if
 20   
  *    any, must include the following acknowlegement:
 21   
  *       "This product includes software developed by the
 22   
  *        Apache Software Foundation (http://www.apache.org/)."
 23   
  *    Alternately, this acknowlegement may appear in the software itself,
 24   
  *    if and wherever such third-party acknowlegements normally appear.
 25   
  *
 26   
  * 4. The names "Ant" and "Apache Software
 27   
  *    Foundation" must not be used to endorse or promote products derived
 28   
  *    from this software without prior written permission. For written
 29   
  *    permission, please contact apache@apache.org.
 30   
  *
 31   
  * 5. Products derived from this software may not be called "Apache"
 32   
  *    nor may "Apache" appear in their names without prior written
 33   
  *    permission of the Apache Group.
 34   
  *
 35   
  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 36   
  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 37   
  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 38   
  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 39   
  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 40   
  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 41   
  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 42   
  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 43   
  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 44   
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 45   
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 46   
  * SUCH DAMAGE.
 47   
  * ====================================================================
 48   
  *
 49   
  * This software consists of voluntary contributions made by many
 50   
  * individuals on behalf of the Apache Software Foundation.  For more
 51   
  * information on the Apache Software Foundation, please see
 52   
  * <http://www.apache.org/>.
 53   
  */
 54   
 package org.apache.tools.ant;
 55   
 
 56   
 import org.apache.tools.ant.util.LoaderUtils;
 57   
 
 58   
 import javax.xml.parsers.SAXParserFactory;
 59   
 import javax.xml.parsers.SAXParser;
 60   
 import java.io.File;
 61   
 import java.io.FilenameFilter;
 62   
 import java.io.PrintStream;
 63   
 import java.io.InputStream;
 64   
 import java.io.IOException;
 65   
 import java.util.Enumeration;
 66   
 import java.util.Properties;
 67   
 import java.lang.reflect.Method;
 68   
 import java.lang.reflect.InvocationTargetException;
 69   
 
 70   
 /**
 71   
  * A little diagnostic helper that output some information that may help
 72   
  * in support. It should quickly give correct information about the
 73   
  * jar existing in ant.home/lib and the jar versions...
 74   
  *
 75   
  * @since Ant 1.5
 76   
  * @author <a href="mailto:sbailliez@apache.org">Stephane Bailliez</a>
 77   
  */
 78   
 public final class Diagnostics {
 79   
 
 80   
     /** utility class */
 81  0
     private Diagnostics(){
 82   
     }
 83   
 
 84   
     /**
 85   
      * Check if optional tasks are available. Not that it does not check
 86   
      * for implementation version. Use <tt>validateVersion()</tt> for this.
 87   
      * @return <tt>true</tt> if optional tasks are available.
 88   
      */
 89  0
     public static boolean isOptionalAvailable() {
 90  0
         try {
 91  0
             Class.forName("org.apache.tools.ant.taskdefs.optional.Test");
 92   
         } catch (ClassNotFoundException e){
 93  0
             return false;
 94   
         }
 95  0
         return true;
 96   
     }
 97   
 
 98   
     /**
 99   
      * Check if core and optional implementation version do match.
 100   
      * @throws BuildException if the implementation version of optional tasks
 101   
      * does not match the core implementation version.
 102   
      */
 103  1
     public static void validateVersion() throws BuildException {
 104  1
         try {
 105  1
             Class optional = Class.forName("org.apache.tools.ant.taskdefs.optional.Test");
 106  1
             String coreVersion = getImplementationVersion(Main.class);
 107  1
             String optionalVersion = getImplementationVersion(optional);
 108   
             
 109  1
             if (coreVersion != null && !coreVersion.equals(optionalVersion) ){
 110  0
                 throw new BuildException(
 111   
                         "Invalid implementation version between Ant core and Ant optional tasks.\n" +
 112   
                         " core    : " + coreVersion + "\n" +
 113   
                         " optional: " + optionalVersion);
 114   
             }
 115   
         } catch (ClassNotFoundException e){
 116   
         }
 117   
     }
 118   
 
 119   
     /**
 120   
      * return the list of jar files existing in ANT_HOME/lib
 121   
      * and that must have been picked up by Ant script.
 122   
      * @return the list of jar files existing in ant.home/lib or
 123   
      * <tt>null</tt> if an error occurs.
 124   
      */
 125  0
     public static File[] listLibraries() {
 126  0
         String home = System.getProperty("ant.home");
 127  0
         if (home == null) {
 128  0
             return null;
 129   
         }
 130  0
         File libDir = new File(home, "lib");
 131  0
         FilenameFilter filter = new FilenameFilter() {
 132  0
             public boolean accept(File dir, String name) {
 133  0
                 return name.endsWith(".jar");
 134   
             }
 135   
         };
 136   
         // listFiles is JDK 1.2+ method...
 137  0
         String[] filenames = libDir.list(filter);
 138  0
         if (filenames == null) {
 139  0
             return null;
 140   
         }
 141  0
         File[] files = new File[filenames.length];
 142  0
         for (int i = 0; i < filenames.length; i++){
 143  0
             files[i] = new File(libDir, filenames[i]);
 144   
         }
 145  0
         return files;
 146   
     }
 147   
 
 148   
     /**
 149   
      * main entry point for command line
 150   
      * @param args command line arguments.
 151   
      */
 152  0
     public static void main(String[] args){
 153  0
         doReport(System.out);
 154   
     }
 155   
 
 156   
 
 157   
     /**
 158   
      * Helper method to get the implementation version.
 159   
      * @param clazz the class to get the information from.
 160   
      * @return null if there is no package or implementation version.
 161   
      * '?.?' for JDK 1.0 or 1.1.
 162   
      */
 163  2
     private static String getImplementationVersion(Class clazz){
 164  2
         try {
 165   
           // Package pkg = clazz.getPackage();        
 166  2
           Method method = Class.class.getMethod("getPackage", new Class[0]);
 167  2
           Object pkg = method.invoke(clazz, null);
 168  2
           if (pkg != null) {
 169   
               // pkg.getImplementationVersion();
 170  2
               method = pkg.getClass().getMethod("getImplementationVersion", new Class[0]);
 171  2
               Object version = method.invoke(pkg, null);          
 172  2
               return (String)version;
 173   
           }
 174   
         } catch (Exception e){
 175   
           // JDK < 1.2 should land here because the methods above don't exist.
 176  0
           return "?.?";
 177   
         }
 178  0
         return null;
 179   
     }
 180   
 
 181   
     /**
 182   
      * what parser are we using.
 183   
      * @return the classname of the parser
 184   
      */
 185  0
     private static String getXmlParserName() {
 186  0
         SAXParser saxParser= getSAXParser();
 187  0
         if (saxParser == null) {
 188  0
             return "Could not create an XML Parser";
 189   
         }
 190   
 
 191   
         // check to what is in the classname
 192  0
         String saxParserName = saxParser.getClass().getName();
 193  0
         return saxParserName;
 194   
     }
 195   
 
 196   
     /**
 197   
      * Create a JAXP SAXParser
 198   
      * @return parser or null for trouble
 199   
      */
 200  0
     private static SAXParser getSAXParser() {
 201  0
         SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
 202  0
         if (saxParserFactory == null) {
 203  0
             return null;
 204   
         }
 205  0
         SAXParser saxParser=null;
 206  0
         try {
 207  0
             saxParser = saxParserFactory.newSAXParser();
 208   
         } catch (Exception e) {
 209   
         }
 210  0
         return saxParser;
 211   
     }
 212   
 
 213   
     /**
 214   
      * get the location of the parser
 215   
      * @return path or null for trouble in tracking it down
 216   
      */
 217   
 
 218  0
     private static String getXMLParserLocation() {
 219  0
         SAXParser saxParser = getSAXParser();
 220  0
         if (saxParser == null) {
 221  0
             return null;
 222   
         }
 223  0
         String location=getClassLocation(saxParser.getClass());
 224  0
         return location;
 225   
     }
 226   
 
 227   
     /**
 228   
      * get the location of a class. Stolen from axis/webapps/happyaxis.jsp
 229   
      * @param clazz
 230   
      * @return the jar file or path where a class was found, or null
 231   
      */
 232   
 
 233  0
     private static String getClassLocation( Class clazz) {
 234  0
         File f = LoaderUtils.getClassSource(clazz);
 235  0
         return f == null ? null : f.getAbsolutePath();
 236   
     }
 237   
 
 238   
 
 239   
     /**
 240   
      * Print a report to the given stream.
 241   
      * @param out the stream to print the report to.
 242   
      */
 243  0
     public static void doReport(PrintStream out){
 244  0
         out.println("------- Ant diagnostics report -------");
 245  0
         out.println(Main.getAntVersion());
 246  0
         out.println();
 247  0
         out.println("-------------------------------------------");
 248  0
         out.println(" Implementation Version (JDK1.2+ only)");
 249  0
         out.println("-------------------------------------------");
 250  0
         out.println("core tasks     : " + getImplementationVersion(Main.class));
 251   
 
 252  0
         Class optional = null;
 253  0
         try {
 254  0
             optional = Class.forName(
 255   
                     "org.apache.tools.ant.taskdefs.optional.Test");
 256  0
             out.println("optional tasks : " + getImplementationVersion(optional));
 257   
         } catch (ClassNotFoundException e){
 258  0
             out.println("optional tasks : not available");
 259   
         }
 260   
 
 261  0
         out.println();
 262  0
         out.println("-------------------------------------------");
 263  0
         out.println(" ANT_HOME/lib jar listing");
 264  0
         out.println("-------------------------------------------");
 265  0
         doReportLibraries(out);
 266   
 
 267  0
         out.println();
 268  0
         out.println("-------------------------------------------");
 269  0
         out.println(" Tasks availability");
 270  0
         out.println("-------------------------------------------");
 271  0
         doReportTasksAvailability(out);
 272   
 
 273  0
         out.println();
 274  0
         out.println("-------------------------------------------");
 275  0
         out.println(" org.apache.env.Which diagnostics");
 276  0
         out.println("-------------------------------------------");
 277  0
         doReportWhich(out);
 278   
 
 279   
 
 280  0
         out.println();
 281  0
         out.println("-------------------------------------------");
 282  0
         out.println(" XML Parser information");
 283  0
         out.println("-------------------------------------------");
 284  0
         doReportParserInfo(out);
 285   
 
 286  0
         out.println();
 287  0
         out.println("-------------------------------------------");
 288  0
         out.println(" System properties");
 289  0
         out.println("-------------------------------------------");
 290  0
         doReportSystemProperties(out);
 291   
 
 292  0
         out.println();
 293   
     }
 294   
 
 295   
     /**
 296   
      * Report a listing of system properties existing in the current vm.
 297   
      * @param out the stream to print the properties to.
 298   
      */
 299  0
     private static void doReportSystemProperties(PrintStream out){
 300  0
         for( Enumeration keys = System.getProperties().keys();
 301  0
             keys.hasMoreElements(); ){
 302  0
             String key = (String)keys.nextElement();
 303  0
             out.println(key + " : " + System.getProperty(key));
 304   
         }
 305   
     }
 306   
 
 307   
 
 308   
     /**
 309   
      * Report the content of ANT_HOME/lib directory
 310   
      * @param out the stream to print the content to
 311   
      */
 312  0
     private static void doReportLibraries(PrintStream out){
 313  0
         out.println("ant.home: " + System.getProperty("ant.home"));
 314  0
         File[] libs = listLibraries();
 315  0
         if (libs == null) {
 316  0
             out.println("Unable to list libraries.");
 317  0
             return;
 318   
         }
 319  0
         for (int i = 0; i < libs.length; i++){
 320  0
             out.println(libs[i].getName()
 321   
                     + " (" + libs[i].length() + " bytes)");
 322   
         }
 323   
     }
 324   
 
 325   
 
 326   
     /**
 327   
      * Call org.apache.env.Which if available
 328   
      * @param out the stream to print the content to.
 329   
      */
 330  0
     private static void doReportWhich(PrintStream out){
 331  0
         Throwable error = null;
 332  0
         try {
 333  0
             Class which = Class.forName("org.apache.env.Which");
 334  0
             Method method = which.getMethod("main", new Class[]{ String[].class });
 335  0
             method.invoke(null, new Object[]{new String[]{}});
 336   
         } catch (ClassNotFoundException e) {
 337  0
             out.println("Not available.");
 338  0
             out.println("Download it at http://xml.apache.org/commons/");
 339   
         } catch (InvocationTargetException e) {
 340  0
             error = e.getTargetException() == null ? e : e.getTargetException();
 341   
         } catch (Throwable e) {
 342  0
             error = e;
 343   
         }
 344   
         // report error if something weird happens...this is diagnostic.
 345  0
         if (error != null) {
 346  0
             out.println("Error while running org.apache.env.Which");
 347  0
             error.printStackTrace();
 348   
         }
 349   
     }
 350   
 
 351   
     /**
 352   
      * Create a report about non-available tasks that are defined in the
 353   
      * mapping but could not be found via lookup. It might generally happen
 354   
      * because Ant requires multiple libraries to compile and one of them
 355   
      * was missing when compiling Ant.
 356   
      * @param out the stream to print the tasks report to
 357   
      * <tt>null</tt> for a missing stream (ie mapping).
 358   
      */
 359  0
     private static void doReportTasksAvailability(PrintStream out){
 360  0
         InputStream is = Main.class.getResourceAsStream(
 361   
                 "/org/apache/tools/ant/taskdefs/defaults.properties");
 362  0
         if (is == null) {
 363  0
             out.println("None available");
 364   
         } else {
 365  0
             Properties props = new Properties();
 366  0
             try {
 367  0
                 props.load(is);
 368  0
                 for (Enumeration keys = props.keys(); keys.hasMoreElements();){
 369  0
                     String key = (String)keys.nextElement();
 370  0
                     String classname = props.getProperty(key);
 371  0
                     try {
 372  0
                         Class.forName(classname);
 373  0
                         props.remove(key);
 374   
                     } catch (ClassNotFoundException e){
 375  0
                         out.println(key + " : Not Available");
 376   
                     } catch (NoClassDefFoundError e) {
 377  0
                         String pkg = e.getMessage().replace('/', '.');
 378  0
                         out.println(key + " : Missing dependency " + pkg );
 379   
                     } catch (Error e) {
 380  0
                         out.println(key + " : Initialization error");
 381   
                     }
 382   
                 }
 383  0
                 if (props.size() == 0){
 384  0
                     out.println("All defined tasks are available");
 385   
                 }
 386   
             } catch (IOException e){
 387  0
                 out.println(e.getMessage());
 388   
             }
 389   
         }
 390   
     }
 391   
 
 392   
     /**
 393   
      * tell the user about the XML parser
 394   
      * @param out
 395   
      */
 396  0
     private static void doReportParserInfo(PrintStream out) {
 397  0
         String parserName=getXmlParserName();
 398  0
         String parserLocation=getXMLParserLocation();
 399  0
         if(parserName==null) {
 400  0
             parserName="unknown";
 401   
         }
 402  0
         if(parserLocation==null) {
 403  0
             parserLocation="unknown";
 404   
         }
 405  0
         out.println("XML Parser : " + parserName);
 406  0
         out.println("XML Parser Location: " + parserLocation);
 407   
     }
 408   
 }
 409