Package org.apache.axis.configuration

Source Code of org.apache.axis.configuration.EngineConfigurationFactoryFinder

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

package org.apache.axis.configuration;

import org.apache.axis.AxisProperties;
import org.apache.axis.EngineConfigurationFactory;
import org.apache.axis.components.logger.LogFactory;
import org.apache.axis.utils.Messages;
import org.apache.commons.discovery.ResourceClassIterator;
import org.apache.commons.discovery.tools.ClassUtils;
import org.apache.commons.logging.Log;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.security.AccessController;
import java.security.PrivilegedAction;


/**
* This is a default implementation of EngineConfigurationFactory.
* It is user-overrideable by a system property without affecting
* the caller. If you decide to override it, use delegation if
* you want to inherit the behaviour of this class as using
* class extension will result in tight loops. That is, your
* class should implement EngineConfigurationFactory and keep
* an instance of this class in a member field and delegate
* methods to that instance when the default behaviour is
* required.
*
* @author Richard A. Sitze
*/
public class EngineConfigurationFactoryFinder
{
    protected static Log log =
        LogFactory.getLog(EngineConfigurationFactoryFinder.class.getName());

    private static final Class mySpi = EngineConfigurationFactory.class;

    private static final Class[] newFactoryParamTypes =
        new Class[] { Object.class };

    private static final String requiredMethod =
        "public static EngineConfigurationFactory newFactory(Object)";

    static {
        AxisProperties.setClassOverrideProperty(
                EngineConfigurationFactory.class,
                EngineConfigurationFactory.SYSTEM_PROPERTY_NAME);

        AxisProperties.setClassDefaults(EngineConfigurationFactory.class,
                            new String[] {
                                "org.apache.axis.configuration.EngineConfigurationFactoryServlet",
                                "org.apache.axis.configuration.EngineConfigurationFactoryDefault",
                                });
    }

    private EngineConfigurationFactoryFinder() {
    }


    /**
     * Create the default engine configuration and detect whether the user
     * has overridden this with their own.
     *
     * The discovery mechanism will use the following logic:
     *
     * - discover all available EngineConfigurationFactories
     *   - find all META-INF/services/org.apache.axis.EngineConfigurationFactory
     *     files available through class loaders.
     *   - read files (see Discovery) to obtain implementation(s) of that
     *     interface
     * - For each impl, call 'newFactory(Object param)'
     * - Each impl should examine the 'param' and return a new factory ONLY
     *   - if it knows what to do with it
     *     (i.e. it knows what to do with the 'real' type)
     *   - it can find it's configuration information
     * - Return first non-null factory found.
     * - Try EngineConfigurationFactoryServlet.newFactory(obj)
     * - Try EngineConfigurationFactoryDefault.newFactory(obj)
     * - If zero found (all return null), throw exception
     *
     * ***
     * This needs more work: System.properties, etc.
     * Discovery will have more tools to help with that
     * (in the manner of use below) in the near future.
     * ***
     *
     */
    public static EngineConfigurationFactory newFactory(final Object obj) {
        /**
         * recreate on each call is critical to gaining
         * the right class loaders.  Do not cache.
         */
        final Object[] params = new Object[] { obj };

        /**
         * Find and examine each service
         */
        return (EngineConfigurationFactory)AccessController.doPrivileged(
                new PrivilegedAction() {
                    public Object run() {
                        ResourceClassIterator services = AxisProperties.getResourceClassIterator(mySpi);

                        EngineConfigurationFactory factory = null;

                        while (factory == null  &&  services.hasNext()) {
                          try {
                            Class service = services.nextResourceClass().loadClass();
               
                            /* service == null
                             * if class resource wasn't loadable
                             */
                            if (service != null) {
                                factory = newFactory(service, newFactoryParamTypes, params);
                            }
                          } catch (Exception e) {
                            // there was an exception creating the factory
                            // the most likely cause was the JDK 1.4 problem
                            // in the discovery code that requires servlet.jar
                            // to be in the client classpath.  For now, fall
                            // through to the next factory
                          }
                        }
               
                        if (factory != null) {
                            if(log.isDebugEnabled()) {
                                log.debug(Messages.getMessage("engineFactory", factory.getClass().getName()));
                            }
                        } else {
                            log.error(Messages.getMessage("engineConfigFactoryMissing"));
                            // we should be throwing an exception here,
                            //
                            // but again, requires more refactoring than we want to swallow
                            // at this point in time.  Ifthis DOES occur, it's a coding error:
                            // factory should NEVER be null.
                            // Testing will find this, as NullPointerExceptions will be generated
                            // elsewhere.
                        }
               
                        return factory;
                    }
                });
    }

    public static EngineConfigurationFactory newFactory() {
        return newFactory(null);
    }

    private static EngineConfigurationFactory newFactory(Class service,
                                                         Class[] paramTypes,
                                                         Object[] param) {
        /**
         * Some JDK's may link on method resolution (findPublicStaticMethod)
         * and others on method call (method.invoke).
         *
         * Either way, catch class load/resolve problems and return null.
         */
       
        try {
            /**
             * Verify that service implements:
             *  public static EngineConfigurationFactory newFactory(Object);
             */
            Method method = ClassUtils.findPublicStaticMethod(service,
                                                  EngineConfigurationFactory.class,
                                                  "newFactory",
                                                  paramTypes);
   
            if (method == null) {
                log.warn(Messages.getMessage("engineConfigMissingNewFactory",
                                              service.getName(),
                                              requiredMethod));
            } else {
                try {
                    return (EngineConfigurationFactory)method.invoke(null, param);
                } catch (InvocationTargetException e) {
                    if (e.getTargetException() instanceof NoClassDefFoundError) {
                        log.debug(Messages.getMessage("engineConfigLoadFactory",
                                                      service.getName()));
                    } else {
                        log.warn(Messages.getMessage("engineConfigInvokeNewFactory",
                                                      service.getName(),
                                                      requiredMethod), e);
                    }
                } catch (Exception e) {
                    log.warn(Messages.getMessage("engineConfigInvokeNewFactory",
                                                  service.getName(),
                                                  requiredMethod), e);
                }
            }
        } catch (NoClassDefFoundError e) {
            log.debug(Messages.getMessage("engineConfigLoadFactory",
                                          service.getName()));
        }

        return null;
    }
}
TOP

Related Classes of org.apache.axis.configuration.EngineConfigurationFactoryFinder

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.