/**************************************************************************** * 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.provider.generic; import java.io.Serializable; import java.security.AccessController; import java.security.PrivilegedAction; import org.eclipse.ecf.core.events.ContainerConnectedEvent; import org.eclipse.ecf.core.events.ContainerDisconnectedEvent; import org.eclipse.ecf.core.identity.ID; import org.eclipse.ecf.core.sharedobject.ISharedObject; import org.eclipse.ecf.core.sharedobject.SharedObjectInitException; import org.eclipse.ecf.core.sharedobject.events.*; import org.eclipse.ecf.core.sharedobject.util.QueueEnqueueImpl; import org.eclipse.ecf.core.sharedobject.util.SimpleFIFOQueue; import org.eclipse.ecf.core.util.Event; import org.eclipse.ecf.core.util.Trace; import org.eclipse.ecf.internal.provider.ECFProviderDebugOptions; import org.eclipse.ecf.internal.provider.ProviderPlugin; import org.eclipse.ecf.provider.generic.gmm.Member; public class SOWrapper { protected ISharedObject sharedObject; private SOConfig sharedObjectConfig; ID sharedObjectID; private SOContainer container; private ID containerID; private Thread thread; SimpleFIFOQueue queue; protected SOWrapper(SOContainer.LoadingSharedObject obj, SOContainer cont) { sharedObjectID = obj.getID(); sharedObject = obj; container = cont; containerID = cont.getID(); sharedObjectConfig = null; thread = null; queue = new SimpleFIFOQueue(); } public SOWrapper(SOConfig aConfig, ISharedObject obj, SOContainer cont) { sharedObjectConfig = aConfig; sharedObjectID = sharedObjectConfig.getSharedObjectID(); sharedObject = obj; container = cont; containerID = cont.getID(); thread = null; queue = new SimpleFIFOQueue(); } protected void init() throws SharedObjectInitException { debug("init()"); //$NON-NLS-1$ sharedObjectConfig.makeActive(new QueueEnqueueImpl(queue)); sharedObject.init(sharedObjectConfig); } protected ID getObjID() { return sharedObjectConfig.getSharedObjectID(); } protected ID getHomeID() { return sharedObjectConfig.getHomeContainerID(); } protected SOConfig getConfig() { return sharedObjectConfig; } protected void activated() { thread = (Thread) AccessController.doPrivileged(new PrivilegedAction() { public Object run() { Thread aThread = getThread(); return aThread; } }); // Notify container and listeners container.notifySharedObjectActivated(sharedObjectID); // Start thread thread.start(); // Send message send(new SharedObjectActivatedEvent(containerID, sharedObjectID)); } protected void deactivated() { container.notifySharedObjectDeactivated(sharedObjectID); send(new SharedObjectDeactivatedEvent(containerID, sharedObjectID)); destroyed(); } protected void destroyed() { if (!queue.isStopped()) { if (thread != null) queue.enqueue(new DisposeEvent()); queue.close(); } } protected void otherChanged(ID otherID, boolean activated) { if (activated && thread != null) { send(new SharedObjectActivatedEvent(containerID, otherID)); } else { send(new SharedObjectDeactivatedEvent(containerID, otherID)); } } protected void memberChanged(Member m, boolean add) { if (thread != null) { if (add) { send(new ContainerConnectedEvent(containerID, m.getID())); } else { send(new ContainerDisconnectedEvent(containerID, m.getID())); } } } protected Thread getThread() { return container.getNewSharedObjectThread(sharedObjectID, new Runnable() { public void run() { debug("runner(" + sharedObjectID + ")"); //$NON-NLS-1$ //$NON-NLS-2$ Event evt = null; for (;;) { if (Thread.currentThread().isInterrupted()) break; evt = (Event) queue.dequeue(); if (Thread.currentThread().isInterrupted() || evt == null) break; try { if (evt instanceof ProcEvent) { SOWrapper.this.svc(((ProcEvent) evt).getEvent()); } else if (evt instanceof DisposeEvent) { SOWrapper.this.doDestroy(); } else { SOWrapper.this.svc(evt); } } catch (Throwable t) { handleRuntimeException(t); } } if (Thread.currentThread().isInterrupted()) { debug("runner(" + sharedObjectID //$NON-NLS-1$ + ") terminating interrupted"); //$NON-NLS-1$ } else { debug("runner(" + sharedObjectID //$NON-NLS-1$ + ") terminating normally"); //$NON-NLS-1$ } } }); } private void send(Event evt) { queue.enqueue(new ProcEvent(evt)); } public static class ProcEvent implements Event { Event theEvent = null; public ProcEvent(Event event) { theEvent = event; } Event getEvent() { return theEvent; } } protected static class DisposeEvent implements Event { DisposeEvent() { // } } protected void svc(Event evt) { sharedObject.handleEvent(evt); } protected void doDestroy() { sharedObject.dispose(containerID); // make config inactive sharedObjectConfig.makeInactive(); } protected void deliverSharedObjectMessage(ID fromID, Serializable data) { send(new RemoteSharedObjectEvent(getObjID(), fromID, data)); } protected void deliverCreateResponse(ID fromID, ContainerMessage.CreateResponseMessage resp) { send(new RemoteSharedObjectCreateResponseEvent(resp.getSharedObjectID(), fromID, resp.getSequence(), resp.getException())); } public void deliverEvent(Event evt) { send(evt); } protected void destroySelf() { debug("destroySelf()"); //$NON-NLS-1$ send(new DisposeEvent()); } public String toString() { StringBuffer sb = new StringBuffer(); sb.append("SharedObjectWrapper[").append(getObjID()).append("]"); //$NON-NLS-1$ //$NON-NLS-2$ return sb.toString(); } protected void debug(String msg) { Trace.trace(ProviderPlugin.PLUGIN_ID, ECFProviderDebugOptions.SHAREDOBJECTWRAPPER, msg + ":oID=" + sharedObjectID + ":cID=" + container.getID()); //$NON-NLS-1$ //$NON-NLS-2$ } protected void traceStack(String msg, Throwable e) { Trace.catching(ProviderPlugin.PLUGIN_ID, ECFProviderDebugOptions.EXCEPTIONS_CATCHING, SOContainerGMM.class, container.getID() + ":" + msg, e); //$NON-NLS-1$ } protected void handleRuntimeException(Throwable except) { except.printStackTrace(System.err); traceStack("runner:handleRuntimeException(" + sharedObjectID.getName() + ")", //$NON-NLS-1$ //$NON-NLS-2$ except); } protected ISharedObject getSharedObject() { return sharedObject; } public SimpleFIFOQueue getQueue() { return queue; } }