/*
* Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*/
/*
* $Id: EnvironmentCheck.java,v 1.2.4.1 2005/09/09 07:13:59 pvedula Exp $
*/
package com.sun.org.apache.xalan.internal.xslt;
import com.sun.org.apache.xalan.internal.utils.ObjectFactory;
import com.sun.org.apache.xalan.internal.utils.SecuritySupport;
import java.io.File;
import java.io.FileWriter;
import java.io.PrintWriter;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
/**
* Utility class to report simple information about the environment.
* Simplistic reporting about certain classes found in your JVM may
* help answer some FAQs for simple problems.
*
*
Usage-command line:
*
* java com.sun.org.apache.xalan.internal.xslt.EnvironmentCheck [-out outFile]
*
*
* Usage-from program:
*
* boolean environmentOK =
* (new EnvironmentCheck()).checkEnvironment(yourPrintWriter);
*
*
* Usage-from stylesheet:
*
* <?xml version="1.0"?>
* <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
* xmlns:xalan="http://xml.apache.org/xalan"
* exclude-result-prefixes="xalan">
* <xsl:output indent="yes"/>
* <xsl:template match="/">
* <xsl:copy-of select="xalan:checkEnvironment()"/>
* </xsl:template>
* </xsl:stylesheet>
*
*
* Xalan users reporting problems are encouraged to use this class
* to see if there are potential problems with their actual
* Java environment before reporting a bug. Note that you
* should both check from the JVM/JRE's command line as well as
* temporarily calling checkEnvironment() directly from your code,
* since the classpath may differ (especially for servlets, etc).
*
* Also see http://xml.apache.org/xalan-j/faq.html
*
* Note: This class is pretty simplistic:
* results are not necessarily definitive nor will it find all
* problems related to environment setup. Also, you should avoid
* calling this in deployed production code, both because it is
* quite slow and because it forces classes to get loaded.
*
* Note: This class explicitly has very limited compile-time
* dependencies to enable easy compilation and usage even when
* Xalan, DOM/SAX/JAXP, etc. are not present.
*
* Note: for an improved version of this utility, please see
* the xml-commons' project Which utility which does the same kind
* of thing but in a much simpler manner.
*
* @author Shane_Curcuru@us.ibm.com
* @version $Id: EnvironmentCheck.java,v 1.10 2010-11-01 04:34:13 joehw Exp $
*/
public class EnvironmentCheck
{
/**
* Command line runnability: checks for [-out outFilename] arg.
* Command line entrypoint; Sets output and calls
* {@link #checkEnvironment(PrintWriter)}.
* @param args command line args
*/
public static void main(String[] args)
{
// Default to System.out, autoflushing
PrintWriter sendOutputTo = new PrintWriter(System.out, true);
// Read our simplistic input args, if supplied
for (int i = 0; i < args.length; i++)
{
if ("-out".equalsIgnoreCase(args[i]))
{
i++;
if (i < args.length)
{
try
{
sendOutputTo = new PrintWriter(new FileWriter(args[i], true));
}
catch (Exception e)
{
System.err.println("# WARNING: -out " + args[i] + " threw "
+ e.toString());
}
}
else
{
System.err.println(
"# WARNING: -out argument should have a filename, output sent to console");
}
}
}
EnvironmentCheck app = new EnvironmentCheck();
app.checkEnvironment(sendOutputTo);
}
/**
* Programmatic entrypoint: Report on basic Java environment
* and CLASSPATH settings that affect Xalan.
*
* Note that this class is not advanced enough to tell you
* everything about the environment that affects Xalan, and
* sometimes reports errors that will not actually affect
* Xalan's behavior. Currently, it very simplistically
* checks the JVM's environment for some basic properties and
* logs them out; it will report a problem if it finds a setting
* or .jar file that is likely to cause problems.
*
* Advanced users can peruse the code herein to help them
* investigate potential environment problems found; other users
* may simply send the output from this tool along with any bugs
* they submit to help us in the debugging process.
*
* @param pw PrintWriter to send output to; can be sent to a
* file that will look similar to a Properties file; defaults
* to System.out if null
* @return true if your environment appears to have no major
* problems; false if potential environment problems found
* @see #getEnvironmentHash()
*/
public boolean checkEnvironment(PrintWriter pw)
{
// Use user-specified output writer if non-null
if (null != pw)
outWriter = pw;
// Setup a hash to store various environment information in
Map hash = getEnvironmentHash();
// Check for ERROR keys in the hashtable, and print report
boolean environmentHasErrors = writeEnvironmentReport(hash);
if (environmentHasErrors)
{
// Note: many logMsg calls have # at the start to
// fake a property-file like output
logMsg("# WARNING: Potential problems found in your environment!");
logMsg("# Check any 'ERROR' items above against the Xalan FAQs");
logMsg("# to correct potential problems with your classes/jars");
logMsg("# http://xml.apache.org/xalan-j/faq.html");
if (null != outWriter)
outWriter.flush();
return false;
}
else
{
logMsg("# YAHOO! Your environment seems to be OK.");
if (null != outWriter)
outWriter.flush();
return true;
}
}
/**
* Fill a hash with basic environment settings that affect Xalan.
*
* Worker method called from various places.
* Various system and CLASSPATH, etc. properties are put into
* the hash as keys with a brief description of the current state
* of that item as the value. Any serious problems will be put in
* with a key that is prefixed with {@link #ERROR 'ERROR.'} so it
* stands out in any resulting report; also a key with just that
* constant will be set as well for any error.
* Note that some legitimate cases are flaged as potential
* errors - namely when a developer recompiles xalan.jar on their
* own - and even a non-error state doesn't guaruntee that
* everything in the environment is correct. But this will help
* point out the most common classpath and system property
* problems that we've seen.
*
* @return Map full of useful environment info about Xalan and related
* system properties, etc.
*/
public Map getEnvironmentHash()
{
// Setup a hash to store various environment information in
Map hash = new HashMap<>();
// Call various worker methods to fill in the hash
// These are explicitly separate for maintenance and so
// advanced users could call them standalone
checkJAXPVersion(hash);
checkProcessorVersion(hash);
checkParserVersion(hash);
checkAntVersion(hash);
if (!checkDOML3(hash)) {
checkDOMVersion(hash);
}
checkSAXVersion(hash);
checkSystemProperties(hash);
return hash;
}
/**
* Dump a basic Xalan environment report to outWriter.
*
* This dumps a simple header and then each of the entries in
* the Map to our PrintWriter; it does special processing
* for entries that are .jars found in the classpath.
*
* @param h Map of items to report on; presumably
* filled in by our various check*() methods
* @return true if your environment appears to have no major
* problems; false if potential environment problems found
* @see #appendEnvironmentReport(Node, Document, Map)
* for an equivalent that appends to a Node instead
*/
protected boolean writeEnvironmentReport(Map h)
{
if (null == h)
{
logMsg("# ERROR: writeEnvironmentReport called with null Map");
return false;
}
boolean errors = false;
logMsg(
"#---- BEGIN writeEnvironmentReport($Revision: 1.10 $): Useful stuff found: ----");
// Fake the Properties-like output
for (Map.Entry entry : h.entrySet()) {
String keyStr = entry.getKey();
try {
// Special processing for classes found..
if (keyStr.startsWith(FOUNDCLASSES)) {
List