Package org.apache.ws.resource.impl

Source Code of org.apache.ws.resource.impl.AbstractResourceHome

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

import commonj.timers.Timer;
import commonj.timers.TimerManager;
import org.apache.commons.collections.map.ReferenceMap;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.ws.Soap1_1Constants;
import org.apache.ws.addressing.EndpointReference;
import org.apache.ws.addressing.XmlBeansEndpointReference;
import org.apache.ws.metadata.MetadataConfiguration;
import org.apache.ws.resource.IllegalResourceTypeException;
import org.apache.ws.resource.JndiConstants;
import org.apache.ws.resource.PersistentResource;
import org.apache.ws.resource.PropertiesResource;
import org.apache.ws.resource.Resource;
import org.apache.ws.resource.ResourceContext;
import org.apache.ws.resource.ResourceCreationEvent;
import org.apache.ws.resource.ResourceCreationListener;
import org.apache.ws.resource.ResourceDestructionEvent;
import org.apache.ws.resource.ResourceDestructionListener;
import org.apache.ws.resource.ResourceException;
import org.apache.ws.resource.ResourceHome;
import org.apache.ws.resource.ResourceUnknownException;
import org.apache.ws.resource.WsrfRuntime;
import org.apache.ws.resource.faults.FaultException;
import org.apache.ws.resource.i18n.Keys;
import org.apache.ws.resource.i18n.MessagesImpl;
import org.apache.ws.resource.lifetime.ScheduledResourceTerminationResource;
import org.apache.ws.util.Cache;
import org.apache.ws.util.NameUtils;
import org.apache.ws.util.XmlBeanUtils;
import org.apache.ws.util.i18n.Messages;
import org.apache.ws.util.jndi.Initializable;
import org.apache.ws.util.jndi.XmlBeanJndiUtils;
import org.apache.ws.util.lock.Lock;
import org.apache.ws.util.lock.LockManager;
import org.apache.ws.util.platform.JaxRpcPlatform;
import org.apache.ws.util.timer.TimerManagerImpl;
import org.apache.xmlbeans.XmlObject;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.ListableBeanFactory;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.xml.namespace.QName;
import javax.xml.rpc.JAXRPCException;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPHeader;
import javax.xml.soap.SOAPHeaderElement;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
* TODO: Update these Javadocs
* <p/>
* LOG-DONE An implementation of the <code>ResourceHome</code> interface. This implementation was designed to work with
* resources that implement the {@link PersistentResource PersistenceCallback} interface as well as memory resident
* resources. If the resource class implements the {@link PersistentResource PersistenceCallback} interface
* <code>SoftReference</code>s will be used to recycle resource objects. The resource class implementation is
* responsible for saving its state to disk. This implementation will <b>not</b> call {@link PersistentResource#store()
* PersistenceCallback.store()}. The resource implementation must have a default constructor. <br><br> Configuration
* options: <ul> <li> sweeperDelay - configures how often the resource sweeper runs in msec. By default the resource
* sweeper runs every minute. For example:
* <pre>
*    &lt;parameter&gt;
*     &lt;name&gt;sweeperDelay&lt;/name&gt;
*     &lt;value&gt;60000&lt;/value&gt;
*    &lt;/parameter&gt;
* </pre>
* <li> resourceClass - configures the name of the resource class. For example:
* <pre>
*    &lt;parameter&gt;
*     &lt;name&gt;resourceClass&lt;/name&gt;
*     &lt;value&gt;org.globus.wsrf.samples.counter.PersistentCounter&lt;/value&gt;
*    &lt;/parameter&gt;
* </pre>
* <li> resourceKeyType - configures the key type class. By default <code>java.lang.String</code> is used. For example:
* <pre>
*    &lt;parameter&gt;
*     &lt;name&gt;resourceKeyType&lt;/name&gt;
*     &lt;value&gt;java.lang.Integer&lt;/value&gt;
*    &lt;/parameter&gt;
* </pre>
* <li> resourceKeyName - configures the key name. For example:
* <pre>
*    &lt;parameter&gt;
*     &lt;name&gt;resourceKeyName&lt;/name&gt;
*     &lt;value&gt;{http://counter.com}CounterKey&lt;/value&gt;
*    &lt;/parameter&gt;
* </pre>
* </ul> <br> <b>Note:</b> Must be deployed with <code>org.globus.wsrf.jndi.BeanFactory</code> in JNDI or user must
* first call {@link #init() initialize()} method. Also when overriding the {@link #init() initialize()} method make
* sure to call <code>super.initialize();</code>.
*
* @author Globus, Ian Springer
*/
public abstract class AbstractResourceHome
   implements ResourceHome,
              Initializable,
              Serializable
{
   private static final Log      LOG = LogFactory.getLog( AbstractResourceHome.class );
   private static final Messages MSG = MessagesImpl.getInstance(  );
   private static final int      DEFAULT_SWEEPER_DELAY = 60000;

   /*
    * A static key used only for registering Singleton Resources
    */
   private static final Object SINGLETON_KEY = new Object(  );
   private static final String CONTEXT_NAME_J2EE_TIMER_MANAGER = "java:comp/env/tm/TimerManager";

   /**
    * DOCUMENT_ME
    */
   protected Map m_resources;

   /**
    * DOCUMENT_ME
    */
   protected boolean m_resourceIsPersistent;
   private QName     m_resourceIdRefParamName;
   private String    m_wsdlTargetNamespace;

   /**
    * DOCUMENT_ME
    */
   protected LockManager         m_lockManager;
   private String                m_cacheLocation;
   private Cache                 m_cache;
   private long                  m_sweeperDelay         = DEFAULT_SWEEPER_DELAY;
   private Sweeper               m_sweeper;
   private boolean               m_initialized;
   private List                  m_creationListeners    = new ArrayList(  );
   private List                  m_destructionListeners = new ArrayList(  );
   private Class                 m_resourceClass;
   private Class                 m_serviceClass;
   private String                m_portComponentName;
   private MetadataConfiguration m_metadataConfig;

   /**
    * DOCUMENT_ME
    *
    * @param jndiLocation DOCUMENT_ME
    */
   public void setCacheLocation( String jndiLocation )
   {
      m_cacheLocation = jndiLocation;
   }

   /**
    * DOCUMENT_ME
    *
    * @return DOCUMENT_ME
    */
   public String getCacheLocation(  )
   {
      return m_cacheLocation;
   }

   /**
    * DOCUMENT_ME
    *
    * @return DOCUMENT_ME
    */
   public abstract org.apache.ws.resource.NamespaceVersionHolder getNamespaceSet(  );

   /**
    * Returns the EndpointReference associated with this Resource. Only the required fields will be filled in (i.e.
    * Address) AND the ReferenceProperty for the ResourceKey (if not a singleton)
    * <p/>
    * If the resourceKey is not equal to null ( not a singleton ), the reference properties will contain the key.
    *
    * @param resourceId the resource identifier, or null if the resource is a singleton
    *
    * @return an EndpointReference (EPR) for the resource
    */
   public EndpointReference getEndpointReference( Object resourceId )
   {
      String endpointAddress =
         JaxRpcPlatform.getJaxRpcPlatform(  ).getEndpointUrl( WsrfRuntime.getRuntime(  ).getBaseWebappUrl(  )
                                                                         .toString(  ),
                                                              getServiceName(  ).getLocalPart(  ) );
      String wsAddressingURI = getNamespaceSet(  ).getAddressingNamespace(  );

      XmlBeansEndpointReference xBeansEPR = new XmlBeansEndpointReference( endpointAddress, wsAddressingURI );
      if ( resourceId != null )
      {
         XmlObject resourceIdRefParam = XmlBeanUtils.createElement( m_resourceIdRefParamName );
         XmlBeanUtils.setValue( resourceIdRefParam,
                                resourceId.toString(  ) );
         xBeansEPR.addReferenceParameter( resourceIdRefParam );
      }

      xBeansEPR.setPortTypeQName( getPortType(  ) );
      xBeansEPR.setServicePortName( getServicePortName(  ) );
      xBeansEPR.setServiceQName( getServiceName(  ) );
      return xBeansEPR;
   }

   /**
    * DOCUMENT_ME
    *
    * @return DOCUMENT_ME
    */
   public abstract QName getPortType(  );

   /**
    * DOCUMENT_ME
    *
    * @param config DOCUMENT_ME
    */
   public void setMetadataConfig( MetadataConfiguration config )
   {
      m_metadataConfig = config;
   }

   /**
    * DOCUMENT_ME
    *
    * @return DOCUMENT_ME
    */
   public MetadataConfiguration getMetadataConfig(  )
   {
      return m_metadataConfig;
   }

   /**
    * DOCUMENT_ME
    *
    * @param portComponentName DOCUMENT_ME
    */
   public void setPortComponentName( String portComponentName )
   {
      m_portComponentName = portComponentName;
   }

   /**
    * DOCUMENT_ME
    *
    * @return DOCUMENT_ME
    */
   public String getPortComponentName(  )
   {
      return m_portComponentName;
   }

   /**
    * DOCUMENT_ME
    *
    * @param resourceClass DOCUMENT_ME
    */
   public void setResourceClass( Class resourceClass )
   {
      if ( ( resourceClass != null ) && !Resource.class.isAssignableFrom( resourceClass ) )
      {
         throw new IllegalArgumentException( "Specified resource class '" + resourceClass.getName(  )
                                             + "' does not implement the " + Resource.class.getName(  )
                                             + " interface." );
      }

      m_resourceClass = resourceClass;
   }

   /**
    * DOCUMENT_ME
    *
    * @param resourceClassName DOCUMENT_ME
    *
    * @deprecated use {@link #setResourceClass(Class)} instead
    */
   public void setResourceClassName( String resourceClassName )
   {
      try
      {
         m_resourceClass = Class.forName( resourceClassName );
      }
      catch ( ClassNotFoundException cnfe )
      {
         throw new RuntimeException( cnfe );
      }
   }

   /**
    * DOCUMENT_ME
    *
    * @return DOCUMENT_ME
    */
   public String getResourceClassName(  )
   {
      return ( m_resourceClass != null ) ? m_resourceClass.getName(  ) : null;
   }

   /**
    * DOCUMENT_ME
    *
    * @param serviceClass
    */
   public void setServiceClass( Class serviceClass )
   {
      m_serviceClass = serviceClass;
   }

   /**
    * DOCUMENT_ME
    *
    * @param serviceClassName DOCUMENT_ME
    *
    * @deprecated use {@link #setServiceClass(Class)} instead
    */
   public void setServiceClassName( String serviceClassName )
   {
      try
      {
         m_serviceClass = Class.forName( serviceClassName );
      }
      catch ( ClassNotFoundException cnfe )
      {
         throw new RuntimeException( cnfe );
      }
   }

   /**
    * DOCUMENT_ME
    *
    * @return DOCUMENT_ME
    */
   public String getServiceClassName(  )
   {
      return ( m_serviceClass != null ) ? m_serviceClass.getName(  ) : null;
   }

   /**
    * DOCUMENT_ME
    *
    * @return DOCUMENT_ME
    */
   public abstract QName getServiceName(  );

   /**
    * DOCUMENT_ME
    *
    * @return DOCUMENT_ME
    */
   public abstract String getServicePortName(  );

   /**
    * Returns true if the home has been initialized, else false
    *
    * @return true if the home has been initialized, else false
    */
   public boolean isInitialized(  )
   {
      return m_initialized;
   }

   /**
    * DOCUMENT_ME
    *
    * @param name DOCUMENT_ME
    */
   public void setResourceIdentifierReferenceParameterName( String name )
   {
      m_resourceIdRefParamName = QName.valueOf( name );
   }

   /**
    * DOCUMENT_ME
    *
    * @return DOCUMENT_ME
    */
   public String getResourceIdentifierReferenceParameterName(  )
   {
      //case of singleton...
      if ( m_resourceIdRefParamName == null )
      {
         return null;
      }

      return m_resourceIdRefParamName.toString(  );
   }

   /**
    * DOCUMENT_ME
    *
    * @return DOCUMENT_ME
    */
   public QName getResourceIdentifierReferenceParameterQName(  )
   {
      return m_resourceIdRefParamName;
   }

   /**
    * DOCUMENT_ME
    *
    * @param delay DOCUMENT_ME
    */
   public void setSweeperDelay( long delay )
   {
      m_sweeperDelay = delay;
   }

   /**
    * DOCUMENT_ME
    *
    * @return DOCUMENT_ME
    */
   public long getSweeperDelay(  )
   {
      return m_sweeperDelay;
   }

   /**
    * DOCUMENT_ME
    *
    * @param targetNamespace DOCUMENT_ME
    */
   public void setWsdlTargetNamespace( String targetNamespace )
   {
      m_wsdlTargetNamespace = targetNamespace;
   }

   /**
    * DOCUMENT_ME
    *
    * @return DOCUMENT_ME
    */
   public String getWsdlTargetNamespace(  )
   {
      return m_wsdlTargetNamespace;
   }

   /**
    * @see ResourceHome#add(org.apache.ws.resource.Resource)
    */
   public boolean add( Resource resource )
   throws IllegalResourceTypeException
   {
      boolean resourceWasAdded = true;
      if ( !m_resourceClass.isAssignableFrom( resource.getClass(  ) ) )
      {
         throw new IllegalResourceTypeException( "This home only supports resources of type "
                                                 + m_resourceClass.getName(  ) );
      }

      if ( m_resources == null )
      {
         m_resources = getResourceMap(  ); // in case this.init() was never called for some reason
      }

      try
      {
         initEndpointReference( resource );
         resource.init(  );
      }
      catch ( RuntimeException re )
      {
         re.printStackTrace(  );
         throw new RuntimeException( MSG.getMessage( Keys.FAILED_TO_INIT_RESOURCE, resource, re ), re );
      }

      LOG.debug( MSG.getMessage( Keys.ADDING_RESOURCE_WITH_ID,
                                 resource.getID(  ),
                                 getClass(  ).getName(  ) ) );
      m_resources.put( getNonNullKey( resource.getID(  ) ),
                       resource );
      scheduleSweeperTask(  );
      notifyResourceCreatedListeners( resource );
      updateCache( resource );
      return resourceWasAdded;
   }

   /**
    * Adds a listener for ResourceCreationEvents
    *
    * @param listener
    */
   public void addResourceCreationListener( ResourceCreationListener listener )
   {
      m_creationListeners.add( listener );
   }

   /**
    * Adds a listener for ResourceDestructionEvents
    *
    * @param listener
    */
   public void addResourceDestructionListener( ResourceDestructionListener listener )
   {
      m_destructionListeners.add( listener );
   }

   /**
    * DOCUMENT_ME
    *
    * @param context DOCUMENT_ME
    *
    * @return DOCUMENT_ME
    */
   public Object extractResourceIdentifier( ResourceContext context )
   {
      if ( getResourceIdentifierReferenceParameterName(  ) == null )
      {
         return null;
      }

      try
      {
         SOAPHeader soapHeader          = context.getSOAPMessage(  ).getSOAPHeader(  );
         Iterator   resourceIdElemsIter =
            soapHeader.getChildElements( NameUtils.toName( getResourceIdentifierReferenceParameterQName(  ) ) );
         if ( !resourceIdElemsIter.hasNext(  ) )
         {
            throw new FaultException( Soap1_1Constants.FAULT_CLIENT,
                                      "The expected resource identifier reference parameter named "
                                      + getResourceIdentifierReferenceParameterName(  )
                                      + " was not found in the SOAP header." );
         }

         SOAPHeaderElement resourceIdElem = (SOAPHeaderElement) resourceIdElemsIter.next(  );
         if ( resourceIdElemsIter.hasNext(  ) )
         {
            throw new FaultException( Soap1_1Constants.FAULT_CLIENT,
                                      "More than one resource identifier reference parameter named "
                                      + getResourceIdentifierReferenceParameterName(  )
                                      + " was found in the SOAP header. Exactly one is expected." );
         }

         return resourceIdElem.getValue(  );
      }
      catch ( SOAPException soape )
      {
         throw new JAXRPCException( soape );
      }
   }

   /**
    * DOCUMENT_ME
    *
    * @param epr the endpoint reference of a WS-Resource
    *
    * @return DOCUMENT_ME
    */
   public Object extractResourceIdentifier( EndpointReference epr )
   {
      QName resourceIdElemName = getResourceIdentifierReferenceParameterQName(  );
      if ( resourceIdElemName == null ) // singletons have a null id
      {
         return null;
      }

      String resourceId = null;
      if ( resourceIdElemName != null )
      {
         Object[] refProps = epr.getReferenceProperties(  );
         for ( int i = 0; i < refProps.length; i++ )
         {
            XmlObject refPropXBean = (XmlObject) refProps[i];
            if ( XmlBeanUtils.getName( refPropXBean ).equals( resourceIdElemName ) )
            {
               resourceId = XmlBeanUtils.getValue( refPropXBean );
            }
         }

         if ( resourceId == null )
         {
            Object[] refParams = epr.getReferenceParameters(  );
            for ( int i = 0; i < refParams.length; i++ )
            {
               XmlObject refParamXBean = (XmlObject) refParams[i];
               if ( XmlBeanUtils.getName( refParamXBean ).equals( resourceIdElemName ) )
               {
                  resourceId = XmlBeanUtils.getValue( refParamXBean );
               }
            }
         }

         if ( resourceId == null )
         {
            throw new FaultException( Soap1_1Constants.FAULT_CLIENT,
                                      "The expected resource identifier reference parameter named "
                                      + getResourceIdentifierReferenceParameterName(  )
                                      + " was not found in the SOAP header." );
         }
      }

      return resourceId;
   }

   /**
    * @see ResourceHome#find(Object)
    */
   public Resource find( Object resourceId )
   throws ResourceUnknownException,
          ResourceException
   {
      LOG.debug( MSG.getMessage( Keys.FINDING_RESOURCE_WITH_KEY,
                                 String.valueOf( resourceId ) ) );
      Resource resource = null;
      synchronized ( m_resources )
      {
         //Lock lock = acquireLock( resourceId );
         //try
         //{
         resource = get( resourceId );
         updateCache( resource );

         //}
         //finally
         //{
         //    lock.release();
         //}
      }

      return resource;
   }

   /**
    * Initializes this home. Should be called <em>after</em> setters have been called on all bean properties.
    *
    * @throws Exception on error
    */
   public void init(  )
   throws Exception
   {
      synchronized ( this )
      {
         if ( m_initialized )
         {
            return;
         }

         LOG.debug( MSG.getMessage( Keys.INIT_HOME ) );
         if ( m_resourceClass == null )
         {
            throw new ResourceException( "The resourceClass property of this home is not defined." );
         }

         if ( PersistentResource.class.isAssignableFrom( m_resourceClass ) )
         {
            m_resourceIsPersistent = true;
         }

         Context initialContext = new InitialContext(  );
         m_resources      = getResourceMap(  );
         m_lockManager    = new LockManager(  );
         if ( ScheduledResourceTerminationResource.class.isAssignableFrom( m_resourceClass ) )
         {
            initSweeper( initialContext );
         }

         initCachePolicy( new InitialContext(  ) );
         m_initialized = true;
      }
   }

   /**
    * @see ResourceHome#remove(Object)
    */
   public void remove( Object resourceId )
   throws ResourceUnknownException,
          ResourceException
   {
      Resource resource = null;
      Lock     lock = acquireLock( resourceId );
      try
      {
         resource = get( resourceId );

         try
         {
            resource.destroy(  );
         }
         catch ( RuntimeException re )
         {
            throw new ResourceException( MSG.getMessage( Keys.FAILED_TO_DESTROY_RESOURCE, resource, re ) );
         }

         Resource removedResource = (Resource) m_resources.remove( getNonNullKey( resourceId ) );
         if ( removedResource instanceof PropertiesResource )
         {
            notifyResourceDeletedListeners( removedResource );
         }

         LOG.debug( MSG.getMessage( Keys.REMOVED_RESOURCE_WITH_KEY,
                                    resource.getClass(  ).getName(  ),
                                    String.valueOf( resourceId ) ) );
         if ( m_cache != null )
         {
            m_cache.remove( resource );
         }
      }
      finally
      {
         lock.release(  );
      }
   }

   /**
    * Removes a listener for ResourceCreationEvents
    *
    * @param listener
    *
    * @return true if the listener was removed, else false
    */
   public boolean removeResourceCreationListener( ResourceCreationListener listener )
   {
      return m_creationListeners.remove( listener );
   }

   /**
    * Removes a listener for ResourceDestructionEvents
    *
    * @param listener
    *
    * @return true if the listener was removed, else false
    */
   public boolean removeResourceDestructionListener( ResourceDestructionListener listener )
   {
      return m_destructionListeners.remove( listener );
   }

   /**
    * DOCUMENT_ME
    *
    * @return DOCUMENT_ME
    */
   protected abstract Map getResourceMap(  );

   /**
    * This method uses reflection to create an instance of a Resource which contains an empty constructor.  It will not
    * work with Resources which do not have an empty constructor.
    * <p/>
    * Note: the returned Resource will an EndpointReference associated with it.
    *
    * @param id the resource identifier
    *
    * @return a resource of the type associated with this home
    *
    * @throws ResourceException
    */
   protected Resource createInstance( Object id )
   throws ResourceException
   {
      LOG.debug( MSG.getMessage( Keys.CREATING_RESOURCE_WITH_ID, id ) );
      Resource resource = createInstanceViaSpringBeanFactory(  );
      if ( resource == null )
      {
         resource = createInstanceViaReflection(  );
      }

      if ( resource.getID(  ) == null )
      {
         resource.setID( id );
      }

      return resource;
   }

   /**
    * DOCUMENT_ME
    *
    * @param id DOCUMENT_ME
    *
    * @return DOCUMENT_ME
    *
    * @throws ResourceException DOCUMENT_ME
    */
   protected Resource createNewInstanceAndLoad( Object id )
   throws ResourceException
   {
      Resource resource = createInstance( id );
      LOG.debug( MSG.getMessage( Keys.LOADING_RESOURCE_FROM_PERSISTENCE,
                                 String.valueOf( id ) ) );
      ( (PersistentResource) resource ).load(  );
      if ( ResourceSweeper.isExpired( resource ) )
      {
         throw new ResourceUnknownException( getNonNullKey( id ),
                                             getServicePortName(  ) );
      }

      return resource;
   }

   /**
    * Creates a synschronized map for storing {@link Resource}s. If the resource is persistent, a {@link ReferenceMap}
    * is used, otherwise a {@link HashMap} is used. Provided for the convenience of subclasses, which are responsible
    * for creating a map of resources and maintaining a static reference to that map.
    *
    * @param isPersistent if the resource is persistent
    *
    * @return a synschronized map for storing {@link Resource}s
    */
   protected static Map createResourceMap( boolean isPersistent )
   {
      Map resourceMap;
      if ( isPersistent )
      {
         resourceMap = new ReferenceMap( ReferenceMap.HARD, ReferenceMap.SOFT, true );
      }
      else
      {
         resourceMap = new HashMap(  );
      }

      return Collections.synchronizedMap( resourceMap );
   }

   /**
    * DOCUMENT_ME
    *
    * @param initialContext DOCUMENT_ME
    *
    * @throws NamingException DOCUMENT_ME
    */
   protected void initCachePolicy( Context initialContext )
   throws NamingException
   {
      if ( m_cacheLocation != null )
      {
         m_cache = (Cache) XmlBeanJndiUtils.lookup( initialContext, m_cacheLocation, Cache.class );
      }
   }

   /**
    * DOCUMENT_ME
    *
    * @param obj DOCUMENT_ME
    *
    * @return DOCUMENT_ME
    */
   Object getNonNullKey( Object obj )
   {
      return ( obj != null ) ? obj : SINGLETON_KEY;
   }

   private TimerManager getTimerManager( Context initialContext )
   {
      TimerManager timerManager;
      try
      {
         timerManager = (TimerManager) initialContext.lookup( CONTEXT_NAME_J2EE_TIMER_MANAGER );
      }
      catch ( NamingException ne )
      {
         try
         {
            timerManager = (TimerManager) initialContext.lookup( JndiConstants.CONTEXT_NAME_DEFAULT_TIMER );
         }
         catch ( NamingException ne2 )
         {
            timerManager = new TimerManagerImpl(  );
         }
      }

      LOG.debug( MSG.getMessage( Keys.TIMER_MANAGER_IMPL,
                                 timerManager.getClass(  ).getName(  ) ) );
      return timerManager;
   }

   private Lock acquireLock( Object resourceId )
   throws ResourceException
   {
      Lock lock = m_lockManager.getLock( getNonNullKey( resourceId ) );
      try
      {
         lock.acquire(  );
      }
      catch ( InterruptedException ie )
      {
         throw new ResourceException( ie );
      }

      return lock;
   }

   private Resource createInstanceViaReflection(  )
   throws ResourceException
   {
      Resource resource;
      try
      {
         resource = (Resource) m_resourceClass.newInstance(  );
      }
      catch ( Exception e )
      {
         throw new ResourceException( e );
      }

      return resource;
   }

   private Resource createInstanceViaSpringBeanFactory(  )
   throws ResourceException
   {
      Resource            resource    = null;
      ListableBeanFactory beanFactory = WsrfRuntime.getRuntime(  ).getBeanFactory(  );
      if ( beanFactory != null )
      {
         String[] beanDefNames = beanFactory.getBeanNamesForType( m_resourceClass );
         if ( beanDefNames.length != 0 )
         {
            if ( beanDefNames.length > 1 )
            {
               LOG.warn( "More than one bean definition found for resource of type " + m_resourceClass.getName(  ) );
            }

            try
            {
               resource = (Resource) beanFactory.getBean( beanDefNames[0], m_resourceClass );
            }
            catch ( BeansException be )
            {
               throw new ResourceException( "Failed to instantiate " + getResourceClassName(  )
                                            + " resource via Spring bean factory.", be );
            }
         }
      }

      return resource;
   }

   private Resource get( Object resourceId )
   throws ResourceException
   {
      LOG.debug( MSG.getMessage( Keys.GETTING_RESOURCE_WITH_ID,
                                 resourceId,
                                 getClass(  ).getName(  ) ) );
      Resource resource = (Resource) m_resources.get( getNonNullKey( resourceId ) );
      if ( resource == null )
      {
         if ( !m_resourceIsPersistent )
         {
            throw new ResourceUnknownException( resourceId,
                                                getServicePortName(  ) );
         }

         add( createNewInstanceAndLoad( resourceId ) );
      }

      return resource;
   }

   private void initEndpointReference( Resource resource )
   {
      if ( resource.getEndpointReference(  ) == null )
      {
         resource.setEndpointReference( getEndpointReference( resource.getID(  ) ) );
      }
   }

   private void initSweeper( Context initialContext )
   {
      m_sweeper = new Sweeper( this,
                               m_resources,
                               getTimerManager( initialContext ),
                               m_sweeperDelay );
   }

   /**
    * This method is used to notify listeners a resource has been created.
    *
    * @param resource The Resource which was created
    */
   private void notifyResourceCreatedListeners( Resource resource )
   {
      for ( int i = 0; i < m_creationListeners.size(  ); i++ )
      {
         ResourceCreationListener resourceCreationListener =
            (ResourceCreationListener) m_creationListeners.get( i );
         resourceCreationListener.creationOccurred( new ResourceCreationEvent( resource ) );
      }
   }

   /**
    * This method is used to notify listeners a resource has been deleted.
    *
    * @param resource The EndpointReference for the Resource which was created
    */
   private void notifyResourceDeletedListeners( Resource resource )
   {
      for ( int i = 0; i < m_destructionListeners.size(  ); i++ )
      {
         ResourceDestructionListener resourceDestructionListener =
            (ResourceDestructionListener) m_destructionListeners.get( i );
         ResourceDestructionEvent    event = new ResourceDestructionEvent( resource );
         resourceDestructionListener.destructionOccurred( event );
      }
   }

   private void scheduleSweeperTask(  )
   {
      if ( m_sweeper != null )
      {
         m_sweeper.schedule(  );
      }
   }

   private void updateCache( Resource resource )
   {
      if ( m_cache != null )
      {
         m_cache.update( resource );
      }
   }

   /**
    * This ResourceSweeper implementation just returns the resources currently stored in the map. The reason is that
    * the sweeper doesn't have to reactivate/reload a persistent resource if the resource object was reclaimed. So
    * lifetime checks are not done on reclained resources. Lifetime checks have to be done on resource load.
    */
   private static class Sweeper
      extends ResourceSweeper
   {
      private TimerManager m_timerManager;
      private Timer        m_timer;
      private long         m_delay;

      /**
       * Creates a new {@link Sweeper} object.
       *
       * @param home         DOCUMENT_ME
       * @param resources    DOCUMENT_ME
       * @param timerManager DOCUMENT_ME
       * @param delay        DOCUMENT_ME
       */
      public Sweeper( ResourceHome home,
                      Map          resources,
                      TimerManager timerManager,
                      long         delay )
      {
         super( home, resources );
         m_timerManager    = timerManager;
         m_delay           = delay;
      }

      /**
       * DOCUMENT_ME
       *
       * @param timer DOCUMENT_ME
       */
      public void timerExpired( Timer timer )
      {
         super.timerExpired( timer );
         cancel(  );
         if ( !m_resources.isEmpty(  ) )
         {
            schedule(  );
         }
      }

      /**
       * Schedules this resource sweeper.
       */
      synchronized void schedule(  )
      {
         if ( m_timer == null )
         {
            LOG.debug( MSG.getMessage( Keys.SCHEDULE_RESOURCE_SWEEPER ) );
            m_timer = m_timerManager.schedule( this, m_delay );
         }
      }

      /**
       * Cancels this resource sweeper.
       */
      private synchronized void cancel(  )
      {
         if ( m_timer != null )
         {
            LOG.debug( MSG.getMessage( Keys.CANCEL_RESOURCE_SWEEPER ) );
            m_timer = null;
         }
      }
   }
}
TOP

Related Classes of org.apache.ws.resource.impl.AbstractResourceHome

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.