summaryrefslogtreecommitdiffstats
path: root/sca-java-1.x/tags/0.91-incubating/modules/binding-ejb/src/main/java/org/apache/tuscany/sca/binding/ejb/util
diff options
context:
space:
mode:
Diffstat (limited to 'sca-java-1.x/tags/0.91-incubating/modules/binding-ejb/src/main/java/org/apache/tuscany/sca/binding/ejb/util')
-rw-r--r--sca-java-1.x/tags/0.91-incubating/modules/binding-ejb/src/main/java/org/apache/tuscany/sca/binding/ejb/util/EJBHandler.java420
-rw-r--r--sca-java-1.x/tags/0.91-incubating/modules/binding-ejb/src/main/java/org/apache/tuscany/sca/binding/ejb/util/EJBLocator.java511
-rw-r--r--sca-java-1.x/tags/0.91-incubating/modules/binding-ejb/src/main/java/org/apache/tuscany/sca/binding/ejb/util/EJBObjectFactory.java188
-rw-r--r--sca-java-1.x/tags/0.91-incubating/modules/binding-ejb/src/main/java/org/apache/tuscany/sca/binding/ejb/util/EJBStubHelper.java69
-rw-r--r--sca-java-1.x/tags/0.91-incubating/modules/binding-ejb/src/main/java/org/apache/tuscany/sca/binding/ejb/util/InterfaceInfo.java125
-rw-r--r--sca-java-1.x/tags/0.91-incubating/modules/binding-ejb/src/main/java/org/apache/tuscany/sca/binding/ejb/util/JavaReflectionAdapter.java155
-rw-r--r--sca-java-1.x/tags/0.91-incubating/modules/binding-ejb/src/main/java/org/apache/tuscany/sca/binding/ejb/util/MethodInfo.java176
-rw-r--r--sca-java-1.x/tags/0.91-incubating/modules/binding-ejb/src/main/java/org/apache/tuscany/sca/binding/ejb/util/NamingEndpoint.java118
8 files changed, 1762 insertions, 0 deletions
diff --git a/sca-java-1.x/tags/0.91-incubating/modules/binding-ejb/src/main/java/org/apache/tuscany/sca/binding/ejb/util/EJBHandler.java b/sca-java-1.x/tags/0.91-incubating/modules/binding-ejb/src/main/java/org/apache/tuscany/sca/binding/ejb/util/EJBHandler.java
new file mode 100644
index 0000000000..8d0d309aef
--- /dev/null
+++ b/sca-java-1.x/tags/0.91-incubating/modules/binding-ejb/src/main/java/org/apache/tuscany/sca/binding/ejb/util/EJBHandler.java
@@ -0,0 +1,420 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.sca.binding.ejb.util;
+
+import java.io.Externalizable;
+import java.io.Serializable;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.rmi.RemoteException;
+import java.rmi.UnexpectedException;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.ejb.EJBObject;
+import javax.rmi.CORBA.Util;
+
+import org.apache.tuscany.sca.binding.ejb.java2idl.ExceptionType;
+import org.apache.tuscany.sca.binding.ejb.java2idl.Java2IDLUtil;
+import org.omg.CORBA.ORB;
+import org.omg.CORBA.SystemException;
+import org.omg.CORBA.portable.ApplicationException;
+import org.omg.CORBA.portable.ObjectImpl;
+import org.omg.CORBA.portable.RemarshalException;
+import org.omg.CORBA.portable.ServantObject;
+import org.omg.CORBA_2_3.portable.InputStream;
+import org.omg.CORBA_2_3.portable.OutputStream;
+import org.osoa.sca.ServiceRuntimeException;
+
+/**
+ * EJBMessageHandler
+ */
+public class EJBHandler {
+ private Object ejbStub;
+
+ private InterfaceInfo interfaceInfo;
+ private Class ejbInterface;
+
+ public EJBHandler(NamingEndpoint namingEndpoint, Class ejbInterface) {
+ this(namingEndpoint, InterfaceInfo.getInstance(ejbInterface));
+ this.ejbInterface = ejbInterface;
+ }
+
+ // locates the stub
+ public EJBHandler(NamingEndpoint namingEndpoint, InterfaceInfo ejbInterface) {
+ try {
+ this.ejbStub = EJBStubHelper.lookup(namingEndpoint);
+ this.interfaceInfo = ejbInterface;
+ } catch (Exception e) {
+ Throwable b = e.getCause();
+ b.printStackTrace();
+ throw new ServiceRuntimeException(e);
+ }
+ }
+
+ private final static Map<String, Class> primitiveClasses = new HashMap<String, Class>();
+ static {
+ primitiveClasses.put("boolean", boolean.class);
+ primitiveClasses.put("byte", byte.class);
+ primitiveClasses.put("char", char.class);
+ primitiveClasses.put("short", short.class);
+ primitiveClasses.put("int", int.class);
+ primitiveClasses.put("long", long.class);
+ primitiveClasses.put("float", float.class);
+ primitiveClasses.put("double", double.class);
+ primitiveClasses.put("void", void.class);
+ }
+
+ private static Class loadClass(final String name) {
+ Class type = (Class)primitiveClasses.get(name);
+ if (type != null)
+ return type;
+ return (Class)AccessController.doPrivileged(new PrivilegedAction<Class>() {
+ public Class run() {
+ try {
+ ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
+ return Class.forName(name, true, classLoader);
+ } catch (ClassNotFoundException e) {
+ return null;
+ }
+ }
+ });
+ }
+
+ // invokes EJB method
+ public Object invoke(String methodName, Object[] args) {
+ Object response = null;
+ try {
+ if (ejbStub instanceof ObjectImpl) {
+ ObjectImpl objectImpl = (ObjectImpl)ejbStub;
+ // TODO: If the Java 2 security is turned on, then
+ // the ORB will try to create proxy
+ // from the interfaces defined on the stub
+ if (System.getSecurityManager() == null && objectImpl._is_local()) {
+ /*
+ * CORBA.Stub is what the object from JNDI will be for a
+ * remote EJB in the same JVM as the client, but with no
+ * stub classes available on the client
+ */
+ response = invokeLocalCORBACall(objectImpl, methodName, args);
+ } else {
+ /*
+ * _EJBObject_Stub is what the object from JNDI will be for
+ * a remote EJB with no stub classes available on the client
+ */
+ response = invokeRemoteCORBACall(objectImpl, methodName, args);
+ }
+ } else {
+ /*
+ * A generated ejb stub or it must be an EJB in the same ear as
+ * the client or an AppServer with a single classloader, so
+ * reflection can be used directly on the JNDI
+ */
+ JavaReflectionAdapter reflectionAdapter =
+ JavaReflectionAdapter.createJavaReflectionAdapter(ejbStub.getClass());
+ try {
+ Method method = reflectionAdapter.getMethod(methodName);
+ response = method.invoke(ejbStub, args);
+ } catch (InvocationTargetException e) {
+ Throwable t = e.getTargetException();
+ // FIXME need to throw really a business exception.
+ // ServiceBusinessException?
+ // Tuscany core doesn't have ServiceBusinessException
+ throw new ServiceRuntimeException(t);
+ }
+ }
+
+ return response;
+ } catch (Exception e) {
+ // FIXME this be business exception? Tuscany core doesn't have
+ // ServiceBusinessException
+ throw new ServiceRuntimeException(e);
+
+ } catch (Throwable e) {
+ throw new ServiceRuntimeException(e);
+ }
+ }
+
+ /**
+ * Get the IDL operation name for a java method
+ *
+ * @param methodName java method name
+ * @return The IDL operation name
+ */
+ private String getOperation(String methodName) {
+ if (interfaceInfo == null)
+ return methodName;
+ MethodInfo methodInfo = interfaceInfo.getMethod(methodName);
+ if (methodInfo != null)
+ return methodInfo.getIDLName();
+ else
+ return null;
+ }
+
+ /*
+ * Derive the EJB interface name from the Stub When loading a stub class
+ * corresponding to an interface or class <packagename>.<typename>, the
+ * class <packagename>._<typename>_Stub shall be used if it exists;
+ * otherwise, the class org.omg.stub.<packagename>._<typename>_Stub shall
+ * be used.
+ */
+ private static String getInterface(String stubName) {
+ int index = stubName.lastIndexOf('.');
+ String packageName = null;
+ String typeName = stubName;
+ if (index != -1) {
+ packageName = stubName.substring(0, index);
+ if (packageName.startsWith("org.omg.stub.")) {
+ packageName = packageName.substring("org.omg.stub.".length());
+ }
+ typeName = stubName.substring(index + 1);
+ }
+ if (typeName.startsWith("_") && typeName.endsWith("_Stub")) {
+ typeName = typeName.substring(1, typeName.length() - "_Stub".length());
+ }
+ if (packageName != null)
+ return packageName + "." + typeName;
+ else
+ return typeName;
+ }
+
+ /**
+ * Invoke a method on the local CORBA object
+ *
+ * @param stub
+ * @param methodName
+ * @param args
+ * @return
+ * @throws RemoteException
+ * @throws ServiceBusinessException
+ */
+ protected Object invokeLocalCORBACall(final ObjectImpl stub, String methodName, Object[] args)
+ throws RemoteException {
+
+ final String operation = getOperation(methodName);
+
+ Class type = loadClass(getInterface(stub.getClass().getName()));
+ if (type == null)
+ type = (ejbInterface != null) ? ejbInterface : EJBObject.class;
+
+ ServantObject so = stub._servant_preinvoke(operation, type);
+ if (so == null) {
+ // The Servant is not local any more
+ return invokeRemoteCORBACall(stub, methodName, args);
+ }
+ Object[] newArgs = null;
+ ORB orb = stub._orb();
+ try {
+ if (args != null)
+ newArgs = Util.copyObjects(args, orb);
+ JavaReflectionAdapter reflectionAdapter =
+ JavaReflectionAdapter.createJavaReflectionAdapter(so.servant.getClass());
+ Method method = reflectionAdapter.getMethod(methodName);
+ Object obj = reflectionAdapter.invoke(method, so.servant, newArgs);
+ Object result = Util.copyObject(obj, orb);
+ return result;
+
+ } catch (InvocationTargetException e) {
+ Throwable exCopy = (Throwable)Util.copyObject(e.getTargetException(), orb);
+ MethodInfo methodInfo = interfaceInfo.getMethod(methodName);
+ String[] exceptionTypes = methodInfo.getExceptionTypes();
+ for (int i = 0; i < exceptionTypes.length; i++) {
+ Class exceptionType = loadClass(exceptionTypes[i]);
+ if (exceptionType.isAssignableFrom(exCopy.getClass()))
+ throw new ServiceRuntimeException(exCopy); // FIXME should
+ // be business
+ // exception?
+ }
+ throw Util.wrapException(exCopy);
+ } catch (Throwable e) {
+ // Other exceptions thrown from "invoke"
+ throw new ServiceRuntimeException(e);
+ } finally {
+ stub._servant_postinvoke(so);
+ }
+ }
+
+ /**
+ * Invoke a method on a remote CORBA object
+ *
+ * @param stub The remote stub
+ * @param methodName The name of the method
+ * @param args Argument list
+ * @return
+ * @throws RemoteException
+ * @throws ServiceBusinessException
+ */
+ protected Object invokeRemoteCORBACall(ObjectImpl stub, String methodName, Object[] args) throws RemoteException {
+
+ try {
+ String operation = getOperation(methodName);
+
+ MethodInfo methodInfo = interfaceInfo.getMethod(methodName);
+ if (methodInfo == null) {
+ throw new ServiceRuntimeException("Invalid Method " + methodName);
+ }
+ String[] types = methodInfo.getParameterTypes();
+ if (args != null) {
+ if (types.length != args.length)
+ throw new ServiceRuntimeException(
+ "The argument list doesn't match the method signature of " + methodName);
+ }
+
+ Class[] parameterTypes = new Class[types.length];
+ for (int i = 0; i < types.length; i++) {
+ parameterTypes[i] = loadClass(types[i]);
+ }
+ Class returnType = loadClass(methodInfo.getReturnType());
+
+ InputStream in = null;
+ try {
+ OutputStream out = (OutputStream)stub._request(operation, true);
+
+ for (int i = 0; i < types.length; i++) {
+ // Object arg = (args.length < i) ? null : args[i];
+ writeValue(out, args[i], parameterTypes[i]);
+ }
+ if (returnType == void.class) {
+ // void return
+ stub._invoke(out);
+ return null;
+ } else {
+ // read the return value
+ in = (InputStream)stub._invoke(out);
+ Object response = readValue(in, returnType);
+ return response;
+ }
+
+ } catch (ApplicationException ex) {
+ in = (InputStream)ex.getInputStream();
+ String id = in.read_string();
+ // Check if the id matches to any declared exceptions for the
+ // method
+ String[] exceptionTypes = methodInfo.getExceptionTypes();
+ for (int i = 0; i < exceptionTypes.length; i++) {
+ Class exceptionType = loadClass(exceptionTypes[i]);
+ String exceptionId = ExceptionType.getExceptionType(exceptionType).getExceptionRepositoryId();
+ if (id.equals(exceptionId)) {
+ Throwable t = (Throwable)in.read_value(exceptionType);
+ throw new ServiceRuntimeException(t); // FIXME should
+ // be
+ // ServcieBusinessException?
+ // no support by
+ // Tuscany core
+ // for
+ // ServcieBusinessException.
+ }
+ }
+ throw new UnexpectedException(id);
+ } catch (RemarshalException ex) {
+ return invokeRemoteCORBACall(stub, methodName, args);
+ } finally {
+ stub._releaseReply(in);
+ }
+ } catch (SystemException ex) {
+ throw Util.mapSystemException(ex);
+ }
+ }
+
+ /**
+ * @param out
+ * @param value
+ * @param type
+ */
+ protected void writeValue(OutputStream out, Object value, Class type) {
+ if (type == null)
+ out.write_value((Serializable)value);
+ else if (type == Object.class || type == Serializable.class || type == Externalizable.class) {
+ // Any
+ Util.writeAny(out, value);
+ } else if (type == Integer.TYPE) {
+ // java int maps to CORBA long
+ out.write_long(((Integer)value).intValue());
+ } else if (type == Short.TYPE) {
+ out.write_short(((Short)value).shortValue());
+ } else if (type == Boolean.TYPE) {
+ out.write_boolean(((Boolean)value).booleanValue());
+ } else if (type == Byte.TYPE) {
+ out.write_octet(((Byte)value).byteValue());
+ } else if (type == Long.TYPE) {
+ out.write_longlong(((Long)value).longValue());
+ } else if (type == Double.TYPE) {
+ out.write_double(((Double)value).doubleValue());
+ } else if (type == Float.TYPE) {
+ out.write_float(((Float)value).floatValue());
+ } else if (type == Character.TYPE) {
+ out.write_wchar(((Character)value).charValue());
+ } else if (type.isArray()) {
+ out.write_value((Serializable)value, type);
+ } else if (Java2IDLUtil.isRemoteInterface(type)) {
+ // Remote interface
+ Util.writeRemoteObject(out, value);
+ } else if (Java2IDLUtil.isAbstractInterface(type)) {
+ // Non-remote Interface
+ Util.writeAbstractObject(out, value);
+ } else {
+ out.write_value((Serializable)value, type);
+ }
+ }
+
+ /**
+ * @param in
+ * @param type
+ * @return
+ */
+ protected Object readValue(InputStream in, Class type) {
+ Object value = null;
+ if (type == null)
+ value = in.read_value();
+ else if (type == Object.class || type == Serializable.class || type == Externalizable.class) {
+ value = Util.readAny(in);
+ } else if (type == Integer.TYPE) {
+ value = new Integer(in.read_long());
+ } else if (type == Short.TYPE) {
+ value = new Short(in.read_short());
+ } else if (type == Boolean.TYPE) {
+ value = new Boolean(in.read_boolean());
+ } else if (type == Byte.TYPE) {
+ value = new Byte(in.read_octet());
+ } else if (type == Long.TYPE) {
+ value = new Long(in.read_longlong());
+ } else if (type == Float.TYPE) {
+ value = new Float(in.read_float());
+ } else if (type == Double.TYPE) {
+ value = new Double(in.read_double());
+ } else if (type == Character.TYPE) {
+ value = new Character(in.read_wchar());
+ } else if (type.isArray()) {
+ // []
+ value = in.read_value(type);
+ } else if (Java2IDLUtil.isRemoteInterface(type)) {
+ // java.rmi.Remote
+ value = in.read_Object(type);
+ } else if (Java2IDLUtil.isAbstractInterface(type)) {
+ // Non-remote Interface
+ value = in.read_abstract_interface(type);
+ } else {
+ // java.io.Serializable
+ value = in.read_value(type);
+ }
+ return value;
+ }
+}
diff --git a/sca-java-1.x/tags/0.91-incubating/modules/binding-ejb/src/main/java/org/apache/tuscany/sca/binding/ejb/util/EJBLocator.java b/sca-java-1.x/tags/0.91-incubating/modules/binding-ejb/src/main/java/org/apache/tuscany/sca/binding/ejb/util/EJBLocator.java
new file mode 100644
index 0000000000..1369b92715
--- /dev/null
+++ b/sca-java-1.x/tags/0.91-incubating/modules/binding-ejb/src/main/java/org/apache/tuscany/sca/binding/ejb/util/EJBLocator.java
@@ -0,0 +1,511 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.sca.binding.ejb.util;
+
+import java.net.URL;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Properties;
+import java.util.Set;
+
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.InvalidNameException;
+import javax.naming.NamingException;
+
+import org.omg.CORBA.ORB;
+import org.omg.CORBA.ORBPackage.InvalidName;
+import org.omg.CosNaming.NamingContextExt;
+import org.omg.CosNaming.NamingContextExtHelper;
+
+/**
+ * CosNaming utility
+ */
+public class EJBLocator {
+
+ /*
+ * Root Context Initial Reference Key ------------
+ * ----------------------------------- Server Root NameServiceServerRoot
+ * Cell Persistent Root NameServiceCellPersistentRoot Cell Root
+ * NameServiceCellRoot, NameService Node Root NameServiceNodeRoot
+ */
+ public static final String SERVER_ROOT = "NameServiceServerRoot";
+ public static final String CELL_PERSISTENT_ROOT = "NameServiceCellPersistentRoot";
+ public static final String CELL_ROOT = "NameServiceCellRoot";
+ public static final String NODE_ROOT = "NameServiceNodeRoot";
+ public static final String DEFAULT_ROOT = "NameService"; // Same as
+ // CELL_ROOT
+
+ private static final Set ROOTS = new HashSet(Arrays.asList(new String[] {SERVER_ROOT, CELL_PERSISTENT_ROOT,
+ CELL_ROOT, DEFAULT_ROOT, NODE_ROOT}));
+
+ public static final String DEFAULT_HOST = "127.0.0.1"; // Default host name
+ // or IP address for
+ // Websphere
+ public static final int DEFAULT_NAMING_PORT = 2809; // Default port
+ public static final String NAMING_SERVICE = "NameService"; // The name of
+ // the naming
+ // service
+
+ // private static final String CHARS_TO_ESCAPE = "\\/.";
+ private static final String RFC2396 = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789;/:?@&=+$,-_.!~*'()";
+ private static final String HEX = "0123456789ABCDEF";
+
+ private String hostName = DEFAULT_HOST;
+ private int port = DEFAULT_NAMING_PORT;
+ private String root = SERVER_ROOT;
+
+ private ORB orb = null;
+ private ObjectLocator locator = null;
+ boolean managed = true;
+
+ public EJBLocator(boolean managed) {
+ this.managed = managed;
+ if (!managed) {
+ String url = (String)AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ return System.getProperty(Context.PROVIDER_URL);
+ }
+ });
+ processCorbaURL(url);
+ }
+ }
+
+ private void processCorbaURL(String url) {
+ if (url != null && (url.startsWith("corbaname:iiop:") || url.startsWith("corbaloc:iiop:"))) {
+ /**
+ * corbaname:iiop:<hostName>:<port>/<root>#name corbaloc:iiop:<hostname>:<port>/<root>
+ * For exmaple,
+ * "corbaname:iiop:localhost:2809/NameServiceServerRoot#ejb/MyEJBHome";
+ * or "corbaloc:iiop:myhost:2809/NameServiceServerRoot"
+ */
+ String[] parts = url.split("(:|/|#)");
+ if (parts.length > 2 && parts[2].length() > 0) {
+ hostName = parts[2]; // The host name
+ int index = hostName.lastIndexOf('@'); // version@hostname
+ if (index != -1)
+ hostName = hostName.substring(index + 1);
+ }
+ if (parts.length > 3 && parts[3].length() > 0)
+ port = Integer.parseInt(parts[3]); // The port number
+ if (parts.length > 4 && parts[4].length() > 0)
+ root = parts[4]; // The root of naming
+ }
+ }
+
+ public EJBLocator(String hostName, int port) {
+ this.hostName = (hostName == null) ? DEFAULT_HOST : hostName;
+ this.port = port > 0 ? port : DEFAULT_NAMING_PORT;
+ this.root = SERVER_ROOT;
+ }
+
+ public EJBLocator(String hostName, int port, String root) {
+ this(hostName, port);
+ if (ROOTS.contains(root))
+ this.root = root;
+ else
+ throw new IllegalArgumentException(root + " is not a legal root");
+ }
+
+ public EJBLocator(String corbaName, boolean managed) {
+ this.managed = managed;
+ if (corbaName.startsWith("corbaname:iiop:")) {
+ processCorbaURL(corbaName);
+ } else
+ throw new IllegalArgumentException(corbaName + " is not a legal corbaname");
+ }
+
+ /**
+ * The corbaloc and corbaname formats enable you to provide a URL to access
+ * CORBA objects. Use the corbaloc format for resolving to a particular
+ * CORBAservice without going through a naming service. Use the corbaname
+ * format to resolve a stringified name from a specific naming context.
+ */
+
+ /**
+ * Compose a corbaloc URI
+ *
+ * @param hostName
+ * @param port
+ * @param service
+ * @return
+ */
+ private static String getCorbaloc(String hostName, int port, String service) {
+ if (service == null)
+ return "corbaloc:iiop:" + hostName + ":" + port;
+ else
+ return "corbaloc:iiop:" + hostName + ":" + port + "/" + service;
+ }
+
+ private String getCorbaloc(String service) {
+ return getCorbaloc(hostName, port, service);
+ }
+
+ /**
+ * corbaname Syntax The full corbaname BNF is: &lt;corbaname&gt; =
+ * "corbaname:"&lt;corbaloc_obj&gt;["#"&lt;string_name&gt;]
+ * &lt;corbaloc_obj&gt; = &lt;obj_addr_list&gt; ["/"&lt;key_string&gt;]
+ * &lt;obj_addr_list&gt; = as defined in a corbaloc URL &lt;key_string&gt; =
+ * as defined in a corbaloc URL &lt;string_name&gt;= stringified Name
+ * empty_string Where:
+ * <ul>
+ * <li>corbaloc_obj: portion of a corbaname URL that identifies the naming
+ * context. The syntax is identical to its use in a corbaloc URL.
+ * <li>obj_addr_list: as defined in a corbaloc URL
+ * <li>key_string: as defined in a corbaloc URL.
+ * <li>string_name: a stringified Name with URL escapes as defined below.
+ * </ul>
+ *
+ * @param hostName The host name or IP address of the naming server
+ * @param port The port number of the naming service
+ * @param root The root of the namespace
+ * @param name The JNDI name
+ */
+ private static String getCorbaname(String hostName, int port, String root, String name) {
+ if (name == null)
+ return "corbaname:iiop:" + hostName + ":" + port + "/" + root;
+ else
+ return "corbaname:iiop:" + hostName + ":" + port + "/" + root + "#" + toCorbaname(name);
+ }
+
+ String getCorbaname(String name) {
+ return getCorbaname(hostName, port, root, name);
+ }
+
+ /**
+ * Connect to the ORB.
+ */
+
+ // FIXME. May need to change the IBM classes if this binding is contributed
+ // to Tuscany
+ public ORB connect() {
+ if (orb == null) {
+ Properties props = new Properties();
+ /* This code is for IBM JVM
+ props.put("org.omg.CORBA.ORBClass", "com.ibm.CORBA.iiop.ORB");
+ props.put("com.ibm.CORBA.ORBInitRef.NameService", getCorbaloc(NAMING_SERVICE));
+ props.put("com.ibm.CORBA.ORBInitRef.NameServiceServerRoot", getCorbaloc("NameServiceServerRoot")); */
+ orb = ORB.init((String[])null, props);
+ }
+ return orb;
+ }
+
+ /**
+ * Replace substrings
+ *
+ * @param source The source string.
+ * @param match The string to search for within the source string.
+ * @param replace The replacement for any matching components.
+ * @return
+ */
+ private static String replace(String source, String match, String replace) {
+ int index = source.indexOf(match, 0);
+ if (index >= 0) {
+
+ // We have at least one match, so gotta do the
+ // work...
+
+ StringBuffer result = new StringBuffer(source.length() + 16);
+ int matchLength = match.length();
+ int startIndex = 0;
+
+ while (index >= 0) {
+ result.append(source.substring(startIndex, index));
+ result.append(replace);
+ startIndex = index + matchLength;
+ index = source.indexOf(match, startIndex);
+ }
+
+ // Grab the last piece, if any...
+ if (startIndex < source.length()) {
+ result.append(source.substring(startIndex));
+ }
+
+ return result.toString();
+
+ } else {
+ // No matches, just return the source...
+ return source;
+ }
+ }
+
+ /**
+ * Resovled the JNDI name from the initial CosNaming context
+ *
+ * @param jndiName
+ * @return resovled CORBA ojbect
+ * @throws NamingException
+ */
+ private static org.omg.CORBA.Object resovleString(NamingContextExt initCtx, String jndiName) throws NamingException {
+ try {
+ String name = stringify(jndiName);
+ return initCtx.resolve_str(name);
+ } catch (Exception e) {
+ NamingException ne = new NamingException(e.getMessage());
+ ne.setRootCause(e);
+ throw ne;
+ }
+ }
+
+ private NamingContextExt getCosNamingContext(String namingRoot) throws NamingException {
+ /*
+ * Using an ORB reference to get an initial naming reference There are
+ * two basic ways to get an initial CosNaming context. Both ways involve
+ * an ORB method invocation. The first way is to invoke the
+ * resolve_initial_references method on the ORB with an initial
+ * reference key. For this call to work, the ORB must be initialized
+ * with an initial reference for that key. The other way is to invoke
+ * the string_to_object method on the ORB, passing in a CORBA object URL
+ * with the host and port of the bootstrap server. The following
+ * examples illustrate both approaches.
+ */
+
+ /*
+ * Invoking resolve_initial_references Once an ORB reference is
+ * obtained, invoke the resolve_initial_references method on the ORB to
+ * obtain a reference to the initial context. The following code example
+ * invokes resolve_initial_reference on an ORB reference
+ */
+ try {
+ connect();
+ org.omg.CORBA.Object rootCtx = orb.resolve_initial_references(namingRoot);
+ return NamingContextExtHelper.narrow(rootCtx);
+ } catch (InvalidName e) {
+ InvalidNameException ne = new InvalidNameException(e.getMessage());
+ ne.setRootCause(e);
+ throw ne;
+ }
+ }
+
+ /**
+ * Look up a CORBA object by its JNDI name
+ *
+ * @param jndiName
+ * @return
+ * @throws NamingException
+ */
+ org.omg.CORBA.Object stringToObject(String jndiName) throws NamingException {
+ /*
+ * Using an existing ORB and invoking string_to_object with a CORBA
+ * object URL with multiple name server addresses to get an initial
+ * context CORBA object URLs can contain more than one bootstrap server
+ * address. Use this feature when attempting to obtain an initial
+ * context from a server cluster. You can specify the bootstrap server
+ * addresses for all servers in the cluster in the URL. The operation
+ * will succeed if at least one of the servers is running, eliminating a
+ * single point of failure. There is no guarantee of any particular
+ * order in which the address list will be processed. For example, the
+ * second bootstrap server address may be used to obtain the initial
+ * context even though the first bootstrap server in the list is
+ * available. An example of a corbaloc URL with multiple addresses
+ * follows. obj =
+ * orb.string_to_object("corbaloc::myhost1:9810,:myhost1:9811,:myhost2:9810/NameService");
+ */
+ String corbaName = null;
+ if (jndiName.startsWith("corbaloc:") || jndiName.startsWith("corbaname:")) {
+ // Keep the qualified URL
+ corbaName = jndiName;
+ } else {
+ // Create a corbaname URL
+ corbaName = getCorbaname(jndiName);
+ }
+
+ connect();
+ org.omg.CORBA.Object obj = orb.string_to_object(corbaName);
+ return obj;
+ }
+
+ private boolean isJndiConfigured() {
+ if (managed)
+ return true;
+ Boolean provided = (Boolean)AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ String initCtxFactory = System.getProperty(Context.INITIAL_CONTEXT_FACTORY);
+ if (initCtxFactory == null) {
+ URL file = Thread.currentThread().getContextClassLoader().getResource("jndi.properties");
+ if (file != null)
+ return Boolean.TRUE;
+ else
+ return Boolean.FALSE;
+ } else
+ return Boolean.TRUE;
+ }
+ });
+ return provided.booleanValue();
+ }
+
+ /**
+ * The character escape rules for the stringified name portion of an
+ * corbaname are: US-ASCII alphanumeric characters are not escaped.
+ * Characters outside this range are escaped, except for the following: ; / : ? @ & = + $ , - _ . ! ~ * ' ( )
+ * corbaname Escape Mechanism The percent '%' character is used as an
+ * escape. If a character that requires escaping is present in a name
+ * component it is encoded as two hexadecimal digits following a "%"
+ * character to represent the octet. (The first hexadecimal character
+ * represent the highorder nibble of the octet, the second hexadecimal
+ * character represents the low-order nibble.) If a '%' is not followed by
+ * two hex digits, the stringified name is syntactically invalid.
+ * @param s
+ * @return RFC2396-encoded stringified name
+ */
+ static String encode2396(String s) {
+ if (s == null)
+ return null;
+ StringBuffer encoded = new StringBuffer(s);
+ for (int i = 0; i < encoded.length(); i++) {
+ char c = encoded.charAt(i);
+ if (RFC2396.indexOf(c) == -1) {
+ encoded.setCharAt(i, '%');
+ char ac[] = Integer.toHexString(c).toCharArray();
+ if (ac.length == 2)
+ encoded.insert(i + 1, ac);
+ else if (ac.length == 1) {
+ encoded.insert(i + 1, '0');
+ encoded.insert(i + 2, ac[0]);
+ } else {
+ throw new IllegalArgumentException("Invalid character '" + c + "' in \"" + s + "\"");
+ }
+ i += 2;
+ }
+ }
+ return encoded.toString();
+ }
+
+ /**
+ * Decode an RFC2396-encoded string
+ *
+ * @param s
+ * @return Plain string
+ */
+ static String decode2396(String s) {
+ if (s == null)
+ return null;
+ StringBuffer decoded = new StringBuffer(s);
+ for (int i = 0; i < decoded.length(); i++) {
+ char c = decoded.charAt(i);
+ if (c == '%') {
+ if (i + 2 >= decoded.length())
+ throw new IllegalArgumentException("Incomplete key_string escape sequence");
+ int j;
+ j = HEX.indexOf(decoded.charAt(i + 1)) * 16 + HEX.indexOf(decoded.charAt(i + 2));
+ decoded.setCharAt(i, (char)j);
+ decoded.delete(i + 1, i + 3);
+ } else if (RFC2396.indexOf(c) == -1)
+ throw new IllegalArgumentException("Invalid key_string character '" + c + "'");
+ }
+ return decoded.toString();
+ }
+
+ /**
+ * The backslash '\' character escapes the reserved meaning of '/', '.', and
+ * '\' in a stringified name.
+ *
+ * @param jndiName
+ * @return Escaped stringified name for CosNaming
+ */
+ private static String stringify(String jndiName) {
+ // Esacpe . into \. since it's an INS naming delimeter
+ return replace(encode2396(jndiName), ".", "\\.");
+ }
+
+ /**
+ * Escape the "." into "%5C%2E"
+ *
+ * @param jndiName
+ * @return corbaname treating "." as a literal
+ */
+ private static String toCorbaname(String jndiName) {
+ // Esacpe . into %5C%2E (\.) since it's an INS naming delimeter
+ // For example, sca.sample.StockQuote --->
+ // sca%5C%2Esample%5C%2EStockQuote/StockQuote
+ return replace(encode2396(jndiName), ".", "%5C%2E");
+ }
+
+ private ObjectLocator getObjectLocator() throws NamingException {
+ if (locator != null)
+ return locator;
+ /*
+ * For managed env, jndi is assumed to be configured by default For
+ * unmanaged environment, jndi could have configured through
+ * jndi.properties file
+ */
+ if (isJndiConfigured()) {
+ locator = new JndiLocator();
+ } else { // this is definitely JSE env without jndi configured. Use
+ // Corba.
+ locator = new CosNamingLocator();
+ }
+ return locator;
+ }
+
+ public Object locate(String jndiName) throws NamingException {
+
+ Object result = getObjectLocator().locate(jndiName);
+ return result;
+ }
+
+ private static interface ObjectLocator {
+ public Object locate(String name) throws NamingException;
+ }
+
+ private class JndiLocator implements ObjectLocator {
+ private Context context;
+
+ private JndiLocator() throws NamingException {
+ this.context = new InitialContext();
+ }
+
+ private JndiLocator(Context context) {
+ this.context = context;
+ }
+
+ public Object locate(String name) throws NamingException {
+ try {
+ return context.lookup(name);
+ } catch (Exception e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+ }
+
+ private class CosNamingLocator implements ObjectLocator {
+ private NamingContextExt context = null;
+
+ private CosNamingLocator() {
+ }
+
+ private CosNamingLocator(NamingContextExt context) {
+ this.context = context;
+ }
+
+ public Object locate(String name) throws NamingException {
+ if (context != null)
+ return resovleString(context, name);
+ else
+ return stringToObject(name);
+ }
+ }
+
+ public void setHostEnv(boolean managed) {
+ this.managed = managed;
+ }
+}
diff --git a/sca-java-1.x/tags/0.91-incubating/modules/binding-ejb/src/main/java/org/apache/tuscany/sca/binding/ejb/util/EJBObjectFactory.java b/sca-java-1.x/tags/0.91-incubating/modules/binding-ejb/src/main/java/org/apache/tuscany/sca/binding/ejb/util/EJBObjectFactory.java
new file mode 100644
index 0000000000..1538c27716
--- /dev/null
+++ b/sca-java-1.x/tags/0.91-incubating/modules/binding-ejb/src/main/java/org/apache/tuscany/sca/binding/ejb/util/EJBObjectFactory.java
@@ -0,0 +1,188 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.sca.binding.ejb.util;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.rmi.RemoteException;
+import java.rmi.UnexpectedException;
+
+import javax.ejb.CreateException;
+import javax.ejb.EJBLocalHome;
+import javax.naming.NamingException;
+import javax.rmi.CORBA.Util;
+
+import org.omg.CORBA.SystemException;
+import org.omg.CORBA.portable.ApplicationException;
+import org.omg.CORBA.portable.ObjectImpl;
+import org.omg.CORBA.portable.RemarshalException;
+import org.osoa.sca.ServiceRuntimeException;
+
+public class EJBObjectFactory {
+
+ private EJBObjectFactory() {
+ }
+
+ /**
+ * Get either a generated of dynamic EJB stub using the specified JNDI
+ * properties.
+ * <p>
+ * The returned stub will implement the specified stubInterface Interface.
+ * If the underlying EJB stub is not assignable from the specified
+ * stubInterface then a proxy is used to convert between the two.
+ * <p>
+ * The returned EJB stub may be either the pregenerated EJB stub or a
+ * dynamic stub. This allows a client to invoke an EJB without requiring any
+ * of the pregenerated EJB stub classes be avaiable in the classpath.
+ * <p>
+ */
+ public static Object createStub(NamingEndpoint namingEndpoint) throws NamingException, RemoteException,
+ CreateException {
+
+ EJBLocator locator = namingEndpoint.getLocator();
+ Object homeObject = locator.locate(namingEndpoint.getJndiName());
+ /*
+ * The type of the object returned from the lookup is as follows: If the
+ * generated stub exists on the classpath, it's an instance of that
+ * type, otherwise, "org.omg.stub.java.rmi._Remote_Stub" or
+ * "org.omg.stub.javax.ejb._EJBHome_Stub"
+ */
+ Object stub = getEJBStub(homeObject);
+ // Cache dynamic stub only
+ return stub;
+ }
+
+ /**
+ * @param homeObject
+ * @param ejbHomeClass
+ * @return
+ * @throws RemoteException
+ */
+ protected static Object getEJBStub(Object homeObject) throws RemoteException, CreateException {
+
+ Object stub = null;
+ if (homeObject instanceof EJBLocalHome) {
+ // Local EJB
+ stub = createEJBLocalObject(homeObject);
+ } else {
+ // Handle dynamic stub
+ if (homeObject instanceof ObjectImpl) {
+ ObjectImpl objectImpl = (ObjectImpl)homeObject;
+ stub = createEJBObject(objectImpl);
+ } /**
+ * Above checks will be satisfied if Bean is running on servers like Websphere. With this
+ * logic, client (SCA composite with EJB ref binding) doesn't need to include home class or
+ * client stubs.
+ *
+ * Below check is needed SCA composite with EJB ref binding is accessing openEJB implementation.
+ * For e.g if the bean is running on Geronimo.
+ */
+ else if ((javax.rmi.PortableRemoteObject.narrow(homeObject, javax.ejb.EJBHome.class)) instanceof javax.ejb.EJBHome) {
+ stub = createEJBObjectFromHome(homeObject);
+ } else
+ throw new ServiceRuntimeException("Invalid stub type: " + homeObject.getClass());
+ }
+ return stub;
+ }
+
+ /**
+ * Create a pre-generated EJB stub
+ *
+ * @param homeObject
+ * @return
+ * @throws RemoteException
+ */
+ protected static Object createEJBLocalObject(Object homeObject) throws RemoteException {
+
+ Object stub = null;
+ try {
+ // Find the "create()" method
+ Method createMethod = homeObject.getClass().getMethod("create", null);
+ // Create an EJB object
+ stub = createMethod.invoke(homeObject, null);
+ } catch (NoSuchMethodException e) {
+ // "create()" method not found, it's still a dynamic stub
+ stub = null;
+ } catch (InvocationTargetException e) {
+ throw new RemoteException(e.getTargetException().toString());
+ } catch (Exception e) {
+ throw new RemoteException(e.toString());
+ }
+ return stub;
+ }
+
+ /**
+ * Here homeObject is instance of EJBHome
+ *
+ * @param homeObject
+ * @return
+ * @throws RemoteException
+ */
+ protected static Object createEJBObjectFromHome(Object homeObject) throws RemoteException {
+
+ Object stub = null;
+ try {
+ // Find the "create()" method
+ Method createMethod = homeObject.getClass().getMethod("create", null);
+ // Create an EJB object
+ stub = createMethod.invoke(homeObject, null);
+ } catch (NoSuchMethodException e) {
+ // "create()" method not found, it's still a dynamic stub
+ stub = null;
+ } catch (InvocationTargetException e) {
+ throw new RemoteException(e.getTargetException().toString());
+ } catch (Exception e) {
+ throw new RemoteException(e.toString());
+ }
+ return stub;
+ }
+
+ /**
+ * Create an EJBObject using RMI/IIOP APIs
+ *
+ * @param ejbHomeObject
+ * @return The EJBObject remote stub
+ * @throws CreateException
+ * @throws RemoteException
+ */
+ protected static Object createEJBObject(ObjectImpl ejbHomeObject) throws CreateException, RemoteException {
+
+ try {
+ org.omg.CORBA_2_3.portable.InputStream in = null;
+ try {
+ org.omg.CORBA.portable.OutputStream out = ejbHomeObject._request("create", true);
+ in = (org.omg.CORBA_2_3.portable.InputStream)ejbHomeObject._invoke(out);
+ return (Object)in.read_Object(Object.class);
+ } catch (ApplicationException ex) {
+ in = (org.omg.CORBA_2_3.portable.InputStream)ex.getInputStream();
+ String id = in.read_string();
+ if (id.equals("IDL:javax/ejb/CreateEx:1.0")) {
+ throw (CreateException)in.read_value(CreateException.class);
+ }
+ throw new UnexpectedException(id);
+ } catch (RemarshalException ex) {
+ return createEJBObject(ejbHomeObject);
+ } finally {
+ ejbHomeObject._releaseReply(in);
+ }
+ } catch (SystemException ex) {
+ throw Util.mapSystemException(ex);
+ }
+ }
+}
diff --git a/sca-java-1.x/tags/0.91-incubating/modules/binding-ejb/src/main/java/org/apache/tuscany/sca/binding/ejb/util/EJBStubHelper.java b/sca-java-1.x/tags/0.91-incubating/modules/binding-ejb/src/main/java/org/apache/tuscany/sca/binding/ejb/util/EJBStubHelper.java
new file mode 100644
index 0000000000..ee05420cd7
--- /dev/null
+++ b/sca-java-1.x/tags/0.91-incubating/modules/binding-ejb/src/main/java/org/apache/tuscany/sca/binding/ejb/util/EJBStubHelper.java
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.sca.binding.ejb.util;
+
+import java.rmi.RemoteException;
+
+import javax.ejb.CreateException;
+import javax.naming.NamingException;
+
+import org.osoa.sca.ServiceRuntimeException;
+import org.osoa.sca.ServiceUnavailableException;
+
+public class EJBStubHelper {
+
+ private static Object stub;
+ private static ServiceRuntimeException exception;
+
+ private EJBStubHelper() {
+ }
+
+ /**
+ * @param owner
+ * @param jndiName
+ * @return
+ */
+
+ public static Object lookup(NamingEndpoint endpoint) {
+ return getStub(endpoint);
+ }
+
+ public static Object getStub(NamingEndpoint namingEndpoint) {
+ try {
+ stub = EJBObjectFactory.createStub(namingEndpoint);
+ } catch (NamingException e) {
+ exception = new ServiceUnavailableException(e);
+ e.printStackTrace();
+ throw (ServiceUnavailableException)exception;
+ } catch (CreateException e) {
+ exception = new ServiceUnavailableException(e);
+ throw (ServiceUnavailableException)exception;
+ } catch (RemoteException e) {
+ exception = new ServiceRuntimeException(e);
+ throw (ServiceRuntimeException)exception;
+ }
+
+ if (exception == null) {
+ return stub; // Normal result
+ } else {
+ throw exception; // Throw the exception
+ }
+ }
+
+}
diff --git a/sca-java-1.x/tags/0.91-incubating/modules/binding-ejb/src/main/java/org/apache/tuscany/sca/binding/ejb/util/InterfaceInfo.java b/sca-java-1.x/tags/0.91-incubating/modules/binding-ejb/src/main/java/org/apache/tuscany/sca/binding/ejb/util/InterfaceInfo.java
new file mode 100644
index 0000000000..19f4063a12
--- /dev/null
+++ b/sca-java-1.x/tags/0.91-incubating/modules/binding-ejb/src/main/java/org/apache/tuscany/sca/binding/ejb/util/InterfaceInfo.java
@@ -0,0 +1,125 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.sca.binding.ejb.util;
+
+import java.io.Serializable;
+import java.lang.reflect.Method;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.WeakHashMap;
+
+import org.apache.tuscany.sca.binding.ejb.java2idl.Java2IDL;
+import org.apache.tuscany.sca.binding.ejb.java2idl.OperationType;
+
+// import commonj.sdo.DataObject;
+
+/**
+ * The signature for a java interface
+ */
+public class InterfaceInfo implements Serializable {
+
+ private static final Map interfaces = Collections.synchronizedMap(new WeakHashMap());
+
+ private static final long serialVersionUID = 2314533906465094860L;
+ private String name;
+
+ private Map methods = new HashMap();
+
+ public synchronized final static InterfaceInfo getInstance(final Class iface) {
+ InterfaceInfo info = (InterfaceInfo)interfaces.get(iface);
+ if (info == null) {
+ info = new InterfaceInfo(iface);
+ interfaces.put(iface, info);
+ }
+ return info;
+ }
+
+ public InterfaceInfo(final Class iface) {
+ super();
+ if (iface == null)
+ throw new IllegalArgumentException("The interface cannot be null");
+ this.name = iface.getName();
+ // SECURITY
+ /*
+ * Permission: accessDeclaredMembers : Access denied
+ * (java.lang.RuntimePermission accessDeclaredMembers)
+ */
+ Map idlNames = (Map)AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ return Java2IDL.getIDLMapping(iface);
+ }
+ });
+ Iterator i = idlNames.entrySet().iterator();
+ while (i.hasNext()) {
+ Map.Entry entry = (Map.Entry)i.next();
+ Method method = (Method)entry.getKey();
+ OperationType operationType = (OperationType)entry.getValue();
+ MethodInfo methodInfo = new MethodInfo(method);
+ methodInfo.setIDLName(operationType.getIDLName());
+ methods.put(method.getName(), methodInfo);
+ }
+ }
+
+ /*
+ * public InterfaceInfo(String portType, String wsdlOperationName) {
+ * super(); this.name = portType; // <DataObject> operation(<DataObject>)
+ * throws RemoteException MethodInfo method = new
+ * MethodInfo(wsdlOperationName, DataObject.class.getName(), new
+ * String[]{DataObject.class.getName()}, new
+ * String[]{RemoteException.class.getName()}); methods.put(method.getName(),
+ * method); }
+ */
+
+ /**
+ * @return
+ */
+ public Map getMethods() {
+ return methods;
+ }
+
+ /**
+ * @return
+ */
+ public MethodInfo getMethod(String name) {
+ return (MethodInfo)methods.get(name);
+ }
+
+ /**
+ * @return
+ */
+ public String getName() {
+ return name;
+ }
+
+ public String toString() {
+ StringBuffer sb = new StringBuffer();
+ sb.append("interface ").append(name).append("{ \n");
+ Iterator i = methods.values().iterator();
+ while (i.hasNext()) {
+ MethodInfo methodInfo = (MethodInfo)i.next();
+ sb.append("\t").append(methodInfo).append("\n");
+ }
+ sb.append("};\n");
+ return sb.toString();
+ }
+}
diff --git a/sca-java-1.x/tags/0.91-incubating/modules/binding-ejb/src/main/java/org/apache/tuscany/sca/binding/ejb/util/JavaReflectionAdapter.java b/sca-java-1.x/tags/0.91-incubating/modules/binding-ejb/src/main/java/org/apache/tuscany/sca/binding/ejb/util/JavaReflectionAdapter.java
new file mode 100644
index 0000000000..db762aeb13
--- /dev/null
+++ b/sca-java-1.x/tags/0.91-incubating/modules/binding-ejb/src/main/java/org/apache/tuscany/sca/binding/ejb/util/JavaReflectionAdapter.java
@@ -0,0 +1,155 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.sca.binding.ejb.util;
+
+import java.beans.PropertyDescriptor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.WeakHashMap;
+
+import org.osoa.sca.ServiceRuntimeException;
+
+/**
+ * An adapter for java classes, indexes the methods by name and provides an
+ * invoke method that takes a method name.
+ */
+public class JavaReflectionAdapter {
+
+ private static Map adapters = Collections.synchronizedMap(new WeakHashMap());
+
+ private Class clazz;
+ private Map methodMap = new HashMap();
+
+ /**
+ * Create a java reflection adapter
+ *
+ * @param clazz
+ */
+ public synchronized static JavaReflectionAdapter createJavaReflectionAdapter(Class clazz) {
+ JavaReflectionAdapter adapter = (JavaReflectionAdapter)adapters.get(clazz);
+ if (adapter == null) {
+ adapter = new JavaReflectionAdapter(clazz);
+ adapters.put(clazz, adapter);
+ }
+ return adapter;
+ }
+
+ /**
+ * Constructor
+ *
+ * @param clazz
+ */
+ private JavaReflectionAdapter(final Class clazz) {
+ this.clazz = clazz;
+
+ // Index the methods on the implementation class
+ Method[] methods = (Method[])AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ return clazz.getMethods();
+ }
+ });
+ for (int i = 0, n = methods.length; i < n; i++) {
+ methodMap.put(methods[i].getName(), methods[i]);
+ }
+ }
+
+ /**
+ * Returns a map containing the methods on the class, keyed by name
+ *
+ * @return
+ */
+ public Map getMethods() {
+ return methodMap;
+ }
+
+ /**
+ * Return the specified method
+ *
+ * @param methodName
+ * @return
+ * @throws NoSuchMethodException
+ */
+ public Method getMethod(String methodName) throws NoSuchMethodException {
+
+ Method method = (Method)methodMap.get(methodName);
+ if (method == null)
+ throw new NoSuchMethodException(methodName);
+ return method;
+ }
+
+ private final static Map DEFAULT_PRIMITIVE_VALUES = new HashMap();
+ static {
+ DEFAULT_PRIMITIVE_VALUES.put(boolean.class, Boolean.FALSE);
+ DEFAULT_PRIMITIVE_VALUES.put(byte.class, new Byte((byte)0));
+ DEFAULT_PRIMITIVE_VALUES.put(char.class, new Character((char)0));
+ DEFAULT_PRIMITIVE_VALUES.put(short.class, new Short((short)0));
+ DEFAULT_PRIMITIVE_VALUES.put(int.class, new Integer(0));
+ DEFAULT_PRIMITIVE_VALUES.put(long.class, new Long(0));
+ DEFAULT_PRIMITIVE_VALUES.put(float.class, new Float(0.0));
+ DEFAULT_PRIMITIVE_VALUES.put(double.class, new Double(0.0));
+ }
+
+ /**
+ * Invoke a method using Java reflection.
+ *
+ * @param method
+ * @param object
+ * @param args
+ * @return
+ * @throws InvocationTargetException
+ * @throws IllegalAccessException
+ */
+ public Object invoke(Method method, Object object, Object[] args) throws InvocationTargetException,
+ IllegalAccessException {
+ Class[] parameterTypes = method.getParameterTypes();
+ for (int i = 0; i < parameterTypes.length; i++) {
+ Class parameterType = parameterTypes[i];
+ if (args[i] == null && parameterType.isPrimitive()) {
+ args[i] = DEFAULT_PRIMITIVE_VALUES.get(parameterType);
+ }
+ }
+ return method.invoke(object, args);
+ }
+
+ /**
+ * Set the java bean property
+ *
+ * @param bean
+ * @param propertyName
+ * @param value
+ * @return
+ */
+ public boolean setProperty(Object bean, String propertyName, Object value) {
+ try {
+ PropertyDescriptor propertyDescriptor = new PropertyDescriptor(propertyName, bean.getClass());
+ Method writeMethod = propertyDescriptor.getWriteMethod();
+ writeMethod.invoke(bean, new Object[] {value});
+ return true;
+ } catch (InvocationTargetException e) {
+ throw new ServiceRuntimeException(e.getTargetException());
+ } catch (Exception e) {
+ return false;
+ }
+ }
+}
diff --git a/sca-java-1.x/tags/0.91-incubating/modules/binding-ejb/src/main/java/org/apache/tuscany/sca/binding/ejb/util/MethodInfo.java b/sca-java-1.x/tags/0.91-incubating/modules/binding-ejb/src/main/java/org/apache/tuscany/sca/binding/ejb/util/MethodInfo.java
new file mode 100644
index 0000000000..ac3ace2d6c
--- /dev/null
+++ b/sca-java-1.x/tags/0.91-incubating/modules/binding-ejb/src/main/java/org/apache/tuscany/sca/binding/ejb/util/MethodInfo.java
@@ -0,0 +1,176 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.sca.binding.ejb.util;
+
+import java.io.Serializable;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * MetaData for a java method
+ */
+public class MethodInfo implements Serializable {
+
+ /** Automatically generated javadoc for: serialVersionUID */
+ private static final long serialVersionUID = -5557260979514687514L;
+ private String name;
+ private String returnType;
+ private String[] parameterTypes;
+ private String[] exceptionTypes;
+
+ private String IDLName;
+
+ /**
+ * Type Signature Java Type -------------- --------- Z boolean B byte C char
+ * S short I int J long F float D double L fully-qualified-class ;
+ * fully-qualified-class [ type type[] ( arg-types ) ret-type method type
+ */
+ private final static Map signatures = new HashMap();
+ static {
+ signatures.put("Z", boolean.class);
+ signatures.put("B", byte.class);
+ signatures.put("C", char.class);
+ signatures.put("S", short.class);
+ signatures.put("I", int.class);
+ signatures.put("J", long.class);
+ signatures.put("F", float.class);
+ signatures.put("D", double.class);
+ signatures.put("V", void.class);
+ }
+
+ public MethodInfo(Method method) {
+ this.name = method.getName();
+ // this.declaringClass = method.getDeclaringClass().getName();
+ this.returnType = method.getReturnType().getName();
+ Class[] types = method.getParameterTypes();
+ this.parameterTypes = new String[types.length];
+ for (int i = 0; i < types.length; i++) {
+ this.parameterTypes[i] = types[i].getName();
+ }
+ types = method.getExceptionTypes();
+ this.exceptionTypes = new String[types.length];
+ for (int i = 0; i < types.length; i++) {
+ this.exceptionTypes[i] = types[i].getName();
+ }
+ IDLName = this.name;
+ }
+
+ protected MethodInfo(String name, String returnType, String[] parameterTypes, String[] exceptionTypes) {
+ this.name = name;
+ this.returnType = returnType;
+ this.parameterTypes = parameterTypes;
+ this.exceptionTypes = exceptionTypes;
+ this.IDLName = name;
+ }
+
+ /**
+ * Parse the class name from the internal signature Sample signatures: int
+ * ---> I; int[] ---> [I Object ---> java/lang/Object Object[] --->
+ * [Ljava/lang/Object;
+ *
+ * @param value
+ * @return
+ */
+ private static String getName(String signature) {
+ String name = signature;
+ // Remove leading ARRAY ([) signatures
+ int index = name.lastIndexOf('[');
+ if (index != -1)
+ name = name.substring(index + 1);
+
+ // Remove L<...>;
+ if (name.charAt(0) == 'L' && name.charAt(name.length() - 1) == ';')
+ name = name.substring(1, name.length() - 1);
+
+ // Primitive types
+ Class primitiveClass = (Class)signatures.get(name);
+ if (primitiveClass != null) {
+ name = primitiveClass.getName();
+ }
+
+ for (int i = 0; i < index + 1; i++) {
+ name = name + "[]";
+ }
+ return name;
+ }
+
+ /**
+ * @return
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * @return
+ */
+ public String[] getParameterTypes() {
+ return parameterTypes;
+ }
+
+ /**
+ * @return
+ */
+ public String getReturnType() {
+ return returnType;
+ }
+
+ /**
+ * @return
+ */
+ public String[] getExceptionTypes() {
+ return exceptionTypes;
+ }
+
+ public String toString() {
+ StringBuffer sb = new StringBuffer();
+ sb.append(getName(returnType)).append(" ").append(name).append("(");
+ for (int j = 0; j < parameterTypes.length; j++) {
+ sb.append(getName(parameterTypes[j])).append(" ").append("arg" + j);
+ if (j < (parameterTypes.length - 1))
+ sb.append(", ");
+ }
+ sb.append(")");
+ if (exceptionTypes.length > 0) {
+ sb.append(" throws ");
+ for (int k = 0; k < exceptionTypes.length; k++) {
+ sb.append(exceptionTypes[k]);
+ if (k < (exceptionTypes.length - 1))
+ sb.append(", ");
+ }
+ }
+ sb.append(";");
+ return sb.toString();
+ }
+
+ /**
+ * @return Returns the iDLName.
+ */
+ public String getIDLName() {
+ return IDLName;
+ }
+
+ /**
+ * @param name The iDLName to set.
+ */
+ public void setIDLName(String name) {
+ IDLName = name;
+ }
+}
diff --git a/sca-java-1.x/tags/0.91-incubating/modules/binding-ejb/src/main/java/org/apache/tuscany/sca/binding/ejb/util/NamingEndpoint.java b/sca-java-1.x/tags/0.91-incubating/modules/binding-ejb/src/main/java/org/apache/tuscany/sca/binding/ejb/util/NamingEndpoint.java
new file mode 100644
index 0000000000..5d4b91d0f9
--- /dev/null
+++ b/sca-java-1.x/tags/0.91-incubating/modules/binding-ejb/src/main/java/org/apache/tuscany/sca/binding/ejb/util/NamingEndpoint.java
@@ -0,0 +1,118 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.sca.binding.ejb.util;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+public class NamingEndpoint {
+ private String jndiName;
+ private EJBLocator locator;
+ private boolean managed = true;
+
+ public NamingEndpoint(String hostName, int port, String jndiName) {
+ this.jndiName = jndiName;
+ this.locator = new EJBLocator(hostName, port);
+ }
+
+ public NamingEndpoint(String name) {
+
+ /**
+ * by default it's a managed environment means SCA composite with ref binding is running on
+ * an AppServer. If running on J2SE, pass -Dmanaged=false for the VM
+ */
+ String managedEnv = (String)AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ return System.getProperty("managed");
+ }
+ });
+
+ if (managedEnv != null)
+ managed = new Boolean(managedEnv);
+
+ if ((!managed) && name.startsWith("corbaname:iiop:")) {
+ /**
+ * if (name.startsWith("corbaname:iiop:")) { corbaname:iiop:<hostName>:<port>/<root>#name
+ * For exmaple,
+ * "corbaname:iiop:localhost:2809/NameServiceServerRoot#ejb/MyEJBHome";
+ */
+
+ String[] parts = split(name, '#');
+ if (parts.length != 2)
+ throw new IllegalArgumentException("Invalid corbaname: " + name);
+
+ this.jndiName = parts[1]; // The logical jndi name
+ this.locator = new EJBLocator(parts[0], managed);
+
+ } else {
+ this.jndiName = name;
+ this.locator = new EJBLocator(managed);
+ }
+
+ }
+
+ private static String[] split(String str, char ch) {
+ int index = str.lastIndexOf(ch);
+ if (index == -1) {
+ return new String[] {str, ""};
+ } else {
+ return new String[] {str.substring(0, index), str.substring(index + 1)};
+ }
+ }
+
+ /**
+ * @return Returns the jndiName.
+ */
+ public String getJndiName() {
+ return jndiName;
+ }
+
+ public EJBLocator getLocator() {
+ return locator;
+ }
+
+ public String getCorbaname() {
+ return locator.getCorbaname(jndiName);
+ }
+
+ /**
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ public boolean equals(Object obj) {
+ if (obj instanceof NamingEndpoint) {
+ NamingEndpoint endpoint = (NamingEndpoint)obj;
+ return jndiName.equals(endpoint.jndiName);
+ }
+ return false;
+ }
+
+ /**
+ * @see java.lang.Object#hashCode()
+ */
+ public int hashCode() {
+ return jndiName.hashCode();
+ }
+
+ /**
+ * @see java.lang.Object#toString()
+ */
+ public String toString() {
+ return jndiName;
+ }
+}