blob: e5ce187a724e4f67ad726f3660ddaee40f1d18d2 [file] [log] [blame]
/****************************************************************************
* 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
*****************************************************************************/
/*
* Created on Dec 20, 2004
*
*/
package org.eclipse.ecf.provider.generic;
import java.lang.reflect.Constructor;
import java.security.AccessController;
import java.security.PrivilegedExceptionAction;
import java.util.*;
import org.eclipse.core.runtime.Assert;
import org.eclipse.ecf.core.identity.*;
import org.eclipse.ecf.core.sharedobject.*;
import org.eclipse.ecf.core.sharedobject.events.*;
import org.eclipse.ecf.core.sharedobject.security.ISharedObjectPolicy;
import org.eclipse.ecf.core.sharedobject.util.IQueueEnqueue;
import org.eclipse.ecf.core.sharedobject.util.QueueEnqueueImpl;
import org.eclipse.ecf.core.util.AbstractFactory;
import org.eclipse.ecf.core.util.Trace;
import org.eclipse.ecf.internal.provider.ECFProviderDebugOptions;
import org.eclipse.ecf.internal.provider.ProviderPlugin;
/**
*
*/
public class SOManager implements ISharedObjectManager {
private static final int GUID_SIZE = 20;
SOContainer container = null;
Vector connectors = null;
public SOManager(SOContainer cont) {
super();
this.container = cont;
connectors = new Vector();
}
protected void debug(String msg) {
Trace.trace(ProviderPlugin.PLUGIN_ID, ECFProviderDebugOptions.SHAREDOBJECTMANAGER, msg + ":" + container.getID()); //$NON-NLS-1$
}
protected void traceStack(String msg, Throwable e) {
Trace.catching(ProviderPlugin.PLUGIN_ID, ECFProviderDebugOptions.EXCEPTIONS_CATCHING, SOManager.class, container.getID() + ":" + msg, e); //$NON-NLS-1$
}
protected void addConnector(ISharedObjectConnector conn) {
connectors.add(conn);
}
protected boolean removeConnector(ISharedObjectConnector conn) {
return connectors.remove(conn);
}
protected List getConnectors() {
return connectors;
}
protected Class[] getArgTypes(String[] argTypes, Object[] args, ClassLoader cl) throws ClassNotFoundException {
return AbstractFactory.getClassesForTypes(argTypes, args, cl);
}
protected ISharedObject createSharedObjectInstance(final Class newClass, final Class[] argTypes, final Object[] args) throws Exception {
Object newObject = null;
try {
newObject = AccessController.doPrivileged(new PrivilegedExceptionAction() {
public Object run() throws Exception {
Constructor aConstructor = newClass.getConstructor(argTypes);
aConstructor.setAccessible(true);
return aConstructor.newInstance(args);
}
});
} catch (java.security.PrivilegedActionException e) {
throw e.getException();
}
return verifySharedObject(newObject);
}
protected ISharedObject verifySharedObject(Object newSharedObject) {
return (ISharedObject) newSharedObject;
}
protected ISharedObject loadSharedObject(SharedObjectDescription sd) throws Exception {
Assert.isNotNull(sd, "shared object description cannot be null"); //$NON-NLS-1$
// Then get args array from properties
Object[] args = container.getArgsFromProperties(sd);
// And arg types
String[] types = container.getArgTypesFromProperties(sd);
ISharedObject res = null;
SharedObjectTypeDescription typeDesc = sd.getTypeDescription();
String descName = typeDesc.getName();
if (descName == null) {
// First get classloader
ClassLoader cl = container.getClassLoaderForSharedObject(sd);
final Class newClass = Class.forName(typeDesc.getClassName(), true, cl);
Class[] argTypes = getArgTypes(types, args, cl);
res = createSharedObjectInstance(newClass, argTypes, args);
// 'new style'
} else {
res = SharedObjectFactory.getDefault().createSharedObject(typeDesc, args);
}
return res;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ecf.core.ISharedObjectManager#getSharedObjectIDs()
*/
public ID[] getSharedObjectIDs() {
return container.getSharedObjectIDs();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ecf.core.ISharedObjectManager#createSharedObject(org.eclipse.ecf.core.SharedObjectDescription)
*/
public ID createSharedObject(SharedObjectDescription sd) throws SharedObjectCreateException {
debug("createSharedObject(" + sd + ")"); //$NON-NLS-1$ //$NON-NLS-2$
// notify listeners
if (sd == null)
throw new SharedObjectCreateException("shared object description cannot be null"); //$NON-NLS-1$
ISharedObject newObject = null;
ID newID = null;
ID result = null;
ID containerID = container.getID();
try {
newObject = loadSharedObject(sd);
newID = createNewSharedObjectID(sd, newObject);
container.fireDelegateContainerEvent(new SharedObjectManagerCreateEvent(containerID, newID));
} catch (Exception e) {
throw new SharedObjectCreateException("container=" + containerID + " had exception creating shared object=" + sd.getID(), e); //$NON-NLS-1$ //$NON-NLS-2$
} catch (NoClassDefFoundError e) {
throw new SharedObjectCreateException("container=" + containerID + " had exception creating shared object=" + sd.getID(), e); //$NON-NLS-1$ //$NON-NLS-2$
}
try {
result = addSharedObject(newID, newObject, sd.getProperties());
} catch (SharedObjectAddException e) {
throw new SharedObjectCreateException("container=" + containerID + " had exception creating shared object=" + sd.getID(), e); //$NON-NLS-1$ //$NON-NLS-2$
}
return result;
}
protected ID createNewSharedObjectID(SharedObjectDescription sd, ISharedObject newObject) throws IDCreateException {
ID descID = sd.getID();
if (descID == null) {
return IDFactory.getDefault().createGUID(GUID_SIZE);
}
return descID;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ecf.core.ISharedObjectManager#addSharedObject(org.eclipse.ecf.core.ISharedObject,
* java.util.Map,
* org.eclipse.ecf.core.ISharedObjectContainerTransaction)
*/
public ID addSharedObject(ID sharedObjectID, ISharedObject sharedObject, Map properties) throws SharedObjectAddException {
debug("addSharedObject(" + sharedObjectID + "," + sharedObject + "," //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ properties + ")"); //$NON-NLS-1$
ID containerID = container.getID();
ID result = sharedObjectID;
try {
ISharedObject so = sharedObject;
container.addSharedObjectAndWait(sharedObjectID, so, properties);
} catch (Exception e) {
throw new SharedObjectAddException("container=" + containerID + " had exception adding shared object=" + sharedObjectID, e); //$NON-NLS-1$ //$NON-NLS-2$
}
// notify listeners
container.fireDelegateContainerEvent(new SharedObjectManagerAddEvent(containerID, sharedObjectID));
return result;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ecf.core.ISharedObjectManager#getSharedObject(org.eclipse.ecf.core.identity.ID)
*/
public ISharedObject getSharedObject(ID sharedObjectID) {
return container.getSharedObject(sharedObjectID);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ecf.core.ISharedObjectManager#removeSharedObject(org.eclipse.ecf.core.identity.ID)
*/
public ISharedObject removeSharedObject(ID sharedObjectID) {
debug("removeSharedObject(" + sharedObjectID + ")"); //$NON-NLS-1$ //$NON-NLS-2$
// notify listeners
container.fireDelegateContainerEvent(new SharedObjectManagerRemoveEvent(container.getID(), sharedObjectID));
return container.removeSharedObject(sharedObjectID);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ecf.core.ISharedObjectManager#connectSharedObjects(org.eclipse.ecf.core.identity.ID,
* org.eclipse.ecf.core.identity.ID[])
*/
public ISharedObjectConnector connectSharedObjects(ID sharedObjectFrom, ID[] sharedObjectsTo) throws SharedObjectConnectException {
debug("connectSharedObjects(" + sharedObjectFrom + "," //$NON-NLS-1$ //$NON-NLS-2$
+ sharedObjectsTo + ")"); //$NON-NLS-1$
if (sharedObjectFrom == null)
throw new SharedObjectConnectException("sender cannot be null"); //$NON-NLS-1$
if (sharedObjectsTo == null)
throw new SharedObjectConnectException("receivers cannot be null"); //$NON-NLS-1$
ISharedObjectConnector result = null;
synchronized (container.getGroupMembershipLock()) {
// Get from to create sure it's there
SOWrapper wrap = container.getSharedObjectWrapper(sharedObjectFrom);
if (wrap == null)
throw new SharedObjectConnectException("sender=" + sharedObjectFrom.getName() + " not found"); //$NON-NLS-1$ //$NON-NLS-2$
IQueueEnqueue[] queues = new IQueueEnqueue[sharedObjectsTo.length];
for (int i = 0; i < sharedObjectsTo.length; i++) {
SOWrapper w = container.getSharedObjectWrapper(sharedObjectsTo[i]);
if (w == null)
throw new SharedObjectConnectException("receiver=" + sharedObjectsTo[i].getName() + " not found"); //$NON-NLS-1$ //$NON-NLS-2$
queues[i] = new QueueEnqueueImpl(w.getQueue());
}
// OK now we've got ids and wrappers, create a connector
result = new SOConnector(sharedObjectFrom, sharedObjectsTo, queues);
addConnector(result);
// notify listeners
container.fireDelegateContainerEvent(new SharedObjectManagerConnectEvent(container.getID(), result));
}
return result;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ecf.core.ISharedObjectManager#disconnectSharedObjects(org.eclipse.ecf.core.ISharedObjectConnector)
*/
public void disconnectSharedObjects(ISharedObjectConnector connector) throws SharedObjectDisconnectException {
if (connector == null)
throw new SharedObjectDisconnectException("shared object connect cannot be null"); //$NON-NLS-1$
debug("disconnectSharedObjects(" + connector.getSenderID() + ")"); //$NON-NLS-1$ //$NON-NLS-2$
if (!removeConnector(connector)) {
throw new SharedObjectDisconnectException("connector=" + connector + " not found"); //$NON-NLS-1$ //$NON-NLS-2$
}
connector.dispose();
container.fireDelegateContainerEvent(new SharedObjectManagerDisconnectEvent(container.getID(), connector));
}
protected void dispose() {
debug("dispose()"); //$NON-NLS-1$
for (Enumeration e = connectors.elements(); e.hasMoreElements();) {
ISharedObjectConnector conn = (ISharedObjectConnector) e.nextElement();
conn.dispose();
}
connectors.clear();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ecf.core.ISharedObjectManager#getSharedObjectConnectors(org.eclipse.ecf.core.identity.ID)
*/
public List getSharedObjectConnectors(ID sharedObjectFrom) {
debug("getSharedObjectConnectors(" + sharedObjectFrom + ")"); //$NON-NLS-1$ //$NON-NLS-2$
List results = new ArrayList();
for (Enumeration e = connectors.elements(); e.hasMoreElements();) {
ISharedObjectConnector conn = (ISharedObjectConnector) e.nextElement();
if (sharedObjectFrom.equals(conn.getSenderID())) {
results.add(conn);
}
}
return results;
}
public static Class[] getClassesForTypes(String[] argTypes, Object[] args, ClassLoader cl) throws ClassNotFoundException {
Class clazzes[] = null;
if (args == null || args.length == 0)
clazzes = new Class[0];
else if (argTypes != null) {
clazzes = new Class[argTypes.length];
for (int i = 0; i < argTypes.length; i++) {
clazzes[i] = Class.forName(argTypes[i], true, cl);
}
} else {
clazzes = new Class[args.length];
for (int i = 0; i < args.length; i++) {
if (args[i] == null)
clazzes[i] = null;
else
clazzes[i] = args[i].getClass();
}
}
return clazzes;
}
public void setRemoteAddPolicy(ISharedObjectPolicy policy) {
container.setRemoteAddPolicy(policy);
}
}