Package org.apache.muse.core

Source Code of org.apache.muse.core.SimpleResource

/*=============================================================================*
*  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;

import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.logging.Logger;

import javax.xml.namespace.QName;

import org.w3c.dom.Element;

import org.apache.muse.core.routing.MessageHandler;
import org.apache.muse.util.LoggingUtils;
import org.apache.muse.util.messages.Messages;
import org.apache.muse.util.messages.MessagesFactory;
import org.apache.muse.ws.addressing.EndpointReference;
import org.apache.muse.ws.addressing.MessageHeaders;
import org.apache.muse.ws.addressing.soap.SoapFault;
import org.apache.muse.ws.addressing.soap.SoapUtils;

/**
*
* SimpleResource is Muse's default implementation of the core resource
* type component. It provides all the code needed to collect capabilities
* and delegate request to them, as well as a central place for them to
* find and contact each other.
*
* @author Dan Jemiolo (danj)
*
*/

public class SimpleResource implements Resource
{
    //
    // Used to lookup all exception messages
    //
    private static Messages _MESSAGES = MessagesFactory.get(SimpleResource.class);
   
    //
    // WS-A Action -> Capability that defines the operation for the action
    //
    private Map _capabilitiesByAction = new HashMap();
   
    //
    // Unique capability URI -> Capability
    //
    private Map _capabilitiesByURI = new LinkedHashMap();
   
    private String _contextPath = null;
   
    private Environment _environment = null;
   
    //
    // The EPR for this resource instance
    //
    private EndpointReference _epr = null;
   
    private boolean _hasBeenInitialized = false;
   
    private boolean _hasBeenShutdown = false;
   
    private Logger _log = null;
   
    private ResourceManager _manager = null;
   
    //
    // initialization parameters from the deployment descriptor
    //
    private Map _parameters = Collections.EMPTY_MAP;
   
    private String _wsdlPath = null;
   
    private QName _wsdlPortType = null;
   
    public void addCapability(Capability capability)
    {
        if (capability == null)
            throw new RuntimeException(_MESSAGES.get("NullCapability"));
       
        //
        // the capability inherits some basic components from the resource
        //
        capability.setResource(this);
        capability.setLog(getLog());
        capability.setEnvironment(getEnvironment());

        String uri = capability.getCapabilityURI();
       
        //
        // make sure we don't already have this capability
        //
        if (_capabilitiesByURI.containsKey(uri))
        {
            Object[] filler = { getContextPath(), uri };
            throw new RuntimeException(_MESSAGES.get("DuplicateCapabilityURI", filler));
        }
       
        _capabilitiesByURI.put(uri, capability);
       
        Iterator i = capability.getActions().iterator();
       
        while (i.hasNext())
        {
            String action = (String)i.next();
           
            //
            // make sure some other capability isn't already using this action
            // URI for one of its operations
            //
            if (_capabilitiesByAction.containsKey(action))
            {
                Capability duplicate = (Capability)_capabilitiesByAction.get(action);
                Object[] filler = { getContextPath(), action, duplicate.getCapabilityURI() };
                throw new RuntimeException(_MESSAGES.get("DuplicateAction", filler));
            }
           
            _capabilitiesByAction.put(action, capability);
        }
    }
   
    public final Capability getCapability(String capabilityURI)
    {
        return (Capability)_capabilitiesByURI.get(capabilityURI);
    }
   
    /**
     *
     * @return All of the WS-A Action URIs supported by this resource.
     *
     */
    protected Collection getCapabilityActions()
    {
        return Collections.unmodifiableSet(_capabilitiesByAction.keySet());
    }
   
    /**
     *
     * @param action
     *        A WS-A Action URI.
     *       
     * @return The Capability object with the method that maps to the
     *         given WS-A Action URI.
     *
     */
    protected Capability getCapabilityForAction(String action)
    {
        return (Capability)_capabilitiesByAction.get(action);
    }
   
    /**
     *
     * @return A collection with all of the capabilities' URIs.
     *
     */
    public final Collection getCapabilityURIs()
    {
        return Collections.unmodifiableSet(_capabilitiesByURI.keySet());
    }
   
    public final String getContextPath()
    {
        return _contextPath;
    }
   
    public final EndpointReference getEndpointReference()
    {
        return _epr;
    }
   
    public final Environment getEnvironment()
    {
        return _environment;
    }
   
    public final String getInitializationParameter(String name)
    {
        return (String)getInitializationParameters().get(name);
    }
   
    public final Map getInitializationParameters()
    {
        return _parameters;
    }
   
    public final Logger getLog()
    {
        return _log;
    }
   
    public ResourceManager getResourceManager()
    {
        return _manager;
    }
   
    public final String getWsdlPath()
    {
        return _wsdlPath;
    }
   
    public final QName getWsdlPortType()
    {
        return _wsdlPortType;
    }
   
    public final boolean hasBeenInitialized()
    {
        return _hasBeenInitialized;
    }
   
    public final boolean hasBeenShutdown()
    {
        return _hasBeenShutdown;
    }
   
    public final boolean hasCapability(String capabilityURI)
    {
        return getCapability(capabilityURI) != null;
    }
   
    public void initialize()
        throws SoapFault
    {
        if (getLog() == null)
            throw new IllegalStateException(_MESSAGES.get("NoLogger"));
       
        if (getEnvironment() == null)
            throw new IllegalStateException(_MESSAGES.get("NoEnvironment"));
       
        if (getResourceManager() == null)
            throw new IllegalStateException(_MESSAGES.get("NoResourceManager"));
       
        if (getContextPath() == null)
            throw new IllegalStateException(_MESSAGES.get("NoContextPath"));
       
        if (getWsdlPath() == null)
            throw new IllegalStateException(_MESSAGES.get("NoWSDLPath"));
       
        if (getWsdlPortType() == null)
            throw new IllegalStateException(_MESSAGES.get("NoWSDLPortType"));
       
        initializeCapabilities();
       
        //
        // we made it! log confirmation message
        //
        Object[] filler = { getContextPath() };
        String message = _MESSAGES.get("ResourceInitialized", filler);
        getLog().info(message);
       
        _hasBeenInitialized = true;
    }
   
    /**
     *
     * This method can be overrided to provide additional capability
     * initialization logic that applies generally to all capabilities.
     * Capability-specific initialization logic should be provided by
     * overriding Capability.initialize().
     *
     */
    protected void initializeCapabilities()
        throws SoapFault
    {
        String contextPath = getContextPath();
        Logger log = getLog();

        Iterator i = getCapabilityURIs().iterator();
       
        //
        // first create and initialize() all capabilities
        //
        while (i.hasNext())
        {
            String nextURI = (String)i.next();
            Capability next = getCapability(nextURI);
            next.initialize();
           
            Object[] filler = { contextPath, nextURI };
            log.fine(_MESSAGES.get("CapabilityInitialized", filler));
        }
       
        i = getCapabilityURIs().iterator();
       
        //
        // then call initializeCompleted() for post-initialize tasks
        //
        while (i.hasNext())
        {
            String nextURI = (String)i.next();
            Capability next = getCapability(nextURI);
            next.initializeCompleted();
           
            Object[] filler = { contextPath, nextURI };
            log.fine(_MESSAGES.get("CapabilityInitializationComplete", filler));
        }
    }
   
    public Element invoke(Element soapBody)
    {
        //
        // get WS-A action, which maps to a Capability's operation
        //
        MessageHeaders wsa = getEnvironment().getAddressingContext();
        String action = wsa.getAction();
       
        //
        // get the capability that owns this operation so we can
        // delegate the request
        //
        Capability capability = getCapabilityForAction(action);
       
        if (capability == null)
        {
            Object[] filler = { getContextPath(), action };
            SoapFault fault = new SoapFault(_MESSAGES.get("ActionNotSupported", filler));
            return fault.toXML();
        }
       
        MessageHandler handler = capability.getMessageHandler(action);
        Method method = handler.getMethod();
       
        Object[] parameters = null;
       
        try
        {
            //
            // translate from XML -> POJO. the reflection call will take
            // care of casting the generic Object references to the actual
            // method parameter types
            //
            parameters = handler.fromXML(soapBody);
           
            //
            // invoke operation and translate result to XML
            //
            Object result = method.invoke(capability, parameters);
           
            return handler.toXML(result);
        }
       
        catch (Throwable error)
        {
            //
            // the exception is the generic reflection error, and useless
            // to the programmer - we want to report on the REAL cause
            //
            Throwable cause = error.getCause();
           
            if (cause != null// sanity check
                error = cause;
           
            Logger log = getLog();
           
            //
            // log the details of de-serialization and reflection
            //
            if (parameters != null)
                LoggingUtils.logCall(log, method, parameters);
           
            LoggingUtils.logError(log, error);
           
            SoapFault response = SoapUtils.convertToFault(error);
            return response.toXML();
        }
    }
   
    public final void setContextPath(String contextPath)
    {
        if (contextPath == null)
            throw new NullPointerException(_MESSAGES.get("NullContextPath"));
       
        _contextPath = contextPath;
    }
   
    public final void setEndpointReference(EndpointReference epr)
    {
        if (_epr != null && hasBeenInitialized())
            throw new RuntimeException(_MESSAGES.get("ExistingResourceEPR"));
       
        _epr = epr;
    }
   
    public final void setEnvironment(Environment environment)
    {
        if (environment == null)
            throw new NullPointerException(_MESSAGES.get("NullEnvironment"));

        _environment = environment;
    }
   
    public final void setInitializationParameters(Map parameters)
    {
        if (parameters == null)
            parameters = Collections.EMPTY_MAP;
       
        _parameters = parameters;
    }
   
    public final void setLog(Logger log)
    {
        if (log == null)
            throw new NullPointerException(_MESSAGES.get("NullLogger"));

        _log = log;
    }
   
    public void setResourceManager(ResourceManager manager)
    {
        if (manager == null)
            throw new NullPointerException(_MESSAGES.get("NullResourceManager"));
       
        _manager = manager;
    }
   
    public final void setWsdlPath(String wsdlPath)
    {
        if (wsdlPath == null)
            throw new NullPointerException(_MESSAGES.get("NullWsdlPath"));
       
        _wsdlPath = wsdlPath;
    }
   
    public final void setWsdlPortType(QName wsdlPortType)
    {
        if (wsdlPortType == null)
            throw new NullPointerException(_MESSAGES.get("NullWsdlPortType"));
       
        _wsdlPortType = wsdlPortType;
    }
       
    /**
     *
     * {@inheritDoc}
     * <br><br>
     * This implementation double-checks to make sure the resource hasn't
     * already been destroyed and then nulls-out all references to internal
     * data structures (this will highlight bugs caused by stale references
     * and prevent "undefined behavior").
     *
     */
    public synchronized void shutdown()
        throws SoapFault
    {
        //
        // error - we've already been here
        //
        if (hasBeenShutdown())
            throw new SoapFault(_MESSAGES.get("ResourceAlreadyDestroyed"));
               
        ResourceManager manager = getResourceManager();

        //
        // remove resource visibility
        //
        // sanity check: make sure the resource was put in manager. this may
        // not be the case for internal resources
        //
        if (manager.getResource(_epr) != null)
            manager.removeResource(_epr);
       
        //
        // sanity check: nullify fields to make sure resource isn't being
        // used afterwards. if it IS being used, the code will throw an NPE
        // instead of performing undefined behavior.
        //
        _epr = null;
        _environment = null;
       
        //
        // log confirmation message, then drop the log reference
        //
        _log.info(_MESSAGES.get("ResourceDestroyed", new Object[]{ _contextPath }));
        _contextPath = null;
        _log = null;
       
        _hasBeenShutdown = true;
    }
   
    /**
     *
     * @return The resource's EPR, in string form.
     *
     */
    public String toString()
    {
        return getEndpointReference().toString();
    }
}
TOP

Related Classes of org.apache.muse.core.SimpleResource

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.