Package org.apache.muse.ws.resource.sg.impl

Source Code of org.apache.muse.ws.resource.sg.impl.SimpleServiceGroup

/*=============================================================================*
*  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.ws.resource.sg.impl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.xml.namespace.QName;

import org.w3c.dom.Element;

import org.apache.muse.core.Persistence;
import org.apache.muse.core.Resource;
import org.apache.muse.core.ResourceManager;
import org.apache.muse.core.ResourceManagerListener;
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.resource.WsResource;
import org.apache.muse.ws.resource.basefaults.BaseFault;
import org.apache.muse.ws.resource.ext.faults.ResourceInitializationFault;
import org.apache.muse.ws.resource.impl.AbstractWsResourceCapability;
import org.apache.muse.ws.resource.lifetime.ScheduledTermination;
import org.apache.muse.ws.resource.lifetime.WsrlConstants;
import org.apache.muse.ws.resource.sg.Entry;
import org.apache.muse.ws.resource.sg.MembershipContentRule;
import org.apache.muse.ws.resource.sg.ServiceGroup;
import org.apache.muse.ws.resource.sg.ServiceGroupPersistence;
import org.apache.muse.ws.resource.sg.WssgConstants;
import org.apache.muse.ws.resource.sg.faults.AddRefusedFault;
import org.apache.muse.ws.addressing.soap.SoapFault;

/**
*
* SimpleServiceGroup is Muse's default implementation of the WS-RF ServiceGroup
* capability. It provides SOAP-level access to the entries it contains and
* lifecycle management for the Entry resources. Users that wish to make entry
* creation available to remote clients should combine this capability with
* the {@linkplain SimpleServiceGroupRegistration ServiceGroupRegistration capability}.
*
* @author Dan Jemiolo (danj)
*
*/

public class SimpleServiceGroup
    extends AbstractWsResourceCapability implements ServiceGroup, ResourceManagerListener
{
    //
    // Used to look up all exception messages
    //
    private static Messages _MESSAGES =
        MessagesFactory.get(SimpleServiceGroup.class);
       
    private MembershipContentRule[] _contentRules = null;
   
    private Map _entriesByMemberEPR = new HashMap();
   
    private String _entryPath = null;
   
    public WsResource addEntry(EndpointReference memberEPR,
                               Element content,
                               Date termination)
        throws AddRefusedFault,
               BaseFault
    {
        WsResource entry = createEntry(memberEPR, content, termination);
        return addEntry(memberEPR, entry);
    }
   
    public WsResource addEntry(EndpointReference memberEPR, WsResource entry)
    {
        _entriesByMemberEPR.put(memberEPR, entry);
        return entry;
    }
   
    protected WsResource createEntry(EndpointReference epr,
                                     Element content,
                                     Date termination)
        throws AddRefusedFault,
               ResourceInitializationFault,
               BaseFault
    {
        //
        // NOTE: this implementation ignores the provided content
        //       because it reads the members' content elements
        //       via WS-RP in order to ensure compliance.
        //
       
        if (epr == null)
            throw new NullPointerException(_MESSAGES.get("NullMemberServiceEPR"));
       
        WsResource sg = getWsResource();
       
        //
        // make sure this is a valid member of the group
        //
        if (!isMatch(epr))
            throw new AddRefusedFault(_MESSAGES.get("ContentCreationFailed"));

        ResourceManager manager = sg.getResourceManager();
        String endpoint = getEntryContextPath();
        WsResource resource = null;
       
        try
        {
            resource = (WsResource)manager.createResource(endpoint);
        }
       
        catch (SoapFault error)
        {
            throw new ResourceInitializationFault(error);
        }
       
        //
        // set the sg entry fields before initializing the entry resource
        //
       
        Entry entry = (Entry)resource.getCapability(WssgConstants.ENTRY_URI);
       
        entry.setServiceGroup(sg);
        entry.setMemberEPR(epr);
       
        try
        {
            resource.initialize();
            manager.addResource(resource.getEndpointReference(), resource);
        }
       
        catch (SoapFault error)
        {
            throw new ResourceInitializationFault(error);
        }
       
        //
        // set termination time AFTER we initialize so that we can rely
        // on the base Resource class' implementation of WS-RL (which
        // tries to apply the change immediately, rather than storing it
        // in a field and setting it during initialization)
        //
        if (resource.hasCapability(WsrlConstants.SCHEDULED_TERMINATION_URI))
        {
            ScheduledTermination wsrl =
                (ScheduledTermination)resource.getCapability(WsrlConstants.SCHEDULED_TERMINATION_URI);
            wsrl.setTerminationTime(termination);
        }
       
        return resource;
    }
   
    protected MembershipContentRule createMembershipContentRule()
    {
        return new SimpleMembershipContentRule(getResource().getEndpointReference());
    }
   
    protected MembershipContentRule createMembershipContentRule(Element xml)
    {
        return new SimpleMembershipContentRule(getResource().getEndpointReference(), xml);
    }
   
    /**
     *
     * This implementation returns an empty array (no content rules, no
     * restrictions on membership).
     *
     */
    protected MembershipContentRule[] createMembershipContentRules()
    {
        return new MembershipContentRule[0];
    }

    public QName[] getContentElements()
    {
        MembershipContentRule[] rules = getMembershipContentRule();
        Collection allContent = new ArrayList();

        for (int n = 0; n < rules.length; ++n)
        {
            QName[] content = rules[n].getContentElements();
            allContent.addAll(Arrays.asList(content));
        }
       
        QName[] array = new QName[allContent.size()];
        return (QName[])allContent.toArray(array);
    }

    public WsResource[] getEntry()
    {
        Collection entryResources = _entriesByMemberEPR.values();
        WsResource[] asArray = new WsResource[entryResources.size()];
        return (WsResource[])entryResources.toArray(asArray);
    }
   
    public WsResource getEntry(EndpointReference memberEPR)
    {
        return (WsResource)_entriesByMemberEPR.get(memberEPR);
    }

    protected String getEntryContextPath()
    {
        return _entryPath;
    }
   
    protected Element[] getEntryElements()
    {
        //
        // convert resource -> entry capability -> entry XML
        //
        WsResource[] entries = getEntry();
        Element[] entryXML = new Element[entries.length];
       
        for (int n = 0; n < entries.length; ++n)
        {
            Entry entryCap = (Entry)entries[n].getCapability(WssgConstants.ENTRY_URI);
            entryXML[n] = entryCap.toXML();
        }
       
        return entryXML;
    }
   
    public MembershipContentRule[] getMembershipContentRule()
    {
        return _contentRules;
    }
   
    public Element[] getProperty(QName property)
        throws BaseFault
    {
        //
        // special case to convert entry resources into entry XML
        //
        if (property.equals(WssgConstants.ENTRY_QNAME))
            return getEntryElements();
       
        return super.getProperty(property);
    }
   
    public QName[] getPropertyNames()
    {
        return PROPERTIES;
    }
   
    public void initialize()
        throws SoapFault
    {
        super.initialize();
       
        _contentRules = createMembershipContentRules();
       
        //
        // make sure the Entry endpoint is exposed, since our entries
        // are all first-class resources
        //
        WsResource resource = getWsResource();
        ResourceManager manager = resource.getResourceManager();
       
        _entryPath = manager.getResourceContextPath(Entry.class);
       
        if (_entryPath == null)
            throw new RuntimeException(_MESSAGES.get("NoEntryEndpoint"));
       
        //
        // set up persistence, if it's used
        //
        Persistence persistence = getPersistence();
       
        if (persistence != null)
        {
            if (!ServiceGroupPersistence.class.isAssignableFrom(persistence.getClass()))
            {
                Object[] filler = { ServiceGroupPersistence.class, persistence.getClass() };
                throw new RuntimeException(_MESSAGES.get("IncorrectPersistenceRoot", filler));
            }
           
            ServiceGroupPersistence sgP = (ServiceGroupPersistence)persistence;
            sgP.setServiceGroup(resource);
        }
               
        //
        // listen for all new resources being created so they can
        // be added to the service group
        //
        manager.addListener(this);
    }

    public boolean isMatch(EndpointReference epr)
    {
        MembershipContentRule[] rules = getMembershipContentRule();
       
        for (int n = 0; n < rules.length; ++n)
            if (!rules[n].isMatch(epr))
                return false;
           
        return true;
    }
   
    public void removeEntry(WsResource entry)
    {
        if (entry == null)
            throw new NullPointerException(_MESSAGES.get("NullEntry"));
       
        //
        // this is hack-ish - we have to loop through a hash table to find
        // the right resource. don't have time to go back and refactor the
        // way we store entries and make this more efficient - besides, it's
        // more important the additions and lookups be fast
        //
        Iterator i = _entriesByMemberEPR.keySet().iterator();
        EndpointReference memberEPR = null;
       
        while (i.hasNext() && memberEPR == null)
        {
            EndpointReference nextEPR = (EndpointReference)i.next();
            WsResource nextEntry = (WsResource)_entriesByMemberEPR.get(memberEPR);
           
            if (entry == nextEntry)
                memberEPR = nextEPR;
        }
       
        if (_entriesByMemberEPR.remove(memberEPR) == null)
            throw new RuntimeException(_MESSAGES.get("EntryNotFound"));
       
        //
        // if we're using persistence, remove the record of the entry
        //
        ServiceGroupPersistence persistence = (ServiceGroupPersistence)getPersistence();
       
        try
        {
            if (persistence != null)
                persistence.resourceRemoved(entry.getEndpointReference());
        }
       
        catch (SoapFault fault)
        {
            LoggingUtils.logError(getLog(), fault);
        }
    }
   
    public void resourceAdded(EndpointReference epr, Resource resource)
        throws SoapFault
    {
        //
        // don't add entries for wssg:Entry resources, or we'll
        // create an infinite recursion
        //
        if (resource.hasCapability(WssgConstants.SERVICE_GROUP_URI) ||
            resource.hasCapability(WssgConstants.ENTRY_URI))
            return;
       
        //
        // don't add duplicate entries. this check was added because of
        // the persistence layer, which may cause duplicate entries to
        // be attempted when the SGEntry resources are re-loaded and then
        // when the actual members are re-loaded
        //
        if (getEntry(epr) != null)
            return;

        //
        // don't add resources that don't validate against our
        // membership content rules
        //
        if (!isMatch(epr))
            return;
               
        Date termination = null;
       
        if (resource.hasCapability(WsrlConstants.SCHEDULED_TERMINATION_URI))
        {
            ScheduledTermination wsrl =
                (ScheduledTermination)resource.getCapability(WsrlConstants.SCHEDULED_TERMINATION_URI);
            termination = wsrl.getTerminationTime();
        }
       
        WsResource entry = addEntry(epr, null, termination);
       
        //
        // if we're using persistence, create a record of the entry
        //
        ServiceGroupPersistence persistence = (ServiceGroupPersistence)getPersistence();
       
        try
        {
            if (persistence != null)
                persistence.resourceAdded(entry.getEndpointReference(), entry);
        }
       
        catch (SoapFault fault)
        {
            throw new AddRefusedFault(fault);
        }
    }
   
    public void resourceRemoved(EndpointReference epr)
    {
        //
        // if the SG is destroyed, it means we're being told about
        // our own destruction - don't do anything
        //
        if (hasBeenShutdown())
            getWsResource().getResourceManager().removeListener(this);
       
        else
        {
            WsResource entry = getEntry(epr);
           
            //
            // if there was no value in the SG for the EPR, it was
            // either a wssg:Entry resource (entries do not have
            // entries themselves, or we'd have infinite recursion)
            // or a member that was removed by a remote client before
            // the member was destroyed
            //
            if (entry != null)
                removeEntry(entry);
        }
    }
   
    public void shutdown()
        throws SoapFault
    {
        //
        // if we're being shutdown, we have to shutdown our entry
        // resources or they'll be orphaned
        //
        WsResource[] entries = getEntry();
       
        for (int n = 0; n < entries.length; ++n)
            entries[n].shutdown();
       
        super.shutdown();
    }
}
TOP

Related Classes of org.apache.muse.ws.resource.sg.impl.SimpleServiceGroup

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.