FileDocCategorySizeDatePackage
DistributedStateImpl.javaAPI DocJBoss 4.2.115621Fri Jul 13 20:52:38 BST 2007org.jboss.ha.framework.server

DistributedStateImpl

public class DistributedStateImpl extends Object implements org.jboss.ha.framework.interfaces.HAPartition.HAPartitionStateTransfer, DistributedStateImplMBean
This class manages distributed state across the cluster.
author
Sacha Labourey.
author
Bill Burke.
author
Scott.Stark@jboss.org
version
$Revision: 57188 $

Fields Summary
protected static final String
SERVICE_NAME
protected static final Class[]
set_types
protected static final Class[]
remove_types
protected HashMap
categories
HashMap. Keys= category, value = HashMap
protected HashMap
keyListeners
protected org.jboss.ha.framework.interfaces.HAPartition
partition
protected Logger
log
protected MBeanServer
mbeanServer
protected String
name
Constructors Summary
public DistributedStateImpl()


   // Static --------------------------------------------------------c

   // Constructors --------------------------------------------------

      
public DistributedStateImpl(org.jboss.ha.framework.interfaces.HAPartition partition, MBeanServer server)

      this.partition = partition;
      this.mbeanServer = server;
      this.log = Logger.getLogger (this.getClass ());
   
Methods Summary
public void_remove(java.lang.String category, java.lang.String key)

      Serializable removed = this._removeInternal (category, key);
      notifyKeyListenersOfRemove (category, key, removed, false);
   
public void_remove(java.lang.String category, java.io.Serializable key)

      Serializable removed = this._removeInternal (category, key);
      notifyKeyListenersOfRemove (category, key, removed, false);
   
public java.io.Serializable_removeInternal(java.lang.String category, java.io.Serializable key)

      synchronized(this.categories)
      {
         HashMap cat = (HashMap)categories.get (category);
         if (cat == null) return null;
         Object removed = cat.remove (key);
         if (removed != null)
         {
            if (cat.size () == 0)
            {
               categories.remove (category);
            }
         }
         return (Serializable)removed;
      }
   
public void_set(java.lang.String category, java.lang.String key, java.io.Serializable value)

      this._setInternal (category, key, value);
      notifyKeyListeners (category, key, value, false);
   
public void_set(java.lang.String category, java.io.Serializable key, java.io.Serializable value)

      this._setInternal (category, key, value);
      notifyKeyListeners (category, key, value, false);
   
public void_setInternal(java.lang.String category, java.io.Serializable key, java.io.Serializable value)

      synchronized(this.categories)
      {
         HashMap cat = (HashMap)categories.get (category);
         if (cat == null)
         {
            cat = new HashMap ();
            categories.put (category, cat);
         }
         cat.put (key, value);
      }
   
protected voidcleanupKeyListeners()

      // NOT IMPLEMENTED YET
   
public voiddestroy()

      Registry.unbind (this.name);
      ObjectName jmxName = new ObjectName(this.name);
      mbeanServer.unregisterMBean (jmxName);
      
      partition.unsubscribeFromStateTransferEvents (SERVICE_NAME, this);
      partition.unregisterRPCHandler(SERVICE_NAME, this);
   
public java.io.Serializableget(java.lang.String category, java.io.Serializable key)

      synchronized(this.categories)
      {
         HashMap cat = (HashMap)categories.get (category);
         if (cat == null) return null;

         return (Serializable)cat.get (key);
      }
   
public java.util.CollectiongetAllCategories()

      synchronized(this.categories)
      {
         return Collections.unmodifiableCollection(categories.keySet ());
      }
   
public java.util.CollectiongetAllKeys(java.lang.String category)

      synchronized(this.categories)
      {
         HashMap cat = (HashMap)categories.get (category);
         if (cat == null) return null;

         return Collections.unmodifiableCollection(cat.keySet ());
      }
   
public java.util.CollectiongetAllValues(java.lang.String category)

      synchronized(this.categories)
      {
         HashMap cat = (HashMap)categories.get (category);
         if (cat == null) return null;

         return Collections.unmodifiableCollection(cat.values ());
      }
   
public java.io.SerializablegetCurrentState()

      HashMap retval=new HashMap();
      Map.Entry entry;
      String catName;
      HashMap value, newVal;

      synchronized(this.categories)
      {

         for(Iterator it=this.categories.entrySet().iterator(); it.hasNext();)
         {
            entry=(Map.Entry)it.next(); // key: category name, value: HashMap
            catName=(String)entry.getKey();
            value=(HashMap)entry.getValue();
            newVal=value != null? (HashMap)value.clone() : null;
            retval.put(catName, newVal);
         }

         return retval;
      }
   
public voidinit()

      // When we subscribe to state transfer events, GetState will be called to initialize
      // this service.
      partition.subscribeToStateTransferEvents (SERVICE_NAME, this);
      partition.registerRPCHandler (SERVICE_NAME, this);

      // subscribed this "sub-service" of HAPartition with JMX
      // TODO: In the future (when state transfer issues will be completed),
      // we will need to redesign the way HAPartitions and its sub-protocols are
      // registered with JMX. They will most probably be independant JMX services.
      //
      this.name = "jboss:service=" + SERVICE_NAME +
                    ",partitionName=" + this.partition.getPartitionName();
      ObjectName jmxName = new ObjectName(this.name);
      mbeanServer.registerMBean(this, jmxName);
      Registry.bind (this.name, this);
   
public java.lang.StringlistContent()

      StringBuffer result = new StringBuffer ();
      Collection cats = this.getAllCategories ();
      Iterator catsIter = cats.iterator ();
      while (catsIter.hasNext ())
      {
         String category = (String)catsIter.next ();
         Iterator keysIter = this.getAllKeys(category).iterator ();

         result.append ("-----------------------------------------------\n");
         result.append ("Category : ").append (category).append ("\n\n");
         result.append ("KEY\t:\tVALUE\n");

         while (keysIter.hasNext ())
         {
            Serializable key = (Serializable) keysIter.next ();
            String value = this.get (category, key).toString ();
            result.append ("'").append(key);
            result.append ("'\t:\t'");
            result.append (value);
            result.append("'\n");
         }
         result.append ("\n");
      }
      return result.toString ();
   
public java.lang.StringlistXmlContent()

      StringBuffer result = new StringBuffer ();
      Collection cats = this.getAllCategories ();
      Iterator catsIter = cats.iterator ();

      result.append ("<DistributedState>\n");

      while (catsIter.hasNext ())
      {
         String category = (String)catsIter.next ();
         Iterator keysIter = this.getAllKeys(category).iterator ();

         result.append ("\t<Category>\n");
         result.append ("\t\t<CategoryName>").append (category).append ("</CategoryName>\n");

         while (keysIter.hasNext ())
         {
            Serializable key = (Serializable) keysIter.next ();
            String value = this.get (category, key).toString ();
            result.append ("\t\t<Entry>\n");
            result.append ("\t\t\t<Key>").append (key).append ("</Key>\n");
            result.append ("\t\t\t<Value>").append (value).append ("</Value>\n");
            result.append ("\t\t</Entry>\n");
         }
         result.append ("\t</Category>\n");
      }
      result.append ("</DistributedState>\n");

      return result.toString ();
   
protected voidnotifyKeyListeners(java.lang.String category, java.io.Serializable key, java.io.Serializable value, boolean locallyModified)

      synchronized(this.keyListeners)
      {
         ArrayList listeners = (ArrayList)keyListeners.get (category);
         if (listeners == null)
            return;
         String strKey = key.toString();

         for (int i = 0; i < listeners.size (); i++)
         {
            Object listener = listeners.get (i);
            if( listener instanceof DSListener )
            {
               DSListener dslistener = (DSListener) listener;
               dslistener.valueHasChanged (category, strKey, value, locallyModified);
            }
            else
            {
               DSListenerEx dslistener = (DSListenerEx) listener;
               dslistener.valueHasChanged (category, key, value, locallyModified);
            }
         }
      }
   
protected voidnotifyKeyListenersOfRemove(java.lang.String category, java.io.Serializable key, java.io.Serializable oldContent, boolean locallyModified)

      synchronized(this.keyListeners)
      {
         ArrayList listeners = (ArrayList)keyListeners.get (category);
         if (listeners == null)
            return;
         String strKey = key.toString();

         for (int i = 0; i < listeners.size (); i++)
         {
            Object listener = listeners.get (i);
            if( listener instanceof DSListener )
            {
               DSListener dslistener = (DSListener) listener;
               dslistener.keyHasBeenRemoved (category, strKey, oldContent, locallyModified);
            }
            else
            {
               DSListenerEx dslistener = (DSListenerEx) listener;
               dslistener.keyHasBeenRemoved (category, key, oldContent, locallyModified);
            }
         }
      }
   
public voidregisterDSListener(java.lang.String category, DSListener subscriber)

      registerListener(category, subscriber);
   
public voidregisterDSListenerEx(java.lang.String category, DSListenerEx subscriber)

      registerListener(category, subscriber);
   
protected voidregisterListener(java.lang.String category, java.lang.Object subscriber)

      synchronized(this.keyListeners)
      {
         ArrayList listeners = (ArrayList)keyListeners.get (category);
         if (listeners == null)
         {
            listeners = new ArrayList ();
            keyListeners.put (category, listeners);
         }
         listeners.add (subscriber);
      }
   
public java.io.Serializableremove(java.lang.String category, java.io.Serializable key)

      return remove (category, key, true);
   
public java.io.Serializableremove(java.lang.String category, java.io.Serializable key, boolean asynchronousCall)

      Object[] args = {category, key};
      if (asynchronousCall)
         partition.callAsynchMethodOnCluster (SERVICE_NAME, "_remove", args, remove_types, true);
      else
         partition.callMethodOnCluster (SERVICE_NAME, "_remove", args, remove_types, true);
      Serializable removed = this._removeInternal (category, key);
      notifyKeyListenersOfRemove (category, key, removed , true);
      return removed ;
   
public voidset(java.lang.String category, java.io.Serializable key, java.io.Serializable value, boolean asynchronousCall)

      Object[] args = {category, key, value};
      if (asynchronousCall)
         partition.callAsynchMethodOnCluster (SERVICE_NAME, "_set", args, set_types, true);
      else
         partition.callMethodOnCluster (SERVICE_NAME, "_set", args, set_types, true);
      this._setInternal (category, key, value);
      notifyKeyListeners (category, key, value, true);
   
public voidset(java.lang.String category, java.io.Serializable key, java.io.Serializable value)

      set (category, key, value, true);
   
public voidsetCurrentState(java.io.Serializable newState)

      synchronized (this.categories)
      {
         categories.clear ();
         categories.putAll ((HashMap)newState);
         if (keyListeners.size () > 0)
         {
            cleanupKeyListeners ();
         }
      }
   
public voidstart()

   
public voidstop()

       // NR 200505:[JBCLUSTER-38] will be done at destroy instead
//      Registry.unbind (this.name);
//      ObjectName jmxName = new ObjectName(this.name);
//      mbeanServer.unregisterMBean (jmxName);
   
public voidunregisterDSListener(java.lang.String category, DSListener subscriber)

      unregisterListener(category, subscriber);
   
public voidunregisterDSListenerEx(java.lang.String category, DSListenerEx subscriber)

      unregisterListener(category, subscriber);
   
protected voidunregisterListener(java.lang.String category, java.lang.Object subscriber)

      synchronized(this.keyListeners)
      {
         ArrayList listeners = (ArrayList)keyListeners.get (category);
         if (listeners == null) return;

         listeners.remove (subscriber);
         if (listeners.size () == 0)
         {
            keyListeners.remove (category);
         }
      }