Package org.apache.muse.core

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

/*=============================================================================*
*  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.net.URI;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.muse.core.descriptor.CapabilityDefinition;
import org.apache.muse.core.descriptor.ResourceDefinition;
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.soap.SoapFault;

/**
*
* SimpleResourceManager is Muse's default implementation of resource lifecycle
* management and the implied resource pattern. It maintains a simple table
* that maps EPRs to Resource objects. Each EPR that is added to the manager
* must be unique, but multiple EPRs may be mapped to the same Resource object.
*
* @author Dan Jemiolo (danj)
*
*/

public class SimpleResourceManager implements ResourceManager
{
    //
    // Used to lookup all exception messages
    //
    private static Messages _MESSAGES =
        MessagesFactory.get(SimpleResourceManager.class);
   
    //
    // context path -> ResourceDefinition - all the data needed to
    // properly instantiate each resource type in muse.xml
    //
    private Map _definitionsByPath = new LinkedHashMap();
   
    private Environment _environment = null;
   
    private boolean _hasBeenInitialized = false;
   
    private boolean _hasBeenShutdown = false;
   
    //
    // the ResourceManagerListeners, in the order they were added
    //
    private List _listeners = new LinkedList();

    //
    // All instances of a resource type currently alive on the system
    //
    private Map _resources = new HashMap();
   
    public synchronized void addListener(ResourceManagerListener listener)
    {
        _listeners.add(listener);
    }
   
    public void addResource(EndpointReference epr, Resource resource)
        throws SoapFault
    {
        if (resource == null)
            throw new NullPointerException(_MESSAGES.get("NullResource"));
       
        synchronized (this)
        {
            //
            // the key already exists - not allowed!
            //     
            if (_resources.containsKey(epr))
                throw new SoapFault(_MESSAGES.get("ResourceEPRExists", new Object[]{ epr }));
           
            _resources.put(epr, resource);
        }
       
        //
        // tell all listeners that a new resource is now available
        //
        Iterator i = getListeners().iterator();
       
        while (i.hasNext())
        {
            ResourceManagerListener next = (ResourceManagerListener)i.next();
            next.resourceAdded(epr, resource);
        }
    }
   
    public void addResourceDefinitions(Collection definitions)
    {
        if (definitions == null)
            throw new NullPointerException(_MESSAGES.get("NullFactoryCollection"));
       
        if (definitions.isEmpty())
            throw new IllegalArgumentException(_MESSAGES.get("EmptyFactoryCollection"));
                   
        Iterator i = definitions.iterator();
       
        while (i.hasNext())
        {
            ResourceDefinition definition = (ResourceDefinition)i.next();
            String endpoint = definition.getContextPath();
           
            //
            // sanity check - don't allow one component to over-write another
            //
            if (_definitionsByPath.containsKey(endpoint))
            {
                Object[] filler = { endpoint };
                throw new RuntimeException(_MESSAGES.get("ContextPathExists", filler));
            }
           
            _definitionsByPath.put(endpoint, definition);
        }
    }
   
    public Resource createResource(String contextPath)
        throws SoapFault
    {
        ResourceDefinition definition = getResourceDefinition(contextPath);
   
        if (definition == null)
        {
            Object[] filler = { contextPath, _definitionsByPath.keySet() };
            throw new SoapFault(_MESSAGES.get("ContextPathNotFound", filler));
        }
       
        Resource resource = definition.newInstance();
        resource.setResourceManager(this);
       
        fixContextPath(resource)// HACK: see javadoc for fixContextPath()
       
        return resource;
    }
   
    /**
     *
     * HACK: This method addresses the fact that all new resources have
     * EPRs with wsa:Addresses of the resource type being targeted
     * by the current request. The Environment looks up the target
     * EPR and uses that as the basis for new EPR. In cases where
     * one resource instance is creating another internally, however,
     * we want the new EPR to have a wsa:Address of the given
     * resource type, not the requester's. This method will hack
     * around that problem by adjusting the wsa:Address to have the
     * proper endpoint value.
     *
     * @param resource
     *        A newly-created resource whose wsa:Address does not
     *        reflect its resource type.
     *
     */
    private void fixContextPath(Resource resource)
    {
        //
        // get the current EPR/Address, and find the part where the
        // context path starts...
        //
        EndpointReference epr = resource.getEndpointReference();
        String address = epr.getAddress().toString();
        int slash = address.lastIndexOf('/');
       
        StringBuffer buffer = new StringBuffer();
        buffer.append(address.substring(0, slash));
       
        //
        // substitute the resource type's context path for the one
        // that was on there originally
        //
        String contextPath = resource.getContextPath();
       
        if (contextPath.charAt(0) != '/')
            buffer.append('/');
       
        buffer.append(contextPath);
       
        //
        // re-set EPR address
        //
        URI addressWithProperEndpoint = URI.create(buffer.toString());
        epr.setAddress(addressWithProperEndpoint);
    }
   
    public Environment getEnvironment()
    {
        return _environment;
    }
   
    /**
     *
     * @return A <em>copy</m> of the list of ResourceManagerListeners.
     *
     */
    protected List getListeners()
    {
        return new LinkedList(_listeners);
    }
   
    public synchronized int getNumberOfResources()
    {
        return _resources.size();
    }
   
    public synchronized Resource getResource(EndpointReference epr)
    {
        if (epr == null)
            throw new NullPointerException(_MESSAGES.get("NullResourceEPR"));
       
        //
        // make sure that required property value is used during
        // equality check of EPRs
        //
        String address = epr.getAddress().toString();
        ResourceDefinition definition = getResourceDefinition(address);
       
        if (definition == null)
            return null;
       
        return (Resource)_resources.get(epr);
    }
   
    public String getResourceContextPath(Class capabilityClass)
    {
        Collection matches = getResourceContextPaths(capabilityClass);
        return matches.isEmpty() ? null : (String)matches.iterator().next();
    }
   
    public Collection getResourceContextPaths()
    {
        return _definitionsByPath.keySet();
    }
   
    public Collection getResourceContextPaths(Class capabilityClass)
    {
        if (capabilityClass == null)
            throw new NullPointerException(_MESSAGES.get("NullClass"));
       
        Iterator i = getResourceContextPaths().iterator();
       
        Collection matches = new LinkedList();
       
        //
        // for all distinct resource types...
        //
        while (i.hasNext())
        {
            String path = (String)i.next();
            ResourceDefinition resource = getResourceDefinition(path);
            Iterator j = resource.getCapabilityDefinitions().iterator();
           
            //
            // read through the capability definitions and try to
            // match the impl or interface class
            //
            while (j.hasNext())
            {
                CapabilityDefinition capability = (CapabilityDefinition)j.next();
                Class next = capability.getImplementationClass();
           
                if (capabilityClass.isAssignableFrom(next))
                    matches.add(resource.getContextPath());
            }
        }
       
        return matches;
    }
   
    /**
     *
     * @param contextPath
     *        The URL targeted by an incoming request - this should map to
     *        a <em>context-path</em> value in muse.xml.
     *
     * @return The ResourceDefinition associated with the given endpoint,
     *         or null if there is no such type.
     *
     */
    protected ResourceDefinition getResourceDefinition(String contextPath)
    {
        if (contextPath == null)
            throw new NullPointerException(_MESSAGES.get("NullContextPath"));
       
        Iterator i = _definitionsByPath.keySet().iterator();
       
        while (i.hasNext())
        {
            String next = (String)i.next();
           
            //
            // NOTE: we use endsWith() instead of equals() because we only
            //       care about the unique part of the URL - the part that
            //       applies to the resource type specifically
            //
            if (contextPath.endsWith(next))
                return (ResourceDefinition)_definitionsByPath.get(next);
        }
       
        return null;
    }

    /**
     *
     * @return This implementation returns an iterator over a <b>copy</b> of the
     *         collection of resource EPRs.
     *
     */
    public synchronized Iterator getResourceEPRs()
    {
        Set copy = new HashSet(_resources.keySet());
        return copy.iterator();
    }
   
    public boolean hasBeenInitialized()
    {
        return _hasBeenInitialized;
    }
   
    public boolean hasBeenShutdown()
    {
        return _hasBeenShutdown;
    }
   
    public void initialize()
        throws SoapFault
    {
        _hasBeenInitialized = true;
    }
   
    public boolean isUsingPersistence(String contextPath)
    {
        return getResourceDefinition(contextPath).isUsingPersistence();
    }
   
    public synchronized void removeListener(ResourceManagerListener listener)
    {
        _listeners.remove(listener);
    }

    public void removeResource(EndpointReference epr)
        throws SoapFault
    {       
        //
        // we use this lock instead of adding synchronized to the
        // signature so that the listeners can access the ResourceManager
        // through other threads (i.e., if a listener causes another
        // remote request to come into this manager, the request will
        // block because the manager is locked).
        //
        synchronized (this)
        {
            Resource resource = (Resource)_resources.remove(epr);
           
            //
            // can't remove things that don't exist
            //
            if (resource == null)
            {
                Object[] filler = { epr };
                throw new SoapFault(_MESSAGES.get("ResourceEPRNotFound", filler));
            }
        }
       
        //
        // tell all listeners that the resource is gone forever
        //
        Iterator i = getListeners().iterator();
       
        while (i.hasNext())
        {
            ResourceManagerListener next = (ResourceManagerListener)i.next();
            next.resourceRemoved(epr);
        }
    }

    public void removeResourceDefinitions(Collection definitions)
    {
        if (definitions == null)
            throw new NullPointerException(_MESSAGES.get("NullFactoryCollection"));
              
        Iterator i = definitions.iterator();
       
        while (i.hasNext())
        {
            ResourceDefinition next = (ResourceDefinition)i.next();
            String path = next.getContextPath();
            _definitionsByPath.remove(path);
        }
    }

    public void setEnvironment(Environment environment)
    {
        if (environment == null)
            throw new NullPointerException(_MESSAGES.get("NullEnvironment"));
       
        _environment = environment;
    }
   
    /**
     *
     * This implementation loops through all existing resource instances
     * and tells them to shutdown().
     *
     */
    public void shutdown()
        throws SoapFault
    {
        Iterator i = getResourceEPRs();
       
        while (i.hasNext())
        {
            Resource next = getResource((EndpointReference)i.next());
            next.shutdown();
        }
       
        _hasBeenShutdown = true;
    }
}
TOP

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

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.