Package org.apache.muse.core.descriptor

Source Code of org.apache.muse.core.descriptor.SimpleResourceDescriptor

/*=============================================================================*
*  Copyright 2006 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.muse.core.descriptor;

import java.io.File;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
import java.util.MissingResourceException;
import java.util.ResourceBundle;

import javax.wsdl.Definition;
import javax.wsdl.Operation;
import javax.wsdl.PortType;
import javax.xml.namespace.QName;

import org.w3c.dom.Document;
import org.w3c.dom.Element;

import org.apache.muse.core.Capability;
import org.apache.muse.core.Environment;
import org.apache.muse.core.Resource;
import org.apache.muse.core.routing.MessageHandler;
import org.apache.muse.core.routing.ReflectionMessageHandler;
import org.apache.muse.core.routing.ResourceIdFactory;
import org.apache.muse.util.ReflectUtils;
import org.apache.muse.util.messages.Messages;
import org.apache.muse.util.messages.MessagesFactory;
import org.apache.muse.util.xml.XmlUtils;
import org.apache.muse.ws.addressing.soap.SoapFault;
import org.apache.muse.ws.wsdl.WsdlUtils;

/**
*
* @author Dan Jemiolo (danj)
*
*/

public class SimpleResourceDescriptor implements ResourceDescriptor
{
    //
    // Used to lookup all exception messages
    //
    private static Messages _MESSAGES =
        MessagesFactory.get(SimpleResourceDescriptor.class);
   
    private static final String _REQUIRED_CAPABILITIES = "org.apache.muse.core.descriptor.ext.RequiredCapabilityImplementations";
   
    private ResourceDefinition _definition = null;
   
    protected Collection createCapabilityDefinitions(Element xml,
                                                     Environment env,
                                                     WsdlConfig wsdlConfig)
        throws SoapFault
    {
        Document wsdlDoc = WsdlUtils.createWSDL(env, wsdlConfig.getWsdlPath(), true);
       
        //
        // read in list of operation names and the return value names
        //
        Map opsByAction = getWsdlOperations(wsdlDoc, wsdlConfig, env);
       
        Element[] capXML = XmlUtils.getElements(xml, DescriptorConstants.CAPABILITY_QNAME);
        Collection definitions = new ArrayList(capXML.length);
       
        //
        // load the (optional) properties file that will tell us if there are
        // any capabilities that the underlying platform provides and does
        // not want to be superceded
        //
        Map requiredClassesByURI = createRequiredClasses(env);
       
        for (int n = 0; n < capXML.length; ++n)
        {
            CapabilityDescriptor cd = createCapabilityDescriptor();
            cd.load(capXML[n], env);
           
            CapabilityDefinition definition = cd.getCapabilityDefinition();
           
            String uri = definition.getURI();
            Class implClass = definition.getImplementationClass();
           
            //
            // make sure it's obvious to the user that they have to use a
            // certain impl class if specified by the platform. we don't
            // want people trying to debug their code when it's not even
            // being called by Muse.
            //
            if (requiredClassesByURI.keySet().contains(uri))
            {
                String requiredClassName = (String)requiredClassesByURI.get(uri);
               
                if (implClass != null)
                {
                    Object[] filler = { uri, requiredClassName };
                    throw new RuntimeException(_MESSAGES.get("RequiredCapability", filler));
                }
               
                //
                // load the required implementation class
                //
                implClass = ReflectUtils.getClass(requiredClassName, env.getClassLoader());
                definition.setImplementationClass(implClass);
            }
           
            //
            // create reflection-based message handlers, which could be
            // overridden by the capability impl
            //
            Collection handlers = createMessageHandlers(wsdlDoc, opsByAction, implClass);
            definition.setMessageHandlers(handlers);
           
            definitions.add(definition);
        }
       
        if (!opsByAction.isEmpty())
        {
            Object[] filler = { wsdlConfig.getWsdlPath(), opsByAction.keySet() };
            throw new RuntimeException(_MESSAGES.get("MissingOperationImplementations", filler));
        }
       
        return definitions;
    }
   
    protected CapabilityDescriptor createCapabilityDescriptor()
    {
        return new SimpleCapabilityDescriptor();
    }
   
    protected String createContextPath(Element xml)
    {
        QName qname = DescriptorConstants.CONTEXT_PATH_QNAME;
        String path = XmlUtils.getElementText(xml, qname);
       
        if (path == null)
            throw new RuntimeException(_MESSAGES.get("NullContextPath"));
       
        return path;
    }
   
    protected InitParamDescriptor createInitParamDescriptor()
    {
        return new SimpleInitParamDescriptor();
    }
   
    protected MessageHandler createMessageHandler(String actionURI,
                                                  QName operationName,
                                                  QName returnValueName)
    {
        return new ReflectionMessageHandler(actionURI, operationName, returnValueName);
    }
   
    protected Collection createMessageHandlers(Document wsdlDoc, Map opsByAction, Class theClass)
    {
        Map methodsByName = new HashMap();
       
        Method[] methods = theClass.getMethods();
       
        for (int n = 0; n < methods.length; ++n)
        {
            Class declaringClass = methods[n].getDeclaringClass();
           
            if (declaringClass != Object.class &&
                declaringClass != Capability.class)
                methodsByName.put(methods[n].getName(), methods[n]);
        }
       
        Collection handlers = new ArrayList(opsByAction.size());
        Iterator i = opsByAction.keySet().iterator();
       
        while (i.hasNext())
        {
            String action = (String)i.next();
            Operation next = (Operation)opsByAction.get(action);
           
            QName inputName = WsdlUtils.getInputPartName(next);
            QName outputName = WsdlUtils.getOutputPartName(next, wsdlDoc);
           
            String localName = next.getName();
            String methodName = getMethodName(localName);
            Method method = (Method)methodsByName.get(methodName);
           
            if (method != null)
            {
                MessageHandler handler = createMessageHandler(action, inputName, outputName);
                handler.setMethod(method);
           
                handlers.add(handler);
               
                i.remove();
            }
        }
       
        return handlers;
    }
   
    protected Map createRequiredClasses(Environment env)
    {
        ResourceBundle bundle = null;
        Map requiredClassesByURI = new HashMap();
       
        try
        {
            bundle = ResourceBundle.getBundle(_REQUIRED_CAPABILITIES, Locale.getDefault(), env.getClassLoader());
        }
       
        catch (MissingResourceException notFound)
        {
            //
            // this is not really an error - the file is optional
            //
            return requiredClassesByURI;
        }
       
        //
        // copy values to a map - worthwhile in case we later change the
        // key or value type to something other than string
        //
        Enumeration keys = bundle.getKeys();
       
        while (keys.hasMoreElements())
        {
            String next = (String)keys.nextElement();
            requiredClassesByURI.put(next, bundle.getString(next));
        }
       
        return requiredClassesByURI;
    }
   
    protected Class createResourceClass(Element xml, Environment env)
    {
        QName qname = DescriptorConstants.JAVA_RESOURCE_QNAME;
        String className = XmlUtils.getElementText(xml, qname);
       
        if (className == null)
            throw new RuntimeException(_MESSAGES.get("NullJavaResourceClass"));
       
        ClassLoader loader = env.getClassLoader();
        Class resourceClass = ReflectUtils.getClass(className, loader);
       
        if (!Resource.class.isAssignableFrom(resourceClass))
        {
            Object[] filler = { className, Resource.class.getName() };
            String message = _MESSAGES.get("IncorrectResourceRoot", filler);
            throw new RuntimeException(message);
        }
       
        return resourceClass;
    }
   
    protected ResourceIdFactory createResourceIdFactory(Element xml,
                                                        Environment env)
    {
        QName qname = DescriptorConstants.JAVA_ID_FACTORY_QNAME;
        String className = XmlUtils.getElementText(xml, qname);
       
        if (className == null)
            return null;
       
        Class theClass = null;
       
        ClassLoader loader = env.getClassLoader();
        theClass = ReflectUtils.getClass(className, loader);
           
        if (!ResourceIdFactory.class.isAssignableFrom(theClass))
        {
            Object[] filler = { className, ResourceIdFactory.class.getName() };
            throw new RuntimeException(_MESSAGES.get("NotResourceIdFactory", filler));
        }
       
        return (ResourceIdFactory)ReflectUtils.newInstance(theClass);
    }
   
    protected boolean createUsingPersistence(Element xml)
    {
        //
        // if there's a null/empty value, Boolean.valueOf() returns 'false'
        //
        String attr = xml.getAttribute(DescriptorConstants.USE_ROUTER_PERSISTENCE);
        return Boolean.valueOf(attr).booleanValue();
    }
   
    protected WsdlConfig createWSDL(Element xml)
    {
        QName qname = DescriptorConstants.WSDL_QNAME;
        Element wsdlXML = XmlUtils.getElement(xml, qname);
       
        if (wsdlXML == null)
            throw new RuntimeException(_MESSAGES.get("NullWSDLFile"));
       
        qname = DescriptorConstants.WSDL_FILE_QNAME;
        String path = XmlUtils.getElementText(wsdlXML, qname);
       
        if (path == null)
            throw new RuntimeException(_MESSAGES.get("NullWSDLLocation"));
       
        //
        // get the WSDL portType
        //
        // NOTE: at this point, we cannot guarantee that the portType is
        //       actually in the WSDL
        //
        qname = DescriptorConstants.WSDL_PORT_TYPE_QNAME;
        QName portType = XmlUtils.getQNameFromChild(wsdlXML, qname);
       
        if (portType == null)
            throw new RuntimeException(_MESSAGES.get("NullWSDLPortType"));
       
        WsdlConfig wsdl = new WsdlConfig();
        wsdl.setWsdlPath(path);
        wsdl.setWsdlPortType(portType);
       
        return wsdl;
    }
   
    private String getMethodName(String actionName)
    {
        return Character.toLowerCase(actionName.charAt(0)) + actionName.substring(1);
    }
       
    public ResourceDefinition getResourceDefinition()
    {
        return _definition;
    }
   
    protected Map getWsdlOperations(Document wsdlDoc,
                                    WsdlConfig wsdlConfig,
                                    Environment env)
    {
        String wsdlPath = wsdlConfig.getWsdlPath();
        String absolutePath = env.getRealDirectory().getAbsolutePath();
       
        if (wsdlPath.charAt(0) != '/')
            absolutePath += '/';
       
        absolutePath += wsdlPath;
        File wsdlFile = new File(absolutePath);
        File wsdlDir = wsdlFile.getParentFile();
       
        Definition def = WsdlUtils.createDefinition(wsdlDoc, wsdlDir);
       
        //
        // find the port type named in the descriptor and process
        // all of the operations
        //
        QName portTypeName = wsdlConfig.getWsdlPortType();
        PortType portType = def.getPortType(portTypeName);
       
        if (portType == null)
        {
            Object[] filler = { absolutePath, portTypeName };
            throw new RuntimeException(_MESSAGES.get("PortTypeNotFound", filler));
        }
       
        Collection ops = portType.getOperations();
        Iterator i = ops.iterator();
       
        Map opsByAction = new HashMap();
       
        while (i.hasNext())
        {
            Operation next = (Operation)i.next();
            String action = WsdlUtils.getAction(next);
            opsByAction.put(action, next);
        }
       
        return opsByAction;
    }
   
    public void load(Element xml, Environment environment)
        throws SoapFault
    {
        boolean isUsingPersistence = createUsingPersistence(xml);
        String contextPath = createContextPath(xml);
        WsdlConfig wsdl = createWSDL(xml);
        ResourceIdFactory idFactory = createResourceIdFactory(xml, environment);
        Class resourceClass = createResourceClass(xml, environment);
        Collection capabilities = createCapabilityDefinitions(xml, environment, wsdl);

        InitParamDescriptor paramDesc = createInitParamDescriptor();
        paramDesc.load(xml);
        Map parameters = paramDesc.getInitializationParameters();
       
        _definition = new ResourceDefinition();
        _definition.setEnvironment(environment);
        _definition.setUsingPersistence(isUsingPersistence);
        _definition.setContextPath(contextPath);
        _definition.setWsdlConfig(wsdl);
        _definition.setResourceIdFactory(idFactory);
        _definition.setResourceClass(resourceClass);
        _definition.setCapabilityDefinitions(capabilities);
        _definition.setInitializationParameters(parameters);
    }
}
TOP

Related Classes of org.apache.muse.core.descriptor.SimpleResourceDescriptor

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.