org.apache.axis.client.HappyClient.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.axis.client.HappyClient.java

Source

/*
 * Copyright 2003,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.axis.client;

import org.apache.axis.utils.Messages;
import org.apache.axis.utils.ClassUtils;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import java.io.InputStream;
import java.io.IOException;
import java.io.PrintStream;

/**
 * Client side equivalent of happyaxis
 */
public class HappyClient {

    PrintStream out;

    public HappyClient(PrintStream out) {
        this.out = out;
    }

    /**
     * test for a class existing
     * @param classname
     * @return class iff present
     */
    Class classExists(String classname) {
        try {
            return Class.forName(classname);
        } catch (ClassNotFoundException e) {
            return null;
        }
    }

    /**
     * test for resource on the classpath
     * @param resource
     * @return true iff present
     */
    boolean resourceExists(String resource) {
        boolean found;
        InputStream instream = ClassUtils.getResourceAsStream(this.getClass(), resource);
        found = instream != null;
        if (instream != null) {
            try {
                instream.close();
            } catch (IOException e) {
            }
        }
        return found;
    }

    /**
     * probe for a class, print an error message is missing
     * @param category text like "warning" or "error"
     * @param classname class to look for
     * @param jarFile where this class comes from
     * @param errorText extra error text
     * @param homePage where to d/l the library
     * @return the number of missing classes
     * @throws java.io.IOException
     */
    int probeClass(String category, String classname, String jarFile, String description, String errorText,
            String homePage) throws IOException {
        String url = "";
        if (homePage != null) {
            url = Messages.getMessage("happyClientHomepage", homePage);
        }
        String errorLine = "";
        if (errorText != null) {
            errorLine = Messages.getMessage(errorText);
        }
        try {
            Class clazz = classExists(classname);
            if (clazz == null) {
                String text;
                text = Messages.getMessage("happyClientMissingClass", category, classname, jarFile);
                out.println(text);
                out.println(url);
                return 1;
            } else {
                String location = getLocation(clazz);
                String text;
                if (location == null) {
                    text = Messages.getMessage("happyClientFoundDescriptionClass", description, classname);
                } else {
                    text = Messages.getMessage("happyClientFoundDescriptionClassLocation", description, classname,
                            location);
                }
                out.println(text);
                return 0;
            }
        } catch (NoClassDefFoundError ncdfe) {
            out.println(Messages.getMessage("happyClientNoDependency", category, classname, jarFile));
            out.println(errorLine);
            out.println(url);
            out.println(ncdfe.getMessage());
            return 1;
        }
    }

    /**
     * get the location of a class
     * @param clazz
     * @return the jar file or path where a class was found
     */

    String getLocation(Class clazz) {
        try {
            java.net.URL url = clazz.getProtectionDomain().getCodeSource().getLocation();
            String location = url.toString();
            if (location.startsWith("jar")) {
                url = ((java.net.JarURLConnection) url.openConnection()).getJarFileURL();
                location = url.toString();
            }

            if (location.startsWith("file")) {
                java.io.File file = new java.io.File(url.getFile());
                return file.getAbsolutePath();
            } else {
                return url.toString();
            }
        } catch (Throwable t) {
        }
        return Messages.getMessage("happyClientUnknownLocation");
    }

    /**
     * a class we need if a class is missing
     * @param classname class to look for
     * @param jarFile where this class comes from
     * @param errorText extra error text
     * @param homePage where to d/l the library
     * @throws java.io.IOException when needed
     * @return the number of missing libraries (0 or 1)
     */
    int needClass(String classname, String jarFile, String description, String errorText, String homePage)
            throws IOException {
        return probeClass(Messages.getMessage("happyClientError"), classname, jarFile, description, errorText,
                homePage);
    }

    /**
     * print warning message if a class is missing
     * @param classname class to look for
     * @param jarFile where this class comes from
     * @param errorText extra error text
     * @param homePage where to d/l the library
     * @throws java.io.IOException when needed
     * @return the number of missing libraries (0 or 1)
     */
    int wantClass(String classname, String jarFile, String description, String errorText, String homePage)
            throws IOException {
        return probeClass(Messages.getMessage("happyClientWarning"), classname, jarFile, description, errorText,
                homePage);
    }

    /**
     * probe for a resource existing,
     * @param resource
     * @param errorText
     * @throws Exception
     */
    int wantResource(String resource, String errorText) throws Exception {
        if (!resourceExists(resource)) {
            out.println(Messages.getMessage("happyClientNoResource", resource));
            out.println(errorText);
            return 0;
        } else {
            out.println(Messages.getMessage("happyClientFoundResource", resource));
            return 1;
        }
    }

    /**
     * what parser are we using.
     * @return the classname of the parser
     */
    private String getParserName() {
        SAXParser saxParser = getSAXParser();
        if (saxParser == null) {
            return Messages.getMessage("happyClientNoParser");
        }

        // 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 SAXParser getSAXParser() {
        SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
        if (saxParserFactory == null) {
            return null;
        }
        SAXParser saxParser = null;
        try {
            saxParser = saxParserFactory.newSAXParser();
        } catch (Exception e) {
        }
        return saxParser;
    }

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

    private String getParserLocation() {
        SAXParser saxParser = getSAXParser();
        if (saxParser == null) {
            return null;
        }
        String location = getLocation(saxParser.getClass());
        return location;
    }

    /**
     * calculate the java version number by probing for classes;
     * this tactic works across many jvm implementations; taken from Ant.
     * @return JRE version as 10,11,12,13,14,...
     */
    public int getJavaVersionNumber() {
        // Determine the Java version by looking at available classes
        // java.lang.CharSequence was introduced in JDK 1.4
        // java.lang.StrictMath was introduced in JDK 1.3
        // java.lang.ThreadLocal was introduced in JDK 1.2
        // java.lang.Void was introduced in JDK 1.1
        // Count up version until a NoClassDefFoundError ends the try
        int javaVersionNumber = 10;
        try {
            Class.forName("java.lang.Void");
            javaVersionNumber++;
            Class.forName("java.lang.ThreadLocal");
            javaVersionNumber++;
            Class.forName("java.lang.StrictMath");
            javaVersionNumber++;
            Class.forName("java.lang.CharSequence");
            javaVersionNumber++;
        } catch (Throwable t) {
            // swallow as we've hit the max class version that
            // we have
        }
        return javaVersionNumber;
    }

    private void title(String title) {
        out.println();
        String message = Messages.getMessage(title);
        out.println(message);
        //subtitle
        for (int i = 0; i < message.length(); i++) {
            out.print("=");
        }
        out.println();
    }

    /**
     *  Audit the client, print out status
     * @param warningsAsErrors should any warning result in failure?
     * @return true if we are happy
     * @throws IOException
     */
    public boolean verifyClientIsHappy(boolean warningsAsErrors) throws IOException {
        int needed = 0, wanted = 0;
        out.println();
        title("happyClientTitle");
        title("happyClientNeeded");

        /**
         * the essentials, without these Axis is not going to work
         */
        needed = needClass("javax.xml.soap.SOAPMessage", "saaj.jar", "SAAJ", "happyClientNoAxis",
                "http://xml.apache.org/axis/");

        needed += needClass("javax.xml.rpc.Service", "jaxrpc.jar", "JAX-RPC", "happyClientNoAxis",
                "http://xml.apache.org/axis/");

        needed += needClass("org.apache.commons.discovery.Resource", "commons-discovery.jar",
                "Jakarta-Commons Discovery", "happyClientNoAxis",
                "http://jakarta.apache.org/commons/discovery.html");

        needed += needClass("org.apache.commons.logging.Log", "commons-logging.jar", "Jakarta-Commons Logging",
                "happyClientNoAxis", "http://jakarta.apache.org/commons/logging.html");

        //all refs to log4j are split to get past the package tester
        needed += needClass("org.apache" + ".log" + "4j" + ".Layout", "log4" + "j-1.2.4.jar", "Log4" + "j",
                "happyClientNoLog4J", "http://jakarta.apache.org/log" + "4j");

        //should we search for a javax.wsdl file here, to hint that it needs
        //to go into an approved directory? because we dont seem to need to do that.
        needed += needClass("com.ibm.wsdl.factory.WSDLFactoryImpl", "wsdl4j.jar", "WSDL4Java", "happyClientNoAxis",
                null);

        needed += needClass("javax.xml.parsers.SAXParserFactory", "xerces.jar", "JAXP", "happyClientNoAxis",
                "http://xml.apache.org/xerces-j/");

        title("happyClientOptional");

        wanted += wantClass("javax.mail.internet.MimeMessage", "mail.jar", "Mail", "happyClientNoAttachments",
                "http://java.sun.com/products/javamail/");

        wanted += wantClass("javax.activation.DataHandler", "activation.jar", "Activation",
                "happyClientNoAttachments", "http://java.sun.com/products/javabeans/glasgow/jaf.html");

        wanted += wantClass("org.apache.xml.security.Init", "xmlsec.jar", "XML Security", "happyClientNoSecurity",
                "http://xml.apache.org/security/");

        wanted += wantClass("javax.net.ssl.SSLSocketFactory", Messages.getMessage("happyClientJSSEsources"),
                "Java Secure Socket Extension", "happyClientNoHTTPS", "http://java.sun.com/products/jsse/");

        /*
        * resources on the classpath path
        */
        int warningMessages = 0;

        String xmlParser = getParserName();
        String xmlParserLocation = getParserLocation();
        out.println(Messages.getMessage("happyClientXMLinfo", xmlParser, xmlParserLocation));
        if (xmlParser.indexOf("xerces") <= 0) {
            warningMessages++;
            out.println();
            out.println(Messages.getMessage("happyClientRecommendXerces"));
        }
        if (getJavaVersionNumber() < 13) {
            warningMessages++;
            out.println();
            out.println(Messages.getMessage("happyClientUnsupportedJVM"));
        }
        /* add more libraries here */

        //print the summary information
        boolean happy;
        title("happyClientSummary");

        //is everythng we need here
        if (needed == 0) {
            //yes, be happy
            out.println(Messages.getMessage("happyClientCorePresent"));
            happy = true;
        } else {
            happy = false;
            //no, be very unhappy
            out.println(Messages.getMessage("happyClientCoreMissing", Integer.toString(needed)));
        }
        //now look at wanted stuff
        if (wanted > 0) {
            out.println();
            out.println(Messages.getMessage("happyClientOptionalMissing", Integer.toString(wanted)));
            out.println(Messages.getMessage("happyClientOptionalOK"));
            if (warningsAsErrors) {
                happy = false;
            }
        } else {
            out.println(Messages.getMessage("happyClientOptionalPresent"));
        }
        if (warningMessages > 0) {
            out.println(Messages.getMessage("happyClientWarningMessageCount", Integer.toString(warningMessages)));
            if (warningsAsErrors) {
                happy = false;
            }
        }

        return happy;
    }

    /**
     * public happiness test. Exits with -1 if the client is unhappy.
     * @param args a list of extra classes to look for
     *
     */
    public static void main(String args[]) {
        boolean isHappy = isClientHappy(args);
        System.exit(isHappy ? 0 : -1);
    }

    /**
     * this is the implementation of the happiness test.
     * @param args a list of extra classes to look for
     * @return true iff we are happy: all needed ant all argument classes
     * found
     */
    private static boolean isClientHappy(String[] args) {
        HappyClient happy = new HappyClient(System.out);
        boolean isHappy;
        int missing = 0;
        try {
            isHappy = happy.verifyClientIsHappy(false);
            for (int i = 0; i < args.length; i++) {
                missing += happy.probeClass("argument", args[i], null, null, null, null);
            }
            if (missing > 0) {
                isHappy = false;
            }
        } catch (IOException e) {
            e.printStackTrace();
            isHappy = false;
        }
        return isHappy;
    }
}