tuscany-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rf...@apache.org
Subject svn commit: r562321 - in /incubator/tuscany/java/sca/modules/binding-ejb/src: main/java/org/apache/tuscany/sca/binding/ejb/corba/ test/java/calculator/
Date Fri, 03 Aug 2007 03:54:15 GMT
Author: rfeng
Date: Thu Aug  2 20:54:14 2007
New Revision: 562321

URL: http://svn.apache.org/viewvc?view=rev&rev=562321
Log:
(Add missing files) Improve the binding-ejb:
* OpenEJB 3.0.0 SNAPSHOT and Geronimo 2.0 SNAPSHOT
* Support for OpenEJB JNDI and CosNaming
* Simplified Java2IDL

Added:
    incubator/tuscany/java/sca/modules/binding-ejb/src/main/java/org/apache/tuscany/sca/binding/ejb/corba/
    incubator/tuscany/java/sca/modules/binding-ejb/src/main/java/org/apache/tuscany/sca/binding/ejb/corba/ClassLoadingUtil.java   (with props)
    incubator/tuscany/java/sca/modules/binding-ejb/src/main/java/org/apache/tuscany/sca/binding/ejb/corba/DynamicStubClassLoader.java   (with props)
    incubator/tuscany/java/sca/modules/binding-ejb/src/main/java/org/apache/tuscany/sca/binding/ejb/corba/Java2IDLUtil.java   (with props)
    incubator/tuscany/java/sca/modules/binding-ejb/src/main/java/org/apache/tuscany/sca/binding/ejb/corba/ObjectInputStreamExt.java   (with props)
    incubator/tuscany/java/sca/modules/binding-ejb/src/main/java/org/apache/tuscany/sca/binding/ejb/corba/StubMethodInterceptor.java   (with props)
    incubator/tuscany/java/sca/modules/binding-ejb/src/main/java/org/apache/tuscany/sca/binding/ejb/corba/UtilInitializer.java   (with props)
    incubator/tuscany/java/sca/modules/binding-ejb/src/test/java/calculator/
    incubator/tuscany/java/sca/modules/binding-ejb/src/test/java/calculator/AddService.java   (with props)
    incubator/tuscany/java/sca/modules/binding-ejb/src/test/java/calculator/AddServiceHome.java   (with props)

Added: incubator/tuscany/java/sca/modules/binding-ejb/src/main/java/org/apache/tuscany/sca/binding/ejb/corba/ClassLoadingUtil.java
URL: http://svn.apache.org/viewvc/incubator/tuscany/java/sca/modules/binding-ejb/src/main/java/org/apache/tuscany/sca/binding/ejb/corba/ClassLoadingUtil.java?view=auto&rev=562321
==============================================================================
--- incubator/tuscany/java/sca/modules/binding-ejb/src/main/java/org/apache/tuscany/sca/binding/ejb/corba/ClassLoadingUtil.java (added)
+++ incubator/tuscany/java/sca/modules/binding-ejb/src/main/java/org/apache/tuscany/sca/binding/ejb/corba/ClassLoadingUtil.java Thu Aug  2 20:54:14 2007
@@ -0,0 +1,365 @@
+/*
+ * 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.corba;
+
+import java.lang.reflect.Array;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Utility class for loading classes by a variety of name variations.
+ * <p/>
+ * Supported names types are:
+ * <p/>
+ * 1)  Fully qualified class name (e.g., "java.lang.String", "org.apache.geronimo.kernel.ClassLoading"
+ * 2)  Method signature encoding ("Ljava.lang.String;", "J", "I", etc.)
+ * 3)  Primitive type names ("int", "boolean", etc.)
+ * 4)  Method array signature strings ("[I", "[Ljava.lang.String")
+ * 5)  Arrays using Java code format ("int[]", "java.lang.String[][]")
+ * <p/>
+ * The classes are loaded using the provided class loader.  For the basic types, the primitive
+ * reflection types are returned.
+ *
+ * @version $Rev$
+ */
+public class ClassLoadingUtil {
+
+    /**
+     * Table for mapping primitive class names/signatures to the implementing
+     * class object
+     */
+    private static final HashMap PRIMITIVE_CLASS_MAP = new HashMap();
+
+    /**
+     * Table for mapping primitive classes back to their name signature type, which
+     * allows a reverse mapping to be performed from a class object into a resolvable
+     * signature.
+     */
+    private static final HashMap CLASS_TO_SIGNATURE_MAP = new HashMap();
+
+
+    /**
+     * Setup the primitives map.  We make any entry for each primitive class using both the
+     * human readable name and the method signature shorthand type.
+     */
+    static {
+        PRIMITIVE_CLASS_MAP.put("boolean", boolean.class);
+        PRIMITIVE_CLASS_MAP.put("Z", boolean.class);
+        PRIMITIVE_CLASS_MAP.put("byte", byte.class);
+        PRIMITIVE_CLASS_MAP.put("B", byte.class);
+        PRIMITIVE_CLASS_MAP.put("char", char.class);
+        PRIMITIVE_CLASS_MAP.put("C", char.class);
+        PRIMITIVE_CLASS_MAP.put("short", short.class);
+        PRIMITIVE_CLASS_MAP.put("S", short.class);
+        PRIMITIVE_CLASS_MAP.put("int", int.class);
+        PRIMITIVE_CLASS_MAP.put("I", int.class);
+        PRIMITIVE_CLASS_MAP.put("long", long.class);
+        PRIMITIVE_CLASS_MAP.put("J", long.class);
+        PRIMITIVE_CLASS_MAP.put("float", float.class);
+        PRIMITIVE_CLASS_MAP.put("F", float.class);
+        PRIMITIVE_CLASS_MAP.put("double", double.class);
+        PRIMITIVE_CLASS_MAP.put("D", double.class);
+        PRIMITIVE_CLASS_MAP.put("void", void.class);
+        PRIMITIVE_CLASS_MAP.put("V", void.class);
+
+        // Now build a reverse mapping table.  The table above has a many-to-one mapping for
+        // class names.  To do the reverse, we need to pick just one.  As long as the
+        // returned name supports "round tripping" of the requests, this will work fine.
+
+        CLASS_TO_SIGNATURE_MAP.put(boolean.class, "Z");
+        CLASS_TO_SIGNATURE_MAP.put(byte.class, "B");
+        CLASS_TO_SIGNATURE_MAP.put(char.class, "C");
+        CLASS_TO_SIGNATURE_MAP.put(short.class, "S");
+        CLASS_TO_SIGNATURE_MAP.put(int.class, "I");
+        CLASS_TO_SIGNATURE_MAP.put(long.class, "J");
+        CLASS_TO_SIGNATURE_MAP.put(float.class, "F");
+        CLASS_TO_SIGNATURE_MAP.put(double.class, "D");
+        CLASS_TO_SIGNATURE_MAP.put(void.class, "V");
+    }
+
+
+    /**
+     * Load a class that matches the requested name, using the provided class loader context.
+     * <p/>
+     * The class name may be a standard class name, the name of a primitive type Java
+     * reflection class (e.g., "boolean" or "int"), or a type in method type signature
+     * encoding.  Array classes in either encoding form are also processed.
+     *
+     * @param className The name of the required class.
+     * @param classLoader The class loader used to resolve the class object.
+     * @return The Class object resolved from "className".
+     * @throws ClassNotFoundException When unable to resolve the class object.
+     * @throws IllegalArgumentException If either argument is null.
+     */
+    public static Class loadClass(String className, ClassLoader classLoader) throws ClassNotFoundException {
+
+        // the tests require IllegalArgumentExceptions for null values on either of these.
+        if (className == null) {
+            throw new IllegalArgumentException("className is null");
+        }
+
+        if (classLoader == null) {
+            throw new IllegalArgumentException("classLoader is null");
+        }
+        // The easiest case is a proper class name.  We just have the class loader resolve this.
+        // If the class loader throws a ClassNotFoundException, then we need to check each of the
+        // special name encodings we support.
+        try {
+            return classLoader.loadClass(className);
+        } catch (ClassNotFoundException ignore) {
+            // if not found, continue on to the other name forms.
+        }
+
+
+        // The second easiest version to resolve is a direct map to a primitive type name
+        // or method signature.  Check our name-to-class map for one of those.
+        Class resolvedClass = (Class) PRIMITIVE_CLASS_MAP.get(className);
+        if (resolvedClass != null) {
+            return resolvedClass;
+        }
+
+        // Class names in method signature have the format "Lfully.resolved.name;",
+        // so if it ends in a semicolon and begins with an "L", this must be in
+        // this format.  Have the class loader try to load this.  There are no other
+        // options if this fails, so just allow the class loader to throw the
+        // ClassNotFoundException.
+        if (className.endsWith(";") && className.startsWith("L")) {
+            // pick out the name portion
+            String typeName = className.substring(1, className.length() - 1);
+            // and delegate the loading to the class loader.
+            return classLoader.loadClass(typeName);
+        }
+
+        // All we have left now are the array types.  Method signature array types
+        // have a series of leading "[" characters to specify the number of dimensions.
+        // The other array type we handle uses trailing "[]" for the dimensions, just
+        // like the Java language syntax.
+
+        // first check for the signature form ([[[[type).
+        if (className.charAt(0) == '[') {
+            // we have at least one array marker, now count how many leading '['s we have
+            // to get the dimension count.
+            int count = 0;
+            int nameLen = className.length();
+
+            while (count < nameLen && className.charAt(count) == '[') {
+                count++;
+            }
+
+            // pull of the name subtype, which is everything after the last '['
+            String arrayTypeName = className.substring(count, className.length());
+            // resolve the type using a recursive call, which will load any of the primitive signature
+            // types as well as class names.
+            Class arrayType = loadClass(arrayTypeName, classLoader);
+
+            // Resolving array types require a little more work.  The array classes are
+            // created dynamically when the first instance of a given dimension and type is
+            // created.  We need to create one using reflection to do this.
+            return getArrayClass(arrayType, count);
+        }
+
+
+        // ok, last chance.  Now check for an array specification in Java language
+        // syntax.  This will be a type name followed by pairs of "[]" to indicate
+        // the number of dimensions.
+        if (className.endsWith("[]")) {
+            // get the base component class name and the arrayDimensions
+            int count = 0;
+            int position = className.length();
+
+            while (position > 1 && className.substring(position - 2, position).equals("[]")) {
+                // count this dimension
+                count++;
+                // and step back the probe position.
+                position -= 2;
+            }
+
+            // position now points at the location of the last successful test.  This makes it
+            // easy to pick off the class name.
+
+            String typeName = className.substring(0, position);
+
+            // load the base type, again, doing this recursively
+            Class arrayType = loadClass(typeName, classLoader);
+            // and turn this into the class object
+            return getArrayClass(arrayType, count);
+        }
+
+        throw new ClassNotFoundException("Could not load class " + className + " from unknown classloader; " + classLoader);
+    }
+
+
+    /**
+     * Map a class object back to a class name.  The returned class object
+     * must be "round trippable", which means
+     * <p/>
+     * type == ClassLoading.loadClass(ClassLoading.getClassName(type), classLoader)
+     * <p/>
+     * must be true.  To ensure this, the class name is always returned in
+     * method signature format.
+     *
+     * @param type The class object we convert into name form.
+     * @return A string representation of the class name, in method signature
+     *         format.
+     */
+    public static String getClassName(Class type) {
+        StringBuffer name = new StringBuffer();
+
+        // we test these in reverse order from the resolution steps,
+        // first handling arrays, then primitive types, and finally
+        // "normal" class objects.
+
+        // First handle arrays.  If a class is an array, the type is
+        // element stored at that level.  So, for a 2-dimensional array
+        // of ints, the top-level type will be "[I".  We need to loop
+        // down the hierarchy until we hit a non-array type.
+        while (type.isArray()) {
+            // add another array indicator at the front of the name,
+            // and continue with the next type.
+            name.append('[');
+            type = type.getComponentType();
+        }
+
+        // we're down to the base type.  If this is a primitive, then
+        // we poke in the single-character type specifier.
+        if (type.isPrimitive()) {
+            name.append((String) CLASS_TO_SIGNATURE_MAP.get(type));
+        }
+        // a "normal" class.  This gets expressing using the "Lmy.class.name;" syntax.
+        else {
+            name.append('L');
+            name.append(type.getName());
+            name.append(';');
+        }
+        return name.toString();
+    }
+
+    private static Class getArrayClass(Class type, int dimension) {
+        // Array.newInstance() requires an array of the requested number of dimensions
+        // that gives the size for each dimension.  We just request 0 in each of the
+        // dimentions, which is not unlike a black hole sigularity.
+        int dimensions[] = new int[dimension];
+        // create an instance and return the associated class object.
+        return Array.newInstance(type, dimensions).getClass();
+    }
+
+    public static Set getAllTypes(Class type) {
+        Set allTypes = new LinkedHashSet();
+        allTypes.add(type);
+        allTypes.addAll(getAllSuperClasses(type));
+        allTypes.addAll(getAllInterfaces(type));
+        return allTypes;
+    }
+
+    private static Set getAllSuperClasses(Class clazz) {
+        Set allSuperClasses = new LinkedHashSet();
+        for (Class superClass = clazz.getSuperclass(); superClass != null; superClass = superClass.getSuperclass()) {
+            allSuperClasses.add(superClass);
+        }
+        return allSuperClasses;
+    }
+
+    private static Set getAllInterfaces(Class clazz) {
+        Set allInterfaces = new LinkedHashSet();
+        LinkedList stack = new LinkedList();
+        stack.addAll(Arrays.asList(clazz.getInterfaces()));
+        while (!stack.isEmpty()) {
+            Class intf = (Class) stack.removeFirst();
+            if (!allInterfaces.contains(intf)) {
+                allInterfaces.add(intf);
+                stack.addAll(Arrays.asList(intf.getInterfaces()));
+            }
+        }
+        return allInterfaces;
+    }
+
+    public static Set reduceInterfaces(Set source) {
+        Class[] classes = (Class[]) source.toArray(new Class[source.size()]);
+        classes = reduceInterfaces(classes);
+        return new LinkedHashSet(Arrays.asList(classes));
+    }
+
+    /**
+     * If there are multiple interfaces, and some of them extend each other,
+     * eliminate the superclass in favor of the subclasses that extend them.
+     *
+     * If one of the entries is a class (not an interface), make sure it's
+     * the first one in the array.  If more than one of the entries is a
+     * class, throws an IllegalArgumentException
+     *
+     * @param source the original list of interfaces
+     * @return the equal or smaller list of interfaces
+     */
+    public static Class[] reduceInterfaces(Class[] source) {
+        // use a copy of the sorce array
+        source = (Class[]) source.clone();
+
+        for (int leftIndex = 0; leftIndex < source.length-1; leftIndex++) {
+            Class left = source[leftIndex];
+            if(left == null) {
+                continue;
+            }
+
+            for (int rightIndex = leftIndex +1; rightIndex < source.length; rightIndex++) {
+                Class right = source[rightIndex];
+                if(right == null) {
+                    continue;
+                }
+
+                if(left == right || right.isAssignableFrom(left)) {
+                    // right is the same as class or a sub class of left
+                    source[rightIndex] = null;
+                } else if(left.isAssignableFrom(right)) {
+                    // left is the same as class or a sub class of right
+                    source[leftIndex] = null;
+
+                    // the left has been eliminated; move on to the next left
+                    break;
+                }
+            }
+        }
+
+        Class clazz = null;
+        for (int i = 0; i < source.length; i++) {
+            if (source[i] != null && !source[i].isInterface()) {
+                if (clazz != null) {
+                    throw new IllegalArgumentException("Source contains two classes which are not subclasses of each other: " + clazz.getName() + ", " + source[i].getName());
+                }
+                clazz = source[i];
+                source[i] = null;
+            }
+        }
+
+        List list = new ArrayList(source.length);
+        if (clazz != null) list.add(clazz);
+        for (int i = 0; i < source.length; i++) {
+            if(source[i] != null) {
+                list.add(source[i]);
+            }
+        }
+        return (Class[]) list.toArray(new Class[list.size()]);
+    }
+}
+

Propchange: incubator/tuscany/java/sca/modules/binding-ejb/src/main/java/org/apache/tuscany/sca/binding/ejb/corba/ClassLoadingUtil.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/tuscany/java/sca/modules/binding-ejb/src/main/java/org/apache/tuscany/sca/binding/ejb/corba/ClassLoadingUtil.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: incubator/tuscany/java/sca/modules/binding-ejb/src/main/java/org/apache/tuscany/sca/binding/ejb/corba/DynamicStubClassLoader.java
URL: http://svn.apache.org/viewvc/incubator/tuscany/java/sca/modules/binding-ejb/src/main/java/org/apache/tuscany/sca/binding/ejb/corba/DynamicStubClassLoader.java?view=auto&rev=562321
==============================================================================
--- incubator/tuscany/java/sca/modules/binding-ejb/src/main/java/org/apache/tuscany/sca/binding/ejb/corba/DynamicStubClassLoader.java (added)
+++ incubator/tuscany/java/sca/modules/binding-ejb/src/main/java/org/apache/tuscany/sca/binding/ejb/corba/DynamicStubClassLoader.java Thu Aug  2 20:54:14 2007
@@ -0,0 +1,146 @@
+/*
+ * 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.corba;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+
+import javax.rmi.CORBA.Stub;
+
+import net.sf.cglib.core.NamingPolicy;
+import net.sf.cglib.core.Predicate;
+import net.sf.cglib.proxy.Callback;
+import net.sf.cglib.proxy.CallbackFilter;
+import net.sf.cglib.proxy.Enhancer;
+import net.sf.cglib.proxy.FixedValue;
+import net.sf.cglib.proxy.MethodInterceptor;
+import net.sf.cglib.proxy.NoOp;
+
+/**
+ * @version $Revision$ $Date$
+ */
+public class DynamicStubClassLoader extends ClassLoader {
+    private final static String PACKAGE_PREFIX = "org.omg.stub.";
+
+    public synchronized Class loadClass(final String name) throws ClassNotFoundException {
+        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
+
+        // check if the stub already exists first
+        try {
+            return classLoader.loadClass(name);
+        } catch (ClassNotFoundException e) {
+        }
+
+        // if this is not a class from the org.omb.stub name space don't attempt to generate
+        if (!name.startsWith(PACKAGE_PREFIX)) {
+            throw new ClassNotFoundException("Could not load class: " + name);
+        }
+
+        // load the interfaces class we are attempting to create a stub for
+        Class iface = loadStubInterfaceClass(name, classLoader);
+
+        // create the stub builder
+        try {
+            Enhancer enhancer = new Enhancer();
+            enhancer.setSuperclass(Stub.class);
+            enhancer.setInterfaces(new Class[] {iface});
+            enhancer.setCallbackFilter(FILTER);
+            enhancer.setCallbackTypes(new Class[] {NoOp.class, MethodInterceptor.class, FixedValue.class});
+            enhancer.setUseFactory(false);
+            enhancer.setClassLoader(classLoader);
+            enhancer.setNamingPolicy(new NamingPolicy() {
+                public String getClassName(String s, String s1, Object o, Predicate predicate) {
+                    return name;
+                }
+            });
+
+            // generate the class
+            Class result = enhancer.createClass();
+            assert result != null;
+
+            StubMethodInterceptor interceptor = new StubMethodInterceptor(iface);
+            Ids ids = new Ids(iface);
+            Enhancer.registerStaticCallbacks(result, new Callback[] {NoOp.INSTANCE, interceptor, ids});
+
+            return result;
+        } catch (RuntimeException e) {
+            throw e;
+        } catch (Error e) {
+            throw e;
+        }
+    }
+
+    private Class loadStubInterfaceClass(String name, ClassLoader classLoader) throws ClassNotFoundException {
+        try {
+            int begin = name.lastIndexOf('.') + 1;
+            String iPackage = name.substring(13, begin);
+            String iName = iPackage + name.substring(begin + 1, name.length() - 5);
+
+            return classLoader.loadClass(iName);
+        } catch (ClassNotFoundException e) {
+            // don't log exceptions from CosNaming because it attempts to load every
+            // class bound into the name server
+            boolean shouldLog = true;
+            StackTraceElement[] stackTrace = e.getStackTrace();
+            for (int i = 0; i < stackTrace.length; i++) {
+                StackTraceElement stackTraceElement = stackTrace[i];
+                if (stackTraceElement.getClassName().equals("org.omg.CosNaming.NamingContextExtPOA") && stackTraceElement
+                    .getMethodName().equals("_invoke")) {
+                    shouldLog = false;
+                    break;
+                }
+            }
+
+            throw new ClassNotFoundException("Unable to generate stub", e);
+        }
+    }
+
+    private static final CallbackFilter FILTER = new CallbackFilter() {
+        public int accept(Method method) {
+            // we don't intercept non-public methods like finalize
+            if (!Modifier.isPublic(method.getModifiers())) {
+                return 0;
+            }
+
+            if (method.getReturnType().equals(String[].class) && method.getParameterTypes().length == 0
+                && method.getName().equals("_ids")) {
+                return 2;
+            }
+
+            if (Modifier.isAbstract(method.getModifiers())) {
+                return 1;
+            }
+
+            return 0;
+        }
+    };
+
+    private static final class Ids implements FixedValue {
+        private final String[] typeIds;
+
+        public Ids(Class type) {
+            typeIds = Java2IDLUtil.createCorbaIds(type);
+        }
+
+        public Object loadObject() throws Exception {
+            return typeIds;
+        }
+    }
+
+}

Propchange: incubator/tuscany/java/sca/modules/binding-ejb/src/main/java/org/apache/tuscany/sca/binding/ejb/corba/DynamicStubClassLoader.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/tuscany/java/sca/modules/binding-ejb/src/main/java/org/apache/tuscany/sca/binding/ejb/corba/DynamicStubClassLoader.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: incubator/tuscany/java/sca/modules/binding-ejb/src/main/java/org/apache/tuscany/sca/binding/ejb/corba/Java2IDLUtil.java
URL: http://svn.apache.org/viewvc/incubator/tuscany/java/sca/modules/binding-ejb/src/main/java/org/apache/tuscany/sca/binding/ejb/corba/Java2IDLUtil.java?view=auto&rev=562321
==============================================================================
--- incubator/tuscany/java/sca/modules/binding-ejb/src/main/java/org/apache/tuscany/sca/binding/ejb/corba/Java2IDLUtil.java (added)
+++ incubator/tuscany/java/sca/modules/binding-ejb/src/main/java/org/apache/tuscany/sca/binding/ejb/corba/Java2IDLUtil.java Thu Aug  2 20:54:14 2007
@@ -0,0 +1,811 @@
+/*
+ * 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.corba;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.io.UnsupportedEncodingException;
+import java.lang.reflect.Method;
+import java.rmi.Remote;
+import java.rmi.RemoteException;
+import java.rmi.UnexpectedException;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.ejb.spi.HandleDelegate;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import javax.rmi.PortableRemoteObject;
+
+import org.omg.CORBA.ORB;
+import org.omg.CORBA.UserException;
+import org.omg.CORBA.portable.IDLEntity;
+import org.omg.CORBA.portable.ResponseHandler;
+import org.omg.CORBA.portable.UnknownException;
+import org.omg.CORBA_2_3.portable.InputStream;
+import org.omg.CORBA_2_3.portable.OutputStream;
+import org.omg.IOP.Codec;
+import org.omg.IOP.CodecFactory;
+import org.omg.IOP.ENCODING_CDR_ENCAPS;
+import org.omg.IOP.Encoding;
+
+/**
+ * Various utility functions.
+ * <p/>
+ * Note: #getORB() and #getCodec() rely on UtilInitializer to initialze the ORB and codec.
+ *
+ * @version $Rev$ $Date$
+ * @see UtilInitializer
+ */
+public final class Java2IDLUtil {
+    private static ORB orb;
+    private static Codec codec;
+    private static HandleDelegate handleDelegate;
+    
+    public static ORB getORB() {
+        assert orb != null;
+        return orb;
+    }
+    
+  
+
+    public static void setORB(ORB orb) throws UserException {
+        if (Java2IDLUtil.orb == null) {
+            Java2IDLUtil.orb = orb;
+            CodecFactory factory = (CodecFactory) Java2IDLUtil.orb.resolve_initial_references("CodecFactory");
+            codec = factory.create_codec(new Encoding(ENCODING_CDR_ENCAPS.value, (byte) 1, (byte) 2));
+        }
+    }
+
+    public static Codec getCodec() {
+        assert codec != null;
+        return codec;
+    }
+
+    public static HandleDelegate getHandleDelegate() throws NamingException {
+        if (handleDelegate == null) {
+            InitialContext ic = new InitialContext();
+            handleDelegate = (HandleDelegate) ic.lookup("java:comp/HandleDelegate");
+        }
+        return handleDelegate;
+    }
+    
+    private static final Pattern SCOPED_NAME_EXTRACTION_PATTERN = Pattern.compile("(\\\\\\\\)|(\\\\@)|(@)|(\\z)");
+
+    /**
+     * See csiv2 spec 16.2.5 par. 63-64.  We extract the username if any and un-escape any
+     * escaped \ and @ characters.
+     * 
+     * @param scopedNameBytes
+     * @return
+     * @throws UnsupportedEncodingException
+     */
+    public static String extractUserNameFromScopedName(byte[] scopedNameBytes) throws UnsupportedEncodingException {
+        String scopedUserName = new String(scopedNameBytes, "UTF8");
+        return extractUserNameFromScopedName(scopedUserName);
+    }
+
+    public static String extractUserNameFromScopedName(String scopedUserName) {
+        Matcher m = SCOPED_NAME_EXTRACTION_PATTERN.matcher(scopedUserName);
+        StringBuffer buf = new StringBuffer();
+        while (m.find()) {
+            m.appendReplacement(buf, "");
+            if (m.group(1) != null) {
+                buf.append('\\');
+            } else if (m.group(2) != null) {
+                buf.append("@");
+            } else if (m.group(3) != null) {
+                break;
+            }
+        }
+        return buf.toString();
+    }
+
+    private static final Pattern SCOPED_NAME_ESCAPE_PATTERN = Pattern.compile("(\\\\)|(@)");
+
+    public static String buildScopedUserName(String user, String domain) {
+        StringBuffer buf = new StringBuffer();
+        if (user != null) {
+            escape(user, buf);
+        }
+        if (domain != null) {
+            buf.append('@');
+            escape(domain, buf);
+        }
+        return buf.toString();
+    }
+
+    private static void escape(String s, StringBuffer buf) {
+        Matcher m = SCOPED_NAME_ESCAPE_PATTERN.matcher(s);
+        while (m.find()) {
+            m.appendReplacement(buf, "");
+            if (m.group(1) != null) {
+                buf.append("\\\\");
+            } else if (m.group(2) != null) {
+                buf.append("\\@");
+            }
+        }
+        m.appendTail(buf);
+    }
+
+
+    public static String byteToString(byte[] data) {
+        StringBuffer buffer = new StringBuffer();
+        for (int i = 0; i < data.length; i++) {
+            buffer.append(HEXCHAR[(data[i] >>> 4) & 0x0F]);
+            buffer.append(HEXCHAR[(data[i]) & 0x0F]);
+        }
+        return buffer.toString();
+
+    }
+
+    private static final char[] HEXCHAR = {
+        '0', '1', '2', '3', '4', '5', '6', '7',
+        '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
+    };
+
+    public static void writeObject(Class type, Object object, OutputStream out) {
+        if (type == Void.TYPE) {
+            // do nothing for a void
+        } else if (type == Boolean.TYPE) {
+            out.write_boolean(((Boolean) object).booleanValue());
+        } else if (type == Byte.TYPE) {
+            out.write_octet(((Byte) object).byteValue());
+        } else if (type == Character.TYPE) {
+            out.write_wchar(((Character) object).charValue());
+        } else if (type == Double.TYPE) {
+            out.write_double(((Double) object).doubleValue());
+        } else if (type == Float.TYPE) {
+            out.write_float(((Float) object).floatValue());
+        } else if (type == Integer.TYPE) {
+            out.write_long(((Integer) object).intValue());
+        } else if (type == Long.TYPE) {
+            out.write_longlong(((Long) object).longValue());
+        } else if (type == Short.TYPE) {
+            out.write_short(((Short) object).shortValue());
+        }  else {
+            // object types must bbe written in the context of the corba application server
+            // which properly write replaces our objects for corba
+            // ApplicationServer oldApplicationServer = ServerFederation.getApplicationServer();
+            try {
+                // ServerFederation.setApplicationServer(corbaApplicationServer);
+
+                // todo check if
+                // copy the result to force replacement
+                // corba does not call writeReplace on remote proxies
+                //
+                // HOWEVER, if this is an array, then we don't want to do the replacement 
+                // because we can end up with a replacement element that's not compatible with the 
+                // original array type, which results in an ArrayStoreException.  Fortunately, 
+                // the Yoko RMI support appears to be able to sort this out for us correctly. 
+                if (object instanceof Serializable && !object.getClass().isArray()) {
+                    try {
+                        object = copyObj(Thread.currentThread().getContextClassLoader(), object);
+                    } catch (Exception e) {
+                        throw new UnknownException(e);
+                    }
+                }
+
+                if (type == Object.class || type == Serializable.class) {
+                    javax.rmi.CORBA.Util.writeAny(out, object);
+                } else if (org.omg.CORBA.Object.class.isAssignableFrom(type)) {
+                    out.write_Object((org.omg.CORBA.Object) object);
+                } else if (Remote.class.isAssignableFrom(type)) {
+                    javax.rmi.CORBA.Util.writeRemoteObject(out, object);
+                } else if (type.isInterface() && Serializable.class.isAssignableFrom(type)) {
+                    javax.rmi.CORBA.Util.writeAbstractObject(out, object);
+                } else {
+                    out.write_value((Serializable) object, type);
+                }
+            } finally {
+                // ServerFederation.setApplicationServer(oldApplicationServer);
+            }
+        }
+    }
+
+    private static Object copyObj(ClassLoader classLoader, Object object) throws IOException, ClassNotFoundException {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        ObjectOutputStream oos = new ObjectOutputStream(baos);
+        oos.writeObject(object);
+        oos.flush();
+        oos.close();
+        ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
+        ObjectInputStreamExt ois = new ObjectInputStreamExt(bais, classLoader);
+        return ois.readObject();
+    }
+
+    public static Object readObject(Class type, InputStream in) {
+        if (type == Void.TYPE) {
+            return null;
+        } else if (type == Boolean.TYPE) {
+            return new Boolean(in.read_boolean());
+        } else if (type == Byte.TYPE) {
+            return new Byte(in.read_octet());
+        } else if (type == Character.TYPE) {
+            return new Character(in.read_wchar());
+        } else if (type == Double.TYPE) {
+            return new Double(in.read_double());
+        } else if (type == Float.TYPE) {
+            return new Float(in.read_float());
+        } else if (type == Integer.TYPE) {
+            return new Integer(in.read_long());
+        } else if (type == Long.TYPE) {
+            return new Long(in.read_longlong());
+        } else if (type == Short.TYPE) {
+            return new Short(in.read_short());
+        } else if (type == Object.class || type == Serializable.class) {
+            return javax.rmi.CORBA.Util.readAny(in);
+        } else if (org.omg.CORBA.Object.class.isAssignableFrom(type)) {
+            return in.read_Object(type);
+        } else if (Remote.class.isAssignableFrom(type)) {
+            return PortableRemoteObject.narrow(in.read_Object(), type);
+        } else if (type.isInterface() && Serializable.class.isAssignableFrom(type)) {
+            return in.read_abstract_interface();
+        } else {
+            return in.read_value(type);
+        }
+    }
+
+    public static void throwException(Method method, InputStream in) throws Throwable {
+        // read the exception id
+        final String id = in.read_string();
+
+        // get the class name from the id
+        if (!id.startsWith("IDL:")) {
+            return;
+        }
+
+        Class[] exceptionTypes = method.getExceptionTypes();
+        for (int i = 0; i < exceptionTypes.length; i++) {
+            Class exceptionType = exceptionTypes[i];
+
+            String exceptionId = getExceptionId(exceptionType);
+            if (id.equals(exceptionId)) {
+                throw (Throwable) in.read_value(exceptionType);
+            }
+        }
+        throw new UnexpectedException(id);
+    }
+
+    public static OutputStream writeUserException(Method method, ResponseHandler reply, Exception exception) throws Exception {
+        if (exception instanceof RuntimeException || exception instanceof RemoteException) {
+            throw exception;
+        }
+
+        Class[] exceptionTypes = method.getExceptionTypes();
+        for (int i = 0; i < exceptionTypes.length; i++) {
+            Class exceptionType = exceptionTypes[i];
+            if (!exceptionType.isInstance(exception)) {
+                continue;
+            }
+
+            OutputStream out = (OutputStream) reply.createExceptionReply();
+            String exceptionId = getExceptionId(exceptionType);
+            out.write_string(exceptionId);
+            out.write_value(exception);
+            return out;
+        }
+        throw exception;
+    }
+
+    public static String getExceptionId(Class exceptionType) {
+        String exceptionName = exceptionType.getName().replace('.', '/');
+        if (exceptionName.endsWith("Exception")) {
+            exceptionName = exceptionName.substring(0, exceptionName.length() - "Exception".length());
+        }
+        exceptionName += "Ex";
+        String exceptionId = "IDL:" + exceptionName + ":1.0";
+        return exceptionId;
+    }
+
+    public static String[] createCorbaIds(Class type) {
+        List ids = new LinkedList();
+        for (Iterator iterator = getAllInterfaces(type).iterator(); iterator.hasNext();) {
+            Class superInterface = (Class) iterator.next();
+            if (Remote.class.isAssignableFrom(superInterface) && superInterface != Remote.class) {
+                ids.add("RMI:" + superInterface.getName() + ":0000000000000000");
+            }
+        }
+        return (String[]) ids.toArray(new String[ids.size()]);
+    }
+
+    private static Set getAllInterfaces(Class intfClass) {
+        Set allInterfaces = new LinkedHashSet();
+
+        LinkedList stack = new LinkedList();
+        stack.addFirst(intfClass);
+
+        while (!stack.isEmpty()) {
+            Class intf = (Class) stack.removeFirst();
+            allInterfaces.add(intf);
+            stack.addAll(0, Arrays.asList(intf.getInterfaces()));
+        }
+
+        return allInterfaces;
+    }
+
+    public static Map mapMethodToOperation(Class intfClass) {
+        return iiopMap(intfClass, false);
+    }
+
+    public static Map mapOperationToMethod(Class intfClass) {
+        return iiopMap(intfClass, true);
+    }
+
+    private static Map iiopMap(Class intfClass, boolean operationToMethod) {
+        Method[] methods = getAllMethods(intfClass);
+
+        // find every valid getter
+        HashMap getterByMethod = new HashMap(methods.length);
+        HashMap getterByName = new HashMap(methods.length);
+        for (int i = 0; i < methods.length; i++) {
+            Method method = methods[i];
+            String methodName = method.getName();
+
+            // no arguments allowed
+            if (method.getParameterTypes().length != 0) {
+                continue;
+            }
+
+            // must start with get or is
+            String verb;
+            if (methodName.startsWith("get") && methodName.length() > 3 && method.getReturnType() != void.class) {
+                verb = "get";
+            } else if (methodName.startsWith("is") && methodName.length() > 2 && method.getReturnType() == boolean.class) {
+                verb = "is";
+            } else {
+                continue;
+            }
+
+            // must only throw Remote or Runtime Exceptions
+            boolean exceptionsValid = true;
+            Class[] exceptionTypes = method.getExceptionTypes();
+            for (int j = 0; j < exceptionTypes.length; j++) {
+                Class exceptionType = exceptionTypes[j];
+                if (!RemoteException.class.isAssignableFrom(exceptionType) &&
+                        !RuntimeException.class.isAssignableFrom(exceptionType) &&
+                        !Error.class.isAssignableFrom(exceptionType)) {
+                    exceptionsValid = false;
+                    break;
+                }
+            }
+            if (!exceptionsValid) {
+                continue;
+            }
+
+            String propertyName;
+            if (methodName.length() > verb.length() + 1 && Character.isUpperCase(methodName.charAt(verb.length() + 1))) {
+                propertyName = methodName.substring(verb.length());
+            } else {
+                propertyName = Character.toLowerCase(methodName.charAt(verb.length())) + methodName.substring(verb.length() + 1);
+            }
+            getterByMethod.put(method, propertyName);
+            getterByName.put(propertyName, method);
+        }
+
+        HashMap setterByMethod = new HashMap(methods.length);
+        for (int i = 0; i < methods.length; i++) {
+            Method method = methods[i];
+            String methodName = method.getName();
+
+            // must have exactally one arg
+            if (method.getParameterTypes().length != 1) {
+                continue;
+            }
+
+            // must return non void
+            if (method.getReturnType() != void.class) {
+                continue;
+            }
+
+            // must start with set
+            if (!methodName.startsWith("set") || methodName.length() <= 3) {
+                continue;
+            }
+
+            // must only throw Remote or Runtime Exceptions
+            boolean exceptionsValid = true;
+            Class[] exceptionTypes = method.getExceptionTypes();
+            for (int j = 0; j < exceptionTypes.length; j++) {
+                Class exceptionType = exceptionTypes[j];
+                if (!RemoteException.class.isAssignableFrom(exceptionType) &&
+                        !RuntimeException.class.isAssignableFrom(exceptionType) &&
+                        !Error.class.isAssignableFrom(exceptionType)) {
+                    exceptionsValid = false;
+                    break;
+                }
+            }
+            if (!exceptionsValid) {
+                continue;
+            }
+
+            String propertyName;
+            if (methodName.length() > 4 && Character.isUpperCase(methodName.charAt(4))) {
+                propertyName = methodName.substring(3);
+            } else {
+                propertyName = Character.toLowerCase(methodName.charAt(3)) + methodName.substring(4);
+            }
+
+            // must have a matching getter
+            Method getter = (Method) getterByName.get(propertyName);
+            if (getter == null) {
+                continue;
+            }
+
+            // setter property must match gettter return value
+            if (!method.getParameterTypes()[0].equals(getter.getReturnType())) {
+                continue;
+            }
+            setterByMethod.put(method, propertyName);
+        }
+
+        // index the methods by name... used to determine which methods are overloaded
+        HashMap overloadedMethods = new HashMap(methods.length);
+        for (int i = 0; i < methods.length; i++) {
+            Method method = methods[i];
+            if (getterByMethod.containsKey(method) || setterByMethod.containsKey(method)) {
+                continue;
+            }
+            String methodName = method.getName();
+            List methodList = (List) overloadedMethods.get(methodName);
+            if (methodList == null) {
+                methodList = new LinkedList();
+                overloadedMethods.put(methodName, methodList);
+            }
+            methodList.add(method);
+        }
+
+        // index the methods by lower case name... used to determine which methods differ only by case
+        HashMap caseCollisionMethods = new HashMap(methods.length);
+        for (int i = 0; i < methods.length; i++) {
+            Method method = methods[i];
+            if (getterByMethod.containsKey(method) || setterByMethod.containsKey(method)) {
+                continue;
+            }
+            String lowerCaseMethodName = method.getName().toLowerCase();
+            Set methodSet = (Set) caseCollisionMethods.get(lowerCaseMethodName);
+            if (methodSet == null) {
+                methodSet = new HashSet();
+                caseCollisionMethods.put(lowerCaseMethodName, methodSet);
+            }
+            methodSet.add(method.getName());
+        }
+
+        String className = getClassName(intfClass);
+        Map iiopMap = new HashMap(methods.length);
+        for (int i = 0; i < methods.length; i++) {
+            Method method = methods[i];
+
+            String iiopName = (String) getterByMethod.get(method);
+            if (iiopName != null) {
+                // if we have a leading underscore prepend with J
+                if (iiopName.charAt(0) == '_') {
+                    iiopName = "J_get_" + iiopName.substring(1);
+                } else {
+                    iiopName = "_get_" + iiopName;
+                }
+            } else {
+                iiopName = (String) setterByMethod.get(method);
+                if (iiopName != null) {
+                    // if we have a leading underscore prepend with J
+                    if (iiopName.charAt(0) == '_') {
+                        iiopName = "J_set_" + iiopName.substring(1);
+                    } else {
+                        iiopName = "_set_" + iiopName;
+                    }
+                } else {
+                    iiopName = method.getName();
+
+                    // if we have a leading underscore prepend with J
+                    if (iiopName.charAt(0) == '_') {
+                        iiopName = "J" + iiopName;
+                    }
+                }
+            }
+
+            // if this name only differs by case add the case index to the end
+            Set caseCollisions = (Set) caseCollisionMethods.get(method.getName().toLowerCase());
+            if (caseCollisions != null && caseCollisions.size() > 1) {
+                iiopName += upperCaseIndexString(iiopName);
+            }
+
+            // if this is an overloaded method append the parameter string
+            List overloads = (List) overloadedMethods.get(method.getName());
+            if (overloads != null && overloads.size() > 1) {
+                iiopName += buildOverloadParameterString(method.getParameterTypes());
+            }
+
+            // if we have a leading underscore prepend with J
+            iiopName = replace(iiopName, '$', "U0024");
+
+            // if we have matched a keyword prepend with an underscore
+            if (keywords.contains(iiopName.toLowerCase())) {
+                iiopName = "_" + iiopName;
+            }
+
+            // if the name is the same as the class name, append an underscore
+            if (iiopName.equalsIgnoreCase(className)) {
+                iiopName += "_";
+            }
+
+            if (operationToMethod) {
+                iiopMap.put(iiopName, method);
+            } else {
+                iiopMap.put(method, iiopName);
+            }
+        }
+
+        return iiopMap;
+    }
+
+    private static Method[] getAllMethods(Class intfClass) {
+        LinkedList methods = new LinkedList();
+        for (Iterator iterator = getAllInterfaces(intfClass).iterator(); iterator.hasNext();) {
+            Class intf = (Class) iterator.next();
+            methods.addAll(Arrays.asList(intf.getDeclaredMethods()));
+        }
+
+        return (Method[]) methods.toArray(new Method[methods.size()]);
+    }
+
+    /**
+     * Return the a string containing an underscore '_' index of each uppercase character in the iiop name.
+     *
+     * This is used for distinction of names that only differ by case, since corba does not support case sensitive names.
+     */
+    private static String upperCaseIndexString(String iiopName) {
+        StringBuffer stringBuffer = new StringBuffer();
+        for (int i = 0; i < iiopName.length(); i++) {
+            char c = iiopName.charAt(i);
+            if (Character.isUpperCase(c)) {
+                stringBuffer.append('_').append(i);
+            }
+        }
+        return stringBuffer.toString();
+    }
+
+    /**
+     * Replaces any occurnace of the specified "oldChar" with the nes string.
+     *
+     * This is used to replace occurances if '$' in corba names since '$' is a special character
+     */
+    private static String replace(String source, char oldChar, String newString) {
+        StringBuffer stringBuffer = new StringBuffer(source.length());
+        for (int i = 0; i < source.length(); i++) {
+            char c = source.charAt(i);
+            if (c == oldChar) {
+                stringBuffer.append(newString);
+            } else {
+                stringBuffer.append(c);
+            }
+        }
+        return stringBuffer.toString();
+    }
+
+    /**
+     * Return the a string containing a double underscore '__' list of parameter types encoded using the Java to IDL rules.
+     *
+     * This is used for distinction of methods that only differ by parameter lists.
+     */
+    private static String buildOverloadParameterString(Class[] parameterTypes) {
+        String name = "";
+        if (parameterTypes.length ==0) {
+            name += "__";
+        } else {
+            for (int i = 0; i < parameterTypes.length; i++) {
+                Class parameterType = parameterTypes[i];
+                name += buildOverloadParameterString(parameterType);
+            }
+        }
+        return name.replace('.', '_');
+    }
+
+    /**
+     * Returns a single parameter type encoded using the Java to IDL rules.
+     */
+    private static String buildOverloadParameterString(Class parameterType) {
+        String name = "_";
+
+        int arrayDimensions = 0;
+        while (parameterType.isArray()) {
+            arrayDimensions++;
+            parameterType = parameterType.getComponentType();
+        }
+
+        // arrays start with org_omg_boxedRMI_
+        if (arrayDimensions > 0) {
+            name += "_org_omg_boxedRMI";
+        }
+
+        // IDLEntity types must be prefixed with org_omg_boxedIDL_
+        if (IDLEntity.class.isAssignableFrom(parameterType)) {
+            name += "_org_omg_boxedIDL";
+        }
+
+        // add package... some types have special mappings in corba
+        String packageName = (String) specialTypePackages.get(parameterType.getName());
+        if (packageName == null) {
+            packageName = getPackageName(parameterType.getName());
+        }
+        if (packageName.length() > 0) {
+            name += "_" + packageName;
+        }
+
+        // arrays now contain a dimension indicator
+        if (arrayDimensions > 0) {
+            name += "_" + "seq" + arrayDimensions;
+        }
+
+        // add the class name
+        String className = (String) specialTypeNames.get(parameterType.getName());
+        if (className == null) {
+            className = buildClassName(parameterType);
+        }
+        name += "_" + className;
+
+        return name;
+    }
+
+    /**
+     * Returns a string contianing an encoded class name.
+     */
+    private static String buildClassName(Class type) {
+        if (type.isArray()) {
+            throw new IllegalArgumentException("type is an array: " + type);
+        }
+
+        // get the classname
+        String typeName = type.getName();
+        int endIndex = typeName.lastIndexOf('.');
+        if (endIndex < 0) {
+            return typeName;
+        }
+        StringBuffer className = new StringBuffer(typeName.substring(endIndex + 1));
+
+        // for innerclasses replace the $ separator with two underscores
+        // we can't just blindly replace all $ characters since class names can contain the $ character
+        if (type.getDeclaringClass() != null) {
+            String declaringClassName = getClassName(type.getDeclaringClass());
+            assert className.toString().startsWith(declaringClassName + "$");
+            className.replace(declaringClassName.length(), declaringClassName.length() + 1, "__");
+        }
+
+        // if we have a leading underscore prepend with J
+        if (className.charAt(0) == '_') {
+            className.insert(0, "J");
+        }
+        return className.toString();
+    }
+
+    private static String getClassName(Class type) {
+        if (type.isArray()) {
+            throw new IllegalArgumentException("type is an array: " + type);
+        }
+
+        // get the classname
+        String typeName = type.getName();
+        int endIndex = typeName.lastIndexOf('.');
+        if (endIndex < 0) {
+            return typeName;
+        }
+        return typeName.substring(endIndex + 1);
+    }
+
+    private static String getPackageName(String interfaceName) {
+        int endIndex = interfaceName.lastIndexOf('.');
+        if (endIndex < 0) {
+            return "";
+        }
+        return interfaceName.substring(0, endIndex);
+    }
+
+    private static final Map specialTypeNames;
+    private static final Map specialTypePackages;
+    private static final Set keywords;
+
+    static {
+       specialTypeNames = new HashMap();
+       specialTypeNames.put("boolean", "boolean");
+       specialTypeNames.put("char", "wchar");
+       specialTypeNames.put("byte", "octet");
+       specialTypeNames.put("short", "short");
+       specialTypeNames.put("int", "long");
+       specialTypeNames.put("long", "long_long");
+       specialTypeNames.put("float", "float");
+       specialTypeNames.put("double", "double");
+       specialTypeNames.put("java.lang.Class", "ClassDesc");
+       specialTypeNames.put("java.lang.String", "WStringValue");
+       specialTypeNames.put("org.omg.CORBA.Object", "Object");
+
+       specialTypePackages = new HashMap();
+       specialTypePackages.put("boolean", "");
+       specialTypePackages.put("char", "");
+       specialTypePackages.put("byte", "");
+       specialTypePackages.put("short", "");
+       specialTypePackages.put("int", "");
+       specialTypePackages.put("long", "");
+       specialTypePackages.put("float", "");
+       specialTypePackages.put("double", "");
+       specialTypePackages.put("java.lang.Class", "javax.rmi.CORBA");
+       specialTypePackages.put("java.lang.String", "CORBA");
+       specialTypePackages.put("org.omg.CORBA.Object", "");
+
+       keywords = new HashSet();
+       keywords.add("abstract");
+       keywords.add("any");
+       keywords.add("attribute");
+       keywords.add("boolean");
+       keywords.add("case");
+       keywords.add("char");
+       keywords.add("const");
+       keywords.add("context");
+       keywords.add("custom");
+       keywords.add("default");
+       keywords.add("double");
+       keywords.add("enum");
+       keywords.add("exception");
+       keywords.add("factory");
+       keywords.add("false");
+       keywords.add("fixed");
+       keywords.add("float");
+       keywords.add("in");
+       keywords.add("inout");
+       keywords.add("interface");
+       keywords.add("long");
+       keywords.add("module");
+       keywords.add("native");
+       keywords.add("object");
+       keywords.add("octet");
+       keywords.add("oneway");
+       keywords.add("out");
+       keywords.add("private");
+       keywords.add("public");
+       keywords.add("raises");
+       keywords.add("readonly");
+       keywords.add("sequence");
+       keywords.add("short");
+       keywords.add("string");
+       keywords.add("struct");
+       keywords.add("supports");
+       keywords.add("switch");
+       keywords.add("true");
+       keywords.add("truncatable");
+       keywords.add("typedef");
+       keywords.add("union");
+       keywords.add("unsigned");
+       keywords.add("valuebase");
+       keywords.add("valuetype");
+       keywords.add("void");
+       keywords.add("wchar");
+       keywords.add("wstring");
+    }
+
+}

Propchange: incubator/tuscany/java/sca/modules/binding-ejb/src/main/java/org/apache/tuscany/sca/binding/ejb/corba/Java2IDLUtil.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/tuscany/java/sca/modules/binding-ejb/src/main/java/org/apache/tuscany/sca/binding/ejb/corba/Java2IDLUtil.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: incubator/tuscany/java/sca/modules/binding-ejb/src/main/java/org/apache/tuscany/sca/binding/ejb/corba/ObjectInputStreamExt.java
URL: http://svn.apache.org/viewvc/incubator/tuscany/java/sca/modules/binding-ejb/src/main/java/org/apache/tuscany/sca/binding/ejb/corba/ObjectInputStreamExt.java?view=auto&rev=562321
==============================================================================
--- incubator/tuscany/java/sca/modules/binding-ejb/src/main/java/org/apache/tuscany/sca/binding/ejb/corba/ObjectInputStreamExt.java (added)
+++ incubator/tuscany/java/sca/modules/binding-ejb/src/main/java/org/apache/tuscany/sca/binding/ejb/corba/ObjectInputStreamExt.java Thu Aug  2 20:54:14 2007
@@ -0,0 +1,59 @@
+/*
+ * 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.corba;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectStreamClass;
+import java.lang.reflect.Proxy;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class ObjectInputStreamExt extends ObjectInputStream {
+
+    private ClassLoader classloader;
+
+    public ObjectInputStreamExt(InputStream in, ClassLoader loader) throws IOException {
+        super(in);
+        this.classloader = loader;
+    }
+
+    protected Class resolveClass(ObjectStreamClass classDesc) throws IOException, ClassNotFoundException {
+        return ClassLoadingUtil.loadClass(classDesc.getName(), classloader);
+    }
+
+    protected Class resolveProxyClass(String[] interfaces) throws IOException, ClassNotFoundException {
+        Class[] cinterfaces = new Class[interfaces.length];
+        for (int i = 0; i < interfaces.length; i++)
+            cinterfaces[i] = classloader.loadClass(interfaces[i]);
+
+        try {
+            return Proxy.getProxyClass(classloader, cinterfaces);
+        } catch (IllegalArgumentException e) {
+            throw new ClassNotFoundException(null, e);
+        }
+    }
+
+    ClassLoader getClassloader() {
+        return classloader;
+    }
+
+}

Propchange: incubator/tuscany/java/sca/modules/binding-ejb/src/main/java/org/apache/tuscany/sca/binding/ejb/corba/ObjectInputStreamExt.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/tuscany/java/sca/modules/binding-ejb/src/main/java/org/apache/tuscany/sca/binding/ejb/corba/ObjectInputStreamExt.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: incubator/tuscany/java/sca/modules/binding-ejb/src/main/java/org/apache/tuscany/sca/binding/ejb/corba/StubMethodInterceptor.java
URL: http://svn.apache.org/viewvc/incubator/tuscany/java/sca/modules/binding-ejb/src/main/java/org/apache/tuscany/sca/binding/ejb/corba/StubMethodInterceptor.java?view=auto&rev=562321
==============================================================================
--- incubator/tuscany/java/sca/modules/binding-ejb/src/main/java/org/apache/tuscany/sca/binding/ejb/corba/StubMethodInterceptor.java (added)
+++ incubator/tuscany/java/sca/modules/binding-ejb/src/main/java/org/apache/tuscany/sca/binding/ejb/corba/StubMethodInterceptor.java Thu Aug  2 20:54:14 2007
@@ -0,0 +1,154 @@
+/*
+ * 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.corba;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Collections;
+import java.util.Map;
+
+import javax.ejb.EJBObject;
+import javax.rmi.CORBA.Stub;
+import javax.rmi.CORBA.Util;
+
+import net.sf.cglib.proxy.MethodInterceptor;
+import net.sf.cglib.proxy.MethodProxy;
+
+import org.omg.CORBA.SystemException;
+import org.omg.CORBA.portable.ApplicationException;
+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;
+
+/**
+ * @version $Revision$ $Date$
+ */
+public class StubMethodInterceptor implements MethodInterceptor {
+    private static final Method ISIDENTICAL;
+
+    static {
+        try {
+            ISIDENTICAL = EJBObject.class.getMethod("isIdentical", new Class[]{EJBObject.class});
+        } catch (NoSuchMethodException e) {
+            throw new ExceptionInInitializerError(e);
+        }
+    }
+
+    private final Class type;
+    private final Map operations;
+
+    public StubMethodInterceptor(Class type) {
+        this.type = type;
+        this.operations = Collections.unmodifiableMap(org.apache.tuscany.sca.binding.ejb.corba.Java2IDLUtil.mapMethodToOperation(type));
+    }
+
+    public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
+        Stub stub = (Stub) proxy;
+
+        // handle is identical in stub to avoid unnecessary round trip
+        if (method.equals(ISIDENTICAL)) {
+            org.omg.CORBA.Object otherObject = (org.omg.CORBA.Object) args[0];
+            return new Boolean(stub._is_equivalent(otherObject));
+        }
+
+        // get the operation name object
+        String operationName = (String) operations.get(method);
+        if (operationName == null) {
+            throw new IllegalStateException("Unknown method: " + method);
+        }
+
+        while (true) {
+            // if this is a stub to a remote object we invoke over the wire
+            if (!Util.isLocal(stub)) {
+
+                InputStream in = null;
+                try {
+                    // create the request output stream
+                    OutputStream out = (OutputStream) stub._request(operationName, true);
+
+                    // write the arguments
+                    Class[] parameterTypes = method.getParameterTypes();
+                    for (int i = 0; i < parameterTypes.length; i++) {
+                        Class parameterType = parameterTypes[i];
+                        org.apache.tuscany.sca.binding.ejb.corba.Java2IDLUtil.writeObject(parameterType, args[i], out);
+                    }
+
+                    // send the invocation
+                    in = (InputStream) stub._invoke(out);
+
+                    // read the result
+                    Object result = org.apache.tuscany.sca.binding.ejb.corba.Java2IDLUtil.readObject(method.getReturnType(), in);
+                    return result;
+                } catch (RemarshalException exception) {
+                    continue;
+                } catch (ApplicationException exception) {
+                    org.apache.tuscany.sca.binding.ejb.corba.Java2IDLUtil.throwException(method, (InputStream) exception.getInputStream());
+                } catch (SystemException e) {
+                    throw Util.mapSystemException(e);
+                } finally {
+                    stub._releaseReply(in);
+                }
+            } else {
+                // get the servant
+                ServantObject servantObject = stub._servant_preinvoke(operationName, type);
+                if (servantObject == null) {
+                    continue;
+                }
+
+                try {
+                    // copy the arguments
+                    Object[] argsCopy = Util.copyObjects(args, stub._orb());
+
+                    // invoke the servant
+                    Object result = null;
+                    try {
+                        result = method.invoke(servantObject.servant, argsCopy);
+                    } catch (InvocationTargetException e) {
+                        if (e.getCause() != null) {
+                            throw e.getCause();
+                        }
+                        throw e;
+                    }
+
+                    // copy the result
+                    result = Util.copyObject(result, stub._orb());
+
+                    return result;
+                } catch (Throwable throwable) {
+                    // copy the exception
+                    Throwable throwableCopy = (Throwable) Util.copyObject(throwable, stub._orb());
+
+                    // if it is one of my exception rethrow it
+                    Class[] exceptionTypes = method.getExceptionTypes();
+                    for (int i = 0; i < exceptionTypes.length; i++) {
+                        Class exceptionType = exceptionTypes[i];
+                        if (exceptionType.isInstance(throwableCopy)) {
+                            throw throwableCopy;
+                        }
+                    }
+
+                    throw Util.wrapException(throwableCopy);
+                } finally {
+                    stub._servant_postinvoke(servantObject);
+                }
+            }
+        }
+    }
+}

Propchange: incubator/tuscany/java/sca/modules/binding-ejb/src/main/java/org/apache/tuscany/sca/binding/ejb/corba/StubMethodInterceptor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/tuscany/java/sca/modules/binding-ejb/src/main/java/org/apache/tuscany/sca/binding/ejb/corba/StubMethodInterceptor.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: incubator/tuscany/java/sca/modules/binding-ejb/src/main/java/org/apache/tuscany/sca/binding/ejb/corba/UtilInitializer.java
URL: http://svn.apache.org/viewvc/incubator/tuscany/java/sca/modules/binding-ejb/src/main/java/org/apache/tuscany/sca/binding/ejb/corba/UtilInitializer.java?view=auto&rev=562321
==============================================================================
--- incubator/tuscany/java/sca/modules/binding-ejb/src/main/java/org/apache/tuscany/sca/binding/ejb/corba/UtilInitializer.java (added)
+++ incubator/tuscany/java/sca/modules/binding-ejb/src/main/java/org/apache/tuscany/sca/binding/ejb/corba/UtilInitializer.java Thu Aug  2 20:54:14 2007
@@ -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.corba;
+
+import org.omg.CORBA.LocalObject;
+import org.omg.PortableInterceptor.ORBInitInfo;
+import org.omg.PortableInterceptor.ORBInitializer;
+
+/**
+ * The sole purpose of this initializer is to register a non-singleton ORB
+ * with the class <code>Util</code>.
+ *
+ * @version $Revision$ $Date$
+ * @see Java2IDLUtil
+ */
+public class UtilInitializer extends LocalObject implements ORBInitializer {
+
+    private static final long serialVersionUID = 4901857563505370955L;
+
+    /**
+     * Called during ORB initialization.  If it is expected that initial
+     * services registered by an interceptor will be used by other
+     * interceptors, then those initial services shall be registered at
+     * this point via calls to
+     * <code>ORBInitInfo.register_initial_reference</code>.
+     *
+     * @param info provides initialization attributes and operations by
+     *             which Interceptors can be registered.
+     */
+    public void pre_init(ORBInitInfo info) {
+    }
+
+    /**
+     * Called during ORB initialization. If a service must resolve initial
+     * references as part of its initialization, it can assume that all
+     * initial references will be available at this point.
+     * <p/>
+     * Calling the <code>post_init</code> operations is not the final
+     * task of ORB initialization. The final task, following the
+     * <code>post_init</code> calls, is attaching the lists of registered
+     * interceptors to the ORB. Therefore, the ORB does not contain the
+     * interceptors during calls to <code>post_init</code>. If an
+     * ORB-mediated call is made from within <code>post_init</code>, no
+     * request interceptors will be invoked on that call.
+     * Likewise, if an operation is performed which causes an IOR to be
+     * created, no IOR interceptors will be invoked.
+     *
+     * @param info provides initialization attributes and
+     *             operations by which Interceptors can be registered.
+     */
+    public void post_init(ORBInitInfo info) {
+    }
+}

Propchange: incubator/tuscany/java/sca/modules/binding-ejb/src/main/java/org/apache/tuscany/sca/binding/ejb/corba/UtilInitializer.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/tuscany/java/sca/modules/binding-ejb/src/main/java/org/apache/tuscany/sca/binding/ejb/corba/UtilInitializer.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: incubator/tuscany/java/sca/modules/binding-ejb/src/test/java/calculator/AddService.java
URL: http://svn.apache.org/viewvc/incubator/tuscany/java/sca/modules/binding-ejb/src/test/java/calculator/AddService.java?view=auto&rev=562321
==============================================================================
--- incubator/tuscany/java/sca/modules/binding-ejb/src/test/java/calculator/AddService.java (added)
+++ incubator/tuscany/java/sca/modules/binding-ejb/src/test/java/calculator/AddService.java Thu Aug  2 20:54:14 2007
@@ -0,0 +1,27 @@
+/*
+ * 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 calculator;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public interface AddService {
+    double add(double n1, double n2);
+}

Propchange: incubator/tuscany/java/sca/modules/binding-ejb/src/test/java/calculator/AddService.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/tuscany/java/sca/modules/binding-ejb/src/test/java/calculator/AddService.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: incubator/tuscany/java/sca/modules/binding-ejb/src/test/java/calculator/AddServiceHome.java
URL: http://svn.apache.org/viewvc/incubator/tuscany/java/sca/modules/binding-ejb/src/test/java/calculator/AddServiceHome.java?view=auto&rev=562321
==============================================================================
--- incubator/tuscany/java/sca/modules/binding-ejb/src/test/java/calculator/AddServiceHome.java (added)
+++ incubator/tuscany/java/sca/modules/binding-ejb/src/test/java/calculator/AddServiceHome.java Thu Aug  2 20:54:14 2007
@@ -0,0 +1,31 @@
+/*
+ * 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 calculator;
+
+import java.rmi.RemoteException;
+
+import javax.ejb.CreateException;
+import javax.ejb.EJBHome;
+
+public interface AddServiceHome extends EJBHome {
+
+    public AddService create() throws CreateException, RemoteException;
+
+}

Propchange: incubator/tuscany/java/sca/modules/binding-ejb/src/test/java/calculator/AddServiceHome.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/tuscany/java/sca/modules/binding-ejb/src/test/java/calculator/AddServiceHome.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date



---------------------------------------------------------------------
To unsubscribe, e-mail: tuscany-commits-unsubscribe@ws.apache.org
For additional commands, e-mail: tuscany-commits-help@ws.apache.org


Mime
View raw message