Package org.apache.xmlrpc.server

Source Code of org.apache.xmlrpc.server.PropertyHandlerMapping

/*
* Copyright 1999,2005 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.xmlrpc.server;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.net.URL;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;

import org.apache.xmlrpc.XmlRpcException;
import org.apache.xmlrpc.XmlRpcHandler;
import org.apache.xmlrpc.XmlRpcRequest;


/** A handler mapping based on a property file. The property file
* contains a set of properties. The property key is taken as the
* handler name. The property value is taken as the name of a
* class being instantiated. For any non-void, non-static, and
* public method in the class, an entry in the handler map is
* generated.<br>
* The following constrains apply to the classes:
* <ol>
*   <li>The classes must be stateless. In other words, any
*     instance of the class must be completely thread safe.</li>
* </ol>
* A typical use would be, to specify interface names as the
* property keys and implementations as the values.
*/
public class PropertyHandlerMapping implements XmlRpcHandlerMapping {
  private final Map handlerMap;

  /** Creates a new instance, loading the property file
   * from the given URL.
   * @param pClassLoader Classloader being used to load the classes.
   * @param pURL The URL, from which the property file is being
   * loaded.
   * @throws IOException Loading the property file failed.
   * @throws XmlRpcException Initializing the handlers failed.
   */
  public PropertyHandlerMapping(ClassLoader pClassLoader, URL pURL)
      throws IOException, XmlRpcException {
    handlerMap = load(pClassLoader, pURL);
  }

  /** Creates a new instance, loading the given property file.
   * @param pClassLoader Classloader being used to load the classes.
   * @param pFile File being loaded.
   * @throws IOException Loading the property file failed.
   * @throws XmlRpcException Initializing the handlers failed.
   */
  public PropertyHandlerMapping(ClassLoader pClassLoader, File pFile)
      throws IOException, XmlRpcException {
    handlerMap = load(pClassLoader, pFile.toURL());
  }

  /** Creates a new instance, loading the properties from
   * the given resource.
   * @param pClassLoader Classloader being used to locate
   * the resource.
   * @param pResource Resource being loaded.
   * @throws IOException Loading the property file failed.
   * @throws XmlRpcException Initializing the handlers failed.
   */
  public PropertyHandlerMapping(ClassLoader pClassLoader, String pResource)
      throws IOException, XmlRpcException {
    URL url = pClassLoader.getResource(pResource);
    if (url == null) {
      throw new IOException("Unable to locate resource " + pResource);
    }
    handlerMap = load(pClassLoader, url);
  }

  private Map load(ClassLoader pClassLoader, URL pURL) throws IOException, XmlRpcException {
    Map map = new HashMap();
    Properties props = new Properties();
    props.load(pURL.openStream());
    for (Iterator iter = props.entrySet().iterator();  iter.hasNext()) {
      Map.Entry entry = (Map.Entry) iter.next();
      String key = (String) entry.getKey();
      String value = (String) entry.getValue();
      final Class c;
      try {
        c = pClassLoader.loadClass(value);
      } catch (ClassNotFoundException e) {
        throw new XmlRpcException("Unable to load class: " + value, e);
      }
      if (c == null) {
        throw new XmlRpcException(0, "Loading class " + value + " returned null.");
      }
      final Object o;
      try {
        o = c.newInstance();
      } catch (InstantiationException e) {
        throw new XmlRpcException("Failed to instantiate class " + c.getName(), e);
      } catch (IllegalAccessException e) {
        throw new XmlRpcException("Illegal access when instantiating class " + c.getName(), e);
      }
      Method[] methods = c.getMethods();
      for (int i = 0;  i < methods.length;  i++) {
        final Method method = methods[i];
        if (!Modifier.isPublic(method.getModifiers())) {
          continue// Ignore methods, which aren't public
        }
        if (Modifier.isStatic(method.getModifiers())) {
          continue// Ignore methods, which are static
        }
        if (method.getReturnType() == void.class) {
          continue// Ignore void methods.
        }
        if (method.getDeclaringClass() == Object.class) {
          continue// Ignore methods from Object.class
        }
        String name = key + "." + method.getName();
        if (!map.containsKey(name)) {
          map.put(name, new XmlRpcHandler(){
            public Object execute(XmlRpcRequest pRequest) throws XmlRpcException {
              Object[] args = new Object[pRequest.getParameterCount()];
              for (int j = 0;  j < args.length;  j++) {
                args[j] = pRequest.getParameter(j);
              }
              try {
                return method.invoke(o, args);
              } catch (IllegalAccessException e) {
                throw new XmlRpcException("Illegal access to method "
                              + method.getName() + " in class "
                              + c.getName(), e);
              } catch (IllegalArgumentException e) {
                throw new XmlRpcException("Illegal argument for method "
                              + method.getName() + " in class "
                              + c.getName(), e);
              } catch (InvocationTargetException e) {
                Throwable t = e.getTargetException();
                throw new XmlRpcException("Failed to invoke method "
                              + method.getName() + " in class "
                              + c.getName() + ": "
                              + t.getMessage(), t);
              }
            }
          });
        }
      }
    }
    return map;
  }

  public XmlRpcHandler getHandler(String handlerName)
      throws XmlRpcNoSuchHandlerException, XmlRpcException {
    XmlRpcHandler result = (XmlRpcHandler) handlerMap.get(handlerName);
    if (result == null) {
      throw new XmlRpcNoSuchHandlerException("No such handler: " + handlerName);
    }
    return result;
  }
}
TOP

Related Classes of org.apache.xmlrpc.server.PropertyHandlerMapping

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.