KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > xalan > xslt > EnvironmentCheck


1 /*
2  * Copyright 2001-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 /*
17  * $Id: EnvironmentCheck.java,v 1.26 2004/02/26 04:00:47 zongaro Exp $
18  */

19 package org.apache.xalan.xslt;
20
21 import java.io.File JavaDoc;
22 import java.io.FileWriter JavaDoc;
23 import java.io.PrintWriter JavaDoc;
24 import java.lang.reflect.Field JavaDoc;
25 import java.lang.reflect.Method JavaDoc;
26 import java.util.Enumeration JavaDoc;
27 import java.util.Hashtable JavaDoc;
28 import java.util.StringTokenizer JavaDoc;
29 import java.util.Vector JavaDoc;
30
31 import org.w3c.dom.Document JavaDoc;
32 import org.w3c.dom.Element JavaDoc;
33 import org.w3c.dom.Node JavaDoc;
34
35 /**
36  * Utility class to report simple information about the environment.
37  * Simplistic reporting about certain classes found in your JVM may
38  * help answer some FAQs for simple problems.
39  *
40  * <p>Usage-command line:
41  * <code>
42  * java org.apache.xalan.xslt.EnvironmentCheck [-out outFile]
43  * </code></p>
44  *
45  * <p>Usage-from program:
46  * <code>
47  * boolean environmentOK =
48  * (new EnvironmentCheck()).checkEnvironment(yourPrintWriter);
49  * </code></p>
50  *
51  * <p>Usage-from stylesheet:
52  * <code><pre>
53  * &lt;?xml version="1.0"?&gt;
54  * &lt;xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
55  * xmlns:xalan="http://xml.apache.org/xalan"
56  * exclude-result-prefixes="xalan"&gt;
57  * &lt;xsl:output indent="yes"/&gt;
58  * &lt;xsl:template match="/"&gt;
59  * &lt;xsl:copy-of select="xalan:checkEnvironment()"/&gt;
60  * &lt;/xsl:template&gt;
61  * &lt;/xsl:stylesheet&gt;
62  * </pre></code></p>
63  *
64  * <p>Xalan users reporting problems are encouraged to use this class
65  * to see if there are potential problems with their actual
66  * Java environment <b>before</b> reporting a bug. Note that you
67  * should both check from the JVM/JRE's command line as well as
68  * temporarily calling checkEnvironment() directly from your code,
69  * since the classpath may differ (especially for servlets, etc).</p>
70  *
71  * <p>Also see http://xml.apache.org/xalan-j/faq.html</p>
72  *
73  * <p>Note: This class is pretty simplistic:
74  * results are not necessarily definitive nor will it find all
75  * problems related to environment setup. Also, you should avoid
76  * calling this in deployed production code, both because it is
77  * quite slow and because it forces classes to get loaded.</p>
78  *
79  * <p>Note: This class explicitly has very limited compile-time
80  * dependencies to enable easy compilation and usage even when
81  * Xalan, DOM/SAX/JAXP, etc. are not present.</p>
82  *
83  * <p>Note: for an improved version of this utility, please see
84  * the xml-commons' project Which utility which does the same kind
85  * of thing but in a much simpler manner.</p>
86  *
87  * @author Shane_Curcuru@us.ibm.com
88  * @version $Id: EnvironmentCheck.java,v 1.26 2004/02/26 04:00:47 zongaro Exp $
89  */

90 public class EnvironmentCheck
91 {
92
93   /**
94    * Command line runnability: checks for [-out outFilename] arg.
95    * <p>Command line entrypoint; Sets output and calls
96    * {@link #checkEnvironment(PrintWriter)}.</p>
97    * @param args command line args
98    */

99   public static void main(String JavaDoc[] args)
100   {
101     // Default to System.out, autoflushing
102
PrintWriter JavaDoc sendOutputTo = new PrintWriter JavaDoc(System.out, true);
103
104     // Read our simplistic input args, if supplied
105
for (int i = 0; i < args.length; i++)
106     {
107       if ("-out".equalsIgnoreCase(args[i]))
108       {
109         i++;
110
111         if (i < args.length)
112         {
113           try
114           {
115             sendOutputTo = new PrintWriter JavaDoc(new FileWriter JavaDoc(args[i], true));
116           }
117           catch (Exception JavaDoc e)
118           {
119             System.err.println("# WARNING: -out " + args[i] + " threw "
120                                + e.toString());
121           }
122         }
123         else
124         {
125           System.err.println(
126             "# WARNING: -out argument should have a filename, output sent to console");
127         }
128       }
129     }
130
131     EnvironmentCheck app = new EnvironmentCheck();
132     app.checkEnvironment(sendOutputTo);
133   }
134
135   /**
136    * Programmatic entrypoint: Report on basic Java environment
137    * and CLASSPATH settings that affect Xalan.
138    *
139    * <p>Note that this class is not advanced enough to tell you
140    * everything about the environment that affects Xalan, and
141    * sometimes reports errors that will not actually affect
142    * Xalan's behavior. Currently, it very simplistically
143    * checks the JVM's environment for some basic properties and
144    * logs them out; it will report a problem if it finds a setting
145    * or .jar file that is <i>likely</i> to cause problems.</p>
146    *
147    * <p>Advanced users can peruse the code herein to help them
148    * investigate potential environment problems found; other users
149    * may simply send the output from this tool along with any bugs
150    * they submit to help us in the debugging process.</p>
151    *
152    * @param pw PrintWriter to send output to; can be sent to a
153    * file that will look similar to a Properties file; defaults
154    * to System.out if null
155    * @return true if your environment appears to have no major
156    * problems; false if potential environment problems found
157    * @see #getEnvironmentHash()
158    */

159   public boolean checkEnvironment(PrintWriter JavaDoc pw)
160   {
161
162     // Use user-specified output writer if non-null
163
if (null != pw)
164       outWriter = pw;
165
166     // Setup a hash to store various environment information in
167
Hashtable JavaDoc hash = getEnvironmentHash();
168
169     // Check for ERROR keys in the hashtable, and print report
170
boolean environmentHasErrors = writeEnvironmentReport(hash);
171
172     if (environmentHasErrors)
173     {
174       // Note: many logMsg calls have # at the start to
175
// fake a property-file like output
176
logMsg("# WARNING: Potential problems found in your environment!");
177       logMsg("# Check any 'ERROR' items above against the Xalan FAQs");
178       logMsg("# to correct potential problems with your classes/jars");
179       logMsg("# http://xml.apache.org/xalan-j/faq.html");
180       if (null != outWriter)
181         outWriter.flush();
182       return false;
183     }
184     else
185     {
186       logMsg("# YAHOO! Your environment seems to be OK.");
187       if (null != outWriter)
188         outWriter.flush();
189       return true;
190     }
191   }
192
193   /**
194    * Fill a hash with basic environment settings that affect Xalan.
195    *
196    * <p>Worker method called from various places.</p>
197    * <p>Various system and CLASSPATH, etc. properties are put into
198    * the hash as keys with a brief description of the current state
199    * of that item as the value. Any serious problems will be put in
200    * with a key that is prefixed with {@link #ERROR 'ERROR.'} so it
201    * stands out in any resulting report; also a key with just that
202    * constant will be set as well for any error.</p>
203    * <p>Note that some legitimate cases are flaged as potential
204    * errors - namely when a developer recompiles xalan.jar on their
205    * own - and even a non-error state doesn't guaruntee that
206    * everything in the environment is correct. But this will help
207    * point out the most common classpath and system property
208    * problems that we've seen.</p>
209    *
210    * @return Hashtable full of useful environment info about Xalan
211    * and related system properties, etc.
212    */

213   public Hashtable JavaDoc getEnvironmentHash()
214   {
215     // Setup a hash to store various environment information in
216
Hashtable JavaDoc hash = new Hashtable JavaDoc();
217
218     // Call various worker methods to fill in the hash
219
// These are explicitly separate for maintenance and so
220
// advanced users could call them standalone
221
checkJAXPVersion(hash);
222     checkProcessorVersion(hash);
223     checkParserVersion(hash);
224     checkAntVersion(hash);
225     checkDOMVersion(hash);
226     checkSAXVersion(hash);
227     checkSystemProperties(hash);
228
229     return hash;
230   }
231
232   /**
233    * Dump a basic Xalan environment report to outWriter.
234    *
235    * <p>This dumps a simple header and then each of the entries in
236    * the Hashtable to our PrintWriter; it does special processing
237    * for entries that are .jars found in the classpath.</p>
238    *
239    * @param h Hashtable of items to report on; presumably
240    * filled in by our various check*() methods
241    * @return true if your environment appears to have no major
242    * problems; false if potential environment problems found
243    * @see #appendEnvironmentReport(Node, Document, Hashtable)
244    * for an equivalent that appends to a Node instead
245    */

246   protected boolean writeEnvironmentReport(Hashtable JavaDoc h)
247   {
248
249     if (null == h)
250     {
251       logMsg("# ERROR: writeEnvironmentReport called with null Hashtable");
252       return false;
253     }
254
255     boolean errors = false;
256
257     logMsg(
258       "#---- BEGIN writeEnvironmentReport($Revision: 1.26 $): Useful stuff found: ----");
259
260     // Fake the Properties-like output
261
for (Enumeration JavaDoc keys = h.keys();
262          keys.hasMoreElements();
263         /* no increment portion */
264         )
265     {
266       Object JavaDoc key = keys.nextElement();
267       String JavaDoc keyStr = (String JavaDoc) key;
268       try
269       {
270         // Special processing for classes found..
271
if (keyStr.startsWith(FOUNDCLASSES))
272         {
273           Vector JavaDoc v = (Vector JavaDoc) h.get(keyStr);
274           errors |= logFoundJars(v, keyStr);
275         }
276         // ..normal processing for all other entries
277
else
278         {
279           // Note: we could just check for the ERROR key by itself,
280
// since we now set that, but since we have to go
281
// through the whole hash anyway, do it this way,
282
// which is safer for maintenance
283
if (keyStr.startsWith(ERROR))
284           {
285             errors = true;
286           }
287           logMsg(keyStr + "=" + h.get(keyStr));
288         }
289       }
290       catch (Exception JavaDoc e)
291       {
292         logMsg("Reading-" + key + "= threw: " + e.toString());
293       }
294     }
295
296     logMsg(
297       "#----- END writeEnvironmentReport: Useful properties found: -----");
298
299     return errors;
300   }
301
302   /** Prefixed to hash keys that signify serious problems. */
303   public static final String JavaDoc ERROR = "ERROR.";
304
305   /** Added to descriptions that signify potential problems. */
306   public static final String JavaDoc WARNING = "WARNING.";
307
308   /** Value for any error found. */
309   public static final String JavaDoc ERROR_FOUND = "At least one error was found!";
310
311   /** Prefixed to hash keys that signify version numbers. */
312   public static final String JavaDoc VERSION = "version.";
313
314   /** Prefixed to hash keys that signify .jars found in classpath. */
315   public static final String JavaDoc FOUNDCLASSES = "foundclasses.";
316
317   /** Marker that a class or .jar was found. */
318   public static final String JavaDoc CLASS_PRESENT = "present-unknown-version";
319
320   /** Marker that a class or .jar was not found. */
321   public static final String JavaDoc CLASS_NOTPRESENT = "not-present";
322
323   /** Listing of common .jar files that include Xalan-related classes. */
324   public String JavaDoc[] jarNames =
325   {
326     "xalan.jar", "xalansamples.jar", "xalanj1compat.jar", "xalanservlet.jar",
327     "xerces.jar", // Xerces-J 1.x
328
"xercesImpl.jar", // Xerces-J 2.x
329
"testxsl.jar",
330     "crimson.jar",
331     "lotusxsl.jar",
332     "jaxp.jar", "parser.jar", "dom.jar", "sax.jar", "xml.jar",
333     "xml-apis.jar",
334     "xsltc.jar"
335   };
336
337   /**
338    * Print out report of .jars found in a classpath.
339    *
340    * Takes the information encoded from a checkPathForJars()
341    * call and dumps it out to our PrintWriter.
342    *
343    * @param v Vector of Hashtables of .jar file info
344    * @param desc description to print out in header
345    *
346    * @return false if OK, true if any .jars were reported
347    * as having errors
348    * @see #checkPathForJars(String, String[])
349    */

350   protected boolean logFoundJars(Vector JavaDoc v, String JavaDoc desc)
351   {
352
353     if ((null == v) || (v.size() < 1))
354       return false;
355
356     boolean errors = false;
357
358     logMsg("#---- BEGIN Listing XML-related jars in: " + desc + " ----");
359
360     for (int i = 0; i < v.size(); i++)
361     {
362       Hashtable JavaDoc subhash = (Hashtable JavaDoc) v.elementAt(i);
363
364       for (Enumeration JavaDoc keys = subhash.keys();
365            keys.hasMoreElements();
366            /* no increment portion */
367           )
368       {
369         Object JavaDoc key = keys.nextElement();
370         String JavaDoc keyStr = (String JavaDoc) key;
371         try
372         {
373           if (keyStr.startsWith(ERROR))
374           {
375             errors = true;
376           }
377           logMsg(keyStr + "=" + subhash.get(keyStr));
378
379         }
380         catch (Exception JavaDoc e)
381         {
382           errors = true;
383           logMsg("Reading-" + key + "= threw: " + e.toString());
384         }
385       }
386     }
387
388     logMsg("#----- END Listing XML-related jars in: " + desc + " -----");
389
390     return errors;
391   }
392
393   /**
394    * Stylesheet extension entrypoint: Dump a basic Xalan
395    * environment report from getEnvironmentHash() to a Node.
396    *
397    * <p>Copy of writeEnvironmentReport that creates a Node suitable
398    * for other processing instead of a properties-like text output.
399    * </p>
400    * @param container Node to append our report to
401    * @param factory Document providing createElement, etc. services
402    * @param h Hash presumably from {@link #getEnvironmentHash()}
403    * @see #writeEnvironmentReport(Hashtable)
404    * for an equivalent that writes to a PrintWriter instead
405    */

406   public void appendEnvironmentReport(Node JavaDoc container, Document JavaDoc factory, Hashtable JavaDoc h)
407   {
408     if ((null == container) || (null == factory))
409     {
410       return;
411     }
412   
413     try
414     {
415       Element JavaDoc envCheckNode = factory.createElement("EnvironmentCheck");
416       envCheckNode.setAttribute("version", "$Revision: 1.26 $");
417       container.appendChild(envCheckNode);
418
419       if (null == h)
420       {
421         Element JavaDoc statusNode = factory.createElement("status");
422         statusNode.setAttribute("result", "ERROR");
423         statusNode.appendChild(factory.createTextNode("appendEnvironmentReport called with null Hashtable!"));
424         envCheckNode.appendChild(statusNode);
425         return;
426       }
427
428       boolean errors = false;
429
430       Element JavaDoc hashNode = factory.createElement("environment");
431       envCheckNode.appendChild(hashNode);
432       
433       for (Enumeration JavaDoc keys = h.keys();
434            keys.hasMoreElements();
435           /* no increment portion */
436           )
437       {
438         Object JavaDoc key = keys.nextElement();
439         String JavaDoc keyStr = (String JavaDoc) key;
440         try
441         {
442           // Special processing for classes found..
443
if (keyStr.startsWith(FOUNDCLASSES))
444           {
445             Vector JavaDoc v = (Vector JavaDoc) h.get(keyStr);
446             // errors |= logFoundJars(v, keyStr);
447
errors |= appendFoundJars(hashNode, factory, v, keyStr);
448           }
449           // ..normal processing for all other entries
450
else
451           {
452             // Note: we could just check for the ERROR key by itself,
453
// since we now set that, but since we have to go
454
// through the whole hash anyway, do it this way,
455
// which is safer for maintenance
456
if (keyStr.startsWith(ERROR))
457             {
458               errors = true;
459             }
460             Element JavaDoc node = factory.createElement("item");
461             node.setAttribute("key", keyStr);
462             node.appendChild(factory.createTextNode((String JavaDoc)h.get(keyStr)));
463             hashNode.appendChild(node);
464           }
465         }
466         catch (Exception JavaDoc e)
467         {
468           errors = true;
469           Element JavaDoc node = factory.createElement("item");
470           node.setAttribute("key", keyStr);
471           node.appendChild(factory.createTextNode(ERROR + " Reading " + key + " threw: " + e.toString()));
472           hashNode.appendChild(node);
473         }
474       } // end of for...
475

476       Element JavaDoc statusNode = factory.createElement("status");
477       statusNode.setAttribute("result", (errors ? "ERROR" : "OK" ));
478       envCheckNode.appendChild(statusNode);
479     }
480     catch (Exception JavaDoc e2)
481     {
482       System.err.println("appendEnvironmentReport threw: " + e2.toString());
483       e2.printStackTrace();
484     }
485   }
486
487   /**
488    * Print out report of .jars found in a classpath.
489    *
490    * Takes the information encoded from a checkPathForJars()
491    * call and dumps it out to our PrintWriter.
492    *
493    * @param container Node to append our report to
494    * @param factory Document providing createElement, etc. services
495    * @param v Vector of Hashtables of .jar file info
496    * @param desc description to print out in header
497    *
498    * @return false if OK, true if any .jars were reported
499    * as having errors
500    * @see #checkPathForJars(String, String[])
501    */

502   protected boolean appendFoundJars(Node JavaDoc container, Document JavaDoc factory,
503         Vector JavaDoc v, String JavaDoc desc)
504   {
505
506     if ((null == v) || (v.size() < 1))
507       return false;
508
509     boolean errors = false;
510
511     for (int i = 0; i < v.size(); i++)
512     {
513       Hashtable JavaDoc subhash = (Hashtable JavaDoc) v.elementAt(i);
514
515       for (Enumeration JavaDoc keys = subhash.keys();
516            keys.hasMoreElements();
517            /* no increment portion */
518           )
519       {
520         Object JavaDoc key = keys.nextElement();
521         try
522         {
523           String JavaDoc keyStr = (String JavaDoc) key;
524           if (keyStr.startsWith(ERROR))
525           {
526             errors = true;
527           }
528           Element JavaDoc node = factory.createElement("foundJar");
529           node.setAttribute("name", keyStr.substring(0, keyStr.indexOf("-")));
530           node.setAttribute("desc", keyStr.substring(keyStr.indexOf("-") + 1));
531           node.appendChild(factory.createTextNode((String JavaDoc)subhash.get(keyStr)));
532           container.appendChild(node);
533         }
534         catch (Exception JavaDoc e)
535         {
536           errors = true;
537           Element JavaDoc node = factory.createElement("foundJar");
538           node.appendChild(factory.createTextNode(ERROR + " Reading " + key + " threw: " + e.toString()));
539           container.appendChild(node);
540         }
541       }
542     }
543     return errors;
544   }
545
546   /**
547    * Fillin hash with info about SystemProperties.
548    *
549    * Logs java.class.path and other likely paths; then attempts
550    * to search those paths for .jar files with Xalan-related classes.
551    *
552    * //@todo NOTE: We don't actually search java.ext.dirs for
553    * // *.jar files therein! This should be updated
554    *
555    * @param h Hashtable to put information in
556    * @see #jarNames
557    * @see #checkPathForJars(String, String[])
558    */

559   protected void checkSystemProperties(Hashtable JavaDoc h)
560   {
561
562     if (null == h)
563       h = new Hashtable JavaDoc();
564
565     // Grab java version for later use
566
try
567     {
568       String JavaDoc javaVersion = System.getProperty("java.version");
569
570       h.put("java.version", javaVersion);
571     }
572     catch (SecurityException JavaDoc se)
573     {
574
575       // For applet context, etc.
576
h.put(
577         "java.version",
578         "WARNING: SecurityException thrown accessing system version properties");
579     }
580
581     // Printout jar files on classpath(s) that may affect operation
582
// Do this in order
583
try
584     {
585
586       // This is present in all JVM's
587
String JavaDoc cp = System.getProperty("java.class.path");
588
589       h.put("java.class.path", cp);
590
591       Vector JavaDoc classpathJars = checkPathForJars(cp, jarNames);
592
593       if (null != classpathJars)
594         h.put(FOUNDCLASSES + "java.class.path", classpathJars);
595
596       // Also check for JDK 1.2+ type classpaths
597
String JavaDoc othercp = System.getProperty("sun.boot.class.path");
598
599       if (null != othercp)
600       {
601         h.put("sun.boot.class.path", othercp);
602
603         classpathJars = checkPathForJars(othercp, jarNames);
604
605         if (null != classpathJars)
606           h.put(FOUNDCLASSES + "sun.boot.class.path", classpathJars);
607       }
608
609       //@todo NOTE: We don't actually search java.ext.dirs for
610
// *.jar files therein! This should be updated
611
othercp = System.getProperty("java.ext.dirs");
612
613       if (null != othercp)
614       {
615         h.put("java.ext.dirs", othercp);
616
617         classpathJars = checkPathForJars(othercp, jarNames);
618
619         if (null != classpathJars)
620           h.put(FOUNDCLASSES + "java.ext.dirs", classpathJars);
621       }
622
623       //@todo also check other System properties' paths?
624
// v2 = checkPathForJars(System.getProperty("sun.boot.library.path"), jarNames); // ?? may not be needed
625
// v3 = checkPathForJars(System.getProperty("java.library.path"), jarNames); // ?? may not be needed
626
}
627     catch (SecurityException JavaDoc se2)
628     {
629       // For applet context, etc.
630
h.put(
631         "java.class.path",
632         "WARNING: SecurityException thrown accessing system classpath properties");
633     }
634   }
635
636   /**
637    * Cheap-o listing of specified .jars found in the classpath.
638    *
639    * cp should be separated by the usual File.pathSeparator. We
640    * then do a simplistic search of the path for any requested
641    * .jar filenames, and return a listing of their names and
642    * where (apparently) they came from.
643    *
644    * @param cp classpath to search
645    * @param jars array of .jar base filenames to look for
646    *
647    * @return Vector of Hashtables filled with info about found .jars
648    * @see #jarNames
649    * @see #logFoundJars(Vector, String)
650    * @see #appendFoundJars(Node, Document, Vector, String )
651    * @see #getApparentVersion(String, long)
652    */

653   protected Vector JavaDoc checkPathForJars(String JavaDoc cp, String JavaDoc[] jars)
654   {
655
656     if ((null == cp) || (null == jars) || (0 == cp.length())
657             || (0 == jars.length))
658       return null;
659
660     Vector JavaDoc v = new Vector JavaDoc();
661     StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(cp, File.pathSeparator);
662
663     while (st.hasMoreTokens())
664     {
665
666       // Look at each classpath entry for each of our requested jarNames
667
String JavaDoc filename = st.nextToken();
668
669       for (int i = 0; i < jars.length; i++)
670       {
671         if (filename.indexOf(jars[i]) > -1)
672         {
673           File JavaDoc f = new File JavaDoc(filename);
674
675           if (f.exists())
676           {
677
678             // If any requested jarName exists, report on
679
// the details of that .jar file
680
try
681             {
682               Hashtable JavaDoc h = new Hashtable JavaDoc(2);
683               // Note "-" char is looked for in appendFoundJars
684
h.put(jars[i] + "-path", f.getAbsolutePath());
685              
686               // We won't bother reporting on the xalan.jar apparent version
687
// since this requires knowing the jar size of the xalan.jar
688
// before we build it.
689
// For other jars, eg. xml-apis.jar and xercesImpl.jar, we
690
// report the apparent version of the file we've found
691
if (!("xalan.jar".equalsIgnoreCase(jars[i]))) {
692                 h.put(jars[i] + "-apparent.version",
693                     getApparentVersion(jars[i], f.length()));
694               }
695               v.addElement(h);
696             }
697             catch (Exception JavaDoc e)
698             {
699
700               /* no-op, don't add it */
701             }
702           }
703           else
704           {
705             Hashtable JavaDoc h = new Hashtable JavaDoc(2);
706             // Note "-" char is looked for in appendFoundJars
707
h.put(jars[i] + "-path", WARNING + " Classpath entry: "
708                   + filename + " does not exist");
709             h.put(jars[i] + "-apparent.version", CLASS_NOTPRESENT);
710             v.addElement(h);
711           }
712         }
713       }
714     }
715
716     return v;
717   }
718
719   /**
720    * Cheap-o method to determine the product version of a .jar.
721    *
722    * Currently does a lookup into a local table of some recent
723    * shipped Xalan builds to determine where the .jar probably
724    * came from. Note that if you recompile Xalan or Xerces
725    * yourself this will likely report a potential error, since
726    * we can't certify builds other than the ones we ship.
727    * Only reports against selected posted Xalan-J builds.
728    *
729    * //@todo actually look up version info in manifests
730    *
731    * @param jarName base filename of the .jarfile
732    * @param jarSize size of the .jarfile
733    *
734    * @return String describing where the .jar file probably
735    * came from
736    */

737   protected String JavaDoc getApparentVersion(String JavaDoc jarName, long jarSize)
738   {
739     // If we found a matching size and it's for our
740
// jar, then return it's description
741
// Lookup in static jarVersions Hashtable
742
String JavaDoc foundSize = (String JavaDoc) jarVersions.get(new Long JavaDoc(jarSize));
743
744     if ((null != foundSize) && (foundSize.startsWith(jarName)))
745     {
746       return foundSize;
747     }
748     else
749     {
750       if ("xerces.jar".equalsIgnoreCase(jarName)
751               || "xercesImpl.jar".equalsIgnoreCase(jarName))
752 // || "xalan.jar".equalsIgnoreCase(jarName))
753
{
754
755         // For xalan.jar and xerces.jar/xercesImpl.jar, which we ship together:
756
// The jar is not from a shipped copy of xalan-j, so
757
// it's up to the user to ensure that it's compatible
758
return jarName + " " + WARNING + CLASS_PRESENT;
759       }
760       else
761       {
762
763         // Otherwise, it's just a jar we don't have the version info calculated for
764
return jarName + " " + CLASS_PRESENT;
765       }
766     }
767   }
768
769   /**
770    * Report version information about JAXP interfaces.
771    *
772    * Currently distinguishes between JAXP 1.0.1 and JAXP 1.1,
773    * and not found; only tests the interfaces, and does not
774    * check for reference implementation versions.
775    *
776    * @param h Hashtable to put information in
777    */

778   protected void checkJAXPVersion(Hashtable JavaDoc h)
779   {
780
781     if (null == h)
782       h = new Hashtable JavaDoc();
783
784     final Class JavaDoc noArgs[] = new Class JavaDoc[0];
785     Class JavaDoc clazz = null;
786
787     try
788     {
789       final String JavaDoc JAXP1_CLASS = "javax.xml.parsers.DocumentBuilder";
790       final String JavaDoc JAXP11_METHOD = "getDOMImplementation";
791
792       clazz = ObjectFactory.findProviderClass(
793         JAXP1_CLASS, ObjectFactory.findClassLoader(), true);
794
795       Method JavaDoc method = clazz.getMethod(JAXP11_METHOD, noArgs);
796
797       // If we succeeded, we at least have JAXP 1.1 available
798
h.put(VERSION + "JAXP", "1.1 or higher");
799     }
800     catch (Exception JavaDoc e)
801     {
802       if (null != clazz)
803       {
804
805         // We must have found the class itself, just not the
806
// method, so we (probably) have JAXP 1.0.1
807
h.put(ERROR + VERSION + "JAXP", "1.0.1");
808         h.put(ERROR, ERROR_FOUND);
809       }
810       else
811       {
812         // We couldn't even find the class, and don't have
813
// any JAXP support at all, or only have the
814
// transform half of it
815
h.put(ERROR + VERSION + "JAXP", CLASS_NOTPRESENT);
816         h.put(ERROR, ERROR_FOUND);
817       }
818     }
819   }
820
821   /**
822    * Report product version information from Xalan-J.
823    *
824    * Looks for version info in xalan.jar from Xalan-J products.
825    *
826    * @param h Hashtable to put information in
827    */

828   protected void checkProcessorVersion(Hashtable JavaDoc h)
829   {
830
831     if (null == h)
832       h = new Hashtable JavaDoc();
833
834     try
835     {
836       final String JavaDoc XALAN1_VERSION_CLASS =
837         "org.apache.xalan.xslt.XSLProcessorVersion";
838
839       Class JavaDoc clazz = ObjectFactory.findProviderClass(
840         XALAN1_VERSION_CLASS, ObjectFactory.findClassLoader(), true);
841
842       // Found Xalan-J 1.x, grab it's version fields
843
StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
844       Field JavaDoc f = clazz.getField("PRODUCT");
845
846       buf.append(f.get(null));
847       buf.append(';');
848
849       f = clazz.getField("LANGUAGE");
850
851       buf.append(f.get(null));
852       buf.append(';');
853
854       f = clazz.getField("S_VERSION");
855
856       buf.append(f.get(null));
857       buf.append(';');
858       h.put(VERSION + "xalan1", buf.toString());
859     }
860     catch (Exception JavaDoc e1)
861     {
862       h.put(VERSION + "xalan1", CLASS_NOTPRESENT);
863     }
864
865     try
866     {
867       // NOTE: This is the old Xalan 2.0, 2.1, 2.2 version class,
868
// is being replaced by class below
869
final String JavaDoc XALAN2_VERSION_CLASS =
870         "org.apache.xalan.processor.XSLProcessorVersion";
871
872       Class JavaDoc clazz = ObjectFactory.findProviderClass(
873         XALAN2_VERSION_CLASS, ObjectFactory.findClassLoader(), true);
874
875       // Found Xalan-J 2.x, grab it's version fields
876
StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
877       Field JavaDoc f = clazz.getField("S_VERSION");
878       buf.append(f.get(null));
879
880       h.put(VERSION + "xalan2x", buf.toString());
881     }
882     catch (Exception JavaDoc e2)
883     {
884       h.put(VERSION + "xalan2x", CLASS_NOTPRESENT);
885     }
886     try
887     {
888       // NOTE: This is the new Xalan 2.2+ version class
889
final String JavaDoc XALAN2_2_VERSION_CLASS =
890         "org.apache.xalan.Version";
891       final String JavaDoc XALAN2_2_VERSION_METHOD = "getVersion";
892       final Class JavaDoc noArgs[] = new Class JavaDoc[0];
893
894       Class JavaDoc clazz = ObjectFactory.findProviderClass(
895         XALAN2_2_VERSION_CLASS, ObjectFactory.findClassLoader(), true);
896
897       Method JavaDoc method = clazz.getMethod(XALAN2_2_VERSION_METHOD, noArgs);
898       Object JavaDoc returnValue = method.invoke(null, new Object JavaDoc[0]);
899
900       h.put(VERSION + "xalan2_2", (String JavaDoc)returnValue);
901     }
902     catch (Exception JavaDoc e2)
903     {
904       h.put(VERSION + "xalan2_2", CLASS_NOTPRESENT);
905     }
906   }
907
908   /**
909    * Report product version information from common parsers.
910    *
911    * Looks for version info in xerces.jar/xercesImpl.jar/crimson.jar.
912    *
913    * //@todo actually look up version info in crimson manifest
914    *
915    * @param h Hashtable to put information in
916    */

917   protected void checkParserVersion(Hashtable JavaDoc h)
918   {
919
920     if (null == h)
921       h = new Hashtable JavaDoc();
922
923     try
924     {
925       final String JavaDoc XERCES1_VERSION_CLASS = "org.apache.xerces.framework.Version";
926
927       Class JavaDoc clazz = ObjectFactory.findProviderClass(
928         XERCES1_VERSION_CLASS, ObjectFactory.findClassLoader(), true);
929
930       // Found Xerces-J 1.x, grab it's version fields
931
Field JavaDoc f = clazz.getField("fVersion");
932       String JavaDoc parserVersion = (String JavaDoc) f.get(null);
933
934       h.put(VERSION + "xerces1", parserVersion);
935     }
936     catch (Exception JavaDoc e)
937     {
938       h.put(VERSION + "xerces1", CLASS_NOTPRESENT);
939     }
940
941     // Look for xerces1 and xerces2 parsers separately
942
try
943     {
944       final String JavaDoc XERCES2_VERSION_CLASS = "org.apache.xerces.impl.Version";
945
946       Class JavaDoc clazz = ObjectFactory.findProviderClass(
947         XERCES2_VERSION_CLASS, ObjectFactory.findClassLoader(), true);
948
949       // Found Xerces-J 2.x, grab it's version fields
950
Field JavaDoc f = clazz.getField("fVersion");
951       String JavaDoc parserVersion = (String JavaDoc) f.get(null);
952
953       h.put(VERSION + "xerces2", parserVersion);
954     }
955     catch (Exception JavaDoc e)
956     {
957       h.put(VERSION + "xerces2", CLASS_NOTPRESENT);
958     }
959
960     try
961     {
962       final String JavaDoc CRIMSON_CLASS = "org.apache.crimson.parser.Parser2";
963
964       Class JavaDoc clazz = ObjectFactory.findProviderClass(
965         CRIMSON_CLASS, ObjectFactory.findClassLoader(), true);
966
967       //@todo determine specific crimson version
968
h.put(VERSION + "crimson", CLASS_PRESENT);
969     }
970     catch (Exception JavaDoc e)
971     {
972       h.put(VERSION + "crimson", CLASS_NOTPRESENT);
973     }
974   }
975
976   /**
977    * Report product version information from Ant.
978    *
979    * @param h Hashtable to put information in
980    */

981   protected void checkAntVersion(Hashtable JavaDoc h)
982   {
983
984     if (null == h)
985       h = new Hashtable JavaDoc();
986
987     try
988     {
989       final String JavaDoc ANT_VERSION_CLASS = "org.apache.tools.ant.Main";
990       final String JavaDoc ANT_VERSION_METHOD = "getAntVersion"; // noArgs
991
final Class JavaDoc noArgs[] = new Class JavaDoc[0];
992
993       Class JavaDoc clazz = ObjectFactory.findProviderClass(
994         ANT_VERSION_CLASS, ObjectFactory.findClassLoader(), true);
995
996       Method JavaDoc method = clazz.getMethod(ANT_VERSION_METHOD, noArgs);
997       Object JavaDoc returnValue = method.invoke(null, new Object JavaDoc[0]);
998
999       h.put(VERSION + "ant", (String JavaDoc)returnValue);
1000    }
1001    catch (Exception JavaDoc e)
1002    {
1003      h.put(VERSION + "ant", CLASS_NOTPRESENT);
1004    }
1005  }
1006
1007  /**
1008   * Report version info from DOM interfaces.
1009   *
1010   * Currently distinguishes between pre-DOM level 2, the DOM
1011   * level 2 working draft, the DOM level 2 final draft,
1012   * and not found.
1013   *
1014   * @param h Hashtable to put information in
1015   */

1016  protected void checkDOMVersion(Hashtable JavaDoc h)
1017  {
1018
1019    if (null == h)
1020      h = new Hashtable JavaDoc();
1021
1022    final String JavaDoc DOM_LEVEL2_CLASS = "org.w3c.dom.Document";
1023    final String JavaDoc DOM_LEVEL2_METHOD = "createElementNS"; // String, String
1024
final String JavaDoc DOM_LEVEL2WD_CLASS = "org.w3c.dom.Node";
1025    final String JavaDoc DOM_LEVEL2WD_METHOD = "supported"; // String, String
1026
final String JavaDoc DOM_LEVEL2FD_CLASS = "org.w3c.dom.Node";
1027    final String JavaDoc DOM_LEVEL2FD_METHOD = "isSupported"; // String, String
1028
final Class JavaDoc twoStringArgs[] = { java.lang.String JavaDoc.class,
1029                                    java.lang.String JavaDoc.class };
1030
1031    try
1032    {
1033      Class JavaDoc clazz = ObjectFactory.findProviderClass(
1034        DOM_LEVEL2_CLASS, ObjectFactory.findClassLoader(), true);
1035
1036      Method JavaDoc method = clazz.getMethod(DOM_LEVEL2_METHOD, twoStringArgs);
1037
1038      // If we succeeded, we have loaded interfaces from a
1039
// level 2 DOM somewhere
1040
h.put(VERSION + "DOM", "2.0");
1041
1042      try
1043      {
1044        // Check for the working draft version, which is
1045
// commonly found, but won't work anymore
1046
clazz = ObjectFactory.findProviderClass(
1047          DOM_LEVEL2WD_CLASS, ObjectFactory.findClassLoader(), true);
1048
1049        method = clazz.getMethod(DOM_LEVEL2WD_METHOD, twoStringArgs);
1050
1051        h.put(ERROR + VERSION + "DOM.draftlevel", "2.0wd");
1052        h.put(ERROR, ERROR_FOUND);
1053      }
1054      catch (Exception JavaDoc e2)
1055      {
1056        try
1057        {
1058          // Check for the final draft version as well
1059
clazz = ObjectFactory.findProviderClass(
1060            DOM_LEVEL2FD_CLASS, ObjectFactory.findClassLoader(), true);
1061
1062          method = clazz.getMethod(DOM_LEVEL2FD_METHOD, twoStringArgs);
1063
1064          h.put(VERSION + "DOM.draftlevel", "2.0fd");
1065        }
1066        catch (Exception JavaDoc e3)
1067        {
1068          h.put(ERROR + VERSION + "DOM.draftlevel", "2.0unknown");
1069          h.put(ERROR, ERROR_FOUND);
1070        }
1071      }
1072    }
1073    catch (Exception JavaDoc e)
1074    {
1075      h.put(ERROR + VERSION + "DOM",
1076            "ERROR attempting to load DOM level 2 class: " + e.toString());
1077      h.put(ERROR, ERROR_FOUND);
1078    }
1079
1080    //@todo load an actual DOM implmementation and query it as well
1081
//@todo load an actual DOM implmementation and check if
1082
// isNamespaceAware() == true, which is needed to parse
1083
// xsl stylesheet files into a DOM
1084
}
1085
1086  /**
1087   * Report version info from SAX interfaces.
1088   *
1089   * Currently distinguishes between SAX 2, SAX 2.0beta2,
1090   * SAX1, and not found.
1091   *
1092   * @param h Hashtable to put information in
1093   */

1094  protected void checkSAXVersion(Hashtable JavaDoc h)
1095  {
1096
1097    if (null == h)
1098      h = new Hashtable JavaDoc();
1099
1100    final String JavaDoc SAX_VERSION1_CLASS = "org.xml.sax.Parser";
1101    final String JavaDoc SAX_VERSION1_METHOD = "parse"; // String
1102
final String JavaDoc SAX_VERSION2_CLASS = "org.xml.sax.XMLReader";
1103    final String JavaDoc SAX_VERSION2_METHOD = "parse"; // String
1104
final String JavaDoc SAX_VERSION2BETA_CLASSNF = "org.xml.sax.helpers.AttributesImpl";
1105    final String JavaDoc SAX_VERSION2BETA_METHODNF = "setAttributes"; // Attributes
1106
final Class JavaDoc oneStringArg[] = { java.lang.String JavaDoc.class };
1107    // Note this introduces a minor compile dependency on SAX...
1108
final Class JavaDoc attributesArg[] = { org.xml.sax.Attributes JavaDoc.class };
1109
1110    try
1111    {
1112      // This method was only added in the final SAX 2.0 release;
1113
// see changes.html "Changes from SAX 2.0beta2 to SAX 2.0prerelease"
1114
Class JavaDoc clazz = ObjectFactory.findProviderClass(
1115        SAX_VERSION2BETA_CLASSNF, ObjectFactory.findClassLoader(), true);
1116
1117      Method JavaDoc method = clazz.getMethod(SAX_VERSION2BETA_METHODNF, attributesArg);
1118
1119      // If we succeeded, we have loaded interfaces from a
1120
// real, final SAX version 2.0 somewhere
1121
h.put(VERSION + "SAX", "2.0");
1122    }
1123    catch (Exception JavaDoc e)
1124    {
1125      // If we didn't find the SAX 2.0 class, look for a 2.0beta2
1126
h.put(ERROR + VERSION + "SAX",
1127            "ERROR attempting to load SAX version 2 class: " + e.toString());
1128      h.put(ERROR, ERROR_FOUND);
1129            
1130      try
1131      {
1132        Class JavaDoc clazz = ObjectFactory.findProviderClass(
1133          SAX_VERSION2_CLASS, ObjectFactory.findClassLoader(), true);
1134
1135        Method JavaDoc method = clazz.getMethod(SAX_VERSION2_METHOD, oneStringArg);
1136
1137        // If we succeeded, we have loaded interfaces from a
1138
// SAX version 2.0beta2 or earlier; these might work but
1139
// you should really have the final SAX 2.0
1140
h.put(VERSION + "SAX-backlevel", "2.0beta2-or-earlier");
1141      }
1142      catch (Exception JavaDoc e2)
1143      {
1144        // If we didn't find the SAX 2.0beta2 class, look for a 1.0 one
1145
h.put(ERROR + VERSION + "SAX",
1146              "ERROR attempting to load SAX version 2 class: " + e.toString());
1147        h.put(ERROR, ERROR_FOUND);
1148          
1149        try
1150        {
1151          Class JavaDoc clazz = ObjectFactory.findProviderClass(
1152            SAX_VERSION1_CLASS, ObjectFactory.findClassLoader(), true);
1153
1154          Method JavaDoc method = clazz.getMethod(SAX_VERSION1_METHOD, oneStringArg);
1155
1156          // If we succeeded, we have loaded interfaces from a
1157
// SAX version 1.0 somewhere; which won't work very
1158
// well for JAXP 1.1 or beyond!
1159
h.put(VERSION + "SAX-backlevel", "1.0");
1160        }
1161        catch (Exception JavaDoc e3)
1162        {
1163          // If we didn't find the SAX 2.0 class, look for a 1.0 one
1164
// Note that either 1.0 or no SAX are both errors
1165
h.put(ERROR + VERSION + "SAX-backlevel",
1166                "ERROR attempting to load SAX version 1 class: " + e3.toString());
1167            
1168        }
1169      }
1170    }
1171  }
1172
1173  /**
1174   * Manual table of known .jar sizes.
1175   * Only includes shipped versions of certain projects.
1176   * key=jarsize, value=jarname ' from ' distro name
1177   * Note assumption: two jars cannot have the same size!
1178   *
1179   * @see #getApparentVersion(String, long)
1180   */

1181  protected static Hashtable JavaDoc jarVersions = new Hashtable JavaDoc();
1182
1183  /**
1184   * Static initializer for jarVersions table.
1185   * Doing this just once saves time and space.
1186   *
1187   * @see #getApparentVersion(String, long)
1188   */

1189  static
1190  {
1191    // Note: hackish Hashtable, this could use improvement
1192
jarVersions.put(new Long JavaDoc(857192), "xalan.jar from xalan-j_1_1");
1193    jarVersions.put(new Long JavaDoc(440237), "xalan.jar from xalan-j_1_2");
1194    jarVersions.put(new Long JavaDoc(436094), "xalan.jar from xalan-j_1_2_1");
1195    jarVersions.put(new Long JavaDoc(426249), "xalan.jar from xalan-j_1_2_2");
1196    jarVersions.put(new Long JavaDoc(702536), "xalan.jar from xalan-j_2_0_0");
1197    jarVersions.put(new Long JavaDoc(720930), "xalan.jar from xalan-j_2_0_1");
1198    jarVersions.put(new Long JavaDoc(732330), "xalan.jar from xalan-j_2_1_0");
1199    jarVersions.put(new Long JavaDoc(872241), "xalan.jar from xalan-j_2_2_D10");
1200    jarVersions.put(new Long JavaDoc(882739), "xalan.jar from xalan-j_2_2_D11");
1201    jarVersions.put(new Long JavaDoc(923866), "xalan.jar from xalan-j_2_2_0");
1202    jarVersions.put(new Long JavaDoc(905872), "xalan.jar from xalan-j_2_3_D1");
1203    jarVersions.put(new Long JavaDoc(906122), "xalan.jar from xalan-j_2_3_0");
1204    jarVersions.put(new Long JavaDoc(906248), "xalan.jar from xalan-j_2_3_1");
1205    jarVersions.put(new Long JavaDoc(983377), "xalan.jar from xalan-j_2_4_D1");
1206    jarVersions.put(new Long JavaDoc(997276), "xalan.jar from xalan-j_2_4_0");
1207    jarVersions.put(new Long JavaDoc(1031036), "xalan.jar from xalan-j_2_4_1");
1208    // Stop recording xalan.jar sizes as of Xalan Java 2.5.0
1209

1210    jarVersions.put(new Long JavaDoc(596540), "xsltc.jar from xalan-j_2_2_0");
1211    jarVersions.put(new Long JavaDoc(590247), "xsltc.jar from xalan-j_2_3_D1");
1212    jarVersions.put(new Long JavaDoc(589914), "xsltc.jar from xalan-j_2_3_0");
1213    jarVersions.put(new Long JavaDoc(589915), "xsltc.jar from xalan-j_2_3_1");
1214    jarVersions.put(new Long JavaDoc(1306667), "xsltc.jar from xalan-j_2_4_D1");
1215    jarVersions.put(new Long JavaDoc(1328227), "xsltc.jar from xalan-j_2_4_0");
1216    jarVersions.put(new Long JavaDoc(1344009), "xsltc.jar from xalan-j_2_4_1");
1217    jarVersions.put(new Long JavaDoc(1348361), "xsltc.jar from xalan-j_2_5_D1");
1218    // Stop recording xsltc.jar sizes as of Xalan Java 2.5.0
1219

1220    jarVersions.put(new Long JavaDoc(1268634), "xsltc.jar-bundled from xalan-j_2_3_0");
1221
1222    jarVersions.put(new Long JavaDoc(100196), "xml-apis.jar from xalan-j_2_2_0 or xalan-j_2_3_D1");
1223    jarVersions.put(new Long JavaDoc(108484), "xml-apis.jar from xalan-j_2_3_0, or xalan-j_2_3_1 from xml-commons-1.0.b2");
1224    jarVersions.put(new Long JavaDoc(109049), "xml-apis.jar from xalan-j_2_4_0 from xml-commons RIVERCOURT1 branch");
1225    jarVersions.put(new Long JavaDoc(113749), "xml-apis.jar from xalan-j_2_4_1 from factoryfinder-build of xml-commons RIVERCOURT1");
1226    jarVersions.put(new Long JavaDoc(124704), "xml-apis.jar from tck-jaxp-1_2_0 branch of xml-commons");
1227    jarVersions.put(new Long JavaDoc(124724), "xml-apis.jar from tck-jaxp-1_2_0 branch of xml-commons, tag: xml-commons-external_1_2_01");
1228
1229    // If the below were more common I would update it to report
1230
// errors better; but this is so old hardly anyone has it
1231
jarVersions.put(new Long JavaDoc(424490), "xalan.jar from Xerces Tools releases - ERROR:DO NOT USE!");
1232
1233    jarVersions.put(new Long JavaDoc(1591855), "xerces.jar from xalan-j_1_1 from xerces-1...");
1234    jarVersions.put(new Long JavaDoc(1498679), "xerces.jar from xalan-j_1_2 from xerces-1_2_0.bin");
1235    jarVersions.put(new Long JavaDoc(1484896), "xerces.jar from xalan-j_1_2_1 from xerces-1_2_1.bin");
1236    jarVersions.put(new Long JavaDoc(804460), "xerces.jar from xalan-j_1_2_2 from xerces-1_2_2.bin");
1237    jarVersions.put(new Long JavaDoc(1499244), "xerces.jar from xalan-j_2_0_0 from xerces-1_2_3.bin");
1238    jarVersions.put(new Long JavaDoc(1605266), "xerces.jar from xalan-j_2_0_1 from xerces-1_3_0.bin");
1239    jarVersions.put(new Long JavaDoc(904030), "xerces.jar from xalan-j_2_1_0 from xerces-1_4.bin");
1240    jarVersions.put(new Long JavaDoc(904030), "xerces.jar from xerces-1_4_0.bin");
1241    jarVersions.put(new Long JavaDoc(1802885), "xerces.jar from xerces-1_4_2.bin");
1242    jarVersions.put(new Long JavaDoc(1734594), "xerces.jar from Xerces-J-bin.2.0.0.beta3");
1243    jarVersions.put(new Long JavaDoc(1808883), "xerces.jar from xalan-j_2_2_D10,D11,D12 or xerces-1_4_3.bin");
1244    jarVersions.put(new Long JavaDoc(1812019), "xerces.jar from xalan-j_2_2_0");
1245    jarVersions.put(new Long JavaDoc(1720292), "xercesImpl.jar from xalan-j_2_3_D1");
1246    jarVersions.put(new Long JavaDoc(1730053), "xercesImpl.jar from xalan-j_2_3_0 or xalan-j_2_3_1 from xerces-2_0_0");
1247    jarVersions.put(new Long JavaDoc(1728861), "xercesImpl.jar from xalan-j_2_4_D1 from xerces-2_0_1");
1248    jarVersions.put(new Long JavaDoc(972027), "xercesImpl.jar from xalan-j_2_4_0 from xerces-2_1");
1249    jarVersions.put(new Long JavaDoc(831587), "xercesImpl.jar from xalan-j_2_4_1 from xerces-2_2");
1250    jarVersions.put(new Long JavaDoc(891817), "xercesImpl.jar from xalan-j_2_5_D1 from xerces-2_3");
1251    jarVersions.put(new Long JavaDoc(895924), "xercesImpl.jar from xerces-2_4");
1252    jarVersions.put(new Long JavaDoc(1010806), "xercesImpl.jar from Xerces-J-bin.2.6.2");
1253
1254    jarVersions.put(new Long JavaDoc(37485), "xalanj1compat.jar from xalan-j_2_0_0");
1255    jarVersions.put(new Long JavaDoc(38100), "xalanj1compat.jar from xalan-j_2_0_1");
1256
1257    jarVersions.put(new Long JavaDoc(18779), "xalanservlet.jar from xalan-j_2_0_0");
1258    jarVersions.put(new Long JavaDoc(21453), "xalanservlet.jar from xalan-j_2_0_1");
1259    jarVersions.put(new Long JavaDoc(24826), "xalanservlet.jar from xalan-j_2_3_1 or xalan-j_2_4_1");
1260    jarVersions.put(new Long JavaDoc(24831), "xalanservlet.jar from xalan-j_2_4_1");
1261    // Stop recording xalanservlet.jar sizes as of Xalan Java 2.5.0; now a .war file
1262

1263    // For those who've downloaded JAXP from sun
1264
jarVersions.put(new Long JavaDoc(5618), "jaxp.jar from jaxp1.0.1");
1265    jarVersions.put(new Long JavaDoc(136133), "parser.jar from jaxp1.0.1");
1266    jarVersions.put(new Long JavaDoc(28404), "jaxp.jar from jaxp-1.1");
1267    jarVersions.put(new Long JavaDoc(187162), "crimson.jar from jaxp-1.1");
1268    jarVersions.put(new Long JavaDoc(801714), "xalan.jar from jaxp-1.1");
1269    jarVersions.put(new Long JavaDoc(196399), "crimson.jar from crimson-1.1.1");
1270    jarVersions.put(new Long JavaDoc(33323), "jaxp.jar from crimson-1.1.1 or jakarta-ant-1.4.1b1");
1271    jarVersions.put(new Long JavaDoc(152717), "crimson.jar from crimson-1.1.2beta2");
1272    jarVersions.put(new Long JavaDoc(88143), "xml-apis.jar from crimson-1.1.2beta2");
1273    jarVersions.put(new Long JavaDoc(206384), "crimson.jar from crimson-1.1.3 or jakarta-ant-1.4.1b1");
1274
1275    // jakarta-ant: since many people use ant these days
1276
jarVersions.put(new Long JavaDoc(136198), "parser.jar from jakarta-ant-1.3 or 1.2");
1277    jarVersions.put(new Long JavaDoc(5537), "jaxp.jar from jakarta-ant-1.3 or 1.2");
1278  }
1279
1280  /** Simple PrintWriter we send output to; defaults to System.out. */
1281  protected PrintWriter JavaDoc outWriter = new PrintWriter JavaDoc(System.out, true);
1282
1283  /**
1284   * Bottleneck output: calls outWriter.println(s).
1285   * @param s String to print
1286   */

1287  protected void logMsg(String JavaDoc s)
1288  {
1289    outWriter.println(s);
1290  }
1291}
1292
Popular Tags