You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@river.apache.org by pe...@apache.org on 2011/10/09 06:07:07 UTC
svn commit: r1180542 -
/river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/
Author: peter_firmstone
Date: Sun Oct 9 04:07:07 2011
New Revision: 1180542
URL: http://svn.apache.org/viewvc?rev=1180542&view=rev
Log:
Adding support for Serialization in ReferenceCollections
Added:
river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferrerWrapper.java (with props)
Modified:
river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/AbstractSerializationOfRC.java
river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceFactory.java
river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceSerializedForm.java
river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/SerialDataReferenceCollection.java
river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/SerializationOfReferenceCollection.java
Modified: river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/AbstractSerializationOfRC.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/AbstractSerializationOfRC.java?rev=1180542&r1=1180541&r2=1180542&view=diff
==============================================================================
--- river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/AbstractSerializationOfRC.java (original)
+++ river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/AbstractSerializationOfRC.java Sun Oct 9 04:07:07 2011
@@ -39,7 +39,11 @@ import java.util.concurrent.BlockingQueu
import java.util.concurrent.TimeUnit;
/**
- *
+ * The purpose of this class is to implement all the possible interfaces
+ * that subclasses of ReferenceCollection may implement. This is designed
+ * to fix the readResolve issue that occurs in object graphs containing
+ * circular references.
+ *
* @author Peter Firmstone.
*/
abstract class AbstractSerializationOfRC<T> extends SerializationOfReferenceCollection<T>
@@ -47,15 +51,15 @@ implements Serializable, List<T>, Set<T>
Queue<T>, Deque<T>, BlockingQueue<T>, BlockingDeque<T>{
private static final long serialVersionUID = 1L;
- // This abstract class must not hold any serial data.
+ // This abstract class must not hold any serial data.
- // Builder created List on deserialization
- private volatile transient Collection<T> serialBuilt = null;
- private volatile transient boolean built = false;
-
+ // Builder created List on deserialization
+ private volatile transient Collection<T> serialBuilt = null;
+ private volatile transient boolean built = false;
@Override
- Collection<T> build() throws InstantiationException, IllegalAccessException {
+ Collection<T> build() throws InstantiationException, IllegalAccessException,
+ ObjectStreamException {
if (isBuilt()) return getSerialBuilt();
setBuilt();
/* Traverse Inheritance heirarchy in reverse order */
Modified: river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceFactory.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceFactory.java?rev=1180542&r1=1180541&r2=1180542&view=diff
==============================================================================
--- river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceFactory.java (original)
+++ river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceFactory.java Sun Oct 9 04:07:07 2011
@@ -40,11 +40,15 @@ class ReferenceFactory<T> {
static <T> Referrer<T> create(T t, ReferenceQueue<? super T> queue, Ref type ){
switch (type){
- case WEAK_IDENTITY: return new WeakIdentityReferenceKey<T>(t, queue);
- case SOFT_IDENTITY: return new SoftIdentityReferenceKey<T>(t, queue);
- case WEAK: return new WeakReferenceKey<T>(t, queue);
- case SOFT: return new SoftReferenceKey<T>(t, queue);
- default: return new StrongReferenceKey<T>(t, queue);
+ case WEAK_IDENTITY:
+ return new ReferrerWrapper<T>(new WeakIdentityReferenceKey<T>(t, queue));
+ case SOFT_IDENTITY:
+ return new ReferrerWrapper<T>(new SoftIdentityReferenceKey<T>(t, queue));
+ case WEAK:
+ return new ReferrerWrapper<T>(new WeakReferenceKey<T>(t, queue));
+ case SOFT:
+ return new ReferrerWrapper<T>(new SoftReferenceKey<T>(t, queue));
+ default: return new ReferrerWrapper<T>(new StrongReferenceKey<T>(t, queue));
}
}
Modified: river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceSerializedForm.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceSerializedForm.java?rev=1180542&r1=1180541&r2=1180542&view=diff
==============================================================================
--- river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceSerializedForm.java (original)
+++ river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceSerializedForm.java Sun Oct 9 04:07:07 2011
@@ -64,10 +64,7 @@ class ReferenceSerializedForm<T> extends
return false;
}
- /* ReferenceQueue is not compared, because a lookup key is used to locate
- * an existing key and ReferenceQueue is null in lookup key's.
- *
- * ReferenceQueue is not part of hashCode or equals.
+ /* In this case we're using Identity
*/
@Override
public boolean equals(Object o) {
@@ -75,7 +72,7 @@ class ReferenceSerializedForm<T> extends
if (!(o instanceof Referrer)) return false;
Object k1 = get();
Object k2 = ((Referrer) o).get();
- if ( k1 != null && k1.equals(k2)) return true;
+ if ( k1 != null && k1 == k2) return true;
return ( k1 == null && k2 == null && hashCode() == o.hashCode()); // Both objects were collected.
}
Added: river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferrerWrapper.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferrerWrapper.java?rev=1180542&view=auto
==============================================================================
--- river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferrerWrapper.java (added)
+++ river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferrerWrapper.java Sun Oct 9 04:07:07 2011
@@ -0,0 +1,95 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.river.impl.util;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+
+/**
+ *
+ * @author peter
+ */
+final class ReferrerWrapper<T> implements Referrer<T>, Serializable{
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * @serialField
+ */
+ private volatile Referrer<T> reference;
+
+ ReferrerWrapper(Referrer<T> ref){
+ if (ref == null) throw new NullPointerException("Referrer cannot be null");
+ reference = ref;
+ }
+
+ void refresh(ReferenceQueuingFactory<T, Referrer<T>> rqf){
+ T object = get();
+ if (object != null){
+ Referrer<T> newRef = rqf.referenced(object, true);
+ synchronized (this){
+ reference = newRef;
+ }
+ }
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true; // Same reference.
+ if (!(o instanceof Referrer)) return false;
+ return reference.equals(o);
+ }
+
+ @Override
+ public int hashCode() {
+ return reference.hashCode();
+ }
+
+ @Override
+ public T get() {
+ return reference.get();
+ }
+
+ @Override
+ public void clear() {
+ reference.clear();
+ }
+
+ @Override
+ public boolean isEnqueued() {
+ return reference.isEnqueued();
+ }
+
+ @Override
+ public boolean enqueue() {
+ return reference.enqueue();
+ }
+
+ private void readObject(ObjectInputStream in)
+ throws IOException, ClassNotFoundException {
+ in.defaultReadObject();
+ if (reference == null) throw new IOException("Attempt to write null Referrer");
+ }
+
+ private void writeObject(ObjectOutputStream out) throws IOException {
+ out.defaultWriteObject();
+ }
+
+}
Propchange: river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferrerWrapper.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/SerialDataReferenceCollection.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/SerialDataReferenceCollection.java?rev=1180542&r1=1180541&r2=1180542&view=diff
==============================================================================
--- river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/SerialDataReferenceCollection.java (original)
+++ river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/SerialDataReferenceCollection.java Sun Oct 9 04:07:07 2011
@@ -19,33 +19,46 @@
package org.apache.river.impl.util;
import java.io.IOException;
+import java.io.InvalidObjectException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
+import java.io.ObjectStreamException;
import java.util.Collection;
+import java.util.Iterator;
/**
- *
+ * This class is the serial form of ReferenceCollection and all it's subclasses.
+ *
+ * While the serial form of this class will remain compatible with itself,
+ * ReferenceCollection may replace this implementation with another
+ * at some point in the future.
+ *
+ * This class will still be able to deserialize into a ReferenceCollection.
+ *
* @author peter
*/
public class SerialDataReferenceCollection<T> extends AbstractSerializationOfRC<T> {
private static final long serialVersionUID = 1L;
- /** @serialData */
- private Ref type = null;
- /** @serialData */
+ /** @serialField */
+ private Ref type;
+ /** @serialField */
private Collection<Referrer<T>> collection;
- /** @serialData */
+ /** @serialField */
private Class clazz;
@SuppressWarnings("unchecked")
SerialDataReferenceCollection( Class clazz,
Collection<Referrer<T>> underlyingCollection, Ref type)
throws InstantiationException, IllegalAccessException{
- // Create a new instance of the underlying collection and
- // add all objects.
- this.collection = underlyingCollection;
- this.type = type;
- this.clazz = clazz;
+ // Create a new instance of the underlying collection and
+ // add all objects.
+ if ( clazz == null || underlyingCollection == null || type == null){
+ throw new NullPointerException("null parameters prohibited");
+ }
+ this.collection = underlyingCollection;
+ this.type = type;
+ this.clazz = clazz;
}
@Override
@@ -64,15 +77,36 @@ public class SerialDataReferenceCollecti
}
@Override
- Collection<T> build() throws InstantiationException, IllegalAccessException{
+ final Collection<T> build() throws InstantiationException, IllegalAccessException,
+ ObjectStreamException{
Collection<T> result = super.build();
- // What if the underlying collection is immutable?
+ /* What if the underlying collection is immutable?
+ * The ReferenceQueuingFactory is unknown until the ReferenceCollection
+ * has been built.
+ */
+ if ( result instanceof ReferenceCollection){
+ ReferenceCollection<T> refCol = (ReferenceCollection<T>) result;
+ ReferenceQueuingFactory<T, Referrer<T>> rqf = refCol.getRQF();
+ Iterator<Referrer<T>> colIt = collection.iterator();
+ while (colIt.hasNext()){
+ Referrer<T> ref = colIt.next();
+ if ( ref == null ) continue;
+ if (ref instanceof ReferrerWrapper){
+ ((ReferrerWrapper<T>) ref).refresh(rqf);
+ } else {
+ throw new InvalidObjectException("Referrer's must be a ReferrerWraper for ReferenceCollection");
+ }
+ }
+ }
return result;
}
private void readObject(ObjectInputStream in)
throws IOException, ClassNotFoundException {
in.defaultReadObject();
+ if ( clazz == null || collection == null || type == null){
+ throw new InvalidObjectException("null fields found after deserialization");
+ }
}
private void writeObject(ObjectOutputStream out) throws IOException {
Modified: river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/SerializationOfReferenceCollection.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/SerializationOfReferenceCollection.java?rev=1180542&r1=1180541&r2=1180542&view=diff
==============================================================================
--- river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/SerializationOfReferenceCollection.java (original)
+++ river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/SerializationOfReferenceCollection.java Sun Oct 9 04:07:07 2011
@@ -18,6 +18,7 @@
package org.apache.river.impl.util;
+import java.io.ObjectStreamException;
import java.util.AbstractCollection;
import java.util.Collection;
@@ -34,6 +35,7 @@ abstract class SerializationOfReferenceC
return new SerialDataReferenceCollection<T>(clazz, refCol, type);
}
- abstract Collection<T> build() throws InstantiationException, IllegalAccessException;
+ abstract Collection<T> build() throws InstantiationException,
+ IllegalAccessException, ObjectStreamException;
}