incubator-yoko-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From a..@apache.org
Subject svn commit: r420804 [7/8] - in /incubator/yoko/trunk/rmi: ./ src/ src/main/ src/main/java/ src/main/java/org/ src/main/java/org/apache/ src/main/java/org/apache/yoko/ src/main/java/org/apache/yoko/rmi/ src/main/java/org/apache/yoko/rmi/api/ src/main/ja...
Date Tue, 11 Jul 2006 11:35:35 GMT
Added: incubator/yoko/trunk/rmi/src/main/java/org/apache/yoko/rmi/util/DynamicHashMap.java
URL: http://svn.apache.org/viewvc/incubator/yoko/trunk/rmi/src/main/java/org/apache/yoko/rmi/util/DynamicHashMap.java?rev=420804&view=auto
==============================================================================
--- incubator/yoko/trunk/rmi/src/main/java/org/apache/yoko/rmi/util/DynamicHashMap.java (added)
+++ incubator/yoko/trunk/rmi/src/main/java/org/apache/yoko/rmi/util/DynamicHashMap.java Tue Jul 11 04:35:32 2006
@@ -0,0 +1,260 @@
+/**
+*
+* Copyright 2006 The Apache Software Foundation
+*
+*  Licensed 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.yoko.rmi.util;
+
+import java.util.Iterator;
+import java.util.Map;
+import java.util.NoSuchElementException;
+
+/**
+ * Class <code>DynamicHashMap</code> is a generic dynamic hash map.
+ */
+public class DynamicHashMap extends GenericMap implements Map {
+    class Entry extends GenericMap.Entry {
+        Entry next;
+
+        int hash;
+
+        Object key;
+
+        Object value;
+
+        Entry(int hash, Object key, Object value, Entry next) {
+            this.hash = hash;
+            this.key = key;
+            this.value = value;
+            this.next = next;
+        }
+
+        public Object getKey() {
+            return key;
+        }
+
+        public Object getValue() {
+            return value;
+        }
+
+        public Object setValue(Object value) {
+            Object result = this.value;
+            this.value = value;
+            return result;
+        }
+
+        boolean sameKey(int hash, Object key) {
+            return this.hash == hash && keyEquals(this.key, key);
+        }
+    }
+
+    /** the hash index */
+    private Entry[] table;
+
+    /** the current range for table. */
+    private int range;
+
+    private float ratio;
+
+    /** translate hash code bucket to index */
+    private int index(int hash) {
+        return (hash & 0x7ffffff) % range;
+    }
+
+    /** the default and only constructor */
+    public DynamicHashMap() {
+        clear();
+    }
+
+    public void clear() {
+        range = 3;
+        size = 0;
+        ratio = 0.75F;
+        table = new Entry[range];
+    }
+
+    /** return the element with the given key */
+    public Object get(Object key) {
+        int hash = keyHash(key);
+        return get(hash, key);
+    }
+
+    public Object get(int hash, Object key) {
+        int idx = index(hash);
+
+        for (Entry ent = table[idx]; ent != null; ent = ent.next) {
+            if (ent.sameKey(hash, key))
+                return ent.value;
+        }
+
+        return null;
+    }
+
+    /** return the element with the given key */
+    public boolean containsKey(Object key) {
+        int hash = keyHash(key);
+        return containsKey(hash, key);
+    }
+
+    public boolean containsKey(int hash, Object key) {
+        int idx = index(hash);
+
+        for (Entry ent = table[idx]; ent != null; ent = ent.next) {
+            if (ent.sameKey(hash, key))
+                return true;
+        }
+
+        return false;
+    }
+
+    public Object put(Object key, Object value) {
+        int hash = keyHash(key);
+        return put(hash, key, value);
+    }
+
+    public Object put(int hash, Object key, Object value) {
+        int idx = index(hash);
+
+        for (Entry ent = table[idx]; ent != null; ent = ent.next) {
+            if (ent.sameKey(hash, key)) {
+                return ent.setValue(value);
+            }
+        }
+
+        if (1.0F * size / range > ratio) {
+            grow();
+            idx = index(hash);
+        }
+
+        table[idx] = new Entry(hash, key, value, table[idx]);
+
+        size += 1;
+
+        return null;
+    }
+
+    public Object remove(Object key) {
+        int hash = keyHash(key);
+        return remove(hash, key);
+    }
+
+    public Object remove(int hash, Object key) {
+        int idx = index(hash);
+
+        Entry entry = table[idx];
+        if (entry != null) {
+
+            if (entry.sameKey(hash, key)) {
+                table[idx] = entry.next;
+                size -= 1;
+                return entry.getValue();
+
+            } else {
+                Entry ahead = entry.next;
+
+                while (ahead != null) {
+                    if (ahead.sameKey(hash, key)) {
+                        entry.next = ahead.next;
+                        size -= 1;
+                        return ahead.getValue();
+                    }
+
+                    entry = ahead;
+                    ahead = ahead.next;
+                }
+            }
+        }
+
+        // it was not found at all!
+        return null;
+    }
+
+    private void grow() {
+        int old_range = range;
+        Entry[] old_table = table;
+
+        range = old_range * 2 + 1;
+        table = new Entry[range];
+
+        for (int i = 0; i < old_range; i++) {
+            Entry entry = old_table[i];
+
+            while (entry != null) {
+                Entry ahead = entry.next;
+                int idx = index(entry.hash);
+                entry.next = table[idx];
+                table[idx] = entry;
+                entry = ahead;
+            }
+        }
+    }
+
+    final class EntryIterator implements Iterator {
+        int idx;
+
+        Entry entry;
+
+        EntryIterator() {
+            idx = 0;
+            entry = table[0];
+            locateNext();
+        }
+
+        private void locateNext() {
+            // we reached the end of a list
+            while (entry == null) {
+                // goto next bucket
+                idx += 1;
+                if (idx == range) {
+                    // we reached the end
+                    return;
+                }
+
+                // entry is the first element of this bucket
+                entry = table[idx];
+            }
+        }
+
+        public boolean hasNext() {
+            return (entry != null);
+        }
+
+        public Object next() {
+            Object result = entry;
+
+            if (result == null) {
+                throw new NoSuchElementException();
+            } else {
+                entry = entry.next;
+                locateNext();
+                return result;
+            }
+        }
+
+        public void remove() {
+            Entry remove = entry;
+
+            entry = entry.next;
+            locateNext();
+
+            DynamicHashMap.this.remove(remove.key);
+        }
+    }
+
+    protected Iterator entryIterator() {
+        return new EntryIterator();
+    }
+
+}

Propchange: incubator/yoko/trunk/rmi/src/main/java/org/apache/yoko/rmi/util/DynamicHashMap.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/yoko/trunk/rmi/src/main/java/org/apache/yoko/rmi/util/DynamicHashMap.java
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/yoko/trunk/rmi/src/main/java/org/apache/yoko/rmi/util/GenericMap.java
URL: http://svn.apache.org/viewvc/incubator/yoko/trunk/rmi/src/main/java/org/apache/yoko/rmi/util/GenericMap.java?rev=420804&view=auto
==============================================================================
--- incubator/yoko/trunk/rmi/src/main/java/org/apache/yoko/rmi/util/GenericMap.java (added)
+++ incubator/yoko/trunk/rmi/src/main/java/org/apache/yoko/rmi/util/GenericMap.java Tue Jul 11 04:35:32 2006
@@ -0,0 +1,256 @@
+/**
+*
+* Copyright 2006 The Apache Software Foundation
+*
+*  Licensed 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.yoko.rmi.util;
+
+import java.util.AbstractCollection;
+import java.util.AbstractSet;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+abstract class GenericMap implements Map {
+    protected int size;
+
+    public int size() {
+        return size;
+    }
+
+    public boolean isEmpty() {
+        return size() == 0;
+    }
+
+    protected int keyHash(Object key) {
+        if (key == null)
+            return 0;
+        else
+            return key.hashCode();
+    }
+
+    protected boolean keyEquals(Object key1, Object key2) {
+        if (key1 == null)
+            return key2 == null;
+        else
+            return key1.equals(key2);
+    }
+
+    protected int valueHash(Object value) {
+        if (value == null)
+            return 0;
+        else
+            return value.hashCode();
+    }
+
+    protected boolean valueEquals(Object value1, Object value2) {
+        if (value1 == null)
+            return value2 == null;
+        else
+            return value1.equals(value2);
+    }
+
+    abstract class Entry implements Map.Entry {
+        public int hashCode() {
+            return keyHash(getKey()) ^ valueHash(getValue());
+        }
+
+        public boolean equals(Object other) {
+            if (other instanceof Map.Entry) {
+                Map.Entry ent = (Map.Entry) other;
+                return keyEquals(getKey(), ent.getKey())
+                        && valueEquals(getValue(), ent.getValue());
+            } else {
+                return false;
+            }
+        }
+
+    }
+
+    public void putAll(Map other) {
+        if (other == this)
+            return;
+
+        Iterator it = other.entrySet().iterator();
+        while (it.hasNext()) {
+            Map.Entry entry = (Map.Entry) it.next();
+            put(entry.getKey(), entry.getValue());
+        }
+    }
+
+    protected abstract Iterator entryIterator();
+
+    protected Iterator keyIterator() {
+        return new KeyIterator();
+    }
+
+    protected Iterator valueIterator() {
+        return new ValueIterator();
+    }
+
+    abstract class KeyOrValueIterator implements Iterator {
+        Iterator iter = entryIterator();
+
+        public boolean hasNext() {
+            return iter.hasNext();
+        }
+
+        protected Map.Entry nextEntry() {
+            return (Map.Entry) iter.next();
+        }
+
+        public void remove() {
+            throw new UnsupportedOperationException();
+        }
+
+    }
+
+    class KeyIterator extends KeyOrValueIterator {
+        public Object next() {
+            return nextEntry().getKey();
+        }
+    }
+
+    class ValueIterator extends KeyOrValueIterator {
+        public Object next() {
+            return nextEntry().getValue();
+        }
+    }
+
+    /**
+     * I don't quite understand why we need to replace this method from
+     * AbstractCollection, but it has been observed that toArray returns the
+     * *reverse* order of elements. --Kresten
+     */
+
+    private static Object[] toArray(Object[] arr, int size, Iterator it) {
+        Object[] out = null;
+
+        if (arr != null && arr.length >= size) {
+            out = arr;
+        } else if (arr == null) {
+            out = new Object[size];
+        } else {
+            out = (Object[]) java.lang.reflect.Array.newInstance(arr.getClass()
+                    .getComponentType(), size);
+        }
+
+        for (int i = 0; i < size; i++) {
+            out[i] = it.next();
+        }
+
+        if (out.length > size)
+            out[size] = null;
+
+        return out;
+    }
+
+    public Collection values() {
+        return new AbstractCollection() {
+            public Iterator iterator() {
+                return valueIterator();
+            }
+
+            public int size() {
+                return GenericMap.this.size();
+            }
+
+            public Object[] toArray(Object[] arr) {
+                return GenericMap.toArray(arr, size(), iterator());
+            }
+        };
+    }
+
+    public Set keySet() {
+        return new AbstractSet() {
+            public Iterator iterator() {
+                return keyIterator();
+            }
+
+            public int size() {
+                return GenericMap.this.size();
+            }
+
+            public Object[] toArray(Object[] arr) {
+                return GenericMap.toArray(arr, size(), iterator());
+            }
+        };
+    }
+
+    public int hashCode() {
+        int code = 0;
+        Iterator it = entryIterator();
+        while (it.hasNext()) {
+            code += it.next().hashCode();
+        }
+        return code;
+    }
+
+    public boolean equals(Object other) {
+        if (other instanceof Map) {
+            Map map = (Map) other;
+
+            if (map.size() != size())
+                return false;
+
+            Iterator it = entryIterator();
+            while (it.hasNext()) {
+                Entry ent = (Entry) it.next();
+                Object key = ent.getKey();
+                Object val = ent.getValue();
+
+                if (map.containsKey(key)) {
+                    Object otherVal = map.get(key);
+                    if (!valueEquals(val, otherVal))
+                        return false;
+                }
+            }
+            return true;
+        }
+        return false;
+    }
+
+    public Set entrySet() {
+        return new AbstractSet() {
+            public Iterator iterator() {
+                return entryIterator();
+            }
+
+            public int size() {
+                return size;
+            }
+
+            public Object[] toArray(Object[] arr) {
+                return GenericMap.toArray(arr, size(), iterator());
+            }
+        };
+    }
+
+    /** return the element with the given key */
+    public boolean containsValue(Object value) {
+        Iterator it = valueIterator();
+        while (it.hasNext()) {
+            if (valueEquals(value, it.next()))
+                return true;
+        }
+        return false;
+    }
+
+    public boolean containsKey(Object key) {
+        return get(key) != null;
+    }
+
+}

Propchange: incubator/yoko/trunk/rmi/src/main/java/org/apache/yoko/rmi/util/GenericMap.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/yoko/trunk/rmi/src/main/java/org/apache/yoko/rmi/util/GenericMap.java
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/yoko/trunk/rmi/src/main/java/org/apache/yoko/rmi/util/NodeleteSynchronizedMap.java
URL: http://svn.apache.org/viewvc/incubator/yoko/trunk/rmi/src/main/java/org/apache/yoko/rmi/util/NodeleteSynchronizedMap.java?rev=420804&view=auto
==============================================================================
--- incubator/yoko/trunk/rmi/src/main/java/org/apache/yoko/rmi/util/NodeleteSynchronizedMap.java (added)
+++ incubator/yoko/trunk/rmi/src/main/java/org/apache/yoko/rmi/util/NodeleteSynchronizedMap.java Tue Jul 11 04:35:32 2006
@@ -0,0 +1,129 @@
+/**
+*
+* Copyright 2006 The Apache Software Foundation
+*
+*  Licensed 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.yoko.rmi.util;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+public class NodeleteSynchronizedMap implements Map {
+    Map global;
+
+    ThreadLocal local = new ThreadLocal() {
+        public Object initialValue() {
+            return NodeleteSynchronizedMap.this.initialValue();
+        }
+    };
+
+    public NodeleteSynchronizedMap() {
+        global = Collections.synchronizedMap(initialValue());
+    }
+
+    private Map localMap() {
+        return (Map) local.get();
+    }
+
+    public int size() {
+        return global.size();
+    }
+
+    public boolean isEmpty() {
+        return global.isEmpty();
+    }
+
+    public boolean containsKey(java.lang.Object key) {
+        Map local = localMap();
+        if (local.containsKey(key)) {
+            return true;
+        }
+
+        if (global.containsKey(key)) {
+            local.put(key, global.get(key));
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    public boolean containsValue(java.lang.Object val) {
+        Map local = localMap();
+        if (local.containsValue(val)) {
+            return true;
+        }
+
+        return global.containsValue(val);
+    }
+
+    public java.lang.Object get(java.lang.Object key) {
+        Map local = localMap();
+        Object val = local.get(key);
+        if (val != null)
+            return val;
+
+        if (local.containsKey(key)) {
+            return null;
+        }
+
+        val = global.get(key);
+        if (val != null) {
+            local.put(key, val);
+        }
+
+        return val;
+    }
+
+    public boolean equals(java.lang.Object other) {
+        return global.equals(other);
+    }
+
+    public int hashCode() {
+        return global.hashCode();
+    }
+
+    public java.util.Set keySet() {
+        return global.keySet();
+    }
+
+    public java.util.Collection values() {
+        return global.values();
+    }
+
+    public java.util.Set entrySet() {
+        return global.entrySet();
+    }
+
+    public java.lang.Object put(java.lang.Object key, java.lang.Object val) {
+        return global.put(key, val);
+    }
+
+    public java.lang.Object remove(java.lang.Object key) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void putAll(java.util.Map other) {
+        global.putAll(other);
+    }
+
+    public void clear() {
+        throw new UnsupportedOperationException();
+    }
+
+    public Map initialValue() {
+        return new HashMap();
+    }
+}

Propchange: incubator/yoko/trunk/rmi/src/main/java/org/apache/yoko/rmi/util/NodeleteSynchronizedMap.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/yoko/trunk/rmi/src/main/java/org/apache/yoko/rmi/util/NodeleteSynchronizedMap.java
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/yoko/trunk/rmi/src/main/java/org/apache/yoko/rmi/util/PriorityQueue.java
URL: http://svn.apache.org/viewvc/incubator/yoko/trunk/rmi/src/main/java/org/apache/yoko/rmi/util/PriorityQueue.java?rev=420804&view=auto
==============================================================================
--- incubator/yoko/trunk/rmi/src/main/java/org/apache/yoko/rmi/util/PriorityQueue.java (added)
+++ incubator/yoko/trunk/rmi/src/main/java/org/apache/yoko/rmi/util/PriorityQueue.java Tue Jul 11 04:35:32 2006
@@ -0,0 +1,208 @@
+/**
+*
+* Copyright 2006 The Apache Software Foundation
+*
+*  Licensed 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.yoko.rmi.util;
+
+import java.util.Comparator;
+
+/**
+ *
+ * @author Kresten Krab Thorup
+ */
+public class PriorityQueue implements org.apache.yoko.rmi.util.Queue
+{
+    /** the default queue size is 4 */
+    public static final int DEFAULT_QUEUE_SIZE = 4;
+
+    Comparator cmp;
+
+    int      elem_count = 0;
+    int      elem_max;
+    Object[] elem_data;
+
+    /** Construct a new <code>PriorityQueue</code> (primary constructor) */
+    public PriorityQueue (int size, Comparator cmp)
+    {
+	if (size < 4)
+	    elem_max = 4;
+	else
+	    elem_max = size;
+
+	elem_count = 0;
+	elem_data = new Object[elem_max+2];
+
+	this.cmp = cmp;
+    }
+
+    public PriorityQueue (int size)
+    {
+	this (size, new ComparableComparator() );
+    }
+
+    public PriorityQueue ()
+    {
+	this (DEFAULT_QUEUE_SIZE, new ComparableComparator());
+    }
+    
+    public PriorityQueue (Comparator cmp)
+    {
+	this (DEFAULT_QUEUE_SIZE, cmp);
+    }
+
+    public int size ()
+    {
+	return elem_count;
+    }
+    
+    public Object[] toArray (Object[] result)
+    {
+	if (result.length < size ()) {
+	    Class elementClass = result.getClass ().getComponentType ();
+	    result = (Object[])
+		java.lang.reflect.Array.newInstance
+		(elementClass, size ());
+	}
+
+	int count = elem_count;
+	for (int i = 0; i < count; i++) {
+	    result[i] = dequeue ();
+	}
+
+	return result;
+    }
+
+    public void clear ()
+    {
+	elem_count = 0;
+    }
+
+    public Object dequeue () 
+    {
+	if (elem_count == 0)
+	    return null;
+
+	Object result = elem_data[1];
+
+	elem_data[1] = elem_data[elem_count];
+	elem_count -= 1;
+	sift_down (1);
+	return result;
+    }
+
+    private void sift_down (int i)
+    {
+      final int top_idx = i;
+      final int left_idx = i*2;
+      final int right_idx = left_idx+1;
+      
+      if (elem_count < left_idx) {
+	return;
+      }
+      
+      // the left one is the last
+      else if (elem_count == left_idx) {
+	Object top   = elem_data[top_idx]; 
+	Object left  = elem_data[left_idx];
+	
+	if (cmp.compare (left, top) < 0) {
+	  elem_data[top_idx] = left;
+	  elem_data[left_idx] = top;
+	}
+	
+	return;
+      }
+
+      // there are more...
+      else 
+	{
+	  Object top   = elem_data[top_idx];
+	  Object left  = elem_data[left_idx];
+	  Object right = elem_data[right_idx];
+	  
+	  if (cmp.compare (left, right) < 0) {
+	    // left is now the smaller
+	    
+	    if (cmp.compare (left, top) < 0)
+	      {
+		elem_data[top_idx]  = left;
+		elem_data[left_idx] = top;
+		
+		sift_down (left_idx);
+	      }
+	  }
+	  
+	  else if (cmp.compare (right, top) < 0) {
+	    // the right one is the smaller
+
+	    elem_data[top_idx]   = right;
+	    elem_data[right_idx] = top; 
+
+	    sift_down (right_idx);
+	  }
+	}
+    }
+
+    public void enqueue (Object o)
+    {
+
+	// make room
+	if (elem_max == elem_count)
+	    {
+		int new_max = elem_max * 2;
+		Object[] new_data = new Object[new_max + 2];
+		System.arraycopy (elem_data, 0, new_data, 0, elem_max+2);
+		elem_max = new_max;
+		elem_data = new_data;
+	    }
+
+	elem_count += 1;
+	elem_data[elem_count] = o;
+
+	sift_up (elem_count);
+    }
+
+    private void sift_up (int idx)
+    {
+	if (idx == 1)
+	    return;
+
+	Object me  = elem_data[idx];
+	Object top = elem_data[idx/2];
+
+	if (cmp.compare (me, top) < 0)
+	    {
+		elem_data[idx] = top;
+		elem_data[idx/2] = me;
+
+		sift_up (idx/2);
+	    }
+    }
+    
+    public void push(Object o) {
+    	enqueue(o);	
+    }
+    
+}
+
+class ComparableComparator implements Comparator
+{
+    public int compare (Object o1, Object o2)
+    {
+	return ((Comparable)o1).compareTo ((Comparable)o2);
+    }
+}
+

Propchange: incubator/yoko/trunk/rmi/src/main/java/org/apache/yoko/rmi/util/PriorityQueue.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/yoko/trunk/rmi/src/main/java/org/apache/yoko/rmi/util/PriorityQueue.java
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/yoko/trunk/rmi/src/main/java/org/apache/yoko/rmi/util/Queue.java
URL: http://svn.apache.org/viewvc/incubator/yoko/trunk/rmi/src/main/java/org/apache/yoko/rmi/util/Queue.java?rev=420804&view=auto
==============================================================================
--- incubator/yoko/trunk/rmi/src/main/java/org/apache/yoko/rmi/util/Queue.java (added)
+++ incubator/yoko/trunk/rmi/src/main/java/org/apache/yoko/rmi/util/Queue.java Tue Jul 11 04:35:32 2006
@@ -0,0 +1,33 @@
+/**
+*
+* Copyright 2006 The Apache Software Foundation
+*
+*  Licensed 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.yoko.rmi.util;
+
+/**
+ * 
+ * 
+ * @author Kim Harding Christensen (khc@eos.dk)
+ **/
+public interface Queue {
+    
+    void enqueue(Object o);
+    Object dequeue();
+    int size();
+    void clear ();
+    Object[] toArray (Object[] result);
+    void push(Object o);
+}

Propchange: incubator/yoko/trunk/rmi/src/main/java/org/apache/yoko/rmi/util/Queue.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/yoko/trunk/rmi/src/main/java/org/apache/yoko/rmi/util/Queue.java
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/yoko/trunk/rmi/src/main/java/org/apache/yoko/rmi/util/StreamUtil.java
URL: http://svn.apache.org/viewvc/incubator/yoko/trunk/rmi/src/main/java/org/apache/yoko/rmi/util/StreamUtil.java?rev=420804&view=auto
==============================================================================
--- incubator/yoko/trunk/rmi/src/main/java/org/apache/yoko/rmi/util/StreamUtil.java (added)
+++ incubator/yoko/trunk/rmi/src/main/java/org/apache/yoko/rmi/util/StreamUtil.java Tue Jul 11 04:35:32 2006
@@ -0,0 +1,78 @@
+/**
+*
+* Copyright 2006 The Apache Software Foundation
+*
+*  Licensed 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.yoko.rmi.util;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.io.Writer;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * 
+ * @author Jeppe Sommer (jso@eos.dk)
+ */
+public class StreamUtil {
+    final static Logger logger = Logger.getLogger(StreamUtil.class.getName());
+
+    static final int BUF_SIZE = 4096;
+
+    public static void copyStream(InputStream is, OutputStream os)
+            throws IOException {
+
+        byte[] buf = new byte[BUF_SIZE];
+
+        if (logger.isLoggable(Level.FINER)) {
+            logger.finer("copyStream(" + is + ", " + os);
+        }
+
+        try {
+            int count;
+
+            while ((count = is.read(buf)) != -1) {
+                // log.debug("copyStream, copying " + count + " bytes");
+                os.write(buf, 0, count);
+            }
+
+        } finally {
+        }
+    }
+
+    public static void copyStream(Reader reader, Writer writer)
+            throws IOException {
+
+        char[] buf = new char[BUF_SIZE];
+
+        if (logger.isLoggable(Level.FINER)) {
+            logger.finer("copyStream(" + reader + ", " + writer);
+        }
+
+        try {
+            int count;
+
+            while ((count = reader.read(buf)) != -1) {
+                // log.debug("copyStream, copying " + count + " bytes");
+                writer.write(buf, 0, count);
+            }
+
+        } finally {
+        }
+    }
+}

Propchange: incubator/yoko/trunk/rmi/src/main/java/org/apache/yoko/rmi/util/StreamUtil.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/yoko/trunk/rmi/src/main/java/org/apache/yoko/rmi/util/StreamUtil.java
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/yoko/trunk/rmi/src/main/java/org/apache/yoko/rmi/util/StringUtil.java
URL: http://svn.apache.org/viewvc/incubator/yoko/trunk/rmi/src/main/java/org/apache/yoko/rmi/util/StringUtil.java?rev=420804&view=auto
==============================================================================
--- incubator/yoko/trunk/rmi/src/main/java/org/apache/yoko/rmi/util/StringUtil.java (added)
+++ incubator/yoko/trunk/rmi/src/main/java/org/apache/yoko/rmi/util/StringUtil.java Tue Jul 11 04:35:32 2006
@@ -0,0 +1,75 @@
+/**
+*
+* Copyright 2006 The Apache Software Foundation
+*
+*  Licensed 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.yoko.rmi.util;
+
+import java.util.ArrayList;
+
+/**
+ * 
+ * @author Jeppe Sommer (jso@eos.dk)
+ * @author Kim Harding Christensen (khc@eos.dk)
+ */
+public class StringUtil {
+    public static String capitalize(String str) {
+        StringBuffer sb = new StringBuffer(str);
+        sb.setCharAt(0, Character.toUpperCase(str.charAt(0)));
+        return sb.toString();
+    }
+
+    public static String join(String[] strings, String delimiter) {
+        StringBuffer sb = new StringBuffer();
+        for (int n = 0; n < strings.length; n++) {
+            sb.append(strings[n]);
+            if (n < strings.length - 1) {
+                sb.append(delimiter);
+            }
+        }
+        return sb.toString();
+    }
+
+    public static String[] split(String str, char splitChar) {
+        ArrayList al = new ArrayList(8);
+        int i = -1;
+        String s;
+        String rest = str;
+        while ((i = rest.indexOf(splitChar)) != -1) {
+            s = rest.substring(0, i);
+            al.add(s);
+            rest = rest.substring(i + 1);
+        }
+        al.add(rest);
+        String[] result = new String[al.size()];
+        al.toArray(result);
+        return result;
+    }
+
+    public static String replace(String str, String oldStr, String newStr) {
+        int prevIndex = 0, nextIndex;
+        StringBuffer result = new StringBuffer();
+
+        while ((nextIndex = str.indexOf(oldStr, prevIndex)) != -1) {
+            result.append(str.substring(prevIndex, nextIndex));
+            result.append(newStr);
+            prevIndex = nextIndex + oldStr.length();
+        }
+
+        result.append(str.substring(prevIndex));
+
+        return result.toString();
+    }
+}

Propchange: incubator/yoko/trunk/rmi/src/main/java/org/apache/yoko/rmi/util/StringUtil.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/yoko/trunk/rmi/src/main/java/org/apache/yoko/rmi/util/StringUtil.java
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/yoko/trunk/rmi/src/main/java/org/apache/yoko/rmi/util/corba/Field.java
URL: http://svn.apache.org/viewvc/incubator/yoko/trunk/rmi/src/main/java/org/apache/yoko/rmi/util/corba/Field.java?rev=420804&view=auto
==============================================================================
--- incubator/yoko/trunk/rmi/src/main/java/org/apache/yoko/rmi/util/corba/Field.java (added)
+++ incubator/yoko/trunk/rmi/src/main/java/org/apache/yoko/rmi/util/corba/Field.java Tue Jul 11 04:35:32 2006
@@ -0,0 +1,145 @@
+/**
+*
+* Copyright 2006 The Apache Software Foundation
+*
+*  Licensed 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.yoko.rmi.util.corba;
+
+import java.lang.reflect.Modifier;
+
+import sun.misc.Unsafe;
+
+public class Field {
+    final long fieldID;
+
+    // static final Category log = Category.getInstance(Field.class);
+    static final Unsafe unsafe = getUnsafe();
+
+    private static Unsafe getUnsafe() {
+        Unsafe unsafe = null;
+        try {
+            Class uc = Unsafe.class;
+            java.lang.reflect.Field[] fields = uc.getDeclaredFields();
+            for (int i = 0; i < fields.length; i++) {
+                if (fields[i].getName().equals("theUnsafe")) {
+                    fields[i].setAccessible(true);
+                    unsafe = (Unsafe) fields[i].get(uc);
+                    break;
+                }
+            }
+        } catch (Exception ignore) {
+            ignore.printStackTrace();
+        }
+        return unsafe;
+    }
+
+    public Field(java.lang.reflect.Field f) {
+        if (Modifier.isStatic(f.getModifiers()))
+            fieldID = unsafe.staticFieldOffset(f);
+        else
+            fieldID = unsafe.objectFieldOffset(f);
+    }
+
+    public void set(Object obj, Object val) throws IllegalArgumentException,
+            IllegalAccessException {
+        unsafe.putObject(obj, fieldID, val);
+    }
+
+    public void setByte(Object obj, byte val) throws IllegalArgumentException,
+            IllegalAccessException {
+        unsafe.putByte(obj, fieldID, val);
+    }
+
+    public void setBoolean(Object obj, boolean val)
+            throws IllegalArgumentException, IllegalAccessException {
+        unsafe.putBoolean(obj, fieldID, val);
+    }
+
+    public void setShort(Object obj, short val)
+            throws IllegalArgumentException, IllegalAccessException {
+        unsafe.putShort(obj, fieldID, val);
+    }
+
+    public void setChar(Object obj, char val) throws IllegalArgumentException,
+            IllegalAccessException {
+        unsafe.putChar(obj, fieldID, val);
+    }
+
+    public void setInt(Object obj, int val) throws IllegalArgumentException,
+            IllegalAccessException {
+        unsafe.putInt(obj, fieldID, val);
+    }
+
+    public void setLong(Object obj, long val) throws IllegalArgumentException,
+            IllegalAccessException {
+        unsafe.putLong(obj, fieldID, val);
+    }
+
+    public void setFloat(Object obj, float val)
+            throws IllegalArgumentException, IllegalAccessException {
+        unsafe.putFloat(obj, fieldID, val);
+    }
+
+    public void setDouble(Object obj, double val)
+            throws IllegalArgumentException, IllegalAccessException {
+        unsafe.putDouble(obj, fieldID, val);
+    }
+
+    public Object get(Object obj) throws IllegalArgumentException,
+            IllegalAccessException {
+        return unsafe.getObject(obj, fieldID);
+    }
+
+    public byte getByte(Object obj) throws IllegalArgumentException,
+            IllegalAccessException {
+        return unsafe.getByte(obj, fieldID);
+    }
+
+    public boolean getBoolean(Object obj) throws IllegalArgumentException,
+            IllegalAccessException {
+        return unsafe.getBoolean(obj, fieldID);
+    }
+
+    public short getShort(Object obj) throws IllegalArgumentException,
+            IllegalAccessException {
+        return unsafe.getShort(obj, fieldID);
+    }
+
+    public char getChar(Object obj) throws IllegalArgumentException,
+            IllegalAccessException {
+        return unsafe.getChar(obj, fieldID);
+    }
+
+    public int getInt(Object obj) throws IllegalArgumentException,
+            IllegalAccessException {
+        return unsafe.getInt(obj, fieldID);
+    }
+
+    public long getLong(Object obj) throws IllegalArgumentException,
+            IllegalAccessException {
+        return unsafe.getLong(obj, fieldID);
+    }
+
+    public float getFloat(Object obj) throws IllegalArgumentException,
+            IllegalAccessException {
+        return unsafe.getFloat(obj, fieldID);
+    }
+
+    public double getDouble(Object obj) throws IllegalArgumentException,
+            IllegalAccessException {
+        return unsafe.getDouble(obj, fieldID);
+    }
+
+}

Propchange: incubator/yoko/trunk/rmi/src/main/java/org/apache/yoko/rmi/util/corba/Field.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/yoko/trunk/rmi/src/main/java/org/apache/yoko/rmi/util/corba/Field.java
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/yoko/trunk/rmi/src/main/java/org/apache/yoko/rmi/util/corba/POAObject.java
URL: http://svn.apache.org/viewvc/incubator/yoko/trunk/rmi/src/main/java/org/apache/yoko/rmi/util/corba/POAObject.java?rev=420804&view=auto
==============================================================================
--- incubator/yoko/trunk/rmi/src/main/java/org/apache/yoko/rmi/util/corba/POAObject.java (added)
+++ incubator/yoko/trunk/rmi/src/main/java/org/apache/yoko/rmi/util/corba/POAObject.java Tue Jul 11 04:35:32 2006
@@ -0,0 +1,105 @@
+/**
+*
+* Copyright 2006 The Apache Software Foundation
+*
+*  Licensed 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.yoko.rmi.util.corba;
+
+import org.omg.PortableServer.POA;
+import org.omg.PortableServer.Servant;
+
+public class POAObject extends org.omg.CORBA_2_3.portable.ObjectImpl {
+    private Servant servant;
+
+    protected POA poa;
+
+    // non-null if object is exported
+    protected byte[] id;
+
+    protected POAObject(Servant servant, POA poa) {
+        this.servant = servant;
+        this.poa = poa;
+
+        if (servant == null || poa == null) {
+            throw new IllegalArgumentException();
+        }
+    }
+
+    public String[] _ids() {
+        return servant._all_interfaces(poa, null);
+    }
+
+    public org.omg.CORBA.portable.Delegate _get_delegate() {
+        try {
+            return super._get_delegate();
+        } catch (org.omg.CORBA.BAD_OPERATION ex) {
+            //
+        }
+
+        synchronized (this) {
+
+            try {
+                return super._get_delegate();
+            } catch (org.omg.CORBA.BAD_OPERATION ex) {
+                //
+            }
+
+            org.omg.CORBA.portable.ObjectImpl ref = export();
+
+            org.omg.CORBA.portable.Delegate delegate = ref._get_delegate();
+            this._set_delegate(delegate);
+
+            return delegate;
+        }
+    }
+
+    private org.omg.CORBA.portable.ObjectImpl export() {
+        try {
+
+            if (id != null) {
+                throw new Error("Internal consistency error!");
+            }
+
+            id = poa.activate_object(servant);
+
+            return (org.omg.CORBA.portable.ObjectImpl) poa.id_to_reference(id);
+
+        } catch (org.omg.PortableServer.POAPackage.ServantAlreadyActive ex) {
+            throw new Error(ex.toString());
+
+        } catch (org.omg.PortableServer.POAPackage.ObjectNotActive ex) {
+            throw new Error(ex.toString());
+
+        } catch (org.omg.PortableServer.POAPackage.WrongPolicy ex) {
+            throw new Error(ex.toString());
+        }
+    }
+
+    public synchronized void unexport() {
+        if (id == null) {
+            return;
+        }
+
+        try {
+            poa.deactivate_object(id);
+            id = null;
+
+        } catch (org.omg.PortableServer.POAPackage.ObjectNotActive ex) {
+            throw new org.omg.CORBA.INTERNAL("ObjectNotActive::" + ex);
+        } catch (org.omg.PortableServer.POAPackage.WrongPolicy ex) {
+            throw new org.omg.CORBA.INTERNAL("WrongPolicy::" + ex);
+        }
+    }
+}

Propchange: incubator/yoko/trunk/rmi/src/main/java/org/apache/yoko/rmi/util/corba/POAObject.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/yoko/trunk/rmi/src/main/java/org/apache/yoko/rmi/util/corba/POAObject.java
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/yoko/trunk/rmi/src/main/java/org/apache/yoko/rmi/util/stub/BCELClassBuilder.java
URL: http://svn.apache.org/viewvc/incubator/yoko/trunk/rmi/src/main/java/org/apache/yoko/rmi/util/stub/BCELClassBuilder.java?rev=420804&view=auto
==============================================================================
--- incubator/yoko/trunk/rmi/src/main/java/org/apache/yoko/rmi/util/stub/BCELClassBuilder.java (added)
+++ incubator/yoko/trunk/rmi/src/main/java/org/apache/yoko/rmi/util/stub/BCELClassBuilder.java Tue Jul 11 04:35:32 2006
@@ -0,0 +1,1042 @@
+/**
+*
+* Copyright 2006 The Apache Software Foundation
+*
+*  Licensed 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.yoko.rmi.util.stub;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.apache.bcel.Constants;
+import org.apache.bcel.classfile.JavaClass;
+import org.apache.bcel.classfile.Synthetic;
+import org.apache.bcel.generic.ALOAD;
+import org.apache.bcel.generic.ARETURN;
+import org.apache.bcel.generic.ASTORE;
+import org.apache.bcel.generic.ATHROW;
+import org.apache.bcel.generic.ArrayType;
+import org.apache.bcel.generic.ClassGen;
+import org.apache.bcel.generic.ConstantPoolGen;
+import org.apache.bcel.generic.DLOAD;
+import org.apache.bcel.generic.DRETURN;
+import org.apache.bcel.generic.FLOAD;
+import org.apache.bcel.generic.FRETURN;
+import org.apache.bcel.generic.FieldGen;
+import org.apache.bcel.generic.ILOAD;
+import org.apache.bcel.generic.INVOKESPECIAL;
+import org.apache.bcel.generic.IRETURN;
+import org.apache.bcel.generic.Instruction;
+import org.apache.bcel.generic.InstructionConstants;
+import org.apache.bcel.generic.InstructionFactory;
+import org.apache.bcel.generic.InstructionHandle;
+import org.apache.bcel.generic.InstructionList;
+import org.apache.bcel.generic.LLOAD;
+import org.apache.bcel.generic.LRETURN;
+import org.apache.bcel.generic.MethodGen;
+import org.apache.bcel.generic.NEW;
+import org.apache.bcel.generic.ObjectType;
+import org.apache.bcel.generic.PUSH;
+import org.apache.bcel.generic.PUTFIELD;
+import org.apache.bcel.generic.Type;
+
+class BCELClassBuilder {
+    static final Logger logger = Logger.getLogger(BCELClassBuilder.class
+            .getName());
+
+    static Class make(ClassLoader loader, Class superClass, Class[] interfaces,
+            MethodRef[] methods, MethodRef[] superMethodRefs, Object[] data,
+            MethodRef handlerMethodRef, String className,
+            StubInitializer initializer)
+
+    throws IllegalAccessException, InstantiationException,
+            IllegalArgumentException {
+        String superClassName = superClass.getName();
+        String[] interfaceNames = new String[interfaces.length + 1];
+        for (int i = 0; i < interfaces.length; i++)
+            interfaceNames[i] = interfaces[i].getName();
+        interfaceNames[interfaces.length] = Stub.class.getName();
+
+        ClassGen newStubClass = new ClassGen(className, superClassName,
+                "generated", // file name
+                Constants.ACC_PUBLIC | Constants.ACC_FINAL, interfaceNames);
+
+        ConstantPoolGen cp = newStubClass.getConstantPool();
+
+        if (handlerMethodRef == null)
+            throw new IllegalArgumentException("handler method is null");
+
+        //
+        // Check that the handler method is valid
+        //
+        Class[] paramTypes = handlerMethodRef.getParameterTypes();
+        if (paramTypes.length != 3) {
+            throw new IllegalArgumentException(
+                    "handler method must have three arguments");
+        }
+
+        if (!paramTypes[0].isAssignableFrom(superClass)) {
+            throw new IllegalArgumentException(
+                    "Handler's 1st argument must be super-type for "
+                            + superClass);
+        }
+
+        // the type of data fields
+        Type typeOfDataFields = translate(paramTypes[1]);
+
+        if (Object[].class != paramTypes[2]) {
+            throw new IllegalArgumentException(
+                    "Handler's 3rd argument must be Object[]");
+        }
+
+        //
+        // Construct field for the handler reference
+        //
+        Class handlerClass = handlerMethodRef.getDeclaringClass();
+        FieldGen handlerFieldGen = new FieldGen(Constants.ACC_PRIVATE
+                | Constants.ACC_FINAL, translate(handlerClass), Util
+                .handlerFieldName(), cp);
+        newStubClass.addField(handlerFieldGen.getField());
+
+        //
+        // Construct the method that gets the stub handler.
+        //
+        generateHandlerGetter(newStubClass, handlerFieldGen);
+
+        //
+        // construct the field that holds the initializer
+        //
+        FieldGen initializerFieldGen = new FieldGen(Constants.ACC_PRIVATE
+                | Constants.ACC_STATIC, translate(StubInitializer.class), Util
+                .initializerFieldName(), cp);
+        newStubClass.addField(initializerFieldGen.getField());
+
+        //
+        // Emit constructor
+        //
+        emitInitializerConstructor(newStubClass, handlerFieldGen,
+                initializerFieldGen);
+
+        //
+        // Construct data fields
+        //
+        FieldGen[] dataFieldGens = new FieldGen[methods.length];
+        for (int i = 0; i < methods.length; i++) {
+            MethodRef method = methods[i];
+
+            dataFieldGens[i] = new FieldGen(Constants.ACC_PRIVATE
+                    | Constants.ACC_STATIC, typeOfDataFields, Util
+                    .methodFieldName(i), cp);
+
+            newStubClass.addField(dataFieldGens[i].getField());
+        }
+
+        //
+        // Construct method stubs
+        //
+        for (int i = 0; i < methods.length; i++) {
+            generate(newStubClass, methods[i], dataFieldGens[i],
+                    handlerFieldGen, handlerMethodRef);
+        }
+
+        //
+        // Construct super-method trampolines
+        //
+        for (int i = 0; i < superMethodRefs.length; i++) {
+            generateSuperMethod(newStubClass, superMethodRefs[i]);
+        }
+
+        JavaClass javaClass = newStubClass.getJavaClass();
+        byte[] classData = javaClass.getBytes();
+
+        try {
+            if (Boolean.getBoolean("org.apache.yoko.rmi.util.stub.debug")) {
+                java.io.File out = new java.io.File(className + ".class");
+                // System.out.println ("dumping to file "+out);
+                javaClass.dump(out);
+            }
+        } catch (java.io.IOException ex) {
+            logger.log(Level.WARNING, "", ex);
+        }
+
+        Class proxyClass = Util.defineClass(loader, className, classData, 0,
+                classData.length);
+
+        // initialize the static data fields
+        for (int i = 0; i < methods.length; i++) {
+            try {
+                java.lang.reflect.Field f = proxyClass
+                        .getDeclaredField(dataFieldGens[i].getName());
+
+                f.setAccessible(true);
+                f.set(null, data[i]);
+                f.setAccessible(false);
+            } catch (NoSuchFieldException ex) {
+                logger
+                        .log(
+                                Level.WARNING,
+                                "cannot find field "
+                                        + dataFieldGens[i].getName()
+                                        + " for stub class "
+                                        + className
+                                        + " extends: "
+                                        + superClassName
+                                        + "implements: "
+                                        + interfaceNames[0]
+                                        + (interfaceNames.length > 2 ? " (among others) "
+                                                : ""), ex);
+                throw new Error("internal error!");
+            }
+        }
+
+        // set the initializer
+        try {
+            java.lang.reflect.Field f = proxyClass.getDeclaredField(Util
+                    .initializerFieldName());
+            f.setAccessible(true);
+            f.set(null, initializer);
+        } catch (NoSuchFieldException ex) {
+            throw new Error("internal error!");
+        }
+
+        return proxyClass;
+
+    }
+
+    static Class make(ClassLoader loader, Class superClass, Class[] interfaces,
+            MethodRef[] methods, Object[] data, MethodRef handlerMethodRef,
+            String className)
+
+    throws IllegalAccessException, InstantiationException,
+            IllegalArgumentException {
+        // construct the name of the new class
+        String superClassName = superClass.getName();
+        String[] interfaceNames = new String[interfaces.length + 1];
+        for (int i = 0; i < interfaces.length; i++)
+            interfaceNames[i] = interfaces[i].getName();
+        interfaceNames[interfaces.length] = Stub.class.getName();
+
+        ClassGen newStubClass = new ClassGen(className, superClassName,
+                "generated", // file name
+                Constants.ACC_PUBLIC | Constants.ACC_FINAL, interfaceNames);
+
+        ConstantPoolGen cp = newStubClass.getConstantPool();
+
+        if (handlerMethodRef == null)
+            throw new IllegalArgumentException("handler method is null");
+
+        //
+        // Check that the handler method is valid
+        //
+        Class[] paramTypes = handlerMethodRef.getParameterTypes();
+        if (paramTypes.length != 3) {
+            throw new IllegalArgumentException(
+                    "handler method must have three arguments");
+        }
+
+        if (!paramTypes[0].isAssignableFrom(superClass)) {
+            throw new IllegalArgumentException(
+                    "Handler's 1st argument must be super-type for "
+                            + superClass);
+        }
+
+        // the type of data fields
+        Type typeOfDataFields = translate(paramTypes[1]);
+
+        if (Object[].class != paramTypes[2]) {
+            throw new IllegalArgumentException(
+                    "Handler's 3rd argument must be Object[]");
+        }
+
+        //
+        // Construct field for the handler reference
+        //
+        Class handlerClass = handlerMethodRef.getDeclaringClass();
+        FieldGen handlerFieldGen = new FieldGen(Constants.ACC_PRIVATE
+                | Constants.ACC_FINAL, translate(handlerClass), Util
+                .handlerFieldName(), cp);
+        newStubClass.addField(handlerFieldGen.getField());
+
+        //
+        // Construct the method that gets the stub handler.
+        //
+        generateHandlerGetter(newStubClass, handlerFieldGen);
+
+        //
+        // Emit constructor
+        //
+        emitOneArgConstructor(newStubClass, handlerFieldGen);
+
+        //
+        // Construct data fields
+        //
+        FieldGen[] dataFieldGens = new FieldGen[methods.length];
+        for (int i = 0; i < methods.length; i++) {
+            MethodRef method = methods[i];
+
+            dataFieldGens[i] = new FieldGen(Constants.ACC_PRIVATE
+                    | Constants.ACC_STATIC, typeOfDataFields, Util
+                    .methodFieldName(i), cp);
+
+            newStubClass.addField(dataFieldGens[i].getField());
+        }
+
+        //
+        // Construct method stubs
+        //
+        for (int i = 0; i < methods.length; i++) {
+            generate(newStubClass, methods[i], dataFieldGens[i],
+                    handlerFieldGen, handlerMethodRef);
+        }
+
+        JavaClass javaClass = newStubClass.getJavaClass();
+        byte[] classData = javaClass.getBytes();
+
+        try {
+            if (Boolean.getBoolean("org.apache.yoko.rmi.util.stub.debug")) {
+                java.io.File out = new java.io.File(className + ".class");
+                // System.out.println ("dumping to file "+out);
+                javaClass.dump(out);
+            }
+        } catch (java.io.IOException ex) {
+            logger.log(Level.WARNING, "", ex);
+        }
+
+        Class proxyClass = Util.defineClass(loader, className, classData, 0,
+                classData.length);
+
+        // initialize the static data fields
+        for (int i = 0; i < methods.length; i++) {
+            try {
+                java.lang.reflect.Field f = proxyClass
+                        .getDeclaredField(dataFieldGens[i].getName());
+
+                f.setAccessible(true);
+                f.set(null, data[i]);
+                f.setAccessible(false);
+            } catch (NoSuchFieldException ex) {
+                throw new Error("internal error!", ex);
+            }
+        }
+
+        return proxyClass;
+    }
+
+    static Type translate(Class clazz) {
+        if (clazz.isPrimitive()) {
+
+            if (clazz == Integer.TYPE) {
+                return Type.INT;
+            } else if (clazz == Boolean.TYPE) {
+                return Type.BOOLEAN;
+            } else if (clazz == Short.TYPE) {
+                return Type.SHORT;
+            } else if (clazz == Byte.TYPE) {
+                return Type.BYTE;
+            } else if (clazz == Long.TYPE) {
+                return Type.LONG;
+            } else if (clazz == Double.TYPE) {
+                return Type.DOUBLE;
+            } else if (clazz == Float.TYPE) {
+                return Type.FLOAT;
+            } else if (clazz == Character.TYPE) {
+                return Type.CHAR;
+            } else if (clazz == Void.TYPE) {
+                return Type.VOID;
+            } else {
+                throw new InternalError();
+            }
+
+        } else if (clazz.isArray()) {
+            return new ArrayType(translate(clazz.getComponentType()), 1);
+
+        } else {
+
+            return new ObjectType(clazz.getName());
+        }
+    }
+
+    static Type[] translate(Class[] clazz) {
+        Type[] result = new Type[clazz.length];
+        for (int i = 0; i < clazz.length; i++) {
+            result[i] = translate(clazz[i]);
+        }
+        return result;
+    }
+
+    public static MethodRef[] getAbstractMethods(Class base, Class[] interfaces) {
+        if (base == null)
+            base = Object.class;
+
+        MethodRef[] methods = collectMethods(base, interfaces);
+
+        return methods;
+    }
+
+    /**
+     * Collect the set of method objects that are would be abstract in a
+     * subclass of <code>super_class</code>, implementing
+     * <code>interfaces</code>.
+     */
+    public static MethodRef[] collectMethods(Class super_class,
+            Class[] interfaces) {
+        HashMap methods = new HashMap();
+
+        if (interfaces != null) {
+            for (int i = 0; i < interfaces.length; i++)
+                collectAbstractMethods(methods, interfaces[i]);
+        }
+
+        collectAbstractMethods(methods, super_class);
+        removeImplementedMethods(methods, super_class);
+
+        Collection c = methods.values();
+        return (MethodRef[]) c.toArray(new MethodRef[c.size()]);
+    }
+
+    /**
+     * Collect all methods to be generated. We'll only collect each method once;
+     * so multiple redeclations will be eliminetd.
+     */
+    private static void collectAbstractMethods(HashMap methods, Class type) {
+        if (type == java.lang.Object.class || type == null)
+            return;
+
+        Class[] if_types = type.getInterfaces();
+        for (int i = 0; i < if_types.length; i++) {
+            collectAbstractMethods(methods, if_types[i]);
+        }
+
+        collectAbstractMethods(methods, type.getSuperclass());
+
+        boolean type_is_interface = type.isInterface();
+
+        java.lang.reflect.Method[] declared = type.getDeclaredMethods();
+        for (int i = 0; i < declared.length; i++) {
+            MethodRef m = new MethodRef(declared[i]);
+
+            if (type_is_interface
+                    || java.lang.reflect.Modifier.isAbstract(m.getModifiers())) {
+                String key = m.getName() + m.getSignature();
+
+                if (!methods.containsKey(key)) {
+                    methods.put(key, m);
+                }
+            }
+        }
+    }
+
+    /**
+     * This is used in the second phase of collect, to remove methods that have
+     * been collected in collectAbstractMethods.
+     */
+    private static void removeImplementedMethods(HashMap methods, Class type) {
+        if (type == java.lang.Object.class || type == null)
+            return;
+
+        removeImplementedMethods(methods, type.getSuperclass());
+
+        java.lang.reflect.Method[] declared = type.getDeclaredMethods();
+        for (int i = 0; i < declared.length; i++) {
+            MethodRef m = new MethodRef(declared[i]);
+
+            if (!java.lang.reflect.Modifier.isAbstract(m.getModifiers())) {
+                String key = m.getName() + m.getSignature();
+                methods.remove(key);
+            }
+        }
+    }
+
+    static String className(String packageName, Class superClass,
+            Class[] interfaces) {
+        String className;
+        String fullName;
+
+        if (packageName == null) {
+            if (!java.lang.reflect.Modifier.isPublic(superClass.getModifiers())) {
+                packageName = Util.getPackageName(superClass);
+            } else {
+                for (int i = 0; i < interfaces.length; i++) {
+                    if (java.lang.reflect.Modifier.isProtected(interfaces[i]
+                            .getModifiers())) {
+                        packageName = Util.getPackageName(interfaces[i]);
+                    }
+                }
+            }
+
+            if (packageName == null) {
+                packageName = "org.apache.yoko.rmi.util.stub.gen";
+            }
+        }
+
+        synchronized (BCELClassBuilder.class) {
+            className = "Stub$$" + counter++;
+        }
+
+        return packageName + "." + className;
+    }
+
+    static int counter = 0;
+
+    static Type stubHandlerType = translate(StubHandler.class);
+
+    static Type initializerType = translate(StubInitializer.class);
+
+    static MethodRef getStubHandlerRef;
+
+    static {
+        try {
+            getStubHandlerRef = new MethodRef(StubInitializer.class
+                    .getDeclaredMethod("getStubHandler", new Class[0]));
+        } catch (NoSuchMethodException ex) {
+            throw new Error(ex.getMessage());
+        }
+    }
+
+    //
+    // Constructor for a stub with an initializer
+    //
+    static void emitInitializerConstructor(ClassGen stubClass,
+            FieldGen handlerField, FieldGen initializerField) {
+        String stubClassName = stubClass.getClassName();
+        ConstantPoolGen cp = stubClass.getConstantPool();
+        InstructionList il = new InstructionList();
+
+        MethodGen mg = new MethodGen(Constants.ACC_PUBLIC, Type.VOID,
+                Type.NO_ARGS, null, "<init>", stubClassName, il, cp);
+
+        InstructionFactory fac = new InstructionFactory(stubClass, cp);
+
+        // call super-constructor
+        il.append(InstructionFactory.createThis());
+        il.append(fac.createInvoke(stubClass.getSuperclassName(), "<init>",
+                Type.VOID, Type.NO_ARGS, Constants.INVOKESPECIAL));
+
+        // push "this"
+        il.append(InstructionFactory.createThis());
+
+        // get static initializer
+        il.append(fac.createGetStatic(stubClassName,
+                initializerField.getName(), initializerField.getType()));
+
+        emitInvoke(il, fac, getStubHandlerRef);
+
+        // checkCast
+        il.append(fac.createCast(Type.OBJECT, handlerField.getType()));
+
+        // put handlerField
+        il.append(new PUTFIELD(cp.addFieldref(stubClassName, handlerField
+                .getName(), handlerField.getSignature())));
+
+        // return
+        il.append(InstructionConstants.RETURN);
+
+        // compute stack and locals...
+        mg.setMaxStack();
+        mg.setMaxLocals();
+
+        stubClass.addMethod(mg.getMethod());
+    }
+
+    //
+    // Constructor for a stub with an initializer
+    //
+    static void emitOneArgConstructor(ClassGen stubClass, FieldGen handlerField) {
+        String stubClassName = stubClass.getClassName();
+        ConstantPoolGen cp = stubClass.getConstantPool();
+        InstructionList il = new InstructionList();
+
+        Type[] args = new Type[] { handlerField.getType() };
+
+        MethodGen mg = new MethodGen(Constants.ACC_PUBLIC, Type.VOID, args,
+                null, "<init>", stubClassName, il, cp);
+
+        InstructionFactory fac = new InstructionFactory(stubClass, cp);
+
+        // call super-constructor
+        il.append(InstructionFactory.createThis());
+        il.append(fac.createInvoke(stubClass.getSuperclassName(), "<init>",
+                Type.VOID, Type.NO_ARGS, Constants.INVOKESPECIAL));
+
+        // push this again...
+        il.append(InstructionFactory.createThis());
+
+        // push the handler
+        il.append(InstructionFactory.createLoad(handlerField.getType(), 1));
+
+        // put handlerField
+        il.append(new PUTFIELD(cp.addFieldref(stubClassName, handlerField
+                .getName(), handlerField.getSignature())));
+
+        // return
+        il.append(InstructionConstants.RETURN);
+
+        // compute stack and locals...
+        mg.setMaxStack();
+        mg.setMaxLocals();
+
+        stubClass.addMethod(mg.getMethod());
+    }
+
+    static void generateHandlerGetter(ClassGen clazz, FieldGen handlerField) {
+
+        java.lang.reflect.Method[] stub_methods = Stub.class
+                .getDeclaredMethods();
+        if (stub_methods.length != 1) {
+            throw new IllegalStateException("" + Stub.class
+                    + " has wrong # methods");
+        }
+        String handlerGetName = stub_methods[0].getName();
+
+        ConstantPoolGen cp = clazz.getConstantPool();
+        InstructionList il = new InstructionList();
+        InstructionFactory fac = new InstructionFactory(clazz, cp);
+
+        Type methodReturnType = translate(Object.class);
+        Type[] methodArgTypes = new Type[0];
+
+        MethodGen mg = new MethodGen(
+                Constants.ACC_FINAL | Constants.ACC_PUBLIC, methodReturnType,
+                methodArgTypes, null, // arg names
+                handlerGetName, clazz.getClassName(), il, cp);
+
+        mg.addAttribute(new Synthetic(cp.addUtf8("Synthetic"), 0, null, cp
+                .getConstantPool()));
+
+        //
+        // construct method body
+        //
+
+        il.append(InstructionFactory.createThis());
+
+        il.append(fac.createGetField(clazz.getClassName(), handlerField
+                .getName(), handlerField.getType()));
+
+        emitReturn(il, methodReturnType);
+
+        //
+        // finish up...
+        //
+
+        mg.setMaxStack();
+        mg.setMaxLocals();
+
+        clazz.addMethod(mg.getMethod());
+    }
+
+    static void generate(ClassGen clazz, MethodRef method, FieldGen dataField,
+            FieldGen handlerField, MethodRef handlerMethodRef) {
+        ConstantPoolGen cp;
+        InstructionList il;
+
+        cp = clazz.getConstantPool();
+        il = new InstructionList();
+
+        InstructionFactory fac = new InstructionFactory(clazz, cp);
+
+        Type methodReturnType = translate(method.getReturnType());
+        Type[] methodArgTypes = translate(method.getParameterTypes());
+
+        MethodGen mg = new MethodGen(
+                Constants.ACC_FINAL | Constants.ACC_PUBLIC, methodReturnType,
+                methodArgTypes, null, // arg names
+                method.getName(), clazz.getClassName(), il, cp);
+
+        mg.addAttribute(new Synthetic(cp.addUtf8("Synthetic"), 0, null, cp
+                .getConstantPool()));
+
+        Class[] throwsException = method.getExceptionTypes();
+        for (int i = 0; i < throwsException.length; i++) {
+            mg.addException(throwsException[i].getName());
+        }
+
+        //
+        // BODY
+        //
+
+        il.append(InstructionFactory.createThis());
+
+        il.append(fac.createGetField(clazz.getClassName(), handlerField
+                .getName(), handlerField.getType()));
+
+        // push "this" as invoke's first argument
+        il.append(InstructionFactory.createThis());
+
+        // load data value
+        if (dataField.isStatic()) {
+            il.append(fac.createGetStatic(clazz.getClassName(), dataField
+                    .getName(), dataField.getType()));
+        } else {
+            il.append(InstructionFactory.createThis());
+            il.append(fac.createGetField(clazz.getClassName(), dataField
+                    .getName(), dataField.getType()));
+        }
+
+        il.append(new PUSH(cp, methodArgTypes.length));
+        il.append((Instruction) fac.createNewArray(Type.OBJECT, (short) 1));
+
+        int index = 1;
+        for (int i = 0; i < methodArgTypes.length; i++) {
+            // dup array ref
+            il.append(InstructionConstants.DUP);
+
+            // push index
+            il.append(new PUSH(cp, i));
+
+            // transform parameter
+            il.append(InstructionFactory.createLoad(methodArgTypes[i], index));
+            emitCoerceToObject(il, fac, methodArgTypes[i]);
+
+            // and store into array
+            il.append(InstructionFactory.createArrayStore(Type.OBJECT));
+
+            index += methodArgTypes[i].getSize();
+        }
+
+        // 
+        // invoke handler's method
+        //
+        InstructionHandle tryStart = emitInvoke(il, fac, handlerMethodRef);
+
+        // convert to primitive type
+        emitCoerceFromObject(il, fac, methodReturnType);
+
+        // and return
+
+        InstructionHandle tryEnd = emitReturn(il, methodReturnType);
+
+        // 
+        // catch...
+        //
+        InstructionHandle rethrowLocation = il.append(new ATHROW());
+
+        Class[] exceptions = method.getExceptionTypes();
+        boolean handle_throwable_exception = true;
+        boolean handle_runtime_exception = true;
+        if (exceptions != null) {
+            for (int i = 0; i < exceptions.length; i++) {
+                Class ex = exceptions[i];
+
+                if (ex == java.lang.Throwable.class)
+                    handle_throwable_exception = false;
+
+                if (ex == java.lang.RuntimeException.class
+                        || ex == java.lang.Exception.class)
+                    handle_runtime_exception = false;
+
+                mg.addExceptionHandler(tryStart, tryEnd, rethrowLocation,
+                        (ObjectType) translate(ex));
+            }
+        }
+
+        // A RuntimeException should not cause an
+        // UndeclaredThrowableException, so we catch and re-throw it
+        // that before throwable.
+        if (handle_throwable_exception && handle_runtime_exception) {
+            mg.addExceptionHandler(tryStart, tryEnd, rethrowLocation,
+                    new ObjectType("java.lang.RuntimeException"));
+        }
+
+        // If anything else is thrown, it is wrapped in an
+        // UndeclaredThrowable
+        if (handle_throwable_exception) {
+            InstructionHandle handlerStart = il.append(new ASTORE(1));
+
+            il
+                    .append(new NEW(
+                            cp
+                                    .addClass("java.lang.reflect.UndeclaredThrowableException")));
+            il.append(InstructionConstants.DUP);
+            il.append(new ALOAD(1));
+            il.append(new INVOKESPECIAL(cp.addMethodref(
+                    "java.lang.reflect.UndeclaredThrowableException", "<init>",
+                    "(Ljava/lang/Throwable;)V")));
+
+            il.append(new ATHROW());
+
+            mg.addExceptionHandler(tryStart, tryEnd, handlerStart,
+                    new ObjectType("java.lang.Throwable"));
+        }
+
+        //
+        // DONE
+        //
+
+        mg.setMaxStack();
+        mg.setMaxLocals();
+
+        clazz.addMethod(mg.getMethod());
+    }
+
+    static void generateSuperMethod(ClassGen clazz, MethodRef method) {
+        ConstantPoolGen cp;
+        InstructionList il;
+
+        cp = clazz.getConstantPool();
+        il = new InstructionList();
+
+        InstructionFactory fac = new InstructionFactory(clazz, cp);
+
+        Type methodReturnType = translate(method.getReturnType());
+        Type[] methodArgTypes = translate(method.getParameterTypes());
+
+        MethodGen mg = new MethodGen(
+                Constants.ACC_FINAL | Constants.ACC_PUBLIC, methodReturnType,
+                methodArgTypes, null, // arg names
+                method.getName(), clazz.getClassName(), il, cp);
+
+        mg.addAttribute(new Synthetic(cp.addUtf8("Synthetic"), 0, null, cp
+                .getConstantPool()));
+
+        Class[] throwsException = method.getExceptionTypes();
+        for (int i = 0; i < throwsException.length; i++) {
+            mg.addException(throwsException[i].getName());
+        }
+
+        // push this
+        il.append(InstructionFactory.createThis());
+
+        // push arguments
+        int index = 1;
+        for (int i = 0; i < methodArgTypes.length; i++) {
+            emitLoad(il, index, methodArgTypes[i]);
+            index += methodArgTypes[i].getSize();
+        }
+
+        // call method
+        il.append(new INVOKESPECIAL(cp.addMethodref(method.getDeclaringClass()
+                .getName(), method.getName(), method.getSignature())));
+
+        emitReturn(il, methodReturnType);
+
+        //
+        // DONE
+        //
+
+        mg.setMaxStack();
+        mg.setMaxLocals();
+
+        clazz.addMethod(mg.getMethod());
+    }
+
+    static InstructionHandle emitLoad(InstructionList il, int index, Type type) {
+        switch (type.getType()) {
+        case Constants.T_BOOLEAN:
+        case Constants.T_CHAR:
+        case Constants.T_BYTE:
+        case Constants.T_SHORT:
+        case Constants.T_INT:
+            return il.append(new ILOAD(index));
+
+        case Constants.T_LONG:
+            return il.append(new LLOAD(index));
+
+        case Constants.T_FLOAT:
+            return il.append(new FLOAD(index));
+
+        case Constants.T_DOUBLE:
+            return il.append(new DLOAD(index));
+
+        default:
+            return il.append(new ALOAD(index));
+        }
+    }
+
+    static InstructionHandle emitReturn(InstructionList il, Type type) {
+        switch (type.getType()) {
+        case Constants.T_BOOLEAN:
+        case Constants.T_CHAR:
+        case Constants.T_BYTE:
+        case Constants.T_SHORT:
+        case Constants.T_INT:
+            return il.append(new IRETURN());
+
+        case Constants.T_LONG:
+            return il.append(new LRETURN());
+
+        case Constants.T_FLOAT:
+            return il.append(new FRETURN());
+
+        case Constants.T_DOUBLE:
+            return il.append(new DRETURN());
+
+        case Constants.T_VOID:
+            return il.append(InstructionConstants.RETURN);
+
+        default:
+            return il.append(new ARETURN());
+        }
+    }
+
+    static void emitCoerceToObject(InstructionList il, InstructionFactory fac,
+            Type type) {
+        int tag = type.getType();
+        switch (tag) {
+
+        case Constants.T_BOOLEAN:
+        case Constants.T_CHAR:
+        case Constants.T_BYTE:
+        case Constants.T_SHORT:
+        case Constants.T_INT:
+        case Constants.T_FLOAT:
+
+            // float
+            il.append(fac.createNew(new ObjectType(BASIC_CLASS_NAMES[tag])));
+
+            // float Float
+            il.append(InstructionConstants.DUP_X1);
+
+            // Float float Float
+            il.append(InstructionConstants.SWAP);
+
+            // Float Float float
+            il.append(fac.createInvoke(BASIC_CLASS_NAMES[tag], "<init>",
+                    Type.VOID, new Type[] { type }, Constants.INVOKESPECIAL));
+
+            // Float
+            return;
+
+        case Constants.T_DOUBLE:
+        case Constants.T_LONG:
+
+            // double/2
+            il.append(fac.createNew(new ObjectType(BASIC_CLASS_NAMES[tag])));
+
+            // double/2 Double
+            il.append(InstructionConstants.DUP_X2);
+
+            // Double double/2 Double
+            il.append(InstructionConstants.DUP_X2);
+
+            // Double Double double/2 Double
+            il.append(InstructionConstants.POP);
+
+            // Double Double double/2
+            il.append(fac.createInvoke(BASIC_CLASS_NAMES[tag], "<init>",
+                    Type.VOID, new Type[] { type }, Constants.INVOKESPECIAL));
+
+            // Double
+            return;
+
+        case Constants.T_VOID:
+            il.append(InstructionConstants.ACONST_NULL);
+
+        default:
+            return;
+        }
+    }
+
+    public static final String[] BASIC_CLASS_NAMES = { null, null, null, null,
+            "java.lang.Boolean", "java.lang.Character", "java.lang.Float",
+            "java.lang.Double", "java.lang.Byte", "java.lang.Short",
+            "java.lang.Integer", "java.lang.Long", "java.lang.Void", null,
+            null, null, null };
+
+    static MethodRef[] UNBOXING_METHOD = new MethodRef[Constants.T_VOID];
+
+    static {
+        try {
+            UNBOXING_METHOD[Constants.T_BOOLEAN] = new MethodRef(
+                    java.lang.Boolean.class.getDeclaredMethod("booleanValue",
+                            new Class[0]));
+
+            UNBOXING_METHOD[Constants.T_CHAR] = new MethodRef(
+                    java.lang.Character.class.getDeclaredMethod("charValue",
+                            new Class[0]));
+
+            UNBOXING_METHOD[Constants.T_BYTE] = new MethodRef(
+                    java.lang.Byte.class.getDeclaredMethod("byteValue",
+                            new Class[0]));
+
+            UNBOXING_METHOD[Constants.T_SHORT] = new MethodRef(
+                    java.lang.Short.class.getDeclaredMethod("shortValue",
+                            new Class[0]));
+
+            UNBOXING_METHOD[Constants.T_INT] = new MethodRef(
+                    java.lang.Integer.class.getDeclaredMethod("intValue",
+                            new Class[0]));
+
+            UNBOXING_METHOD[Constants.T_LONG] = new MethodRef(
+                    java.lang.Long.class.getDeclaredMethod("longValue",
+                            new Class[0]));
+
+            UNBOXING_METHOD[Constants.T_FLOAT] = new MethodRef(
+                    java.lang.Float.class.getDeclaredMethod("floatValue",
+                            new Class[0]));
+
+            UNBOXING_METHOD[Constants.T_DOUBLE] = new MethodRef(
+                    java.lang.Double.class.getDeclaredMethod("doubleValue",
+                            new Class[0]));
+        } catch (NoSuchMethodException ex) {
+            throw new Error(ex);
+        }
+    }
+
+    static InstructionHandle emitCoerceFromObject(InstructionList il,
+            InstructionFactory fac, Type type) {
+        int tag = type.getType();
+        switch (tag) {
+        case Constants.T_BOOLEAN:
+        case Constants.T_CHAR:
+        case Constants.T_BYTE:
+        case Constants.T_SHORT:
+        case Constants.T_INT:
+        case Constants.T_LONG:
+        case Constants.T_FLOAT:
+        case Constants.T_DOUBLE:
+            il.append(fac.createCast(Type.OBJECT, new ObjectType(
+                    BASIC_CLASS_NAMES[tag])));
+            return emitInvoke(il, fac, UNBOXING_METHOD[tag]);
+
+        case Constants.T_OBJECT:
+        case Constants.T_ARRAY:
+            return il.append(fac.createCast(Type.OBJECT, type));
+
+        case Constants.T_VOID:
+            return il.append(InstructionConstants.POP);
+
+        default:
+            throw new RuntimeException("internal error");
+        }
+    }
+
+    static InstructionHandle emitInvoke(InstructionList il,
+            InstructionFactory fac, MethodRef method) {
+        String signature = method.getSignature();
+        Type[] args = Type.getArgumentTypes(signature);
+        Type ret = Type.getReturnType(signature);
+        String mname = method.getName();
+        String cname = method.getDeclaringClass().getName();
+
+        short kind;
+        if (method.getDeclaringClass().isInterface()) {
+            kind = Constants.INVOKEINTERFACE;
+
+        } else if (java.lang.reflect.Modifier.isStatic(method.getModifiers())) {
+            kind = Constants.INVOKESTATIC;
+
+        } else if (method.getName().charAt(0) == '<') {
+            kind = Constants.INVOKESPECIAL;
+
+        } else {
+            kind = Constants.INVOKEVIRTUAL;
+        }
+
+        return il.append(fac.createInvoke(cname, mname, ret, args, kind));
+    }
+
+}

Propchange: incubator/yoko/trunk/rmi/src/main/java/org/apache/yoko/rmi/util/stub/BCELClassBuilder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/yoko/trunk/rmi/src/main/java/org/apache/yoko/rmi/util/stub/BCELClassBuilder.java
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/yoko/trunk/rmi/src/main/java/org/apache/yoko/rmi/util/stub/MethodRef.java
URL: http://svn.apache.org/viewvc/incubator/yoko/trunk/rmi/src/main/java/org/apache/yoko/rmi/util/stub/MethodRef.java?rev=420804&view=auto
==============================================================================
--- incubator/yoko/trunk/rmi/src/main/java/org/apache/yoko/rmi/util/stub/MethodRef.java (added)
+++ incubator/yoko/trunk/rmi/src/main/java/org/apache/yoko/rmi/util/stub/MethodRef.java Tue Jul 11 04:35:32 2006
@@ -0,0 +1,157 @@
+/**
+*
+* Copyright 2006 The Apache Software Foundation
+*
+*  Licensed 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.yoko.rmi.util.stub;
+
+import java.lang.reflect.Method;
+
+/**
+ * Describes the interface of a method to be generated by the stub utility
+ */
+public class MethodRef {
+    String name;
+
+    Class declaringClass;
+
+    Class[] parameterTypes;
+
+    Class returnType;
+
+    Class[] exceptionTypes;
+
+    int modifiers;
+
+    Method method;
+
+    String signature;
+
+    public MethodRef() {
+
+    }
+
+    public MethodRef(Method method) {
+        this.method = method;
+
+        name = method.getName();
+        setDeclaringClass(method.getDeclaringClass());
+        setParameterTypes(method.getParameterTypes());
+        setReturnType(method.getReturnType());
+        setExceptionTypes(method.getExceptionTypes());
+        setModifiers(method.getModifiers());
+    }
+
+    public Method getMethod() {
+        return method;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setDeclaringClass(Class declaringClass) {
+        this.declaringClass = declaringClass;
+    }
+
+    public Class getDeclaringClass() {
+        return declaringClass;
+    }
+
+    public void setParameterTypes(Class[] parameterTypes) {
+        this.parameterTypes = parameterTypes;
+    }
+
+    public Class[] getParameterTypes() {
+        return parameterTypes;
+    }
+
+    public void setReturnType(Class returnType) {
+        this.returnType = returnType;
+    }
+
+    public Class getReturnType() {
+        return returnType;
+    }
+
+    public void setExceptionTypes(Class[] exceptionTypes) {
+        this.exceptionTypes = exceptionTypes;
+    }
+
+    public Class[] getExceptionTypes() {
+        return exceptionTypes;
+    }
+
+    public void setModifiers(int modifiers) {
+        this.modifiers = modifiers;
+    }
+
+    public int getModifiers() {
+        return modifiers;
+    }
+
+    public String getSignature() {
+        if (signature != null)
+            return signature;
+
+        StringBuffer sb = new StringBuffer();
+
+        sb.append('(');
+
+        for (int i = 0; i < parameterTypes.length; i++)
+            sb.append(getSignature(parameterTypes[i]));
+
+        sb.append(')');
+
+        sb.append(getSignature(returnType));
+
+        signature = sb.toString();
+        return signature;
+    }
+
+    static String getSignature(Class clz) {
+        if (clz.isPrimitive()) {
+            if (clz == Integer.TYPE) {
+                return "I";
+            } else if (clz == Boolean.TYPE) {
+                return "Z";
+            } else if (clz == Byte.TYPE) {
+                return "B";
+            } else if (clz == Short.TYPE) {
+                return "S";
+            } else if (clz == Long.TYPE) {
+                return "J";
+            } else if (clz == Double.TYPE) {
+                return "D";
+            } else if (clz == Float.TYPE) {
+                return "F";
+            } else if (clz == Void.TYPE) {
+                return "V";
+            } else if (clz == Character.TYPE) {
+                return "C";
+            } else {
+                throw new InternalError("cannot handle " + clz);
+            }
+        } else if (clz.isArray()) {
+            return "[" + getSignature(clz.getComponentType());
+        } else {
+            return "L" + clz.getName().replace('.', '/') + ";";
+        }
+    }
+}

Propchange: incubator/yoko/trunk/rmi/src/main/java/org/apache/yoko/rmi/util/stub/MethodRef.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/yoko/trunk/rmi/src/main/java/org/apache/yoko/rmi/util/stub/MethodRef.java
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/yoko/trunk/rmi/src/main/java/org/apache/yoko/rmi/util/stub/Stub.java
URL: http://svn.apache.org/viewvc/incubator/yoko/trunk/rmi/src/main/java/org/apache/yoko/rmi/util/stub/Stub.java?rev=420804&view=auto
==============================================================================
--- incubator/yoko/trunk/rmi/src/main/java/org/apache/yoko/rmi/util/stub/Stub.java (added)
+++ incubator/yoko/trunk/rmi/src/main/java/org/apache/yoko/rmi/util/stub/Stub.java Tue Jul 11 04:35:32 2006
@@ -0,0 +1,38 @@
+/**
+*
+* Copyright 2006 The Apache Software Foundation
+*
+*  Licensed 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.yoko.rmi.util.stub;
+
+/**
+ * Interface implemented by stub classes. Surprise!
+ * <p>
+ * For now, this plays no significant role; but we may use it in the future to
+ * handle serialization of stubs.
+ * 
+ * @author Kresten Krab Thorup (krab@trifork.com)
+ */
+public interface Stub {
+    /** Object array used for calling methods with no arguments */
+    public static final Object[] noarg = new Object[0];
+
+    /**
+     * Get the stub handler object.
+     * 
+     * This method is generated separately for each stub method.
+     */
+    public Object ____getTriforkStubHandler();
+}

Propchange: incubator/yoko/trunk/rmi/src/main/java/org/apache/yoko/rmi/util/stub/Stub.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/yoko/trunk/rmi/src/main/java/org/apache/yoko/rmi/util/stub/Stub.java
------------------------------------------------------------------------------
    svn:executable = *



Mime
View raw message