Package org.eclipse.ecf.example.collab.share

Source Code of org.eclipse.ecf.example.collab.share.GenericSharedObject$MsgMap

/****************************************************************************
* Copyright (c) 2004 Composent, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
*    Composent, Inc. - initial API and implementation
*****************************************************************************/

package org.eclipse.ecf.example.collab.share;

import java.io.IOException;
import java.io.Serializable;
import java.util.Hashtable;
import java.util.Random;

import org.eclipse.core.runtime.Assert;
import org.eclipse.ecf.core.events.IContainerConnectedEvent;
import org.eclipse.ecf.core.events.IContainerDisconnectedEvent;
import org.eclipse.ecf.core.identity.ID;
import org.eclipse.ecf.core.identity.IDFactory;
import org.eclipse.ecf.core.sharedobject.ISharedObject;
import org.eclipse.ecf.core.sharedobject.ISharedObjectConfig;
import org.eclipse.ecf.core.sharedobject.ISharedObjectContainerTransaction;
import org.eclipse.ecf.core.sharedobject.ISharedObjectContext;
import org.eclipse.ecf.core.sharedobject.ReplicaSharedObjectDescription;
import org.eclipse.ecf.core.sharedobject.SharedObjectInitException;
import org.eclipse.ecf.core.sharedobject.events.ISharedObjectActivatedEvent;
import org.eclipse.ecf.core.sharedobject.events.ISharedObjectCreateResponseEvent;
import org.eclipse.ecf.core.sharedobject.events.ISharedObjectDeactivatedEvent;
import org.eclipse.ecf.core.sharedobject.events.ISharedObjectMessageEvent;
import org.eclipse.ecf.core.sharedobject.events.RemoteSharedObjectEvent;
import org.eclipse.ecf.core.sharedobject.util.IQueueEnqueue;
import org.eclipse.ecf.core.sharedobject.util.QueueException;
import org.eclipse.ecf.core.util.Event;
import org.eclipse.ecf.internal.example.collab.ClientPlugin;

public class GenericSharedObject implements ISharedObject {
  protected static final String ARGS_PROPERTY_NAME = "args"; //$NON-NLS-1$

  protected static final class MsgMap {
    String meth;
    Object obj;

    MsgMap(Object o, String m) {
      obj = o;
      meth = m;
    }

    public Object getObject() {
      return obj;
    }
  }

  private static long replicateID = 0;
  protected ISharedObjectConfig config;
  protected SharedObjectMsg currentMsg;
  protected ID currentMsgFromContainerID;
  protected ID currentMsgFromObjID;
  protected Hashtable msgMap;
  protected Object msgMapLock = new Object();

  ID localContainerID;

  protected static long getNextReplicateID() {
    return replicateID++;
  }

  public void activated(ID[] ids) {
    if (isHost())
      replicate(null);
  }

  public void deactivated() {
  }

  public void destroyRemote(ID remoteID) throws IOException {
    getContext().sendDispose(remoteID);
  }

  public void destroySelf() {
    if (isHost()) {
      try {
        // Send destroy message to all known remotes
        destroyRemote(null);
      } catch (IOException e) {
        log("Exception sending destroy message to remotes", e); //$NON-NLS-1$
      }
    }
    destroySelfLocal();
  }

  public void destroySelfLocal() {
    getContext().getSharedObjectManager().removeSharedObject(
        getConfig().getSharedObjectID());
  }

  /*
   * (non-Javadoc)
   *
   * @see org.eclipse.ecf.core.ISharedObject#dispose(org.eclipse.ecf.core.identity.ID)
   */
  public void dispose(ID containerID) {
  }

  protected void execMsg(ID fromID, SharedObjectMsg msg) {
    try {
      MsgMap m = null;
      synchronized (msgMapLock) {
        m = (MsgMap) ((msgMap == null) ? null : (msgMap.get(msg
            .getMethodName())));
      }
      Object o = this;
      String methName = null;
      if (m != null) {
        if (m.obj != null) {
          o = m.obj;
        }
        if (m.meth != null) {
          methName = m.meth;
        }
      }
      if (methName != null) {
        msg = SharedObjectMsg.createMsg(msg.getClassName(), methName,
            msg.getArgs());
      }
      if (currentMsgFromObjID == null)
        currentMsgFromObjID = getID();
      currentMsgFromContainerID = fromID;
      currentMsg = msg;
      // Actually invoke msg on given object. Typically will be 'this'.
      execMsgInvoke(msg, currentMsgFromObjID, o);
      currentMsg = null;
      currentMsgFromContainerID = null;
    } catch (Throwable e) {
      msgException(this, msg, e);
    }
  }

  protected void execMsgInvoke(SharedObjectMsg msg, ID fromID, Object o)
      throws Exception {
    if (msg == null || fromID == null || o == null) return;
    try {
      msg.invoke(o);
    } catch (NoSuchMethodException e) {
      msg.invokeFrom(fromID, o);
    }
  }

  protected void forwardMsgHome(SharedObjectMsg msg) throws IOException {
    forwardMsgTo(config.getHomeContainerID(), msg);
  }

  protected void forwardMsgTo(ID toID, SharedObjectMsg msg)
      throws IOException {
    getContext().sendMessage(toID,
        new RemoteSharedObjectMsgEvent(getID(), toID, msg));
  }

  /*
   * (non-Javadoc)
   *
   * @see org.eclipse.ecf.core.ISharedObject#getAdapter(java.lang.Class)
   */
  public Object getAdapter(Class clazz) {
    if (clazz.equals(ISharedObjectContainerTransaction.class)
        && (this instanceof ISharedObjectContainerTransaction)) {
      return this;
    }
    return null;
  }

  public ISharedObjectContext getContext() {
    return getConfig().getContext();
  }

  public ISharedObjectConfig getConfig() {
    return config;
  }

  protected ID getHomeContainerID() {
    return getConfig().getHomeContainerID();
  }

  public ID getID() {
    return getConfig().getSharedObjectID();
  }

  protected ReplicaSharedObjectDescription getReplicaDescription(ID receiver) {
    return new ReplicaSharedObjectDescription(getClass(), getID(),
        getHomeContainerID(), getConfig().getProperties(),
        getNextReplicateID());
  }

  protected void handleCreateResponse(ID fromID, Throwable t, Long identifier) {
  }

  /*
   * (non-Javadoc)
   *
   * @see org.eclipse.ecf.core.ISharedObject#handleEvent(org.eclipse.ecf.core.util.Event)
   */
  public void handleEvent(Event event) {
    if (event instanceof ISharedObjectActivatedEvent) {
      ISharedObjectActivatedEvent ae = (ISharedObjectActivatedEvent) event;
      ID myID = getID();
      if (myID == null)
        return;
      if (myID.equals(ae.getActivatedID())) {
        activated(getContext().getSharedObjectManager()
            .getSharedObjectIDs());
      } else {
        otherActivated(ae.getActivatedID());
      }
    } else if (event instanceof ISharedObjectDeactivatedEvent) {
      ISharedObjectDeactivatedEvent ae = (ISharedObjectDeactivatedEvent) event;
      ID myID = getID();
      if (myID == null)
        return;
      if (myID.equals(ae.getDeactivatedID())) {
        deactivated();
      } else {
        otherDeactivated(ae.getDeactivatedID());
      }
    } else if (event instanceof IContainerConnectedEvent) {
      memberAdded(((IContainerConnectedEvent) event).getTargetID());
    } else if (event instanceof IContainerDisconnectedEvent) {
      memberRemoved(((IContainerDisconnectedEvent) event).getTargetID());
    } else if (event instanceof ISharedObjectMessageEvent) {
      handleSharedObjectMessageEvent(((ISharedObjectMessageEvent) event));
    }
  }

  protected void handleSharedObjectMessageEvent(
      ISharedObjectMessageEvent event) {
    if (event instanceof RemoteSharedObjectEvent) {
      if (event instanceof ISharedObjectCreateResponseEvent) {
        handleCreateResponseMessageEvent((ISharedObjectCreateResponseEvent) event);
      } else if (event instanceof RemoteSharedObjectMsgEvent) {
        handleSelfSendMessageEvent((RemoteSharedObjectMsgEvent) event);
      } else {
        RemoteSharedObjectMsgEvent me = (RemoteSharedObjectMsgEvent) event
            .getData();
        SharedObjectMsg msg = me.getMsg();
        execMsg(me.getRemoteContainerID(), msg);
      }
    }
  }

  protected void handleSelfSendMessageEvent(RemoteSharedObjectMsgEvent event) {
    execMsg(event.getRemoteContainerID(), event.getMsg());
  }

  protected void handleCreateResponseMessageEvent(
      ISharedObjectCreateResponseEvent event) {
    handleCreateResponse(event.getRemoteContainerID(),
        event.getException(), new Long(event.getSequence()));
  }

  /*
   * (non-Javadoc)
   *
   * @see org.eclipse.ecf.core.ISharedObject#handleEvents(org.eclipse.ecf.core.util.Event[])
   */
  public void handleEvents(Event[] events) {
    for (int i = 0; i < events.length; i++) {
      handleEvent(events[i]);
    }
  }

  public void handleRemoteData(ID spaceID, Serializable msg) {
    SharedObjectMsg aMsg = (SharedObjectMsg) msg;
    if (isReplicaMsgAllowed(spaceID, aMsg) != null) {
      execMsg(spaceID, aMsg);
    } else {
      ignoreReplicaMsg(spaceID, aMsg);
    }
  }

  protected void ignoreReplicaMsg(ID fromID, SharedObjectMsg msg) {
    // Do nothing
  }

  protected void ignoreSharedObjectMsg(ID fromID, SharedObjectMsg aMsg) {
    // Do nothing
  }

  /*
   * (non-Javadoc)
   *
   * @see org.eclipse.ecf.core.ISharedObject#init(org.eclipse.ecf.core.ISharedObjectConfig)
   */
  public void init(ISharedObjectConfig initData)
      throws SharedObjectInitException {
    this.config = initData;
    this.localContainerID = getContext().getLocalContainerID();
  }

  public boolean isHost() {
    ID homeContainerID = getHomeContainerID();
    if (homeContainerID == null)
      return false;
    else
      return (homeContainerID.equals(localContainerID));
  }

  protected Object isMsgAllowed(ID fromID, SharedObjectMsg aMsg) {
    return this;
  }

  protected Object isReplicaMsgAllowed(ID fromID, SharedObjectMsg aMsg) {
    return this;
  }

  public boolean isServer() {
    return getContext().isGroupManager();
  }

  public void memberAdded(ID member) {
    if (isHost())
      replicate(member);
  }

  public void memberRemoved(ID member) {
  }

  public void msgException(Object target, SharedObjectMsg aMsg, Throwable e) {
    if (e != null)
      e.printStackTrace(System.err);
  }

  public void otherActivated(ID member) {
  }

  public void otherDeactivated(ID member) {
  }

  public void registerProxy(Object object, String msg) {
    registerProxy(object, msg, null);
  }

  protected void registerProxy(Object target, String msg, String method) {
    Assert.isNotNull(msg);
    Assert.isNotNull(target);
    synchronized (msgMapLock) {
      // Create table lazily
      if (msgMap == null)
        msgMap = new Hashtable();
      else if (msgMap.containsKey(msg))
        throw new IllegalArgumentException(
            "registerProxy:  proxy already registered for " //$NON-NLS-1$
                + method + " by " + target); //$NON-NLS-1$
      // Then put entry into table with msg as key
      msgMap.put(msg, new MsgMap(target, method));
    }
  }

  protected void replicate(ID remote) {
    try {
      // Get current group membership
      ID[] group = getContext().getGroupMemberIDs();
      if (group == null || group.length < 1) {
        // we're done
        return;
      }
      ReplicaSharedObjectDescription createInfo = getReplicaDescription(remote);
      if (createInfo != null)
        getContext().sendCreate(remote, createInfo);
      else
        return;
    } catch (IOException e) {
      log("Exception in replicate", e); //$NON-NLS-1$
    }
  }

  protected void sendSelf(SharedObjectMsg msg) {
    IQueueEnqueue queue = getContext().getQueue();
    try {
      queue.enqueue(new RemoteSharedObjectMsgEvent(getID(), getContext()
          .getLocalContainerID(), msg));
    } catch (QueueException e) {
      log("QueueException enqueing message to self", e); //$NON-NLS-1$
    }
  }

  public void sharedObjectMsg(ID fromID, SharedObjectMsg msg) {
    if (isMsgAllowed(fromID, msg) != null) {
      currentMsgFromObjID = fromID;
      execMsg(localContainerID, msg);
      currentMsgFromObjID = null;
    } else {
      ignoreSharedObjectMsg(fromID, msg);
    }
  }

  protected void trace(String msg) {
  }

  protected void log(String msg, Throwable t) {
    ClientPlugin.log(msg, t);
  }

  public ID createObject(ID target, ReplicaSharedObjectDescription desc)
      throws Exception {
    if (target == null) {
      if (desc.getID() == null) {
        desc.setID(IDFactory.getDefault().createStringID(
            getUniqueString()));
      }
      try {
        return getContext().getSharedObjectManager()
            .createSharedObject(desc);
      } catch (Exception e) {
        log("Exception creating replicated object", e); //$NON-NLS-1$
        throw e;
      }
    } else
      throw new Exception(
          "Cannot send object creation request direct to target"); //$NON-NLS-1$
  }

  public String getUniqueString() {
    return String.valueOf((new Random()).nextLong());
  }
}
TOP

Related Classes of org.eclipse.ecf.example.collab.share.GenericSharedObject$MsgMap

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.