You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by to...@apache.org on 2008/05/01 05:14:38 UTC

svn commit: r652421 [3/6] - in /harmony/enhanced/classlib/branches/java6/modules: beans/src/main/java/java/beans/ beans/src/main/java/org/apache/harmony/beans/editors/ beans/src/test/java/org/apache/harmony/beans/tests/java/beans/ imageio/src/main/java...

Modified: harmony/enhanced/classlib/branches/java6/modules/jndi/src/test/java/org/apache/harmony/jndi/provider/ldap/LdapContextServerMockedTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/jndi/src/test/java/org/apache/harmony/jndi/provider/ldap/LdapContextServerMockedTest.java?rev=652421&r1=652420&r2=652421&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/jndi/src/test/java/org/apache/harmony/jndi/provider/ldap/LdapContextServerMockedTest.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/jndi/src/test/java/org/apache/harmony/jndi/provider/ldap/LdapContextServerMockedTest.java Wed Apr 30 20:14:31 2008
@@ -17,25 +17,44 @@
 
 package org.apache.harmony.jndi.provider.ldap;
 
+import java.util.ArrayList;
 import java.util.Hashtable;
+import java.util.List;
 
+import javax.naming.CannotProceedException;
+import javax.naming.CompositeName;
 import javax.naming.Context;
+import javax.naming.InvalidNameException;
+import javax.naming.Name;
 import javax.naming.PartialResultException;
+import javax.naming.RefAddr;
+import javax.naming.Reference;
 import javax.naming.ReferralException;
 import javax.naming.directory.DirContext;
 import javax.naming.directory.InitialDirContext;
+import javax.naming.directory.SearchControls;
+import javax.naming.event.EventDirContext;
+import javax.naming.event.NamingExceptionEvent;
 import javax.naming.ldap.Control;
 import javax.naming.ldap.InitialLdapContext;
 import javax.naming.ldap.LdapContext;
 import javax.naming.ldap.PagedResultsControl;
 import javax.naming.ldap.SortControl;
+import javax.naming.ldap.UnsolicitedNotification;
+import javax.naming.ldap.UnsolicitedNotificationEvent;
+import javax.naming.ldap.UnsolicitedNotificationListener;
 
 import junit.framework.TestCase;
 
+import org.apache.harmony.jndi.provider.ldap.asn1.ASN1Encodable;
 import org.apache.harmony.jndi.provider.ldap.asn1.LdapASN1Constant;
+import org.apache.harmony.jndi.provider.ldap.asn1.Utils;
 import org.apache.harmony.jndi.provider.ldap.mock.BindResponse;
+import org.apache.harmony.jndi.provider.ldap.mock.DisconnectResponse;
 import org.apache.harmony.jndi.provider.ldap.mock.EncodableLdapResult;
+import org.apache.harmony.jndi.provider.ldap.mock.MockLdapMessage;
 import org.apache.harmony.jndi.provider.ldap.mock.MockLdapServer;
+import org.apache.harmony.security.x509.IssuingDistributionPoint;
 
 public class LdapContextServerMockedTest extends TestCase {
     private MockLdapServer server;
@@ -46,8 +65,14 @@
     public void setUp() throws Exception {
         server = new MockLdapServer();
         server.start();
-        env.put(Context.INITIAL_CONTEXT_FACTORY,
-                "org.apache.harmony.jndi.provider.ldap.LdapContextFactory");
+        try {
+            Class.forName("com.sun.jndi.ldap.LdapCtxFactory");
+            env.put(Context.INITIAL_CONTEXT_FACTORY,
+                    "com.sun.jndi.ldap.LdapCtxFactory");
+        } catch (Exception e) {
+            env.put(Context.INITIAL_CONTEXT_FACTORY,
+                    "org.apache.harmony.jndi.provider.ldap.LdapContextFactory");
+        }
         env.put(Context.PROVIDER_URL, server.getURL());
         env.put(Context.SECURITY_AUTHENTICATION, "simple");
         env.put(Context.SECURITY_PRINCIPAL, "");
@@ -304,6 +329,41 @@
         }
     }
 
+    public void testSearchReferralFollow() throws Exception {
+        env.put(Context.REFERRAL, "follow");
+        server.setResponseSeq(new LdapMessage[] { new LdapMessage(
+                LdapASN1Constant.OP_BIND_RESPONSE, new BindResponse(), null) });
+        DirContext context = new InitialDirContext(env);
+
+        final MockLdapServer referralServer = new MockLdapServer();
+        referralServer.start();
+
+        ASN1Encodable ref = new ASN1Encodable() {
+
+            public void encodeValues(Object[] values) {
+                List<byte[]> list = new ArrayList<byte[]>();
+                list.add(Utils.getBytes(referralServer.getURL()));
+                values[0] = list;
+            }
+
+        };
+
+        server.setResponseSeq(new LdapMessage[] {
+                new LdapMessage(LdapASN1Constant.OP_SEARCH_RESULT_REF, ref,
+                        null),
+                new LdapMessage(LdapASN1Constant.OP_SEARCH_RESULT_DONE,
+                        new EncodableLdapResult(), null) });
+
+        referralServer.setResponseSeq(new LdapMessage[] {
+                new LdapMessage(LdapASN1Constant.OP_BIND_RESPONSE,
+                        new BindResponse(), null),
+                new LdapMessage(LdapASN1Constant.OP_SEARCH_RESULT_DONE,
+                        new EncodableLdapResult(), null) });
+
+        context.search("cn=test", null);
+        
+    }
+
     public void testReferralFollow() throws Exception {
         env.put(Context.REFERRAL, "follow");
         server.setResponseSeq(new LdapMessage[] { new LdapMessage(
@@ -465,4 +525,155 @@
         another.reconnect(null);
     }
 
+    public void testFederation() throws Exception {
+        server.setResponseSeq(new LdapMessage[] { new LdapMessage(
+                LdapASN1Constant.OP_BIND_RESPONSE, new BindResponse(), null) });
+        LdapContext context = new InitialLdapContext(env, null);
+
+        /*
+         * test invalid name 'test'
+         */
+        try {
+            context.getAttributes(new CompositeName("test"));
+            fail("Should throw InvalidNameException");
+        } catch (InvalidNameException e) {
+            // expected
+        }
+
+        /*
+         * test name '/usr/bin/cn=test'
+         */
+        server.setResponseSeq(new LdapMessage[] { new LdapMessage(
+                LdapASN1Constant.OP_SEARCH_RESULT_DONE,
+                new EncodableLdapResult(), null) });
+        try {
+            context.lookup("/usr/bin/cn=test");
+            fail("Should throw CannotProceedException");
+        } catch (CannotProceedException e) {
+            assertEquals("/", e.getAltName().toString());
+            assertEquals("usr/bin/cn=test", e.getRemainingName().toString());
+            assertNull(e.getRemainingNewName());
+            assertTrue(e.getResolvedName() instanceof CompositeName);
+            assertEquals(1, e.getResolvedName().size());
+            assertEquals("/", e.getResolvedName().toString());
+            assertTrue(e.getAltNameCtx() instanceof LdapContext);
+            assertEquals(context.getNameInNamespace(), e
+                    .getAltNameCtx().getNameInNamespace());
+            assertTrue(e.getResolvedObj() instanceof Reference);
+
+            Reference ref = (Reference) e.getResolvedObj();
+            assertEquals(Object.class.getName(), ref.getClassName());
+            assertNull(ref.getFactoryClassLocation());
+            assertNull(ref.getFactoryClassName());
+
+            assertEquals(1, ref.size());
+            RefAddr addr = ref.get(0);
+            assertTrue(addr.getContent() instanceof LdapContext);
+            assertEquals(context.getNameInNamespace(),
+                    ((LdapContext) addr.getContent()).getNameInNamespace());
+            assertEquals("nns", addr.getType());
+        }
+
+        /*
+         * test name 'usr/bin/cn=test'
+         */
+        try {
+            context.getAttributes("usr/bin/cn=test");
+            fail("Should throw InvalidNameException");
+        } catch (InvalidNameException e) {
+            // expected
+        }
+
+        /*
+         * test name '/'
+         */
+        server.setResponseSeq(new LdapMessage[] { new LdapMessage(
+                LdapASN1Constant.OP_SEARCH_RESULT_DONE,
+                new EncodableLdapResult(), null) });
+        try {
+            Name name = new CompositeName();
+            name.add("");
+            context.getAttributes(name);
+            fail("Should throw CannotProceedException");
+        } catch (CannotProceedException e) {
+            assertEquals("/", e.getAltName().toString());
+            assertTrue(e.getRemainingName() instanceof CompositeName);
+            assertEquals(0, e.getRemainingName().size());
+            assertEquals("", e.getRemainingName().toString());
+            assertNull(e.getRemainingNewName());
+            assertTrue(e.getResolvedName() instanceof CompositeName);
+            assertEquals(1, e.getResolvedName().size());
+            assertEquals("/", e.getResolvedName().toString());
+            assertTrue(e.getAltNameCtx() instanceof LdapContext);
+            assertEquals(context.getNameInNamespace(), e
+                    .getAltNameCtx().getNameInNamespace());
+            assertTrue(e.getResolvedObj() instanceof Reference);
+
+            Reference ref = (Reference) e.getResolvedObj();
+            assertEquals(Object.class.getName(), ref.getClassName());
+            assertNull(ref.getFactoryClassLocation());
+            assertNull(ref.getFactoryClassName());
+
+            assertEquals(1, ref.size());
+            RefAddr addr = ref.get(0);
+            assertTrue(addr.getContent() instanceof LdapContext);
+            assertEquals(context.getNameInNamespace(),
+                    ((LdapContext) addr.getContent()).getNameInNamespace());
+            assertEquals("nns", addr.getType());
+        }
+    }
+    public void testUnsolicitedNotification() throws Exception {
+        server.setResponseSeq(new LdapMessage[] { new LdapMessage(
+                LdapASN1Constant.OP_BIND_RESPONSE, new BindResponse(), null) });
+        LdapContext context = new InitialLdapContext(env, null);
+
+        server.setResponseSeq(new LdapMessage[] { new LdapMessage(
+                LdapASN1Constant.OP_SEARCH_RESULT_DONE,
+                new EncodableLdapResult(), null) });
+        EventDirContext eventContext = (EventDirContext) context.lookup("");
+
+        assertTrue(eventContext.targetMustExist());
+
+        MockUnsolicitedNotificationListener listener = new MockUnsolicitedNotificationListener();
+
+        MockLdapMessage message = new MockLdapMessage(new LdapMessage(
+                LdapASN1Constant.OP_EXTENDED_RESPONSE,
+                new DisconnectResponse(), null));
+        message.setMessageId(0);
+        server.setResponseSeq(new LdapMessage[] { message });
+
+        eventContext.addNamingListener("", "(objectclass=cn)", new Object[0],
+                new SearchControls(), listener);
+        server.disconnectNotify();
+        Thread.sleep(5000);
+        assertNull(listener.exceptionEvent);
+        assertNotNull(listener.unsolicatedEvent);
+        assertTrue(listener.unsolicatedEvent.getSource() instanceof LdapContext);
+        UnsolicitedNotification notification = listener.unsolicatedEvent
+                .getNotification();
+        assertNotNull(notification);
+        assertEquals(DisconnectResponse.oid, notification.getID());
+        assertNull(notification.getControls());
+        assertNull(notification.getException());
+        assertNull(notification.getReferrals());
+        assertNull(notification.getEncodedValue());
+    }
+
+    public class MockUnsolicitedNotificationListener implements
+            UnsolicitedNotificationListener {
+
+        UnsolicitedNotificationEvent unsolicatedEvent;
+
+        NamingExceptionEvent exceptionEvent;
+
+        public void notificationReceived(UnsolicitedNotificationEvent e) {
+            unsolicatedEvent = e;
+        }
+
+        public void namingExceptionThrown(
+                NamingExceptionEvent namingExceptionEvent) {
+            exceptionEvent = namingExceptionEvent;
+        }
+
+    }
 }

Modified: harmony/enhanced/classlib/branches/java6/modules/jndi/src/test/java/org/apache/harmony/jndi/provider/ldap/mock/BindResponse.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/jndi/src/test/java/org/apache/harmony/jndi/provider/ldap/mock/BindResponse.java?rev=652421&r1=652420&r2=652421&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/jndi/src/test/java/org/apache/harmony/jndi/provider/ldap/mock/BindResponse.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/jndi/src/test/java/org/apache/harmony/jndi/provider/ldap/mock/BindResponse.java Wed Apr 30 20:14:31 2008
@@ -18,6 +18,7 @@
 package org.apache.harmony.jndi.provider.ldap.mock;
 
 import org.apache.harmony.jndi.provider.ldap.asn1.ASN1Encodable;
+import org.apache.harmony.jndi.provider.ldap.asn1.Utils;
 
 public class BindResponse implements ASN1Encodable {
 
@@ -36,7 +37,9 @@
 
     public void encodeValues(Object[] values) {
         result.encodeValues(values);
-        values[4] = saslCreds;
+        if (saslCreds != null) {
+            values[4] = Utils.getBytes(saslCreds);
+        }
     }
 
 }

Modified: harmony/enhanced/classlib/branches/java6/modules/jndi/src/test/java/org/apache/harmony/jndi/provider/ldap/mock/MockLdapServer.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/jndi/src/test/java/org/apache/harmony/jndi/provider/ldap/mock/MockLdapServer.java?rev=652421&r1=652420&r2=652421&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/jndi/src/test/java/org/apache/harmony/jndi/provider/ldap/mock/MockLdapServer.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/jndi/src/test/java/org/apache/harmony/jndi/provider/ldap/mock/MockLdapServer.java Wed Apr 30 20:14:31 2008
@@ -25,6 +25,7 @@
 import java.util.LinkedList;
 
 import org.apache.harmony.jndi.provider.ldap.LdapMessage;
+import org.apache.harmony.jndi.provider.ldap.asn1.LdapASN1Constant;
 import org.apache.harmony.security.asn1.ASN1Integer;
 
 /**
@@ -41,7 +42,7 @@
 
     private Socket socket;
 
-	private LinkedList<LdapMessage> responses = new LinkedList<LdapMessage>();
+    private LinkedList<LdapMessage> responses = new LinkedList<LdapMessage>();
 
     private int port;
 
@@ -49,8 +50,6 @@
 
     private boolean isStopped;
 
-    private static int DEFAULT_PORT = 1024;
-
     public MockLdapServer() {
         // do nothing
     }
@@ -98,12 +97,12 @@
         return port;
     }
 
-	public void setResponseSeq(LdapMessage[] msges) {
-		synchronized (responses) {
-			for (LdapMessage message : msges) {
-				responses.addLast(message);
-			}
-		}
+    public void setResponseSeq(LdapMessage[] msges) {
+        synchronized (responses) {
+            for (LdapMessage message : msges) {
+                responses.addLast(message);
+            }
+        }
 
         synchronized (lock) {
             lock.notify();
@@ -113,12 +112,14 @@
     public void run() {
         InputStream in = null;
         OutputStream out = null;
+        int searchID = -1;
+
         try {
             socket = server.accept();
             in = socket.getInputStream();
             out = socket.getOutputStream();
             while (!isStopped) {
-				if (responses.size() == 0) {
+                if (responses.size() == 0) {
                     try {
                         synchronized (lock) {
                             lock.wait();
@@ -128,28 +129,47 @@
                     }
                 } else {
 
-					while (true) {
-						LdapMessage temp = null;
-						synchronized (responses) {
-							if (responses.size() == 0) {
-								break;
-							}
-							temp = responses.removeFirst();
-						}
-						
+                    boolean isContinue = false;
+
+                    while (true) {
+                        LdapMessage temp = null;
+                        synchronized (responses) {
+                            if (responses.size() == 0) {
+                                break;
+                            }
+                            temp = responses.removeFirst();
+                        }
+
                         final MockLdapMessage response = new MockLdapMessage(
-								temp);
-                        LdapMessage request = new LdapMessage(null) {
-                            public void decodeValues(Object[] values) {
-                                response.setMessageId(ASN1Integer
-                                        .toIntValue(values[0]));
+                                temp);
+
+                        if (!isContinue) {
+                            LdapMessage request = new LdapMessage(null) {
+                                public void decodeValues(Object[] values) {
+                                    response.setMessageId(ASN1Integer
+                                            .toIntValue(values[0]));
+                                }
+                            };
+
+                            request.decode(in);
+
+                            if (response.getOperationIndex() == LdapASN1Constant.OP_SEARCH_RESULT_ENTRY
+                                    || response.getOperationIndex() == LdapASN1Constant.OP_SEARCH_RESULT_REF) {
+                                isContinue = true;
+                                searchID = response.getMessageId();
+                            } else {
+                                isContinue = false;
                             }
-                        };
-                        request.decode(in);
+                        }
+
                         try {
                             Thread.sleep(10);
                         } catch (InterruptedException e) {
-                            //ignore
+                            // ignore
+                        }
+
+                        if (isContinue) {
+                            response.setMessageId(searchID);
                         }
                         out.write(response.encode());
                     }
@@ -176,6 +196,15 @@
         }
     }
 
+    public void disconnectNotify() throws IOException {
+        MockLdapMessage message = new MockLdapMessage(new LdapMessage(
+                LdapASN1Constant.OP_EXTENDED_RESPONSE,
+                new DisconnectResponse(), null));
+        message.setMessageId(0);
+        OutputStream out = socket.getOutputStream();
+        out.write(message.encode());
+    }
+
     public String getURL() {
         return "ldap://localhost:" + port;
     }

Modified: harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/io/ObjectInputStream.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/io/ObjectInputStream.java?rev=652421&r1=652420&r2=652421&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/io/ObjectInputStream.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/io/ObjectInputStream.java Wed Apr 30 20:14:31 2008
@@ -30,6 +30,9 @@
 import java.util.HashMap;
 import java.util.Iterator;
 
+import org.apache.harmony.misc.accessors.ObjectAccessor;
+import org.apache.harmony.misc.accessors.AccessorFactory;
+
 import org.apache.harmony.kernel.vm.VM;
 import org.apache.harmony.luni.internal.nls.Messages;
 import org.apache.harmony.luni.util.Msg;
@@ -119,6 +122,8 @@
         PRIMITIVE_CLASSES.put("double", double.class); //$NON-NLS-1$
     }
 
+    private ObjectAccessor accessor = AccessorFactory.getObjectAccessor();
+
     // Internal type used to keep track of validators & corresponding priority
     static class InputValidationDesc {
         ObjectInputValidation validator;
@@ -490,25 +495,6 @@
     }
 
     /**
-     * Create and return a new instance of class <code>instantiationClass</code>
-     * but running the constructor defined in class
-     * <code>constructorClass</code> (same as <code>instantiationClass</code>
-     * or a superclass).
-     * 
-     * Has to be native to avoid visibility rules and to be able to have
-     * <code>instantiationClass</code> not the same as
-     * <code>constructorClass</code> (no such API in java.lang.reflect).
-     * 
-     * @param instantiationClass
-     *            The new object will be an instance of this class
-     * @param constructorClass
-     *            The empty constructor to run will be in this class
-     * @return the object created from <code>instantiationClass</code>
-     */
-    private static native Object newInstance(Class<?> instantiationClass,
-            Class<?> constructorClass);
-
-    /**
      * Return the next <code>int</code> handle to be used to indicate cyclic
      * references being loaded from the stream.
      * 
@@ -1124,41 +1110,61 @@
         }
 
         for (ObjectStreamField fieldDesc : fields) {
+
+            // get associated Field 
+            long fieldID = fieldDesc.getFieldID(accessor, declaringClass);
+
             // Code duplication starts, just because Java is typed
             if (fieldDesc.isPrimitive()) {
                 try {
                     switch (fieldDesc.getTypeCode()) {
                         case 'B':
-                            setField(obj, declaringClass, fieldDesc.getName(),
-                                    input.readByte());
+                            byte srcByte = input.readByte();
+                            if (fieldID != ObjectStreamField.FIELD_IS_ABSENT) { 
+                                accessor.setByte(obj, fieldID, srcByte);
+                            };
                             break;
                         case 'C':
-                            setField(obj, declaringClass, fieldDesc.getName(),
-                                    input.readChar());
+                            char srcChar = input.readChar();
+                            if (fieldID != ObjectStreamField.FIELD_IS_ABSENT) { 
+                                accessor.setChar(obj, fieldID, srcChar);
+                            }
                             break;
                         case 'D':
-                            setField(obj, declaringClass, fieldDesc.getName(),
-                                    input.readDouble());
+                            double srcDouble = input.readDouble();
+                            if (fieldID != ObjectStreamField.FIELD_IS_ABSENT) { 
+                                accessor.setDouble(obj, fieldID, srcDouble);
+                            }
                             break;
                         case 'F':
-                            setField(obj, declaringClass, fieldDesc.getName(),
-                                    input.readFloat());
+                            float srcFloat = input.readFloat();
+                            if (fieldID != ObjectStreamField.FIELD_IS_ABSENT) { 
+                                accessor.setFloat(obj, fieldID, srcFloat);
+                            }
                             break;
                         case 'I':
-                            setField(obj, declaringClass, fieldDesc.getName(),
-                                    input.readInt());
+                            int srcInt = input.readInt();
+                            if (fieldID != ObjectStreamField.FIELD_IS_ABSENT) { 
+                                accessor.setInt(obj, fieldID, srcInt);
+                            }
                             break;
                         case 'J':
-                            setField(obj, declaringClass, fieldDesc.getName(),
-                                    input.readLong());
+                            long srcLong = input.readLong();
+                            if (fieldID != ObjectStreamField.FIELD_IS_ABSENT) { 
+                                accessor.setLong(obj, fieldID, srcLong);
+                            }
                             break;
                         case 'S':
-                            setField(obj, declaringClass, fieldDesc.getName(),
-                                    input.readShort());
+                            short srcShort = input.readShort();
+                            if (fieldID != ObjectStreamField.FIELD_IS_ABSENT) { 
+                                accessor.setShort(obj, fieldID, srcShort);
+                            }
                             break;
                         case 'Z':
-                            setField(obj, declaringClass, fieldDesc.getName(),
-                                    input.readBoolean());
+                            boolean srcBoolean = input.readBoolean();
+                            if (fieldID != ObjectStreamField.FIELD_IS_ABSENT) { 
+                                accessor.setBoolean(obj, fieldID, srcBoolean);
+                            }
                             break;
                         default:
                             throw new StreamCorruptedException(Msg.getString(
@@ -1195,8 +1201,9 @@
                                                     + fieldName }));
                         }
                         try {
-                            objSetField(obj, declaringClass, fieldName, fieldDesc
-                                    .getTypeString(), toSet);
+                            if (fieldID != ObjectStreamField.FIELD_IS_ABSENT) { 
+                                accessor.setObject(obj, fieldID, toSet);
+                            }
                         } catch (NoSuchFieldError e) {
                             // Ignored
                         }
@@ -1834,51 +1841,9 @@
         return Integer.valueOf(input.readInt());
     }
 
-    /**
-     * Read a new object from the stream. It is assumed the object has not been
-     * loaded yet (not a cyclic reference). Return the object read.
-     * 
-     * If the object implements <code>Externalizable</code> its
-     * <code>readExternal</code> is called. Otherwise, all fields described by
-     * the class hierarchy are loaded. Each class can define how its declared
-     * instance fields are loaded by defining a private method
-     * <code>readObject</code>
-     * 
-     * @param unshared
-     *            read the object unshared
-     * @return the object read
-     * 
-     * @throws IOException
-     *             If an IO exception happened when reading the object.
-     * @throws OptionalDataException
-     *             If optional data could not be found when reading the object
-     *             graph
-     * @throws ClassNotFoundException
-     *             If a class for one of the objects could not be found
-     */
-    private Object readNewObject(boolean unshared)
-            throws OptionalDataException, ClassNotFoundException, IOException {
-        ObjectStreamClass classDesc = readClassDesc();
-
-        if (classDesc == null) {
-            throw new InvalidClassException(Msg.getString("K00d1")); //$NON-NLS-1$
-        }
-
-        Integer newHandle = Integer.valueOf(nextHandle());
-
-        // Note that these values come from the Stream, and in fact it could be
-        // that the classes have been changed so that the info below now
-        // conflicts with the newer class
-        boolean wasExternalizable = (classDesc.getFlags() & SC_EXTERNALIZABLE) > 0;
-        boolean wasSerializable = (classDesc.getFlags() & SC_SERIALIZABLE) > 0;
-
-        // Maybe we should cache the values above in classDesc ? It may be the
-        // case that when reading classDesc we may need to read more stuff
-        // depending on the values above
-        Class<?> objectClass = classDesc.forClass();
+    private Class<?> resolveConstructorClass(Class<?> objectClass, boolean wasSerializable, boolean wasExternalizable)
+        throws OptionalDataException, ClassNotFoundException, IOException {
 
-        Object result, registeredResult = null;
-        if (objectClass != null) {
             // The class of the instance may not be the same as the class of the
             // constructor to run
             // This is the constructor to run if Externalizable
@@ -1938,9 +1903,66 @@
                 }
             }
 
+            return constructorClass;
+    }
+
+    /**
+     * Read a new object from the stream. It is assumed the object has not been
+     * loaded yet (not a cyclic reference). Return the object read.
+     * 
+     * If the object implements <code>Externalizable</code> its
+     * <code>readExternal</code> is called. Otherwise, all fields described by
+     * the class hierarchy are loaded. Each class can define how its declared
+     * instance fields are loaded by defining a private method
+     * <code>readObject</code>
+     * 
+     * @param unshared
+     *            read the object unshared
+     * @return the object read
+     * 
+     * @throws IOException
+     *             If an IO exception happened when reading the object.
+     * @throws OptionalDataException
+     *             If optional data could not be found when reading the object
+     *             graph
+     * @throws ClassNotFoundException
+     *             If a class for one of the objects could not be found
+     */
+    private Object readNewObject(boolean unshared)
+            throws OptionalDataException, ClassNotFoundException, IOException {
+        ObjectStreamClass classDesc = readClassDesc();
+
+        if (classDesc == null) {
+            throw new InvalidClassException(Msg.getString("K00d1")); //$NON-NLS-1$
+        }
+
+        Integer newHandle = Integer.valueOf(nextHandle());
+
+        // Note that these values come from the Stream, and in fact it could be
+        // that the classes have been changed so that the info below now
+        // conflicts with the newer class
+        boolean wasExternalizable = (classDesc.getFlags() & SC_EXTERNALIZABLE) > 0;
+        boolean wasSerializable = (classDesc.getFlags() & SC_SERIALIZABLE) > 0;
+
+
+        // Maybe we should cache the values above in classDesc ? It may be the
+        // case that when reading classDesc we may need to read more stuff
+        // depending on the values above
+        Class<?> objectClass = classDesc.forClass();
+
+        Object result, registeredResult = null;
+        if (objectClass != null) {
+
+            long constructor = classDesc.getConstructor();
+            if (constructor == ObjectStreamClass.CONSTRUCTOR_IS_NOT_RESOLVED) {
+                constructor = accessor.getMethodID(resolveConstructorClass(objectClass, wasSerializable, wasExternalizable), null, new Class[0]);
+                classDesc.setConstructor(constructor);
+            }
+
             // Now we know which class to instantiate and which constructor to
             // run. We are allowed to run the constructor.
-            result = newInstance(objectClass, constructorClass);
+            result = accessor.newInstance(objectClass, constructor, null);
+
             registerObjectRead(result, newHandle, unshared);
 
             registeredResult = result;
@@ -2434,250 +2456,6 @@
     }
 
     /**
-     * Set a given declared field named <code>fieldName</code> of
-     * <code>instance</code> to the new <code>byte</code> value
-     * <code>value</code>.
-     * 
-     * This method could be implemented non-natively on top of java.lang.reflect
-     * implementations that support the <code>setAccessible</code> API, at the
-     * expense of extra object creation (java.lang.reflect.Field). Otherwise
-     * Serialization could not set private fields, except by the use of a native
-     * method like this one.
-     * 
-     * @param instance
-     *            Object whose field to set
-     * @param declaringClass
-     *            <code>instance</code>'s declaring class
-     * @param fieldName
-     *            Name of the field to set
-     * @param value
-     *            New value for the field
-     * 
-     * @throws NoSuchFieldError
-     *             If the field does not exist.
-     */
-    private static native void setField(Object instance,
-            Class<?> declaringClass, String fieldName, byte value)
-            throws NoSuchFieldError;
-
-    /**
-     * Set a given declared field named <code>fieldName</code> of
-     * <code>instance</code> to the new <code>char</code> value
-     * <code>value</code>.
-     * 
-     * This method could be implemented non-natively on top of java.lang.reflect
-     * implementations that support the <code>setAccessible</code> API, at the
-     * expense of extra object creation (java.lang.reflect.Field). Otherwise
-     * Serialization could not set private fields, except by the use of a native
-     * method like this one.
-     * 
-     * @param instance
-     *            Object whose field to set
-     * @param declaringClass
-     *            <code>instance</code>'s declaring class
-     * @param fieldName
-     *            Name of the field to set
-     * @param value
-     *            New value for the field
-     * 
-     * @throws NoSuchFieldError
-     *             If the field does not exist.
-     */
-    private static native void setField(Object instance,
-            Class<?> declaringClass, String fieldName, char value)
-            throws NoSuchFieldError;
-
-    /**
-     * Set a given declared field named <code>fieldName</code> of
-     * <code>instance</code> to the new <code>double</code> value
-     * <code>value</code>.
-     * 
-     * This method could be implemented non-natively on top of java.lang.reflect
-     * implementations that support the <code>setAccessible</code> API, at the
-     * expense of extra object creation (java.lang.reflect.Field). Otherwise
-     * Serialization could not set private fields, except by the use of a native
-     * method like this one.
-     * 
-     * @param instance
-     *            Object whose field to set
-     * @param declaringClass
-     *            <code>instance</code>'s declaring class
-     * @param fieldName
-     *            Name of the field to set
-     * @param value
-     *            New value for the field
-     * 
-     * @throws NoSuchFieldError
-     *             If the field does not exist.
-     */
-    private static native void setField(Object instance,
-            Class<?> declaringClass, String fieldName, double value)
-            throws NoSuchFieldError;
-
-    /**
-     * Set a given declared field named <code>fieldName</code> of
-     * <code>instance</code> to the new <code>float</code> value
-     * <code>value</code>.
-     * 
-     * This method could be implemented non-natively on top of java.lang.reflect
-     * implementations that support the <code>setAccessible</code> API, at the
-     * expense of extra object creation (java.lang.reflect.Field). Otherwise
-     * Serialization could not set private fields, except by the use of a native
-     * method like this one.
-     * 
-     * @param instance
-     *            Object whose field to set
-     * @param declaringClass
-     *            <code>instance</code>'s declaring class
-     * @param fieldName
-     *            Name of the field to set
-     * @param value
-     *            New value for the field
-     * 
-     * @throws NoSuchFieldError
-     *             If the field does not exist.
-     */
-    private static native void setField(Object instance,
-            Class<?> declaringClass, String fieldName, float value)
-            throws NoSuchFieldError;
-
-    /**
-     * Set a given declared field named <code>fieldName</code> of
-     * <code>instance</code> to the new <code>int</code> value
-     * <code>value</code>.
-     * 
-     * This method could be implemented non-natively on top of java.lang.reflect
-     * implementations that support the <code>setAccessible</code> API, at the
-     * expense of extra object creation (java.lang.reflect.Field). Otherwise
-     * Serialization could not set private fields, except by the use of a native
-     * method like this one.
-     * 
-     * @param instance
-     *            Object whose field to set
-     * @param declaringClass
-     *            <code>instance</code>'s declaring class
-     * @param fieldName
-     *            Name of the field to set
-     * @param value
-     *            New value for the field
-     * 
-     * @throws NoSuchFieldError
-     *             If the field does not exist.
-     */
-    private static native void setField(Object instance,
-            Class<?> declaringClass, String fieldName, int value)
-            throws NoSuchFieldError;
-
-    /**
-     * Set a given declared field named <code>fieldName</code> of
-     * <code>instance</code> to the new <code>long</code> value
-     * <code>value</code>.
-     * 
-     * This method could be implemented non-natively on top of java.lang.reflect
-     * implementations that support the <code>setAccessible</code> API, at the
-     * expense of extra object creation (java.lang.reflect.Field). Otherwise
-     * Serialization could not set private fields, except by the use of a native
-     * method like this one.
-     * 
-     * @param instance
-     *            Object whose field to set
-     * @param declaringClass
-     *            <code>instance</code>'s declaring class
-     * @param fieldName
-     *            Name of the field to set
-     * @param value
-     *            New value for the field
-     * 
-     * @throws NoSuchFieldError
-     *             If the field does not exist.
-     */
-    private static native void setField(Object instance,
-            Class<?> declaringClass, String fieldName, long value)
-            throws NoSuchFieldError;
-
-    /**
-     * Set a given declared field named <code>fieldName</code> of
-     * <code>instance</code> to the new value <code>value</code>.
-     * 
-     * This method could be implemented non-natively on top of java.lang.reflect
-     * implementations that support the <code>setAccessible</code> API, at the
-     * expense of extra object creation (java.lang.reflect.Field). Otherwise
-     * Serialization could not set private fields, except by the use of a native
-     * method like this one.
-     * 
-     * @param instance
-     *            Object whose field to set
-     * @param declaringClass
-     *            Class which declares the field
-     * @param fieldName
-     *            Name of the field to set
-     * @param fieldTypeName
-     *            Name of the class defining the type of the field
-     * @param value
-     *            New value for the field
-     * 
-     * @throws NoSuchFieldError
-     *             If the field does not exist.
-     */
-    private static native void objSetField(Object instance,
-            Class<?> declaringClass, String fieldName, String fieldTypeName,
-            Object value) throws NoSuchFieldError;
-
-    /**
-     * Set a given declared field named <code>fieldName</code> of
-     * <code>instance</code> to the new <code>short</code> value
-     * <code>value</code>.
-     * 
-     * This method could be implemented non-natively on top of java.lang.reflect
-     * implementations that support the <code>setAccessible</code> API, at the
-     * expense of extra object creation (java.lang.reflect.Field). Otherwise
-     * Serialization could not set private fields, except by the use of a native
-     * method like this one.
-     * 
-     * @param instance
-     *            Object whose field to set
-     * @param declaringClass
-     *            <code>instance</code>'s declaring class
-     * @param fieldName
-     *            Name of the field to set
-     * @param value
-     *            New value for the field
-     * 
-     * @throws NoSuchFieldError
-     *             If the field does not exist.
-     */
-    private static native void setField(Object instance,
-            Class<?> declaringClass, String fieldName, short value)
-            throws NoSuchFieldError;
-
-    /**
-     * Set a given declared field named <code>fieldName</code> of
-     * <code>instance</code> to the new <code>boolean</code> value
-     * <code>value</code>.
-     * 
-     * This method could be implemented non-natively on top of java.lang.reflect
-     * implementations that support the <code>setAccessible</code> API, at the
-     * expense of extra object creation (java.lang.reflect.Field). Otherwise
-     * Serialization could not set private fields, except by the use of a native
-     * method like this one.
-     * 
-     * @param instance
-     *            Object whose field to set
-     * @param declaringClass
-     *            <code>instance</code>'s declaring class
-     * @param fieldName
-     *            Name of the field to set
-     * @param value
-     *            New value for the field
-     * 
-     * @throws NoSuchFieldError
-     *             If the field does not exist.
-     */
-    private static native void setField(Object instance,
-            Class<?> declaringClass, String fieldName, boolean value)
-            throws NoSuchFieldError;
-
-    /**
      * Skips <code>length</code> bytes of primitive data from the receiver. It
      * should not be used to skip bytes at any arbitrary position; just when
      * reading primitive data types (ints, chars, etc).

Modified: harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/io/ObjectOutputStream.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/io/ObjectOutputStream.java?rev=652421&r1=652420&r2=652421&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/io/ObjectOutputStream.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/io/ObjectOutputStream.java Wed Apr 30 20:14:31 2008
@@ -22,6 +22,9 @@
 import java.lang.reflect.Proxy;
 import java.util.IdentityHashMap;
 
+import org.apache.harmony.misc.accessors.ObjectAccessor;
+import org.apache.harmony.misc.accessors.AccessorFactory;
+
 import org.apache.harmony.luni.util.Msg;
 
 /**
@@ -108,7 +111,9 @@
      * Allows the receiver to decide if it needs to call writeObjectOverride
      */
     private boolean subclassOverridingImplementation;
+    
 
+    private ObjectAccessor accessor = AccessorFactory.getObjectAccessor();
 
     /**
      * Inner class to provide access to serializable fields
@@ -416,195 +421,6 @@
         output.flush();
     }
 
-    /**
-     * Get the value of field named
-     * <code>fieldName<code> of object <code>instance</code>. The
-     * field is declared by class <code>declaringClass</code>. The field is supposed to be
-     * a boolean.
-     *
-     * This method could be implemented non-natively on top of java.lang.reflect implementations
-     * that support the <code>setAccessible</code> API, at the expense of extra object creation
-     * (java.lang.reflect.Field). Otherwise Serialization could not fetch private fields, except
-     * by the use of a native method like this one.
-     *
-     * @param		instance		Object whose field value we want to fetch
-     * @param		declaringClass	The class that declares the field
-     * @param		fieldName		Name of the field we want to fetch
-     * @return		the value of the field
-     *
-     * @throws		NoSuchFieldError If the field does not exist.
-     */
-    private static native boolean getFieldBool(Object instance,
-            Class<?> declaringClass, String fieldName);
-
-    /**
-     * Get the value of field named
-     * <code>fieldName<code> of object <code>instance</code>. The
-     * field is declared by class <code>declaringClass</code>. The field is supposed to be
-     * a byte
-     *
-     * This method could be implemented non-natively on top of java.lang.reflect implementations
-     * that support the <code>setAccessible</code> API, at the expense of extra object creation
-     * (java.lang.reflect.Field). Otherwise Serialization could not fetch private fields, except
-     * by the use of a native method like this one.
-     *
-     * @param		instance		Object whose field value we want to fetch
-     * @param		declaringClass	The class that declares the field
-     * @param		fieldName		Name of the field we want to fetch
-     * @return		the value of the field
-     *
-     * @throws		NoSuchFieldError If the field does not exist.
-     */
-    private static native byte getFieldByte(Object instance,
-            Class<?> declaringClass, String fieldName);
-
-    /**
-     * Get the value of field named
-     * <code>fieldName<code> of object <code>instance</code>. The
-     * field is declared by class <code>declaringClass</code>. The field is supposed to be
-     * a char.
-     *
-     * This method could be implemented non-natively on top of java.lang.reflect implementations
-     * that support the <code>setAccessible</code> API, at the expense of extra object creation
-     * (java.lang.reflect.Field). Otherwise Serialization could not fetch private fields, except
-     * by the use of a native method like this one.
-     *
-     * @param		instance		Object whose field value we want to fetch
-     * @param		declaringClass	The class that declares the field
-     * @param		fieldName		Name of the field we want to fetch
-     * @return		the value of the field
-     *
-     * @throws		NoSuchFieldError If the field does not exist.
-     */
-    private static native char getFieldChar(Object instance,
-            Class<?> declaringClass, String fieldName);
-
-    /**
-     * Get the value of field named
-     * <code>fieldName<code> of object <code>instance</code>. The
-     * field is declared by class <code>declaringClass</code>. The field is supposed to be
-     * a double.
-     *
-     * This method could be implemented non-natively on top of java.lang.reflect implementations
-     * that support the <code>setAccessible</code> API, at the expense of extra object creation
-     * (java.lang.reflect.Field). Otherwise Serialization could not fetch private fields, except
-     * by the use of a native method like this one.
-     *
-     * @param		instance		Object whose field value we want to fetch
-     * @param		declaringClass	The class that declares the field
-     * @param		fieldName		Name of the field we want to fetch
-     * @return		the value of the field
-     *
-     * @throws		NoSuchFieldError If the field does not exist.
-     */
-    private static native double getFieldDouble(Object instance,
-            Class<?> declaringClass, String fieldName);
-
-    /**
-     * Get the value of field named
-     * <code>fieldName<code> of object <code>instance</code>. The
-     * field is declared by class <code>declaringClass</code>. The field is supposed to be
-     * a float.
-     *
-     * This method could be implemented non-natively on top of java.lang.reflect implementations
-     * that support the <code>setAccessible</code> API, at the expense of extra object creation
-     * (java.lang.reflect.Field). Otherwise Serialization could not fetch private fields, except
-     * by the use of a native method like this one.
-     *
-     * @param		instance		Object whose field value we want to fetch
-     * @param		declaringClass	The class that declares the field
-     * @param		fieldName		Name of the field we want to fetch
-     * @return		the value of the field
-     *
-     * @throws		NoSuchFieldError If the field does not exist.
-     */
-    private static native float getFieldFloat(Object instance,
-            Class<?> declaringClass, String fieldName);
-
-    /**
-     * Get the value of field named
-     * <code>fieldName<code> of object <code>instance</code>. The
-     * field is declared by class <code>declaringClass</code>. The field is supposed to be
-     * an int.
-     *
-     * This method could be implemented non-natively on top of java.lang.reflect implementations
-     * that support the <code>setAccessible</code> API, at the expense of extra object creation
-     * (java.lang.reflect.Field). Otherwise Serialization could not fetch private fields, except
-     * by the use of a native method like this one.
-     *
-     * @param		instance		Object whose field value we want to fetch
-     * @param		declaringClass	The class that declares the field
-     * @param		fieldName		Name of the field we want to fetch
-     * @return		the value of the field
-     *
-     * @throws		NoSuchFieldError If the field does not exist.
-     */
-    private static native int getFieldInt(Object instance,
-            Class<?> declaringClass, String fieldName);
-
-    /**
-     * Get the value of field named
-     * <code>fieldName<code> of object <code>instance</code>. The
-     * field is declared by class <code>declaringClass</code>. The field is supposed to be
-     * a long.
-     *
-     * This method could be implemented non-natively on top of java.lang.reflect implementations
-     * that support the <code>setAccessible</code> API, at the expense of extra object creation
-     * (java.lang.reflect.Field). Otherwise Serialization could not fetch private fields, except
-     * by the use of a native method like this one.
-     *
-     * @param		instance		Object whose field value we want to fetch
-     * @param		declaringClass	The class that declares the field
-     * @param		fieldName		Name of the field we want to fetch
-     * @return		the value of the field
-     *
-     * @throws		NoSuchFieldError If the field does not exist.
-     */
-    private static native long getFieldLong(Object instance,
-            Class<?> declaringClass, String fieldName);
-
-    /**
-     * Get the value of field named
-     * <code>fieldName<code> of object <code>instance</code>. The
-     * field is declared by class <code>declaringClass</code>. The field is supposed to be
-     * an Object type whose name is <code>fieldTypeName</code>.
-     *
-     * This method could be implemented non-natively on top of java.lang.reflect implementations
-     * that support the <code>setAccessible</code> API, at the expense of extra object creation
-     * (java.lang.reflect.Field). Otherwise Serialization could not fetch private fields, except
-     * by the use of a native method like this one.
-     *
-     * @param		instance		Object whose field value we want to fetch
-     * @param		declaringClass	The class that declares the field
-     * @param		fieldName		Name of the field we want to fetch
-     * @param		fieldTypeName	Name of the class that defines the type of this field
-     * @return		the value of the field
-     *
-     * @throws		NoSuchFieldError If the field does not exist.
-     */
-    private static native Object getFieldObj(Object instance,
-            Class<?> declaringClass, String fieldName, String fieldTypeName);
-
-    /**
-     * Get the value of field named
-     * <code>fieldName<code> of object <code>instance</code>. The
-     * field is declared by class <code>declaringClass</code>. The field is supposed to be
-     * a short.
-     *
-     * This method could be implemented non-natively on top of java.lang.reflect implementations
-     * that support the <code>setAccessible</code> API, at the expense of extra object creation
-     * (java.lang.reflect.Field). Otherwise Serialization could not fetch private fields, except
-     * by the use of a native method like this one.
-     *
-     * @param		instance		Object whose field value we want to fetch
-     * @param		declaringClass	The class that declares the field
-     * @param		fieldName		Name of the field we want to fetch
-     * @return		the value of the field
-     *
-     * @throws		NoSuchFieldError If the field does not exist.
-     */
-    private static native short getFieldShort(Object instance,
-            Class<?> declaringClass, String fieldName);
 
     /**
      * Return the next <code>int</code> handle to be used to indicate cyclic
@@ -1160,6 +976,7 @@
         }
     }
 
+
     /**
      * Writes a collection of field values for the fields described by class
      * descriptor <code>classDesc</code> (an <code>ObjectStreamClass</code>).
@@ -1182,43 +999,38 @@
             throws IOException {
         ObjectStreamField[] fields = classDesc.fields();
         Class<?> declaringClass = classDesc.forClass();
-        for (int i = 0; i < fields.length; i++) {
+        for(ObjectStreamField fieldDesc : fields) {
             try {
+                
+                // get associated Field 
+                long fieldID = fieldDesc.getFieldID(accessor, declaringClass);
+
                 // Code duplication starts, just because Java is typed
-                ObjectStreamField fieldDesc = fields[i];
                 if (fieldDesc.isPrimitive()) {
                     switch (fieldDesc.getTypeCode()) {
                         case 'B':
-                            output.writeByte(getFieldByte(obj, declaringClass,
-                                    fieldDesc.getName()));
+                            output.writeByte(accessor.getByte(obj, fieldID));
                             break;
                         case 'C':
-                            output.writeChar(getFieldChar(obj, declaringClass,
-                                    fieldDesc.getName()));
+                            output.writeChar(accessor.getChar(obj, fieldID));
                             break;
                         case 'D':
-                            output.writeDouble(getFieldDouble(obj,
-                                    declaringClass, fieldDesc.getName()));
+                            output.writeDouble(accessor.getDouble(obj, fieldID));
                             break;
                         case 'F':
-                            output.writeFloat(getFieldFloat(obj,
-                                    declaringClass, fieldDesc.getName()));
+                            output.writeFloat(accessor.getFloat(obj, fieldID));
                             break;
                         case 'I':
-                            output.writeInt(getFieldInt(obj, declaringClass,
-                                    fieldDesc.getName()));
+                            output.writeInt(accessor.getInt(obj, fieldID));
                             break;
                         case 'J':
-                            output.writeLong(getFieldLong(obj, declaringClass,
-                                    fieldDesc.getName()));
+                            output.writeLong(accessor.getLong(obj, fieldID));
                             break;
                         case 'S':
-                            output.writeShort(getFieldShort(obj,
-                                    declaringClass, fieldDesc.getName()));
+                            output.writeShort(accessor.getShort(obj, fieldID));
                             break;
                         case 'Z':
-                            output.writeBoolean(getFieldBool(obj,
-                                    declaringClass, fieldDesc.getName()));
+                            output.writeBoolean(accessor.getBoolean(obj, fieldID));
                             break;
                         default:
                             throw new IOException(
@@ -1227,12 +1039,11 @@
                     }
                 } else {
                     // Object type (array included).
-                    Object field = getFieldObj(obj, declaringClass, fieldDesc
-                            .getName(), fieldDesc.getTypeString());
+                    Object objField = accessor.getObject(obj, fieldID);
                     if (fieldDesc.isUnshared()) {
-                        writeUnshared(field);
+                        writeUnshared(objField);
                     } else {
-                        writeObject(field);
+                        writeObject(objField);
                     }
                 }
             } catch (NoSuchFieldError nsf) {
@@ -2013,8 +1824,8 @@
         // Only write field "name" for enum class, which is the second field of
         // enum, that is fields[1]. Ignore all non-fields and fields.length < 2
         if (null != fields && fields.length > 1) {
-            String str = (String) getFieldObj(object, declaringClass, fields[1]
-                    .getName(), fields[1].getTypeString());
+            String str = (String) accessor.getObject(object, fields[1].getFieldID(accessor, declaringClass));
+
             Integer strhandle = null;
             if (!unshared) {
                 strhandle = dumpCycle(str);

Modified: harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/io/ObjectStreamClass.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/io/ObjectStreamClass.java?rev=652421&r1=652420&r2=652421&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/io/ObjectStreamClass.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/io/ObjectStreamClass.java Wed Apr 30 20:14:31 2008
@@ -34,6 +34,7 @@
 
 import org.apache.harmony.luni.util.Msg;
 import org.apache.harmony.luni.util.PriviAction;
+import org.apache.harmony.luni.util.ThreadLocalCache;
 
 /**
  * Instances of ObjectStreamClass are used to describe classes of objects used
@@ -57,6 +58,8 @@
     // Name of the field that contains the SUID value (if present)
     private static final String UID_FIELD_NAME = "serialVersionUID"; //$NON-NLS-1$
 
+    static final long CONSTRUCTOR_IS_NOT_RESOLVED = -1;
+
     private static final int CLASS_MODIFIERS_MASK;
 
     private static final int FIELD_MODIFIERS_MASK;
@@ -135,10 +138,6 @@
 
     static final Class<ObjectStreamClass> OBJECTSTREAMCLASSCLASS = ObjectStreamClass.class;
 
-    // Table mapping instances of java.lang.Class to to corresponding instances
-    // of ObjectStreamClass
-    private static final WeakHashMap<Class<?>, ObjectStreamClass> classesAndDescriptors = new WeakHashMap<Class<?>, ObjectStreamClass>();
-
     private transient Method methodWriteReplace;
 
     private transient Method methodReadResolve;
@@ -177,6 +176,17 @@
     // Array of ObjectStreamField describing the serialized fields of this class
     private transient ObjectStreamField[] loadFields;
 
+    // MethodID for deserialization constructor
+    private transient long constructor = CONSTRUCTOR_IS_NOT_RESOLVED;
+
+    void setConstructor(long newConstructor) {
+        constructor = newConstructor;
+    }
+
+    long getConstructor() {
+        return constructor;
+    }
+
     /*
      * If an ObjectStreamClass describes an Externalizable class, it (the
      * descriptor) should not have field descriptors (ObjectStreamField) at all.
@@ -944,15 +954,13 @@
      */
     private static ObjectStreamClass lookupStreamClass(Class<?> cl,
             boolean computeSUID) {
-        // Synchronized because of the lookup table 'classesAndDescriptors'
 
-        ObjectStreamClass cachedValue;
-        synchronized (classesAndDescriptors) {
-            cachedValue = classesAndDescriptors.get(cl);
-            if (cachedValue == null) {
-                cachedValue = createClassDesc(cl, computeSUID);
-                classesAndDescriptors.put(cl, cachedValue);
-            }
+        WeakHashMap<Class<?>,ObjectStreamClass> tlc = OSCThreadLocalCache.oscWeakHashMap.get();
+
+        ObjectStreamClass cachedValue = tlc.get(cl);
+        if (cachedValue == null) {
+            cachedValue = createClassDesc(cl, computeSUID);
+            tlc.put(cl, cachedValue);
         }
         return cachedValue;
 
@@ -1167,4 +1175,16 @@
         return getName() + ": static final long serialVersionUID =" //$NON-NLS-1$
                 + getSerialVersionUID() + "L;"; //$NON-NLS-1$
     }
+
+    static class OSCThreadLocalCache extends ThreadLocalCache {
+
+        // thread-local cache for ObjectStreamClass.lookup
+        public static ThreadLocalCache<WeakHashMap<Class<?>,ObjectStreamClass>> oscWeakHashMap = new ThreadLocalCache<WeakHashMap<Class<?>,ObjectStreamClass>>() {
+            protected WeakHashMap<Class<?>,ObjectStreamClass> initialValue() {
+                return new WeakHashMap<Class<?>,ObjectStreamClass>();
+            }
+        };
+
+    }
+
 }

Modified: harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/io/ObjectStreamField.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/io/ObjectStreamField.java?rev=652421&r1=652420&r2=652421&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/io/ObjectStreamField.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/io/ObjectStreamField.java Wed Apr 30 20:14:31 2008
@@ -21,6 +21,8 @@
 import java.util.Arrays;
 import java.util.Comparator;
 
+import org.apache.harmony.misc.accessors.ObjectAccessor;
+
 /**
  * This class represents object fields that are saved to the stream, by
  * serialization. Classes can define the collection of fields to be dumped,
@@ -31,6 +33,9 @@
  */
 public class ObjectStreamField implements Comparable<Object> {
 
+    static final int FIELD_IS_NOT_RESOLVED = -1;
+    static final int FIELD_IS_ABSENT = -2;
+
     // Declared name of the field
     private String name;
 
@@ -47,6 +52,21 @@
 
     private boolean isDeserialized;
 
+    private long assocFieldID = FIELD_IS_NOT_RESOLVED;
+
+    long getFieldID(ObjectAccessor accessor, Class<?> declaringClass) {
+        if (assocFieldID != FIELD_IS_NOT_RESOLVED) {
+            return assocFieldID;
+        } else {
+            try {  
+                assocFieldID = accessor.getFieldID(declaringClass, name);
+            } catch(NoSuchFieldError e) {
+                assocFieldID = FIELD_IS_ABSENT;
+            }
+            return assocFieldID;
+        }
+    }
+
     /**
      * Constructs an ObjectStreamField with the given name and the given type
      * 

Modified: harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/net/InetAddress.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/net/InetAddress.java?rev=652421&r1=652420&r2=652421&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/net/InetAddress.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/net/InetAddress.java Wed Apr 30 20:14:31 2008
@@ -403,10 +403,12 @@
             return element.inetAddress();
         }
 
+        // TODO Clean up NegativeCache; there's no need to maintain the failure message
+        
         // now try the negative cache
         String failedMessage = NegativeCache.getFailedMessage(host);
         if (failedMessage != null) {
-            throw new UnknownHostException(host + " - " + failedMessage); //$NON-NLS-1$
+            throw new UnknownHostException(host);
         }
 
         InetAddress anInetAddress;
@@ -415,7 +417,8 @@
         } catch (UnknownHostException e) {
             // put the entry in the negative cache
             NegativeCache.put(host, e.getMessage());
-            throw new UnknownHostException(host + " - " + e.getMessage()); //$NON-NLS-1$
+            // use host for message to match RI, save the cause for giggles
+            throw (UnknownHostException)new UnknownHostException(host).initCause(e);
         }
 
         Cache.add(anInetAddress);
@@ -508,11 +511,11 @@
     }
 
     class CacheElement {
-        long timeAdded = System.currentTimeMillis();
+        final long timeAdded = System.currentTimeMillis();
 
         CacheElement next;
 
-        public CacheElement() {
+        CacheElement() {
             super();
         }
 
@@ -526,18 +529,18 @@
     }
 
     static class Cache {
-        static int maxSize = 5;
+        private static int maxSize = 5;
 
         private static int size = 0;
 
         private static CacheElement head;
 
-        static void clear() {
+        static synchronized void clear() {
             size = 0;
             head = null;
         }
 
-        static void add(InetAddress value) {
+        static synchronized void add(InetAddress value) {
             CacheElement newElement = value.cacheElement();
             if (size < maxSize) {
                 size++;
@@ -548,7 +551,7 @@
             head = newElement;
         }
 
-        static CacheElement get(String name) {
+        static synchronized CacheElement get(String name) {
             CacheElement previous = null;
             CacheElement current = head;
             boolean notFound = true;
@@ -564,7 +567,7 @@
             return current;
         }
 
-        private static void deleteTail() {
+        private synchronized static void deleteTail() {
             if (0 == size) {
                 return;
             }
@@ -581,7 +584,7 @@
             previous.next = null;
         }
 
-        private static void moveToHead(CacheElement element,
+        private synchronized static void moveToHead(CacheElement element,
                 CacheElement elementPredecessor) {
             if (null == elementPredecessor) {
                 head = element;

Modified: harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/net/NegCacheElement.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/net/NegCacheElement.java?rev=652421&r1=652420&r2=652421&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/net/NegCacheElement.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/net/NegCacheElement.java Wed Apr 30 20:14:31 2008
@@ -22,17 +22,10 @@
 class NegCacheElement {
 
     // we need the time to figure out when the entry is stale
-    long timeAdded = System.currentTimeMillis();
+    final long timeAdded = System.currentTimeMillis();
 
     // holds the name of the host for which the lookup failed
-    String hostName;
-
-    /**
-     * default constructor
-     */
-    public NegCacheElement() {
-        super();
-    }
+    final String hostName;
 
     /**
      * Constructor used to set the hostname for the failed entry
@@ -40,16 +33,7 @@
      * @param hostName
      *            name of the host on which the lookup failed
      */
-    public NegCacheElement(String hostName) {
+    NegCacheElement(String hostName) {
         this.hostName = hostName;
     }
-
-    /**
-     * Answers the hostname for the cache element
-     * 
-     * @return hostName name of the host on which the lookup failed
-     */
-    String hostName() {
-        return hostName;
-    }
 }

Modified: harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/net/NegativeCache.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/net/NegativeCache.java?rev=652421&r1=652420&r2=652421&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/net/NegativeCache.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/net/NegativeCache.java Wed Apr 30 20:14:31 2008
@@ -29,13 +29,13 @@
 
     private static final long serialVersionUID = 1L;
 
-    static NegativeCache<String, NegCacheElement> negCache;
+    private static NegativeCache<String, NegCacheElement> negCache;
 
     // maximum number of entries in the cache
-    static final int MAX_NEGATIVE_ENTRIES = 5;
+    private static final int MAX_NEGATIVE_ENTRIES = 5;
 
     // the loading for the cache
-    static final float LOADING = 0.75F;
+    private static final float LOADING = 0.75F;
 
     /**
      * Answers the hostname for the cache element
@@ -69,7 +69,7 @@
      * @param failedMessage
      *            the message returned when we failed the lookup
      */
-    static void put(String hostName, String failedMessage) {
+    static synchronized void put(String hostName, String failedMessage) {
         checkCacheExists();
         negCache.put(hostName, new NegCacheElement(failedMessage));
     }
@@ -83,7 +83,7 @@
      * @return the message which was returned when the host failed to be looked
      *         up if there is still a valid entry within the cache
      */
-    static String getFailedMessage(String hostName) {
+    static synchronized String getFailedMessage(String hostName) {
         checkCacheExists();
         NegCacheElement element = negCache.get(hostName);
         if (element != null) {
@@ -111,7 +111,7 @@
             }
         }
         if (element != null) {
-            return element.hostName();
+            return element.hostName;
         }
         return null;
     }
@@ -119,7 +119,7 @@
     /**
      * This method checks if we have created the cache and if not creates it
      */
-    static void checkCacheExists() {
+    static synchronized void checkCacheExists() {
         if (negCache == null) {
             /*
              * Create with the access order set so ordering is based on when the

Modified: harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/util/ArrayList.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/util/ArrayList.java?rev=652421&r1=652420&r2=652421&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/util/ArrayList.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/util/ArrayList.java Wed Apr 30 20:14:31 2008
@@ -224,19 +224,17 @@
      */
     @Override
     public boolean addAll(Collection<? extends E> collection) {
-        int growSize = collection.size();
-        if (growSize > 0) {
-            if (lastIndex > array.length - growSize) {
-                growAtEnd(growSize);
-            }
-            Object[] dumparray = new Object[growSize];
-            collection.toArray(dumparray);
-            System.arraycopy(dumparray, 0, this.array, lastIndex, growSize);
-            lastIndex += growSize;
-            modCount++;
-            return true;
+        Object[] dumpArray = collection.toArray();
+        if (dumpArray.length == 0) {
+            return false;
         }
-        return false;
+        if (dumpArray.length > array.length - lastIndex) {
+            growAtEnd(dumpArray.length);
+        }
+        System.arraycopy(dumpArray, 0, this.array, lastIndex, dumpArray.length);
+        lastIndex += dumpArray.length;
+        modCount++;
+        return true;
     }
 
     /**
@@ -521,6 +519,9 @@
                     array[--lastIndex] = null;
                 }
             }
+            if (firstIndex == lastIndex) {
+                firstIndex = lastIndex = 0;
+            }
         } else {
             throw new IndexOutOfBoundsException();
         }

Modified: harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/util/GregorianCalendar.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/util/GregorianCalendar.java?rev=652421&r1=652420&r2=652421&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/util/GregorianCalendar.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/util/GregorianCalendar.java Wed Apr 30 20:14:31 2008
@@ -446,7 +446,9 @@
     protected void computeFields() {
         int zoneOffset = getTimeZone().getRawOffset();
 
-        fields[ZONE_OFFSET] = zoneOffset;
+        if(!isSet[ZONE_OFFSET]) {
+            fields[ZONE_OFFSET] = zoneOffset;
+        }
 
         int millis = (int) (time % 86400000);
         int savedMillis = millis;

Modified: harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/file/FileURLConnection.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/file/FileURLConnection.java?rev=652421&r1=652420&r2=652421&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/file/FileURLConnection.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/file/FileURLConnection.java Wed Apr 30 20:14:31 2008
@@ -59,9 +59,6 @@
     public FileURLConnection(URL url) {
         super(url);
         fileName = url.getFile();
-        if (url.getRef() != null) {
-            fileName += "#" + url.getRef(); //$NON-NLS-1$
-        }
         if (fileName == null) {
             fileName = ""; //$NON-NLS-1$
         }

Modified: harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/ftp/FtpURLConnection.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/ftp/FtpURLConnection.java?rev=652421&r1=652420&r2=652421&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/ftp/FtpURLConnection.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/ftp/FtpURLConnection.java Wed Apr 30 20:14:31 2008
@@ -183,22 +183,24 @@
             ProxySelector selector = ProxySelector.getDefault();
             Iterator<Proxy> iter = proxyList.iterator();
             boolean connectOK = false;
+            String failureReason = ""; //$NON-NLS-1$
             while (iter.hasNext() && !connectOK) {
                 currentProxy = iter.next();
                 try {
                     connectInternal();
                     connectOK = true;
                 } catch (IOException ioe) {
+                    failureReason = ioe.getLocalizedMessage();
                     // If connect failed, callback "connectFailed"
                     // should be invoked.
                     if (null != selector && Proxy.NO_PROXY != currentProxy) {
-                        selector
-                                .connectFailed(uri, currentProxy.address(), ioe);
+                        selector.connectFailed(uri, currentProxy.address(), ioe);
                     }
                 }
             }
             if (!connectOK) {
-                throw new IOException(Msg.getString("K0097")); //$NON-NLS-1$
+                // K0097=Unable to connect to server\: {0}
+                throw new IOException(Msg.getString("K0097", failureReason)); //$NON-NLS-1$
             }
         }
     }

Modified: harmony/enhanced/classlib/branches/java6/modules/luni/src/main/native/luni/unix/makefile
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/luni/src/main/native/luni/unix/makefile?rev=652421&r1=652420&r2=652421&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/luni/src/main/native/luni/unix/makefile (original)
+++ harmony/enhanced/classlib/branches/java6/modules/luni/src/main/native/luni/unix/makefile Wed Apr 30 20:14:31 2008
@@ -26,8 +26,8 @@
 
 BUILDFILES = \
 	$(SHAREDSUB)luni_copyright.o $(SHAREDSUB)file.o procimpl.o \
-	$(SHAREDSUB)oos.o $(SHAREDSUB)nethelp.o \
-	$(SHAREDSUB)floatbits.o $(SHAREDSUB)ois.o \
+	$(SHAREDSUB)nethelp.o \
+	$(SHAREDSUB)floatbits.o \
 	helpers.o $(SHAREDSUB)math.o $(SHAREDSUB)luniglob.o \
 	$(SHAREDSUB)proxy.o \
 	$(SHAREDSUB)cbigint.o $(SHAREDSUB)dblparse.o $(SHAREDSUB)fltparse.o \

Modified: harmony/enhanced/classlib/branches/java6/modules/luni/src/main/native/luni/windows/makefile
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/luni/src/main/native/luni/windows/makefile?rev=652421&r1=652420&r2=652421&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/luni/src/main/native/luni/windows/makefile (original)
+++ harmony/enhanced/classlib/branches/java6/modules/luni/src/main/native/luni/windows/makefile Wed Apr 30 20:14:31 2008
@@ -27,9 +27,8 @@
 
 BUILDFILES = \
   $(SHAREDSUB)luni_copyright.obj $(SHAREDSUB)file.obj procimpl.obj \
-  $(SHAREDSUB)oos.obj \
   $(SHAREDSUB)nethelp.obj $(SHAREDSUB)floatbits.obj \
-  $(SHAREDSUB)ois.obj helpers.obj $(SHAREDSUB)math.obj \
+  helpers.obj $(SHAREDSUB)math.obj \
   $(SHAREDSUB)luniglob.obj $(SHAREDSUB)proxy.obj $(SHAREDSUB)netif.obj \
   $(SHAREDSUB)cbigint.obj $(SHAREDSUB)dblparse.obj $(SHAREDSUB)fltparse.obj \
   $(SHAREDSUB)process.obj $(SHAREDSUB)bigint.obj $(SHAREDSUB)osc.obj \

Modified: harmony/enhanced/classlib/branches/java6/modules/luni/src/test/api/common/org/apache/harmony/luni/tests/internal/net/www/protocol/file/FileURLConnectionTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/luni/src/test/api/common/org/apache/harmony/luni/tests/internal/net/www/protocol/file/FileURLConnectionTest.java?rev=652421&r1=652420&r2=652421&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/luni/src/test/api/common/org/apache/harmony/luni/tests/internal/net/www/protocol/file/FileURLConnectionTest.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/luni/src/test/api/common/org/apache/harmony/luni/tests/internal/net/www/protocol/file/FileURLConnectionTest.java Wed Apr 30 20:14:31 2008
@@ -45,4 +45,15 @@
         assertEquals("application/xml", getContentType("test.xml"));
         assertEquals("text/plain", getContentType("."));
     }
+    
+    public void testGetInputStream() throws IOException {
+        // Regression for Harmony-5737
+        String resourceName = "org/apache/harmony/luni/tests/" + "test.rtf";
+        URL url = ClassLoader.getSystemClassLoader().getResource(resourceName);
+        URL anchorUrl = new URL(url,"#anchor");
+        assertNotNull("Cannot find test resource " + resourceName, anchorUrl);
+        
+        FileURLConnection conn = new FileURLConnection(anchorUrl);
+        assertNotNull(conn.getInputStream());
+    }
 }

Modified: harmony/enhanced/classlib/branches/java6/modules/luni/src/test/api/common/org/apache/harmony/luni/tests/java/io/ObjectInputStreamTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/luni/src/test/api/common/org/apache/harmony/luni/tests/java/io/ObjectInputStreamTest.java?rev=652421&r1=652420&r2=652421&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/luni/src/test/api/common/org/apache/harmony/luni/tests/java/io/ObjectInputStreamTest.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/luni/src/test/api/common/org/apache/harmony/luni/tests/java/io/ObjectInputStreamTest.java Wed Apr 30 20:14:31 2008
@@ -23,6 +23,7 @@
 import java.io.Externalizable;
 import java.io.File;
 import java.io.FileInputStream;
+import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
@@ -40,6 +41,7 @@
 import java.io.Serializable;
 import java.io.SerializablePermission;
 import java.io.StreamCorruptedException;
+import java.lang.reflect.Proxy;
 import java.security.Permission;
 import java.util.Arrays;
 import java.util.HashMap;
@@ -216,6 +218,56 @@
             System.setSecurityManager(sm);
         }
     }
+    
+    /**
+     * @tests {@link java.io.ObjectInputStream#resolveProxyClass(String[])}
+     */
+    public void test_resolveProxyClass() throws IOException,
+            ClassNotFoundException {
+        oos.writeBytes("HelloWorld");
+        oos.close();
+        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
+        MockObjectInputStream mockIn = new MockObjectInputStream(
+                new ByteArrayInputStream(bao.toByteArray()));
+        Class[] clazzs = { java.io.ObjectInputStream.class,
+                java.io.Reader.class };
+        for (int i = 0; i < clazzs.length; i++) {
+            Class clazz = clazzs[i];
+            Class[] interfaceNames = clazz.getInterfaces();
+            String[] interfaces = new String[interfaceNames.length];
+            int index = 0;
+            for (Class c : interfaceNames) {
+                interfaces[index] = c.getName();
+                index++;
+            }
+            Class<?> s = mockIn.resolveProxyClass(interfaces);
+
+            if (Proxy.isProxyClass(s)) {
+                Class[] implementedInterfaces = s.getInterfaces();
+                for (index = 0; index < implementedInterfaces.length; index++) {
+                    assertEquals(interfaceNames[index],
+                            implementedInterfaces[index]);
+                }
+            } else {
+                fail("Should return a proxy class that implements the interfaces named in a proxy class descriptor");
+            }
+        }
+        mockIn.close();
+    }
+
+    class MockObjectInputStream extends ObjectInputStream {
+
+        public MockObjectInputStream(InputStream input)
+                throws StreamCorruptedException, IOException {
+            super(input);
+        }
+
+        @Override
+        public Class<?> resolveProxyClass(String[] interfaceNames) throws IOException, ClassNotFoundException {
+            return super.resolveProxyClass(interfaceNames);
+        }
+
+    }
 
     /**
      * @tests java.io.ObjectInputStream#available()

Modified: harmony/enhanced/classlib/branches/java6/modules/luni/src/test/api/common/org/apache/harmony/luni/tests/java/io/ObjectOutputStreamTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/luni/src/test/api/common/org/apache/harmony/luni/tests/java/io/ObjectOutputStreamTest.java?rev=652421&r1=652420&r2=652421&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/luni/src/test/api/common/org/apache/harmony/luni/tests/java/io/ObjectOutputStreamTest.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/luni/src/test/api/common/org/apache/harmony/luni/tests/java/io/ObjectOutputStreamTest.java Wed Apr 30 20:14:31 2008
@@ -1053,6 +1053,31 @@
             ois.close();
         }
     }
+    
+    /**
+     * @tests {@link java.io.ObjectOutputStream#annotateProxyClass(java.lang.Class<T>)}
+     */
+    public void test_annotateProxyClass() throws SecurityException, IOException {
+        MockObjectOutputStream mockObjectOutputStream = new MockObjectOutputStream();
+        mockObjectOutputStream.annotateProxyClass(this.getClass());
+        assertEquals("The default implementation is doing nothing.",
+                mockObjectOutputStream, mockObjectOutputStream);
+
+    }
+
+    class MockObjectOutputStream extends ObjectOutputStream {
+
+        protected MockObjectOutputStream() throws IOException,
+                SecurityException {
+            super();
+        }
+
+        @Override
+        public void annotateProxyClass(Class<?> aClass) throws IOException {
+            super.annotateProxyClass(aClass);
+        }
+
+    }
 
     /**
      * Sets up the fixture, for example, open a network connection. This method

Modified: harmony/enhanced/classlib/branches/java6/modules/luni/src/test/api/common/org/apache/harmony/luni/tests/java/io/ReaderTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/luni/src/test/api/common/org/apache/harmony/luni/tests/java/io/ReaderTest.java?rev=652421&r1=652420&r2=652421&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/luni/src/test/api/common/org/apache/harmony/luni/tests/java/io/ReaderTest.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/luni/src/test/api/common/org/apache/harmony/luni/tests/java/io/ReaderTest.java Wed Apr 30 20:14:31 2008
@@ -69,6 +69,93 @@
         assertEquals(s.substring(CHARBUFFER_REMAINING), String
                 .valueOf(destBuffer));
     }
+    
+    /**
+     * @tests {@link java.io.Reader#mark(int)}
+     */
+    public void test_mark() {
+        MockReader mockReader = new MockReader();
+        try {
+            mockReader.mark(0);
+            fail("Should throw IOException for Reader do not support mark");
+        } catch (IOException e) {
+            // Excepted
+        }
+    }
+
+    /**
+     * @tests {@link java.io.Reader#read()}
+     */
+    public void test_read() throws IOException {
+        MockReader reader = new MockReader();
+
+        // return -1 when the stream is null;
+        assertEquals("Should be equal to -1", -1, reader.read());
+
+        String string = "MY TEST STRING";
+        char[] srcBuffer = string.toCharArray();
+        MockReader mockReader = new MockReader(srcBuffer);
+
+        // normal read
+        for (char c : srcBuffer) {
+            assertEquals("Should be equal to \'" + c + "\'", c, mockReader
+                    .read());
+        }
+
+        // return -1 when read Out of Index
+        mockReader.read();
+        assertEquals("Should be equal to -1", -1, reader.read());
+
+    }
+
+    /**
+     * @tests {@link java.io.Reader#ready()}
+     */
+    public void test_ready() throws IOException {
+        MockReader mockReader = new MockReader();
+        assertFalse("Should always return false", mockReader.ready());
+
+    }
+
+    /**
+     * @tests {@link java.io.Reader#reset()}
+     */
+    public void test_reset() {
+        MockReader mockReader = new MockReader();
+        try {
+            mockReader.reset();
+            fail("Should throw IOException");
+        } catch (IOException e) {
+            // Excepted
+        }
+    }
+
+    /**
+     * @tests {@link java.io.Reader#skip(long)}
+     */
+    public void test_skip() throws IOException {
+        String string = "MY TEST STRING";
+        char[] srcBuffer = string.toCharArray();
+        int length = srcBuffer.length;
+        MockReader mockReader = new MockReader(srcBuffer);
+        assertEquals("Should be equal to \'M\'", 'M', mockReader.read());
+
+        // normal skip
+        mockReader.skip(length / 2);
+        assertEquals("Should be equal to \'S\'", 'S', mockReader.read());
+
+        // try to skip a bigger number of characters than the total
+        // Should do nothing
+        mockReader.skip(length);
+
+        // try to skip a negative number of characters throw IllegalArgumentException
+        try {
+            mockReader.skip(-1);
+            fail("Should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Excepted
+        }
+    }
 
     class MockReader extends Reader {
 
@@ -77,6 +164,10 @@
         private int current_offset = 0;
 
         private int length = 0;
+        
+        public MockReader() {
+            super();
+        }
 
         public MockReader(char[] data) {
             contents = data;

Modified: harmony/enhanced/classlib/branches/java6/modules/luni/src/test/api/common/org/apache/harmony/luni/tests/java/lang/EnumTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/luni/src/test/api/common/org/apache/harmony/luni/tests/java/lang/EnumTest.java?rev=652421&r1=652420&r2=652421&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/luni/src/test/api/common/org/apache/harmony/luni/tests/java/lang/EnumTest.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/luni/src/test/api/common/org/apache/harmony/luni/tests/java/lang/EnumTest.java Wed Apr 30 20:14:31 2008
@@ -45,6 +45,14 @@
         Red, Green, Blue {};
     }
     
+    enum MockCloneEnum {
+        ONE;
+        
+        public void callClone() throws CloneNotSupportedException{
+            super.clone();
+        }
+    }
+    
     /**
      * @tests java.lang.Enum#compareTo(java.lang.Enum) 
      */
@@ -182,6 +190,19 @@
         
         assertEquals(0, Empty.values().length);
     }
+
+    /**
+     * @tests java.lang.Enum#clone()
+     */
+    public void test_clone() {
+        try {
+            MockCloneEnum.ONE.callClone();
+            fail("Should throw CloneNotSupprotedException");
+        } catch (CloneNotSupportedException e1) {
+            // expected
+        }
+
+    }
     
     /**
      * @test Serialization/deserilazation compatibility with Harmony.