dain 2004/04/13 16:18:49
Modified: modules/core/src/java/org/openejb/proxy
EJBMethodInterceptor.java EJBProxyFactory.java
Added: modules/core/src/java/org/openejb/proxy
ProxyObjectFactory.java ProxyRefAddr.java
Log:
Added support for ejb-ref and ejb-local-ref
Change EJBProxyFactory to only need a ProxyInfo to construct proxies
Added a hack version of Stateful BMT policy (does not handle holding a tx
open between calls)
Revision Changes Path
1.7 +36 -25
openejb/modules/core/src/java/org/openejb/proxy/EJBMethodInterceptor.java
Index: EJBMethodInterceptor.java
===================================================================
RCS file:
/home/projects/openejb/scm/openejb/modules/core/src/java/org/openejb/proxy/EJBMethodInterceptor.java,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- EJBMethodInterceptor.java 11 Apr 2004 05:55:25 -0000 1.6
+++ EJBMethodInterceptor.java 13 Apr 2004 20:18:49 -0000 1.7
@@ -16,7 +16,7 @@
import org.openejb.EJBInvocation;
import org.openejb.EJBInvocationImpl;
-public class EJBMethodInterceptor implements MethodInterceptor, Serializable {
+public class EJBMethodInterceptor implements MethodInterceptor, EJBInterceptor,
Serializable {
private final ProxyInfo proxyInfo;
private final Object primaryKey;
@@ -26,6 +26,11 @@
private final EJBInterceptor next;
/**
+ * Proxy factory for this proxy
+ */
+ private final EJBProxyFactory proxyFactory;
+
+ /**
* The type of the ejb interface. This is used during construction of the
EJBInvocation object.
*/
private final EJBInterfaceType interfaceType;
@@ -33,16 +38,18 @@
/**
* Map from interface method ids to vop ids.
*/
- private final int[] operationMap;
+ private transient int[] operationMap;
+ /**
+ * The container we are invokeing
+ */
+ private transient EJBContainer container;
- private final EJBProxyFactory proxyFactory;
-
- public EJBMethodInterceptor(EJBContainer container, EJBProxyFactory
proxyFactory, EJBInterfaceType type, int[] operationMap) {
- this(container, proxyFactory, type, operationMap, null);
+ public EJBMethodInterceptor(EJBProxyFactory proxyFactory, EJBInterfaceType
type, EJBContainer container, int[] operationMap) {
+ this(proxyFactory, type, container, operationMap, null);
}
- public EJBMethodInterceptor(EJBContainer container, EJBProxyFactory
proxyFactory, EJBInterfaceType type, int[] operationMap, Object primaryKey) {
+ public EJBMethodInterceptor(EJBProxyFactory proxyFactory, EJBInterfaceType
type, EJBContainer container, int[] operationMap, Object primaryKey) {
// @todo REMOVE: this is a dirty dirty dirty hack to make the old openejb
code work
// this lets really stupid clients get access to the primary key of the
proxy, which is readily
// available from several other sources
@@ -50,27 +57,29 @@
this.primaryKey = primaryKey;
this.interfaceType = type;
+ this.container = container;
this.operationMap = operationMap;
this.proxyFactory = proxyFactory;
- EJBInterceptor interceptor;
- if (container == null){
- interceptor = new ContainerReferenceHandler(proxyInfo.getContainerID());
- } else {
- interceptor = new ContainerHandler(container);
- }
-
if (!interfaceType.isLocal() && !skipCopy()) {
- interceptor = new SerializationHanlder(interceptor);
+ next = new SerializationHanlder(this);
+ } else {
+ next = this;
}
-
- next = interceptor;
}
public EJBProxyFactory getProxyFactory() {
return proxyFactory;
}
+ public ProxyInfo getProxyInfo() {
+ return proxyInfo;
+ }
+
+ public Object getPrimaryKey() {
+ return primaryKey;
+ }
+
/** Returns true of the EJB 1.1 comliant copying of
* remote interfaces should be skipped.
* @return
@@ -85,11 +94,13 @@
return false;
}
- private void readObject(java.io.ObjectInputStream in) throws
java.io.IOException, ClassNotFoundException {
- in.defaultReadObject();
- }
-
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy
methodProxy) throws Throwable {
+ // fault in the operation map if we don't have it yet
+ if (operationMap == null) {
+ container = proxyFactory.getContainer();
+ operationMap = proxyFactory.getOperationMap(interfaceType);
+ }
+
int methodIndex = operationMap[methodProxy.getSuperIndex()];
if (methodIndex < 0) throw new AssertionError("Unknown method: method=" +
method);
@@ -134,11 +145,11 @@
}
}
- public ProxyInfo getProxyInfo() {
- return proxyInfo;
+ public InvocationResult invoke(EJBInvocation ejbInvocation) throws Throwable {
+ return container.invoke(ejbInvocation);
}
- public Object getPrimaryKey() {
- return primaryKey;
+ private void readObject(java.io.ObjectInputStream in) throws
java.io.IOException, ClassNotFoundException {
+ in.defaultReadObject();
}
}
1.6 +90 -55
openejb/modules/core/src/java/org/openejb/proxy/EJBProxyFactory.java
Index: EJBProxyFactory.java
===================================================================
RCS file:
/home/projects/openejb/scm/openejb/modules/core/src/java/org/openejb/proxy/EJBProxyFactory.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- EJBProxyFactory.java 13 Apr 2004 18:13:16 -0000 1.5
+++ EJBProxyFactory.java 13 Apr 2004 20:18:49 -0000 1.6
@@ -57,6 +57,7 @@
import org.openejb.EJBContainer;
import org.openejb.EJBInterfaceType;
+import org.openejb.ContainerIndex;
import org.openejb.dispatch.InterfaceMethodSignature;
public class EJBProxyFactory implements Serializable {
@@ -68,45 +69,29 @@
{EntityEJBObject.class, EntityEJBHome.class, EntityEJBLocalObject.class,
EntityEJBLocalHome.class}, // CMP_ENTITY
};
+ private final ProxyInfo proxyInfo;
+
private transient final CglibEJBProxyFactory ejbLocalObjectFactory;
private transient final CglibEJBProxyFactory ejbLocalHomeFactory;
private transient final CglibEJBProxyFactory ejbObjectFactory;
private transient final CglibEJBProxyFactory ejbHomeFactory;
- private transient final int[] ejbLocalObjectMap;
- private transient final int[] ejbLocalHomeMap;
- private transient final int[] ejbObjectMap;
- private transient final int[] ejbHomeMap;
-
- private transient final Map legacyMethodMap;
-
private transient EJBContainer container;
-
- private final ProxyInfo proxyInfo;
- private final InterfaceMethodSignature[] signatures;
+ private transient int[] ejbLocalObjectMap;
+ private transient int[] ejbLocalHomeMap;
+ private transient int[] ejbObjectMap;
+ private transient int[] ejbHomeMap;
+
+ private transient Map legacyMethodMap;
- public EJBProxyFactory(ProxyInfo proxyInfo, InterfaceMethodSignature[]
signatures) {
- this.signatures = signatures;
+ public EJBProxyFactory(ProxyInfo proxyInfo) {
this.proxyInfo = proxyInfo;
this.ejbLocalObjectFactory =
getFactory(EJBInterfaceType.LOCAL.getOrdinal(), proxyInfo.getLocalInterface());
this.ejbLocalHomeFactory =
getFactory(EJBInterfaceType.LOCALHOME.getOrdinal(), proxyInfo.getLocalHomeInterface());
this.ejbObjectFactory = getFactory(EJBInterfaceType.REMOTE.getOrdinal(),
proxyInfo.getRemoteInterface());
this.ejbHomeFactory = getFactory(EJBInterfaceType.HOME.getOrdinal(),
proxyInfo.getHomeInterface());
-
- // build the legacy map
- Map map = new HashMap();
- addLegacyMethods(map, proxyInfo.getHomeInterface(), signatures);
- addLegacyMethods(map, proxyInfo.getRemoteInterface(), signatures);
- addLegacyMethods(map, proxyInfo.getLocalHomeInterface(), signatures);
- addLegacyMethods(map, proxyInfo.getLocalInterface(), signatures);
- legacyMethodMap = Collections.unmodifiableMap(map);
-
- ejbLocalObjectMap = getOperationsMap(ejbLocalObjectFactory);
- ejbLocalHomeMap = getOperationsMap(ejbLocalHomeFactory);
- ejbObjectMap = getOperationsMap(ejbObjectFactory);
- ejbHomeMap = getOperationsMap(ejbHomeFactory);
}
public int getMethodIndex(Method method) {
@@ -117,23 +102,54 @@
return index.intValue();
}
+ EJBContainer getContainer() {
+ if (container == null) {
+ locateContainer();
+ }
+
+ return container;
+ }
+
public void setContainer(EJBContainer container) {
+ assert container != null: "container is null";
this.container = container;
- }
- public String getEJBName() {
- return container.getEJBName();
+ InterfaceMethodSignature[] signatures = container.getSignatures();
+
+ // build the legacy map
+ Map map = new HashMap();
+ addLegacyMethods(map, proxyInfo.getHomeInterface(), signatures);
+ addLegacyMethods(map, proxyInfo.getRemoteInterface(), signatures);
+ addLegacyMethods(map, proxyInfo.getLocalHomeInterface(), signatures);
+ addLegacyMethods(map, proxyInfo.getLocalInterface(), signatures);
+ legacyMethodMap = Collections.unmodifiableMap(map);
+
+ ejbLocalObjectMap = createOperationsMap(ejbLocalObjectFactory, signatures);
+ ejbLocalHomeMap = createOperationsMap(ejbLocalHomeFactory, signatures);
+ ejbObjectMap = createOperationsMap(ejbObjectFactory, signatures);
+ ejbHomeMap = createOperationsMap(ejbHomeFactory, signatures);
}
- private int[] getOperationsMap(CglibEJBProxyFactory factory){
- if (factory == null) return new int[0];
- return EJBProxyHelper.getOperationMap(factory.getType(), signatures);
+ int[] getOperationMap(EJBInterfaceType type) {
+ if (container == null) {
+ locateContainer();
+ }
+
+ if (type == EJBInterfaceType.HOME) {
+ return ejbHomeMap;
+ } else if (type == EJBInterfaceType.REMOTE) {
+ return ejbObjectMap;
+ } else if (type == EJBInterfaceType.LOCALHOME) {
+ return ejbLocalHomeMap;
+ } else if (type == EJBInterfaceType.LOCAL) {
+ return ejbLocalObjectMap;
+ } else {
+ throw new IllegalArgumentException("Unsupported interface type " +
type);
+ }
}
-
- private CglibEJBProxyFactory getFactory(int interfaceType, Class
interfaceClass){
- if (interfaceClass == null) return null;
- Class baseClass = baseClasses[proxyInfo.getComponentType()][interfaceType];
- return new CglibEJBProxyFactory(baseClass, interfaceClass);
+
+ public String getEJBName() {
+ return container.getEJBName();
}
public ProxyInfo getProxyInfo() {
@@ -147,9 +163,9 @@
* @return the proxy for this EJB's home interface
*/
public EJBHome getEJBHome(){
- EJBInterfaceType type = EJBInterfaceType.HOME;
- int[] map = ejbHomeMap;
- EJBMethodInterceptor handler = new EJBMethodInterceptor(container, this,
type, map);
+ EJBMethodInterceptor handler = new EJBMethodInterceptor(
+ this, EJBInterfaceType.HOME, container,
+ ejbHomeMap);
return (EJBHome) ejbHomeFactory.create(handler);
}
@@ -160,11 +176,10 @@
* @return the proxy for this EJB's home interface
*/
public EJBObject getEJBObject(Object primaryKey){
- // TODO: Refactor EJBMethodHandler so it can take a primary key as a
parameter
- // TODO: Refactor ProxyInfo so it doesn't have a primary key
- EJBInterfaceType type = EJBInterfaceType.REMOTE;
- int[] map = ejbObjectMap;
- EJBMethodInterceptor handler = new EJBMethodInterceptor(container, this,
type, map, primaryKey);
+ EJBMethodInterceptor handler = new EJBMethodInterceptor(
+ this, EJBInterfaceType.REMOTE, container,
+ ejbObjectMap,
+ primaryKey);
return (EJBObject) ejbObjectFactory.create(handler);
}
@@ -175,10 +190,10 @@
* @return the proxy for this EJB's local home interface
*/
public EJBLocalHome getEJBLocalHome(){
- EJBInterfaceType type = EJBInterfaceType.LOCALHOME;
- int[] map = ejbLocalHomeMap;
- EJBMethodInterceptor handler = new EJBMethodInterceptor(container, this,
type, map);
- return (EJBLocalHome) ejbLocalHomeFactory.create(handler);
+ EJBMethodInterceptor handler = new EJBMethodInterceptor(
+ this, EJBInterfaceType.LOCALHOME, container,
+ ejbLocalHomeMap);
+ return (EJBLocalHome) ejbLocalHomeFactory.create(handler);
}
/**
@@ -188,16 +203,24 @@
* @return the proxy for this EJB's local interface
*/
public EJBLocalObject getEJBLocalObject(Object primaryKey){
- EJBInterfaceType type = EJBInterfaceType.LOCAL;
- int[] map = ejbLocalObjectMap;
- EJBMethodInterceptor handler = new EJBMethodInterceptor(container, this,
type, map, primaryKey);
+ EJBMethodInterceptor handler = new EJBMethodInterceptor(
+ this, EJBInterfaceType.LOCAL, container,
+ ejbLocalObjectMap,
+ primaryKey);
return (EJBLocalObject) ejbLocalObjectFactory.create(handler);
}
- private Object readResolve() {
- return new EJBProxyFactory(proxyInfo, signatures);
+ private int[] createOperationsMap(CglibEJBProxyFactory factory,
InterfaceMethodSignature[] signatures){
+ if (factory == null) return new int[0];
+ return EJBProxyHelper.getOperationMap(factory.getType(), signatures);
}
-
+
+ private CglibEJBProxyFactory getFactory(int interfaceType, Class
interfaceClass){
+ if (interfaceClass == null) return null;
+ Class baseClass = baseClasses[proxyInfo.getComponentType()][interfaceType];
+ return new CglibEJBProxyFactory(baseClass, interfaceClass);
+ }
+
private static void addLegacyMethods(Map legacyMethodMap, Class clazz,
InterfaceMethodSignature[] signatures) {
if (clazz == null) {
return;
@@ -212,4 +235,16 @@
}
}
+ private void locateContainer() {
+ ContainerIndex containerIndex = ContainerIndex.getInstance();
+ EJBContainer c =
containerIndex.getContainer((String)proxyInfo.getContainerID());
+ if (c == null) {
+ throw new IllegalStateException("Contianer not found: " +
proxyInfo.getContainerID());
+ }
+ setContainer(c);
+ }
+
+ private Object readResolve() {
+ return new EJBProxyFactory(proxyInfo);
+ }
}
1.1
openejb/modules/core/src/java/org/openejb/proxy/ProxyObjectFactory.java
Index: ProxyObjectFactory.java
===================================================================
/* ====================================================================
* Redistribution and use of this software and associated documentation
* ("Software"), with or without modification, are permitted provided
* that the following conditions are met:
*
* 1. Redistributions of source code must retain copyright
* statements and notices. Redistributions must also contain a
* copy of this document.
*
* 2. Redistributions in binary form must reproduce this list of
* conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name "OpenEJB" must not be used to endorse or promote
* products derived from this Software without prior written
* permission of The OpenEJB Group. For written permission,
* please contact [EMAIL PROTECTED]
*
* 4. Products derived from this Software may not be called "OpenEJB"
* nor may "OpenEJB" appear in their names without prior written
* permission of The OpenEJB Group. OpenEJB is a registered
* trademark of The OpenEJB Group.
*
* 5. Due credit should be given to the OpenEJB Project
* (http://openejb.org/).
*
* THIS SOFTWARE IS PROVIDED BY THE OPENEJB GROUP AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
* NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE OPENEJB GROUP OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the OpenEJB Project. For more information
* please see <http://openejb.org/>.
*
* ====================================================================
*/
package org.openejb.proxy;
import java.util.Hashtable;
import javax.naming.Context;
import javax.naming.Name;
import javax.naming.RefAddr;
import javax.naming.Reference;
import javax.naming.spi.ObjectFactory;
/**
*
*
* @version $Revision: 1.1 $ $Date: 2004/04/13 20:18:49 $
*/
public class ProxyObjectFactory implements ObjectFactory {
public Object getObjectInstance(Object obj, Name name, Context nameCtx,
Hashtable environment) throws Exception {
if (!(obj instanceof Reference)) {
return null;
}
Reference ref = (Reference) obj;
RefAddr refAddr = ref.get(0);
if (!(refAddr instanceof ProxyRefAddr)) {
throw new IllegalStateException("Invalid ref addr in Proxy Factory: " +
refAddr);
}
ProxyRefAddr proxyRefAddr = (ProxyRefAddr) refAddr;
return proxyRefAddr.getContent();
}
}
1.1
openejb/modules/core/src/java/org/openejb/proxy/ProxyRefAddr.java
Index: ProxyRefAddr.java
===================================================================
/* ====================================================================
* Redistribution and use of this software and associated documentation
* ("Software"), with or without modification, are permitted provided
* that the following conditions are met:
*
* 1. Redistributions of source code must retain copyright
* statements and notices. Redistributions must also contain a
* copy of this document.
*
* 2. Redistributions in binary form must reproduce this list of
* conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name "OpenEJB" must not be used to endorse or promote
* products derived from this Software without prior written
* permission of The OpenEJB Group. For written permission,
* please contact [EMAIL PROTECTED]
*
* 4. Products derived from this Software may not be called "OpenEJB"
* nor may "OpenEJB" appear in their names without prior written
* permission of The OpenEJB Group. OpenEJB is a registered
* trademark of The OpenEJB Group.
*
* 5. Due credit should be given to the OpenEJB Project
* (http://openejb.org/).
*
* THIS SOFTWARE IS PROVIDED BY THE OPENEJB GROUP AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
* NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE OPENEJB GROUP OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the OpenEJB Project. For more information
* please see <http://openejb.org/>.
*
* ====================================================================
*/
package org.openejb.proxy;
import javax.naming.RefAddr;
/**
*
*
* @version $Revision: 1.1 $ $Date: 2004/04/13 20:18:49 $
*/
public class ProxyRefAddr extends RefAddr {
private final static String TYPE = "org.openejb.proxy.EJBType";
private final ProxyInfo proxyInfo;
private final boolean isLocal;
public ProxyRefAddr(ProxyInfo proxyInfo, boolean local) {
super(TYPE);
this.proxyInfo = proxyInfo;
isLocal = local;
}
public Object getContent() {
EJBProxyFactory proxyFactory = new EJBProxyFactory(proxyInfo);
if (isLocal) {
return proxyFactory.getEJBLocalHome();
} else {
return proxyFactory.getEJBHome();
}
}
}