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.