Package org.jboss.cache.invocation

Source Code of org.jboss.cache.invocation.CacheInvocationDelegate

package org.jboss.cache.invocation;

import org.apache.commons.logging.LogFactory;
import org.jboss.cache.*;
import org.jboss.cache.buddyreplication.BuddyManager;
import org.jboss.cache.buddyreplication.GravitateResult;
import org.jboss.cache.config.Configuration;
import org.jboss.cache.config.Option;
import org.jboss.cache.factories.InterceptorChainFactory;
import org.jboss.cache.factories.annotations.Inject;
import org.jboss.cache.interceptors.Interceptor;
import org.jboss.cache.loader.CacheLoaderManager;
import org.jboss.cache.marshall.Marshaller;
import org.jboss.cache.marshall.MethodCall;
import org.jboss.cache.marshall.MethodCallFactory;
import org.jboss.cache.marshall.MethodDeclarations;
import org.jboss.cache.notifications.Notifier;
import org.jboss.cache.statetransfer.StateTransferManager;
import org.jboss.cache.transaction.GlobalTransaction;
import org.jboss.cache.transaction.TransactionTable;
import org.jgroups.Address;

import javax.transaction.Transaction;
import javax.transaction.TransactionManager;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
* The delegate that users (and interceptor authors) interact with when they create a cache by using a cache factory.
* This wrapper delegates calls down the interceptor chain.
*
* @author Manik Surtani (<a href="mailto:manik@jboss.org">manik@jboss.org</a>)
* @since 2.1.0
*/
@SuppressWarnings("unchecked")
public class CacheInvocationDelegate<K, V> extends AbstractInvocationDelegate implements CacheSPI<K, V>
{

   // this stuff is needed since the SPI has methods to retrieve these.
   private StateTransferManager stateTransferManager;
   private CacheLoaderManager cacheLoaderManager;
   private Notifier notifier;
   private TransactionManager transactionManager;
   private BuddyManager buddyManager;
   private TransactionTable transactionTable;
   private RPCManager rpcManager;
   private RegionManager regionManager;
   private Marshaller marshaller;

   public CacheInvocationDelegate()
   {
      log = LogFactory.getLog(CacheInvocationDelegate.class);
   }

   @Inject
   private void injectDependencies(StateTransferManager stateTransferManager, CacheLoaderManager cacheLoaderManager, Notifier notifier,
                                   TransactionManager transactionManager, BuddyManager buddyManager, TransactionTable transactionTable,
                                   RPCManager rpcManager, RegionManager regionManager, Marshaller marshaller)
   {
      this.stateTransferManager = stateTransferManager;
      this.cacheLoaderManager = cacheLoaderManager;
      this.notifier = notifier;
      this.transactionManager = transactionManager;
      this.buddyManager = buddyManager;
      this.transactionTable = transactionTable;
      this.rpcManager = rpcManager;
      this.regionManager = regionManager;
      this.marshaller = marshaller;
   }

   private void reset()
   {
      this.stateTransferManager = null;
      this.cacheLoaderManager = null;
      this.transactionManager = null;
      this.buddyManager = null;
      this.transactionTable = null;
      this.rpcManager = null;
      this.marshaller = null;
   }

   @Override
   public String toString()
   {
      return cache == null ? super.toString() : cache.toString();
   }

   public Configuration getConfiguration()
   {
      return configuration;
   }

   public NodeSPI<K, V> getRoot()
   {
      return (NodeSPI<K, V>) cache.getRoot();
   }

   public TransactionManager getTransactionManager()
   {
      return transactionManager;
   }

   public List<Interceptor> getInterceptorChain()
   {
      List interceptors = InterceptorChainFactory.asList(interceptorChain);
      return interceptors == null ? Collections.emptyList() : Collections.unmodifiableList(interceptors);
   }

   public void addInterceptor(Interceptor i, int position)
   {
      cache.addInterceptor(i, position);
   }

   public void addInterceptor(Interceptor i, Class<? extends Interceptor> afterInterceptor)
   {
      cache.addInterceptor(i, afterInterceptor);
   }

   public void removeInterceptor(int position)
   {
      cache.removeInterceptor(position);
   }

   public void removeInterceptor(Class<? extends Interceptor> interceptorType)
   {
      cache.removeInterceptor(interceptorType);
   }

   public CacheLoaderManager getCacheLoaderManager()
   {
      return cacheLoaderManager;
   }

   public BuddyManager getBuddyManager()
   {
      return buddyManager;
   }

   public TransactionTable getTransactionTable()
   {
      return transactionTable;
   }

   public RPCManager getRPCManager()
   {
      return rpcManager;
   }

   public StateTransferManager getStateTransferManager()
   {
      return stateTransferManager;
   }

   public String getClusterName()
   {
      return cache.getClusterName();
   }

   public int getNumberOfAttributes()
   {
      return cache.getNumberOfAttributes();
   }

   public int getNumberOfNodes()
   {
      return cache.getNumberOfNodes();
   }

   public RegionManager getRegionManager()
   {
      return regionManager;
   }

   public GlobalTransaction getCurrentTransaction(Transaction tx, boolean createIfNotExists)
   {
      return cache.getCurrentTransaction(tx, createIfNotExists);
   }

   public GlobalTransaction getCurrentTransaction()
   {
      return cache.getCurrentTransaction();
   }

   public Set<Fqn> getInternalFqns()
   {
      return cache.getInternalFqns();
   }

   public int getNumberOfLocksHeld()
   {
      return cache.getNumberOfLocksHeld();
   }

   public boolean exists(String fqn)
   {
      return exists(Fqn.fromString(fqn));
   }

   public boolean exists(Fqn<?> fqn)
   {
      return peek(fqn, false, false) != null;
   }

   public Notifier getNotifier()
   {
      return notifier;
   }

   public Marshaller getMarshaller()
   {
      return marshaller;
   }

   public GravitateResult gravitateData(Fqn fqn, boolean searchBuddyBackupSubtrees)
   {
      return cache.gravitateData(fqn, searchBuddyBackupSubtrees);
   }

   public NodeSPI<K, V> peek(Fqn fqn, boolean includeDeletedNodes, boolean includeInvalidNodes)
   {
      return (NodeSPI<K, V>) cache.peek(fqn, includeDeletedNodes, includeInvalidNodes);
   }

   public NodeSPI<K, V> peek(Fqn fqn, boolean includeDeletedNodes)
   {
      return (NodeSPI<K, V>) cache.peek(fqn, includeDeletedNodes);
   }

   public void addCacheListener(Object listener)
   {
      notifier.addCacheListener(listener);
   }

   public void removeCacheListener(Object listener)
   {
      notifier.removeCacheListener(listener);
   }

   public Set<Object> getCacheListeners()
   {
      return notifier.getCacheListeners();
   }

   public void create() throws CacheException
   {
      cache.create();
   }

   public void start() throws CacheException
   {
      cache.start();
   }

   public void stop()
   {
      cache.stop();
   }

   public void destroy()
   {
      reset();
      cache.destroy();
   }

   public CacheStatus getCacheStatus()
   {
      return cache == null ? null : cache.getCacheStatus();
   }

   public InvocationContext getInvocationContext()
   {

      assertIsConstructed();
      return invocationContextContainer.get();
   }

   public void setInvocationContext(InvocationContext ctx)
   {
      assertIsConstructed();

      // assume a null ctx is meant to "un-set" the context?
      if (ctx == null) invocationContextContainer.remove();
      else invocationContextContainer.set(ctx);
   }

   public Address getLocalAddress()
   {
      if (rpcManager == null) return null;
      return rpcManager.getLocalAddress();
   }

   public List<Address> getMembers()
   {
      if (rpcManager == null) return null;
      return rpcManager.getMembers();
   }

   public String getVersion()
   {
      return Version.printVersion();
   }

   public void move(Fqn<?> nodeToMove, Fqn<?> newParent) throws NodeNotExistsException
   {
      MethodCall m = MethodCallFactory.create(MethodDeclarations.moveMethodLocal_id, nodeToMove, newParent);
      invoke(m);
   }

   public void move(String nodeToMove, String newParent) throws NodeNotExistsException
   {
      move(Fqn.fromString(nodeToMove), Fqn.fromString(newParent));
   }

   public boolean removeRegion(Fqn fqn)
   {
      return regionManager.removeRegion(fqn);
   }

   public Region getRegion(Fqn fqn, boolean createIfAbsent)
   {
      return regionManager.getRegion(fqn, createIfAbsent);
   }

   public void evict(Fqn<?> fqn, boolean recursive)
   {
      if (!getCacheStatus().allowInvocations()) throw new IllegalStateException("Cache is not in STARTED state");
      //this method should be called by eviction thread only, so no transaction - expected (sec param is false)
      Node<K, V> node = peek(fqn, false);
      if (node != null && node.isResident())
      {
         return;
      }
      if (recursive)
      {
         if (node != null)
         {
            evictChildren((NodeSPI<K, V>) node);
         }
      }
      else
      {
         evict(fqn);
      }
   }

   private void evictChildren(NodeSPI<K, V> n)
   {
      for (NodeSPI<K, V> child : n.getChildrenDirect())
      {
         evictChildren(child);
      }
      evict(n.getFqn());
   }

   public void evict(Fqn<?> fqn)
   {
      Node<K, V> node = peek(fqn, false);
      if (node != null && node.isResident())
      {
         return;
      }
      if (fqn.isRoot())
      {
         // special treatment for root eviction
         // we need to preserve options
         InvocationContext ctx = getInvocationContext();
         Option o = ctx.getOptionOverrides();
         for (Object childName : cache.peek(fqn, false, false).getChildrenNames())
         {
            ctx.setOptionOverrides(o);
            evict(new Fqn<Object>(fqn, childName));
         }
      }
      else
      {
         MethodCall m = MethodCallFactory.create(MethodDeclarations.evictNodeMethodLocal_id, fqn);
         invoke(m);
      }
   }

   public V get(Fqn<?> fqn, K key)
   {
      MethodCall m = MethodCallFactory.create(MethodDeclarations.getKeyValueMethodLocal_id, fqn, key, true);
      return (V) invoke(m);
   }

   public V get(String fqn, K key)
   {
      return get(Fqn.fromString(fqn), key);
   }

   public boolean removeNode(Fqn<?> fqn)
   {
      GlobalTransaction tx = cache.getCurrentTransaction();
      // special case if we are removing the root.  Remove all children instead.
      if (fqn.isRoot())
      {
         boolean result = true;
         // we need to preserve options
         InvocationContext ctx = getInvocationContext();
         Option o = ctx.getOptionOverrides();
         Set<Fqn> internalFqns = getInternalFqns();
         for (Object childName : peek(fqn, false, false).getChildrenNames())
         {
            if (!internalFqns.contains(new Fqn(childName)))
            {
               ctx.setOptionOverrides(o);
               result = removeNode(new Fqn<Object>((Fqn<Object>) fqn, childName)) && result;
            }
         }

         return result;
      }
      else
      {
         MethodCall m = MethodCallFactory.create(MethodDeclarations.removeNodeMethodLocal_id, tx, fqn, true, false);
         Object retval = invoke(m);
         return retval != null && (Boolean) retval;
      }

   }

   public boolean removeNode(String fqn)
   {
      return removeNode(Fqn.fromString(fqn));
   }

   public NodeSPI<K, V> getNode(Fqn<?> fqn)
   {
      MethodCall m = MethodCallFactory.create(MethodDeclarations.getNodeMethodLocal_id, fqn);
      return (NodeSPI) invoke(m);
   }

   public NodeSPI<K, V> getNode(String fqn)
   {
      return getNode(Fqn.fromString(fqn));
   }

   public V remove(Fqn<?> fqn, K key) throws CacheException
   {
      GlobalTransaction tx = cache.getCurrentTransaction();
      MethodCall m = MethodCallFactory.create(MethodDeclarations.removeKeyMethodLocal_id, tx, fqn, key, true);
      return (V) invoke(m);
   }

   public V remove(String fqn, K key)
   {
      return remove(Fqn.fromString(fqn), key);
   }

   public void put(Fqn<?> fqn, Map<K, V> data)
   {
      GlobalTransaction tx = cache.getCurrentTransaction();
      MethodCall m = MethodCallFactory.create(MethodDeclarations.putDataMethodLocal_id, tx, fqn, data, true);
      invoke(m);
   }

   public void put(String fqn, Map<K, V> data)
   {
      put(Fqn.fromString(fqn), data);
   }

   public void putForExternalRead(Fqn<?> fqn, K key, V value)
   {
      // if the node exists then this should be a no-op.
      if (peek(fqn, false, false) == null)
      {
         getInvocationContext().getOptionOverrides().setFailSilently(true);
         getInvocationContext().getOptionOverrides().setForceAsynchronous(true);
         //GlobalTransaction tx = cache.getCurrentTransaction();
         MethodCall m = MethodCallFactory.create(MethodDeclarations.putForExternalReadMethodLocal_id, null, fqn, key, value);
         invoke(m);
      }
      else
      {
         if (log.isDebugEnabled())
            log.debug("putForExternalRead() called with Fqn " + fqn + " and this node already exists.  This method is hence a no op.");
      }
   }

   public V put(Fqn<?> fqn, K key, V value)
   {
      GlobalTransaction tx = cache.getCurrentTransaction();
      MethodCall m = MethodCallFactory.create(MethodDeclarations.putKeyValMethodLocal_id, tx, fqn, key, value, true);
      return (V) invoke(m);
   }

   public V put(String fqn, K key, V value)
   {
      return put(Fqn.fromString(fqn), key, value);
   }

   public Set<Object> getCacheListeners(Fqn region)
   {
      throw new UnsupportedOperationException("Not implemented in this release");
   }

   public void removeCacheListener(Fqn region, Object listener)
   {
      throw new UnsupportedOperationException("Not implemented in this release");
   }

   public void addCacheListener(Fqn region, Object listener)
   {
      throw new UnsupportedOperationException("Not implemented in this release");
   }

   /**
    * Retrieves a defensively copied data map of the underlying node.
    *
    * @param fqn
    * @return map of data, or an empty map
    * @throws CacheException
    */
   public Map<K, V> getData(Fqn<?> fqn)
   {
      MethodCall m = MethodCallFactory.create(MethodDeclarations.getDataMapMethodLocal_id, fqn);
      return (Map<K, V>) invoke(m);
   }

   /**
    * Returns a set of attribute keys for the Fqn.
    * Returns null if the node is not found, otherwise a Set.
    * The set is a copy of the actual keys for this node.
    *
    * @param fqn name of the node
    */
   public Set getKeys(String fqn)
   {
      return getKeys(Fqn.fromString(fqn));
   }

   /**
    * Returns a set of attribute keys for the Fqn.
    * Returns null if the node is not found, otherwise a Set.
    * The set is a copy of the actual keys for this node.
    *
    * @param fqn name of the node
    */
   public Set<K> getKeys(Fqn<?> fqn)
   {
      MethodCall m = MethodCallFactory.create(MethodDeclarations.getKeysMethodLocal_id, fqn);
      return (Set<K>) invoke(m);
   }

   /**
    * Removes the keys and properties from a node.
    */
   public void clearData(String fqn) throws CacheException
   {
      clearData(Fqn.fromString(fqn));
   }

   /**
    * Removes the keys and properties from a named node.
    */
   public void clearData(Fqn fqn)
   {
      GlobalTransaction tx = getCurrentTransaction();
      MethodCall m = MethodCallFactory.create(MethodDeclarations.removeDataMethodLocal_id, tx, fqn, true);
      invoke(m);
   }

   /**
    * Returns all children of a given node.  Returns an empty set if there are no children.
    * The set is unmodifiable.
    *
    * @param fqn The fully qualified name of the node
    * @return Set an unmodifiable set of children names, Object.
    */
   public <E> Set<E> getChildrenNames(Fqn<E> fqn)
   {
      MethodCall m = MethodCallFactory.create(MethodDeclarations.getChildrenNamesMethodLocal_id, fqn);
      Set<E> retval = null;
      retval = (Set<E>) invoke(m);
      if (retval != null)
         retval = Collections.unmodifiableSet(new HashSet<E>(retval));
      else
         retval = Collections.emptySet();
      return retval;
   }

   public Set getChildrenNames(String fqn)
   {
      return getChildrenNames(Fqn.fromString(fqn));
   }

   public CacheImpl getDelegationTarget()
   {
      return cache;
   }
}
TOP

Related Classes of org.jboss.cache.invocation.CacheInvocationDelegate

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.