[infinispan-commits] Infinispan SVN: r113 - in trunk/core: src/main/java/org/infinispan/marshall and 8 other directories.
infinispan-commits at lists.jboss.org
infinispan-commits at lists.jboss.org
Tue Apr 14 14:09:18 EDT 2009
Author: galder.zamarreno at jboss.com
Date: 2009-04-14 14:09:18 -0400 (Tue, 14 Apr 2009)
New Revision: 113
Added:
trunk/core/src/main/java/org/infinispan/marshall/jboss/
trunk/core/src/main/java/org/infinispan/marshall/jboss/ArrayListExternalizer.java
trunk/core/src/main/java/org/infinispan/marshall/jboss/CustomObjectTable.java
trunk/core/src/main/java/org/infinispan/marshall/jboss/DeltaAwareExternalizer.java
trunk/core/src/main/java/org/infinispan/marshall/jboss/ExtendedResponseExternalizer.java
trunk/core/src/main/java/org/infinispan/marshall/jboss/ExternalizerClassFactory.java
trunk/core/src/main/java/org/infinispan/marshall/jboss/GlobalTransactionExternalizer.java
trunk/core/src/main/java/org/infinispan/marshall/jboss/ImmutableMapExternalizer.java
trunk/core/src/main/java/org/infinispan/marshall/jboss/InternalCachedEntryExternalizer.java
trunk/core/src/main/java/org/infinispan/marshall/jboss/JBossMarshaller.java
trunk/core/src/main/java/org/infinispan/marshall/jboss/JGroupsAddressExternalizer.java
trunk/core/src/main/java/org/infinispan/marshall/jboss/LinkedListExternalizer.java
trunk/core/src/main/java/org/infinispan/marshall/jboss/MagicNumberClassTable.java
trunk/core/src/main/java/org/infinispan/marshall/jboss/MapExternalizer.java
trunk/core/src/main/java/org/infinispan/marshall/jboss/MarshallUtil.java
trunk/core/src/main/java/org/infinispan/marshall/jboss/MarshalledValueExternalizer.java
trunk/core/src/main/java/org/infinispan/marshall/jboss/ReplicableCommandExternalizer.java
trunk/core/src/main/java/org/infinispan/marshall/jboss/SetExternalizer.java
trunk/core/src/main/java/org/infinispan/marshall/jboss/SingletonListExternalizer.java
trunk/core/src/main/java/org/infinispan/marshall/jboss/StateTransferControlCommandExternalizer.java
trunk/core/src/main/java/org/infinispan/marshall/jboss/TransactionLogExternalizer.java
trunk/core/src/test/java/org/infinispan/marshall/jboss/
trunk/core/src/test/java/org/infinispan/marshall/jboss/JBossMarshallerTest.java
Modified:
trunk/core/
trunk/core/pom.xml
trunk/core/src/main/java/org/infinispan/marshall/HorizonMarshaller.java
trunk/core/src/main/java/org/infinispan/marshall/Marshaller.java
trunk/core/src/main/java/org/infinispan/marshall/VersionAwareMarshaller.java
trunk/core/src/main/java/org/infinispan/statetransfer/StateTransferManagerImpl.java
trunk/core/src/main/java/org/infinispan/transaction/TransactionLog.java
trunk/core/src/main/java/org/infinispan/util/Util.java
trunk/core/src/test/java/org/infinispan/marshall/ObjectStreamMarshaller.java
trunk/core/src/test/java/org/infinispan/test/fwk/TestCacheManagerFactory.java
trunk/core/src/test/java/org/infinispan/test/testng/SuiteResourcesAndLogTest.java
Log:
[ISPN-44] (Integrate JBoss Marshalling) JBMAR based marshalling framework added, integrated and tested.
Property changes on: trunk/core
___________________________________________________________________
Name: svn:ignore
+ target
.settings
eclipse-output
.classpath
.project
temp-testng-customsuite.xml
Modified: trunk/core/pom.xml
===================================================================
--- trunk/core/pom.xml 2009-04-14 17:00:56 UTC (rev 112)
+++ trunk/core/pom.xml 2009-04-14 18:09:18 UTC (rev 113)
@@ -44,12 +44,26 @@
<artifactId>jboss-common-core</artifactId>
<version>2.2.10.GA</version>
</dependency>
-
+
<dependency>
+ <groupId>org.jboss.marshalling</groupId>
+ <artifactId>marshalling-api</artifactId>
+ <version>1.1.1.GA</version>
+ </dependency>
+
+ <dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.14</version>
<optional>true</optional>
</dependency>
+
+ <dependency>
+ <groupId>org.jboss.marshalling</groupId>
+ <artifactId>river</artifactId>
+ <version>1.1.1.GA</version>
+ <scope>test</scope>
+ </dependency>
+
</dependencies>
</project>
Modified: trunk/core/src/main/java/org/infinispan/marshall/HorizonMarshaller.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/HorizonMarshaller.java 2009-04-14 17:00:56 UTC (rev 112)
+++ trunk/core/src/main/java/org/infinispan/marshall/HorizonMarshaller.java 2009-04-14 18:09:18 UTC (rev 113)
@@ -40,6 +40,7 @@
import org.infinispan.transaction.TransactionLog;
import org.infinispan.util.FastCopyHashMap;
import org.infinispan.util.Immutables;
+import org.infinispan.util.Util;
import org.jboss.util.NotImplementedException;
import org.jboss.util.stream.MarshalledValueInputStream;
@@ -47,8 +48,10 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInput;
+import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;
+import java.io.OutputStream;
import java.io.Serializable;
import java.lang.reflect.Array;
import java.util.*;
@@ -57,6 +60,7 @@
* Abstract marshaller
*
* @author <a href="mailto:manik at jboss.org">Manik Surtani (manik at jboss.org)</a>
+ * @author Galder Zamarreño
* @since 4.0
*/
public class HorizonMarshaller implements Marshaller {
@@ -795,6 +799,14 @@
c.equals(Double.class));
}
+ public ObjectOutput startObjectOutput(OutputStream os) throws IOException {
+ return new ObjectOutputStream(os);
+ }
+
+ public void finishObjectOutput(ObjectOutput oo) {
+ Util.flushAndCloseOutput(oo);
+ }
+
public void objectToObjectStream(Object o, ObjectOutput out) throws IOException {
Map<Object, Integer> refMap = useRefs ? new IdentityHashMap<Object, Integer>() : null;
ClassLoader toUse = defaultClassLoader;
@@ -810,6 +822,14 @@
current.setContextClassLoader(old);
}
}
+
+ public ObjectInput startObjectInput(InputStream is) throws IOException {
+ return new ObjectInputStream(is);
+ }
+
+ public void finishObjectInput(ObjectInput oi) {
+ Util.closeInput(oi);
+ }
public Object objectFromObjectStream(ObjectInput in) throws IOException, ClassNotFoundException {
UnmarshalledReferences refMap = useRefs ? new UnmarshalledReferences() : null;
Modified: trunk/core/src/main/java/org/infinispan/marshall/Marshaller.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/Marshaller.java 2009-04-14 17:00:56 UTC (rev 112)
+++ trunk/core/src/main/java/org/infinispan/marshall/Marshaller.java 2009-04-14 18:09:18 UTC (rev 113)
@@ -29,6 +29,7 @@
import java.io.InputStream;
import java.io.ObjectInput;
import java.io.ObjectOutput;
+import java.io.OutputStream;
/**
* A marshaller is a class that is able to marshall and unmarshall objects efficiently.
@@ -52,11 +53,33 @@
* transferring state en-masse.
*
* @author <a href="mailto://manik@jboss.org">Manik Surtani</a>
+ * @author Galder Zamarreño
* @since 4.0
*/
@Scope(Scopes.GLOBAL)
public interface Marshaller {
+
/**
+ * Create and open a new ObjectOutput for the given output stream. This
+ * method should be used for opening data outpus when multiple
+ * objectToObjectStream() calls will be made before the stream is closed
+ *
+ * @param os output stream
+ * @return ObjectOutput to write to
+ * @throws IOException
+ */
+ ObjectOutput startObjectOutput(OutputStream os) throws IOException;
+
+ /**
+ * Finish using the given ObjectOutput. After opening a ObjectOutput and
+ * calling objectToObjectStream() mutliple times, use this method to flush
+ * the data and close if necessary
+ *
+ * @param oo data output that finished using
+ */
+ void finishObjectOutput(ObjectOutput oo);
+
+ /**
* Marshalls an object to a given {@link java.io.ObjectOutput}
*
* @param obj object to marshall
@@ -65,6 +88,26 @@
void objectToObjectStream(Object obj, ObjectOutput out) throws IOException;
/**
+ * Create and open a new ObjectInput for the given input stream. This
+ * method should be used for opening data inputs when multiple
+ * objectFromObjectStream() calls will be made before the stream is closed.
+ *
+ * @param is input stream
+ * @return ObjectInput to read from
+ * @throws IOException
+ */
+ ObjectInput startObjectInput(InputStream is) throws IOException;
+
+ /**
+ * Finish using the given ObjectInput. After opening a ObjectInput and
+ * calling objectFromObjectStream() mutliple times, use this method to flush
+ * the data and close if necessary
+ *
+ * @param oi data input that finished using
+ */
+ void finishObjectInput(ObjectInput oi);
+
+ /**
* Unmarshalls an object from an {@link java.io.ObjectInput}
*
* @param in stream to unmarshall from
Modified: trunk/core/src/main/java/org/infinispan/marshall/VersionAwareMarshaller.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/VersionAwareMarshaller.java 2009-04-14 17:00:56 UTC (rev 112)
+++ trunk/core/src/main/java/org/infinispan/marshall/VersionAwareMarshaller.java 2009-04-14 18:09:18 UTC (rev 113)
@@ -36,6 +36,7 @@
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;
+import java.io.OutputStream;
/**
* A delegate to various other marshallers like {@link HorizonMarshaller}. This delegating marshaller adds versioning
@@ -43,7 +44,7 @@
* based on the versioning information when unmarshalling objects.
*
* @author <a href="mailto:manik at jboss.org">Manik Surtani (manik at jboss.org)</a>
- * @author <a href="mailto:galder.zamarreno at jboss.com">Galder Zamarreno</a>
+ * @author Galder Zamarreño
* @since 4.0
*/
public class VersionAwareMarshaller implements Marshaller {
@@ -109,12 +110,28 @@
}
return defaultMarshaller.objectFromObjectStream(in);
}
+
+ public ObjectOutput startObjectOutput(OutputStream os) throws IOException {
+ return defaultMarshaller.startObjectOutput(os);
+ }
+
+ public void finishObjectOutput(ObjectOutput oo) {
+ defaultMarshaller.finishObjectOutput(oo);
+ }
public void objectToObjectStream(Object obj, ObjectOutput out) throws IOException {
out.writeShort(VERSION_400);
log.trace("Wrote version {0}", VERSION_400);
defaultMarshaller.objectToObjectStream(obj, out);
}
+
+ public ObjectInput startObjectInput(InputStream is) throws IOException {
+ return defaultMarshaller.startObjectInput(is);
+ }
+
+ public void finishObjectInput(ObjectInput oi) {
+ defaultMarshaller.finishObjectInput(oi);
+ }
public Object objectFromObjectStream(ObjectInput in) throws IOException, ClassNotFoundException {
int versionId;
Added: trunk/core/src/main/java/org/infinispan/marshall/jboss/ArrayListExternalizer.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/jboss/ArrayListExternalizer.java (rev 0)
+++ trunk/core/src/main/java/org/infinispan/marshall/jboss/ArrayListExternalizer.java 2009-04-14 18:09:18 UTC (rev 113)
@@ -0,0 +1,64 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.marshall.jboss;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.util.ArrayList;
+import java.util.Collection;
+
+import net.jcip.annotations.Immutable;
+
+import org.jboss.marshalling.Creator;
+import org.jboss.marshalling.Externalizer;
+
+/**
+ * List externalizer dealing with ArrayList and LinkedList implementations.
+ *
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+ at Immutable
+public class ArrayListExternalizer implements Externalizer {
+
+ /** The serialVersionUID */
+ private static final long serialVersionUID = 589638638644295615L;
+
+ public void writeExternal(Object subject, ObjectOutput output) throws IOException {
+ MarshallUtil.marshallCollection((Collection) subject, output);
+ }
+
+ public Object createExternal(Class<?> subjectType, ObjectInput input, Creator defaultCreator)
+ throws IOException, ClassNotFoundException {
+ int size = MarshallUtil.readUnsignedInt(input);
+ ArrayList l = new ArrayList(size);
+ for (int i = 0; i < size; i++) l.add(input.readObject());
+ return l;
+ }
+
+ public void readExternal(Object subject, ObjectInput input) throws IOException,
+ ClassNotFoundException {
+ // No-op since size was needed both for the creation and list population,
+ // so all the work was done in createExternal
+ }
+}
\ No newline at end of file
Added: trunk/core/src/main/java/org/infinispan/marshall/jboss/CustomObjectTable.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/jboss/CustomObjectTable.java (rev 0)
+++ trunk/core/src/main/java/org/infinispan/marshall/jboss/CustomObjectTable.java 2009-04-14 18:09:18 UTC (rev 113)
@@ -0,0 +1,84 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.marshall.jboss;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.IdentityHashMap;
+import java.util.List;
+import java.util.Map;
+
+import net.jcip.annotations.Immutable;
+
+import org.infinispan.remoting.transport.jgroups.RequestIgnoredResponse;
+import org.jboss.marshalling.Marshaller;
+import org.jboss.marshalling.ObjectTable;
+import org.jboss.marshalling.Unmarshaller;
+
+/**
+ * CustomObjectTable.
+ *
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+public class CustomObjectTable implements ObjectTable {
+
+ private final List<Object> objects = new ArrayList<Object>();
+ private final Map<Object, Writer> writers = new IdentityHashMap<Object, Writer>();
+ private byte index;
+
+ public void init() {
+ objects.add(RequestIgnoredResponse.INSTANCE);
+ writers.put(RequestIgnoredResponse.INSTANCE, new CustomObjectWriter(index++));
+ }
+
+ public void stop() {
+ writers.clear();
+ objects.clear();
+ }
+
+ public void add(Object o) {
+ objects.add(o);
+ writers.put(o, new CustomObjectWriter(index++));
+ }
+
+ public Writer getObjectWriter(Object o) throws IOException {
+ return writers.get(o);
+ }
+
+ public Object readObject(Unmarshaller unmarshaller) throws IOException, ClassNotFoundException {
+ return objects.get(unmarshaller.readUnsignedByte());
+ }
+
+ @Immutable
+ static class CustomObjectWriter implements Writer {
+ private final byte id;
+
+ CustomObjectWriter(byte objectId) {
+ this.id = objectId;
+ }
+
+ public void writeObject(Marshaller marshaller, Object object) throws IOException {
+ marshaller.write(id);
+ }
+ }
+}
Added: trunk/core/src/main/java/org/infinispan/marshall/jboss/DeltaAwareExternalizer.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/jboss/DeltaAwareExternalizer.java (rev 0)
+++ trunk/core/src/main/java/org/infinispan/marshall/jboss/DeltaAwareExternalizer.java 2009-04-14 18:09:18 UTC (rev 113)
@@ -0,0 +1,60 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.marshall.jboss;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+
+import net.jcip.annotations.Immutable;
+
+import org.infinispan.atomic.DeltaAware;
+import org.jboss.marshalling.Creator;
+import org.jboss.marshalling.Externalizer;
+
+/**
+ * DeltaAwareExternalizer.
+ *
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+ at Immutable
+public class DeltaAwareExternalizer implements Externalizer {
+
+ /** The serialVersionUID */
+ private static final long serialVersionUID = -1635913024455984627L;
+
+ public void writeExternal(Object subject, ObjectOutput output) throws IOException {
+ DeltaAware dw = (DeltaAware) subject;
+ output.writeObject(dw.delta());
+ }
+
+ public Object createExternal(Class<?> subjectType, ObjectInput input, Creator defaultCreator)
+ throws IOException, ClassNotFoundException {
+ return input.readObject();
+ }
+
+ public void readExternal(Object subject, ObjectInput input) throws IOException,
+ ClassNotFoundException {
+ // No-op
+ }
+}
Added: trunk/core/src/main/java/org/infinispan/marshall/jboss/ExtendedResponseExternalizer.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/jboss/ExtendedResponseExternalizer.java (rev 0)
+++ trunk/core/src/main/java/org/infinispan/marshall/jboss/ExtendedResponseExternalizer.java 2009-04-14 18:09:18 UTC (rev 113)
@@ -0,0 +1,62 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.marshall.jboss;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+
+import net.jcip.annotations.Immutable;
+
+import org.infinispan.remoting.transport.jgroups.ExtendedResponse;
+import org.jboss.marshalling.Creator;
+import org.jboss.marshalling.Externalizer;
+
+/**
+ * ExtendedResponseExternalizer.
+ *
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+ at Immutable
+public class ExtendedResponseExternalizer implements Externalizer {
+ /** The serialVersionUID */
+ private static final long serialVersionUID = 1529506931234856884L;
+
+ public void writeExternal(Object subject, ObjectOutput output) throws IOException {
+ ExtendedResponse er = (ExtendedResponse) subject;
+ output.writeBoolean(er.isReplayIgnoredRequests());
+ output.writeObject(er.getResponse());
+ }
+
+ public Object createExternal(Class<?> subjectType, ObjectInput input, Creator defaultCreator)
+ throws IOException, ClassNotFoundException {
+ boolean replayIgnoredRequests = input.readBoolean();
+ Object response = input.readObject();
+ return new ExtendedResponse(response, replayIgnoredRequests);
+ }
+
+ public void readExternal(Object subject, ObjectInput input) throws IOException,
+ ClassNotFoundException {
+ // No-op
+ }
+}
Added: trunk/core/src/main/java/org/infinispan/marshall/jboss/ExternalizerClassFactory.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/jboss/ExternalizerClassFactory.java (rev 0)
+++ trunk/core/src/main/java/org/infinispan/marshall/jboss/ExternalizerClassFactory.java 2009-04-14 18:09:18 UTC (rev 113)
@@ -0,0 +1,121 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.marshall.jboss;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.WeakHashMap;
+
+import net.jcip.annotations.Immutable;
+
+import org.infinispan.CacheException;
+import org.infinispan.remoting.RpcManager;
+import org.infinispan.util.Util;
+import org.jboss.marshalling.ClassExternalizerFactory;
+import org.jboss.marshalling.Externalizer;
+
+/**
+ * CustomExternalizerFactory.
+ *
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+ at Immutable
+public class ExternalizerClassFactory implements ClassExternalizerFactory {
+ private static final Map<String, String> EXTERNALIZERS = new HashMap<String, String>();
+
+ static {
+ EXTERNALIZERS.put("org.infinispan.transaction.GlobalTransaction", "org.infinispan.marshall.jboss.GlobalTransactionExternalizer");
+ EXTERNALIZERS.put("org.infinispan.remoting.transport.jgroups.JGroupsAddress", "org.infinispan.marshall.jboss.JGroupsAddressExternalizer");
+ EXTERNALIZERS.put("java.util.ArrayList", "org.infinispan.marshall.jboss.ArrayListExternalizer");
+ EXTERNALIZERS.put("java.util.LinkedList", "org.infinispan.marshall.jboss.LinkedListExternalizer");
+ EXTERNALIZERS.put("java.util.HashMap", "org.infinispan.marshall.jboss.MapExternalizer");
+ EXTERNALIZERS.put("java.util.TreeMap", "org.infinispan.marshall.jboss.MapExternalizer");
+ EXTERNALIZERS.put("java.util.HashSet", "org.infinispan.marshall.jboss.SetExternalizer");
+ EXTERNALIZERS.put("java.util.TreeSet", "org.infinispan.marshall.jboss.SetExternalizer");
+ EXTERNALIZERS.put("org.infinispan.util.Immutables$ImmutableMapWrapper", "org.infinispan.marshall.jboss.ImmutableMapExternalizer");
+ EXTERNALIZERS.put("org.infinispan.marshall.MarshalledValue", "org.infinispan.marshall.jboss.MarshalledValueExternalizer");
+ EXTERNALIZERS.put("org.infinispan.util.FastCopyHashMap", "org.infinispan.marshall.jboss.MapExternalizer");
+ EXTERNALIZERS.put("java.util.Collections$SingletonList", "org.infinispan.marshall.jboss.SingletonListExternalizer");
+ EXTERNALIZERS.put("org.infinispan.transaction.TransactionLog$LogEntry", "org.infinispan.marshall.jboss.TransactionLogExternalizer");
+ EXTERNALIZERS.put("org.infinispan.remoting.transport.jgroups.ExtendedResponse", "org.infinispan.marshall.jboss.ExtendedResponseExternalizer");
+ EXTERNALIZERS.put("org.infinispan.atomic.AtomicHashMap", "org.infinispan.marshall.jboss.DeltaAwareExternalizer");
+
+ EXTERNALIZERS.put("org.infinispan.commands.control.StateTransferControlCommand", "org.infinispan.marshall.jboss.StateTransferControlCommandExternalizer");
+ EXTERNALIZERS.put("org.infinispan.commands.remote.ClusteredGetCommand", "org.infinispan.marshall.jboss.ReplicableCommandExternalizer");
+ EXTERNALIZERS.put("org.infinispan.commands.remote.MultipleRpcCommand", "org.infinispan.marshall.jboss.ReplicableCommandExternalizer");
+ EXTERNALIZERS.put("org.infinispan.commands.remote.SingleRpcCommand", "org.infinispan.marshall.jboss.ReplicableCommandExternalizer");
+ EXTERNALIZERS.put("org.infinispan.commands.read.GetKeyValueCommand", "org.infinispan.marshall.jboss.ReplicableCommandExternalizer");
+ EXTERNALIZERS.put("org.infinispan.commands.write.PutKeyValueCommand", "org.infinispan.marshall.jboss.ReplicableCommandExternalizer");
+ EXTERNALIZERS.put("org.infinispan.commands.write.RemoveCommand", "org.infinispan.marshall.jboss.ReplicableCommandExternalizer");
+ EXTERNALIZERS.put("org.infinispan.commands.write.InvalidateCommand", "org.infinispan.marshall.jboss.ReplicableCommandExternalizer");
+ EXTERNALIZERS.put("org.infinispan.commands.write.ReplaceCommand", "org.infinispan.marshall.jboss.ReplicableCommandExternalizer");
+ EXTERNALIZERS.put("org.infinispan.commands.write.ClearCommand", "org.infinispan.marshall.jboss.ReplicableCommandExternalizer");
+ EXTERNALIZERS.put("org.infinispan.commands.write.PutMapCommand", "org.infinispan.marshall.jboss.ReplicableCommandExternalizer");
+ EXTERNALIZERS.put("org.infinispan.commands.tx.PrepareCommand", "org.infinispan.marshall.jboss.ReplicableCommandExternalizer");
+ EXTERNALIZERS.put("org.infinispan.commands.tx.CommitCommand", "org.infinispan.marshall.jboss.ReplicableCommandExternalizer");
+ EXTERNALIZERS.put("org.infinispan.commands.tx.RollbackCommand", "org.infinispan.marshall.jboss.ReplicableCommandExternalizer");
+
+ EXTERNALIZERS.put("org.infinispan.container.entries.ImmortalCacheEntry", "org.infinispan.marshall.jboss.InternalCachedEntryExternalizer");
+ EXTERNALIZERS.put("org.infinispan.container.entries.MortalCacheEntry", "org.infinispan.marshall.jboss.InternalCachedEntryExternalizer");
+ EXTERNALIZERS.put("org.infinispan.container.entries.TransientCacheEntry", "org.infinispan.marshall.jboss.InternalCachedEntryExternalizer");
+ EXTERNALIZERS.put("org.infinispan.container.entries.TransientMortalCacheEntry", "org.infinispan.marshall.jboss.InternalCachedEntryExternalizer");
+ }
+
+ private final Map<Class<?>, Externalizer> externalizers = new WeakHashMap<Class<?>, Externalizer>();
+ private final RpcManager rpcManager;
+ private final CustomObjectTable objectTable;
+
+ public ExternalizerClassFactory(RpcManager rpcManager, CustomObjectTable objectTable) {
+ this.rpcManager = rpcManager;
+ this.objectTable = objectTable;
+ }
+
+ public void init() {
+ try {
+ for (Map.Entry<String, String> entry : EXTERNALIZERS.entrySet()) {
+ Class typeClazz = Util.loadClass(entry.getKey());
+ Externalizer ext = (Externalizer) Util.getInstance(entry.getValue());
+ if (ext instanceof StateTransferControlCommandExternalizer) {
+ ((StateTransferControlCommandExternalizer) ext).init(rpcManager);
+ }
+ externalizers.put(typeClazz, ext);
+ objectTable.add(ext);
+ }
+ } catch (IOException e) {
+ throw new CacheException("Unable to open load magicnumbers.properties", e);
+ } catch (ClassNotFoundException e) {
+ throw new CacheException("Unable to load one of the classes defined in the magicnumbers.properties", e);
+ } catch (Exception e) {
+ throw new CacheException("Unable to instantiate Externalizer class", e);
+ }
+ }
+
+ public void stop() {
+ externalizers.clear();
+ }
+
+ public Externalizer getExternalizer(Class<?> clazz) {
+ return externalizers.get(clazz);
+ }
+}
Added: trunk/core/src/main/java/org/infinispan/marshall/jboss/GlobalTransactionExternalizer.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/jboss/GlobalTransactionExternalizer.java (rev 0)
+++ trunk/core/src/main/java/org/infinispan/marshall/jboss/GlobalTransactionExternalizer.java 2009-04-14 18:09:18 UTC (rev 113)
@@ -0,0 +1,66 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.marshall.jboss;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+
+import net.jcip.annotations.Immutable;
+
+import org.infinispan.remoting.transport.Address;
+import org.infinispan.transaction.GlobalTransaction;
+import org.jboss.marshalling.Creator;
+import org.jboss.marshalling.Externalizer;
+
+/**
+ * GlobalTransactionExternalizer.
+ *
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+ at Immutable
+public class GlobalTransactionExternalizer implements Externalizer {
+
+ /** The serialVersionUID */
+ private static final long serialVersionUID = -8677909497367726531L;
+
+ public void writeExternal(Object subject, ObjectOutput output) throws IOException {
+ GlobalTransaction gtx = (GlobalTransaction) subject;
+ output.writeLong(gtx.getId());
+ output.writeObject(gtx.getAddress());
+ }
+
+ public Object createExternal(Class<?> subjectType, ObjectInput input, Creator defaultCreator)
+ throws IOException, ClassNotFoundException {
+ return new GlobalTransaction();
+ }
+
+ public void readExternal(Object subject, ObjectInput input) throws IOException,
+ ClassNotFoundException {
+ GlobalTransaction gtx = (GlobalTransaction) subject;
+ long id = input.readLong();
+ Object address = input.readObject();
+ gtx.setId(id);
+ gtx.setAddress((Address) address);
+ }
+}
Added: trunk/core/src/main/java/org/infinispan/marshall/jboss/ImmutableMapExternalizer.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/jboss/ImmutableMapExternalizer.java (rev 0)
+++ trunk/core/src/main/java/org/infinispan/marshall/jboss/ImmutableMapExternalizer.java 2009-04-14 18:09:18 UTC (rev 113)
@@ -0,0 +1,63 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.marshall.jboss;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.util.HashMap;
+import java.util.Map;
+
+import net.jcip.annotations.Immutable;
+
+import org.infinispan.util.Immutables;
+import org.jboss.marshalling.Creator;
+import org.jboss.marshalling.Externalizer;
+
+/**
+ * ImmutableExternalizer.
+ *
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+ at Immutable
+public class ImmutableMapExternalizer implements Externalizer {
+
+ /** The serialVersionUID */
+ private static final long serialVersionUID = -3592193723750924806L;
+
+ public void writeExternal(Object subject, ObjectOutput output) throws IOException {
+ MarshallUtil.marshallMap((Map)subject, output);
+ }
+
+ public Object createExternal(Class<?> subjectType, ObjectInput input, Creator defaultCreator)
+ throws IOException, ClassNotFoundException {
+ Map map = new HashMap();
+ MarshallUtil.unmarshallMap(map, input);
+ return Immutables.immutableMapWrap(map);
+ }
+
+ public void readExternal(Object subject, ObjectInput input) throws IOException,
+ ClassNotFoundException {
+ // No-op since all the work is done in createExternal in order to be able to change identity.
+ }
+}
Added: trunk/core/src/main/java/org/infinispan/marshall/jboss/InternalCachedEntryExternalizer.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/jboss/InternalCachedEntryExternalizer.java (rev 0)
+++ trunk/core/src/main/java/org/infinispan/marshall/jboss/InternalCachedEntryExternalizer.java 2009-04-14 18:09:18 UTC (rev 113)
@@ -0,0 +1,82 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.marshall.jboss;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+
+import net.jcip.annotations.Immutable;
+
+import org.infinispan.container.entries.InternalCacheEntry;
+import org.infinispan.container.entries.InternalEntryFactory;
+import org.jboss.marshalling.Creator;
+import org.jboss.marshalling.Externalizer;
+
+/**
+ * InternalCachedEntryExternalizer.
+ *
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+ at Immutable
+public class InternalCachedEntryExternalizer implements Externalizer {
+
+ /** The serialVersionUID */
+ private static final long serialVersionUID = -3475239737916428837L;
+
+ public void writeExternal(Object subject, ObjectOutput output) throws IOException {
+ InternalCacheEntry ice = (InternalCacheEntry) subject;
+ output.writeObject(ice.getKey());
+ output.writeObject(ice.getValue());
+ if (ice.canExpire()) {
+ output.writeBoolean(true);
+ MarshallUtil.writeUnsignedLong(output, ice.getCreated());
+ output.writeLong(ice.getLifespan()); // could be negative so should not use unsigned longs
+ MarshallUtil.writeUnsignedLong(output, ice.getLastUsed());
+ output.writeLong(ice.getMaxIdle()); // could be negative so should not use unsigned longs
+ } else {
+ output.writeBoolean(false);
+ }
+ }
+
+ public Object createExternal(Class<?> subjectType, ObjectInput input, Creator defaultCreator)
+ throws IOException, ClassNotFoundException {
+ Object k = input.readObject();
+ Object v = input.readObject();
+ boolean canExpire = input.readBoolean();
+ if (canExpire) {
+ long created = MarshallUtil.readUnsignedLong(input);
+ long lifespan = input.readLong(); // could be negative so should not use unsigned longs
+ long lastUsed = MarshallUtil.readUnsignedLong(input);
+ long maxIdle = input.readLong(); // could be negative so should not use unsigned longs
+ return InternalEntryFactory.create(k, v, created, lifespan, lastUsed, maxIdle);
+ } else {
+ return InternalEntryFactory.create(k, v);
+ }
+ }
+
+ public void readExternal(Object subject, ObjectInput input) throws IOException,
+ ClassNotFoundException {
+ // No-op
+ }
+}
Added: trunk/core/src/main/java/org/infinispan/marshall/jboss/JBossMarshaller.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/jboss/JBossMarshaller.java (rev 0)
+++ trunk/core/src/main/java/org/infinispan/marshall/jboss/JBossMarshaller.java 2009-04-14 18:09:18 UTC (rev 113)
@@ -0,0 +1,206 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.marshall.jboss;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.io.OutputStream;
+
+import org.infinispan.CacheException;
+import org.infinispan.factories.annotations.Inject;
+import org.infinispan.factories.annotations.Stop;
+import org.infinispan.factories.scopes.Scope;
+import org.infinispan.factories.scopes.Scopes;
+import org.infinispan.io.ByteBuffer;
+import org.infinispan.io.ExposedByteArrayOutputStream;
+import org.infinispan.logging.Log;
+import org.infinispan.logging.LogFactory;
+import org.infinispan.marshall.Marshaller;
+import org.infinispan.remoting.RpcManager;
+import org.infinispan.util.Util;
+import org.jboss.marshalling.ContextClassResolver;
+import org.jboss.marshalling.MarshallerFactory;
+import org.jboss.marshalling.Marshalling;
+import org.jboss.marshalling.MarshallingConfiguration;
+import org.jboss.marshalling.Unmarshaller;
+import org.jboss.marshalling.reflect.SunReflectiveCreator;
+
+/**
+ * JBossMarshaller.
+ *
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+ at Scope(Scopes.GLOBAL)
+public class JBossMarshaller implements Marshaller {
+ private static final Log log = LogFactory.getLog(JBossMarshaller.class);
+ private static final String DEFAULT_MARSHALLER_FACTORY = "org.jboss.marshalling.river.RiverMarshallerFactory";
+// private static final int VERSION_400 = 400;
+// private static final int DEFAULT_VERSION = VERSION_400;
+ private ClassLoader defaultClassLoader;
+ private MarshallingConfiguration configuration;
+ private MarshallerFactory factory;
+ private MagicNumberClassTable classTable;
+ private CustomObjectTable objectTable;
+ private ExternalizerClassFactory externalizerFactoryAndObjectTable;
+/// private boolean trace;
+
+ @Inject
+ public void init(ClassLoader defaultCl, RpcManager rpcManager) {
+ log.debug("Using JBoss Marshalling based marshaller.");
+
+// trace = log.isTraceEnabled();
+ defaultClassLoader = defaultCl;
+
+ try {
+ // Todo: Enable different marshaller factories via configuration
+ factory = (MarshallerFactory)Util.getInstance(DEFAULT_MARSHALLER_FACTORY);
+ } catch(Exception e) {
+ throw new CacheException("Unable to load JBoss Marshalling marshaller factory " + DEFAULT_MARSHALLER_FACTORY, e);
+ }
+
+ classTable = createMagicNumberClassTable();
+ objectTable = createCustomObjectTable();
+ externalizerFactoryAndObjectTable = createCustomExternalizerFactory(rpcManager, objectTable);
+
+ configuration = new MarshallingConfiguration();
+ configuration.setCreator(new SunReflectiveCreator());
+ configuration.setClassTable(classTable);
+ configuration.setClassExternalizerFactory(externalizerFactoryAndObjectTable);
+ configuration.setObjectTable(objectTable);
+
+ // ContextClassResolver provides same functionality as MarshalledValueInputStream
+ configuration.setClassResolver(new ContextClassResolver());
+// // Todo: This is the JBMAR underlying protocol version, don't touch! Think about how to get VAM into JBMAR
+// configuration.setVersion(DEFAULT_VERSION);
+ }
+
+ @Stop
+ public void stop() {
+ // Do not leak classloader when cache is stopped.
+ defaultClassLoader = null;
+ classTable.stop();
+ objectTable.stop();
+ externalizerFactoryAndObjectTable.stop();
+ }
+
+ public byte[] objectToByteBuffer(Object obj) throws IOException {
+ ByteBuffer b = objectToBuffer(obj);
+ byte[] bytes = new byte[b.getLength()];
+ System.arraycopy(b.getBuf(), b.getOffset(), bytes, 0, b.getLength());
+ return bytes;
+ }
+
+ public ByteBuffer objectToBuffer(Object o) throws IOException {
+ ExposedByteArrayOutputStream baos = new ExposedByteArrayOutputStream(128);
+ ObjectOutput marshaller = startObjectOutput(baos);
+ objectToObjectStream(o, marshaller);
+ finishObjectOutput(marshaller);
+ return new ByteBuffer(baos.getRawBuffer(), 0, baos.size());
+ }
+
+ public ObjectOutput startObjectOutput(OutputStream os) throws IOException {
+ org.jboss.marshalling.Marshaller marshaller = factory.createMarshaller(configuration);
+ marshaller.start(Marshalling.createByteOutput(os));
+ return marshaller;
+ }
+
+ public void finishObjectOutput(ObjectOutput oo) {
+ try {
+ ((org.jboss.marshalling.Marshaller) oo).finish();
+ } catch (IOException ioe) {
+ }
+ }
+
+ public void objectToObjectStream(Object obj, ObjectOutput out) throws IOException {
+ ClassLoader toUse = defaultClassLoader;
+ Thread current = Thread.currentThread();
+ ClassLoader old = current.getContextClassLoader();
+ if (old != null) toUse = old;
+
+ try {
+ current.setContextClassLoader(toUse);
+ out.writeObject(obj);
+ }
+ finally {
+ current.setContextClassLoader(old);
+ }
+ }
+
+ public Object objectFromByteBuffer(byte[] buf) throws IOException, ClassNotFoundException {
+ return objectFromByteBuffer(buf, 0, buf.length);
+ }
+
+ public Object objectFromByteBuffer(byte[] buf, int offset, int length) throws IOException,
+ ClassNotFoundException {
+ ByteArrayInputStream is = new ByteArrayInputStream(buf, offset, length);
+ ObjectInput unmarshaller = startObjectInput(is);
+ Object o = objectFromObjectStream(unmarshaller);
+ finishObjectInput(unmarshaller);
+ return o;
+ }
+
+ public ObjectInput startObjectInput(InputStream is) throws IOException {
+ Unmarshaller unmarshaller = factory.createUnmarshaller(configuration);
+ unmarshaller.start(Marshalling.createByteInput(is));
+ return unmarshaller;
+ }
+
+ public void finishObjectInput(ObjectInput oi) {
+ try {
+ ((Unmarshaller) oi).finish();
+ } catch (IOException e) {
+ }
+ }
+
+ public Object objectFromObjectStream(ObjectInput in) throws IOException, ClassNotFoundException {
+ return in.readObject();
+ }
+
+ public Object objectFromStream(InputStream is) throws IOException, ClassNotFoundException {
+ ObjectInput unmarshaller = startObjectInput(is);
+ Object o = objectFromObjectStream(unmarshaller);
+ finishObjectInput(unmarshaller);
+ return o;
+ }
+
+ protected MagicNumberClassTable createMagicNumberClassTable() {
+ MagicNumberClassTable classTable = new MagicNumberClassTable();
+ classTable.init();
+ return classTable;
+ }
+
+ protected ExternalizerClassFactory createCustomExternalizerFactory(RpcManager rpcManager, CustomObjectTable objectTable) {
+ ExternalizerClassFactory externalizerFactory = new ExternalizerClassFactory(rpcManager, objectTable);
+ externalizerFactory.init();
+ return externalizerFactory;
+ }
+
+ private CustomObjectTable createCustomObjectTable() {
+ CustomObjectTable objectTable = new CustomObjectTable();
+ objectTable.init();
+ return objectTable;
+ }
+}
Added: trunk/core/src/main/java/org/infinispan/marshall/jboss/JGroupsAddressExternalizer.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/jboss/JGroupsAddressExternalizer.java (rev 0)
+++ trunk/core/src/main/java/org/infinispan/marshall/jboss/JGroupsAddressExternalizer.java 2009-04-14 18:09:18 UTC (rev 113)
@@ -0,0 +1,61 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.marshall.jboss;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+
+import net.jcip.annotations.Immutable;
+
+import org.infinispan.remoting.transport.jgroups.JGroupsAddress;
+import org.jboss.marshalling.Creator;
+import org.jboss.marshalling.Externalizer;
+
+/**
+ * JGroupsAddressExternalizer.
+ *
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+ at Immutable
+public class JGroupsAddressExternalizer implements Externalizer {
+
+ /** The serialVersionUID */
+ private static final long serialVersionUID = 2400716389425727329L;
+
+ public void writeExternal(Object subject, ObjectOutput output) throws IOException {
+ JGroupsAddress address = (JGroupsAddress) subject;
+ address.writeExternal(output);
+ }
+
+ public Object createExternal(Class<?> subjectType, ObjectInput input, Creator defaultCreator)
+ throws IOException, ClassNotFoundException {
+ return new JGroupsAddress();
+ }
+
+ public void readExternal(Object subject, ObjectInput input) throws IOException,
+ ClassNotFoundException {
+ JGroupsAddress address = (JGroupsAddress) subject;
+ address.readExternal(input);
+ }
+}
Added: trunk/core/src/main/java/org/infinispan/marshall/jboss/LinkedListExternalizer.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/jboss/LinkedListExternalizer.java (rev 0)
+++ trunk/core/src/main/java/org/infinispan/marshall/jboss/LinkedListExternalizer.java 2009-04-14 18:09:18 UTC (rev 113)
@@ -0,0 +1,65 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.marshall.jboss;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.util.Collection;
+import java.util.LinkedList;
+
+import net.jcip.annotations.Immutable;
+
+import org.jboss.marshalling.Creator;
+import org.jboss.marshalling.Externalizer;
+
+/**
+ * LinkedListExternalizer.
+ *
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+ at Immutable
+public class LinkedListExternalizer implements Externalizer {
+
+ /** The serialVersionUID */
+ private static final long serialVersionUID = -3222803557498456230L;
+
+ public void writeExternal(Object subject, ObjectOutput output) throws IOException {
+ MarshallUtil.marshallCollection((Collection) subject, output);
+ }
+
+ public Object createExternal(Class<?> subjectType, ObjectInput input, Creator defaultCreator)
+ throws IOException, ClassNotFoundException {
+ int size = MarshallUtil.readUnsignedInt(input);
+ LinkedList l = new LinkedList();
+ for (int i = 0; i < size; i++) l.add(input.readObject());
+ return l;
+ }
+
+ public void readExternal(Object subject, ObjectInput input) throws IOException,
+ ClassNotFoundException {
+ // No-op since size was needed both for the creation and list population,
+ // so work was done in createExternal
+ }
+
+}
Added: trunk/core/src/main/java/org/infinispan/marshall/jboss/MagicNumberClassTable.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/jboss/MagicNumberClassTable.java (rev 0)
+++ trunk/core/src/main/java/org/infinispan/marshall/jboss/MagicNumberClassTable.java 2009-04-14 18:09:18 UTC (rev 113)
@@ -0,0 +1,132 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.marshall.jboss;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.WeakHashMap;
+
+import net.jcip.annotations.Immutable;
+
+import org.infinispan.CacheException;
+import org.infinispan.util.Util;
+import org.jboss.marshalling.ClassTable;
+import org.jboss.marshalling.Marshaller;
+import org.jboss.marshalling.Unmarshaller;
+
+/**
+ * MagicNumberClassTable.
+ *
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+ at Immutable
+public class MagicNumberClassTable implements ClassTable {
+ private static final Map<String, Integer> MAGIC_NUMBERS = new WeakHashMap<String, Integer>();
+
+ static {
+ MAGIC_NUMBERS.put("org.infinispan.transaction.GlobalTransaction", 1);
+ MAGIC_NUMBERS.put("org.infinispan.remoting.transport.jgroups.JGroupsAddress", 2);
+ MAGIC_NUMBERS.put("java.util.ArrayList", 3);
+ MAGIC_NUMBERS.put("java.util.LinkedList", 8);
+ MAGIC_NUMBERS.put("java.util.HashMap", 9);
+ MAGIC_NUMBERS.put("java.util.TreeMap", 10);
+ MAGIC_NUMBERS.put("java.util.HashSet", 11);
+ MAGIC_NUMBERS.put("java.util.TreeSet", 12);
+ MAGIC_NUMBERS.put("org.infinispan.util.Immutables$ImmutableMapWrapper", 14);
+ MAGIC_NUMBERS.put("org.infinispan.marshall.MarshalledValue", 15);
+ MAGIC_NUMBERS.put("org.infinispan.util.FastCopyHashMap", 16);
+ MAGIC_NUMBERS.put("java.util.Collections$SingletonList", 23);
+ MAGIC_NUMBERS.put("org.infinispan.transaction.TransactionLog$LogEntry", 25);
+ MAGIC_NUMBERS.put("org.infinispan.remoting.transport.jgroups.ExtendedResponse", 28);
+ MAGIC_NUMBERS.put("org.infinispan.atomic.AtomicHashMap", 29);
+
+ MAGIC_NUMBERS.put("org.infinispan.commands.control.StateTransferControlCommand", 30);
+ MAGIC_NUMBERS.put("org.infinispan.commands.remote.ClusteredGetCommand", 31);
+ MAGIC_NUMBERS.put("org.infinispan.commands.remote.MultipleRpcCommand", 32);
+ MAGIC_NUMBERS.put("org.infinispan.commands.remote.SingleRpcCommand", 33);
+ MAGIC_NUMBERS.put("org.infinispan.commands.read.GetKeyValueCommand", 34);
+ MAGIC_NUMBERS.put("org.infinispan.commands.write.PutKeyValueCommand", 35);
+ MAGIC_NUMBERS.put("org.infinispan.commands.write.RemoveCommand", 36);
+ MAGIC_NUMBERS.put("org.infinispan.commands.write.InvalidateCommand", 38);
+ MAGIC_NUMBERS.put("org.infinispan.commands.write.ReplaceCommand", 39);
+ MAGIC_NUMBERS.put("org.infinispan.commands.write.ClearCommand", 40);
+ MAGIC_NUMBERS.put("org.infinispan.commands.write.PutMapCommand", 41);
+ MAGIC_NUMBERS.put("org.infinispan.commands.tx.PrepareCommand", 42);
+ MAGIC_NUMBERS.put("org.infinispan.commands.tx.CommitCommand", 43);
+ MAGIC_NUMBERS.put("org.infinispan.commands.tx.RollbackCommand", 44);
+
+ MAGIC_NUMBERS.put("org.infinispan.container.entries.ImmortalCacheEntry", 45);
+ MAGIC_NUMBERS.put("org.infinispan.container.entries.MortalCacheEntry", 46);
+ MAGIC_NUMBERS.put("org.infinispan.container.entries.TransientCacheEntry", 47);
+ MAGIC_NUMBERS.put("org.infinispan.container.entries.TransientMortalCacheEntry", 48);
+ }
+
+ private final Map<Class<?>, Writer> writers = new WeakHashMap<Class<?>, Writer>();
+ private final Map<Byte, Class<?>> classes = new HashMap<Byte, Class<?>>();
+
+ public void init() {
+ try {
+ for (Map.Entry<String, Integer> entry : MAGIC_NUMBERS.entrySet()) {
+ Class clazz = Util.loadClass(entry.getKey());
+ Byte magicNumber = entry.getValue().byteValue();
+ Writer writer = createWriter(magicNumber);
+ writers.put(clazz, writer);
+ classes.put(magicNumber, clazz);
+ }
+ } catch (ClassNotFoundException e) {
+ throw new CacheException("Unable to load one of the classes defined in the magicnumbers.properties", e);
+ }
+ }
+
+ public void stop() {
+ writers.clear();
+ classes.clear();
+ }
+
+ public Writer getClassWriter(Class<?> clazz) throws IOException {
+ return writers.get(clazz);
+ }
+
+ public Class<?> readClass(Unmarshaller unmarshaller) throws IOException, ClassNotFoundException {
+ byte magicNumber = unmarshaller.readByte();
+ return classes.get(magicNumber);
+ }
+
+ protected Writer createWriter(byte magicNumber) {
+ return new MagicNumberWriter(magicNumber);
+ }
+
+ @Immutable
+ static class MagicNumberWriter implements Writer {
+ private final byte magicNumber;
+
+ MagicNumberWriter(byte magicNumber) {
+ this.magicNumber = magicNumber;
+ }
+
+ public void writeClass(Marshaller marshaller, Class<?> clazz) throws IOException {
+ marshaller.writeByte(magicNumber);
+ }
+ }
+}
Added: trunk/core/src/main/java/org/infinispan/marshall/jboss/MapExternalizer.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/jboss/MapExternalizer.java (rev 0)
+++ trunk/core/src/main/java/org/infinispan/marshall/jboss/MapExternalizer.java 2009-04-14 18:09:18 UTC (rev 113)
@@ -0,0 +1,66 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.marshall.jboss;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.util.Map;
+
+import net.jcip.annotations.Immutable;
+
+import org.infinispan.CacheException;
+import org.infinispan.util.Util;
+import org.jboss.marshalling.Creator;
+import org.jboss.marshalling.Externalizer;
+
+/**
+ * Map externalizer for all map implementations except immutable maps and singleton maps,
+ * i.e. FastCopyHashMap, HashMap, TreeMap.
+ *
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+ at Immutable
+public class MapExternalizer implements Externalizer {
+
+ /** The serialVersionUID */
+ private static final long serialVersionUID = -532896252671303391L;
+
+ public void writeExternal(Object subject, ObjectOutput output) throws IOException {
+ MarshallUtil.marshallMap((Map) subject, output);
+ }
+
+ public Object createExternal(Class<?> subjectType, ObjectInput input, Creator defaultCreator)
+ throws IOException, ClassNotFoundException {
+ try {
+ return Util.getInstance(subjectType);
+ } catch(Exception e) {
+ throw new CacheException("Unable to create new instance of ReplicableCommand", e);
+ }
+ }
+
+ public void readExternal(Object subject, ObjectInput input) throws IOException,
+ ClassNotFoundException {
+ MarshallUtil.unmarshallMap((Map) subject, input);
+ }
+}
Added: trunk/core/src/main/java/org/infinispan/marshall/jboss/MarshallUtil.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/jboss/MarshallUtil.java (rev 0)
+++ trunk/core/src/main/java/org/infinispan/marshall/jboss/MarshallUtil.java 2009-04-14 18:09:18 UTC (rev 113)
@@ -0,0 +1,120 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.marshall.jboss;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+
+import net.jcip.annotations.Immutable;
+
+/**
+ * MarshallUtil.
+ *
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+ at Immutable
+public class MarshallUtil {
+
+ /**
+ * Writes an int in a variable-length format. Writes between one and five bytes. Smaller values take fewer bytes.
+ * Negative numbers are not supported.
+ *
+ * @param i int to write
+ */
+ protected static void writeUnsignedInt(ObjectOutput out, int i) throws IOException {
+ while ((i & ~0x7F) != 0) {
+ out.writeByte((byte) ((i & 0x7f) | 0x80));
+ i >>>= 7;
+ }
+ out.writeByte((byte) i);
+ }
+
+ /**
+ * Reads an int stored in variable-length format. Reads between one and five bytes. Smaller values take fewer
+ * bytes. Negative numbers are not supported.
+ */
+ protected static int readUnsignedInt(ObjectInput in) throws IOException {
+ byte b = in.readByte();
+ int i = b & 0x7F;
+ for (int shift = 7; (b & 0x80) != 0; shift += 7) {
+ b = in.readByte();
+ i |= (b & 0x7FL) << shift;
+ }
+ return i;
+ }
+
+ protected static void marshallCollection(Collection c, ObjectOutput out) throws IOException {
+ writeUnsignedInt(out, c.size());
+ for (Object o : c) {
+ out.writeObject(o);
+ }
+ }
+
+ protected static void marshallMap(Map map, ObjectOutput out) throws IOException {
+ int mapSize = map.size();
+ writeUnsignedInt(out, mapSize);
+ if (mapSize == 0) return;
+
+ for (Map.Entry me : (Set<Map.Entry>) map.entrySet()) {
+ out.writeObject(me.getKey());
+ out.writeObject(me.getValue());
+ }
+ }
+
+ protected static void unmarshallMap(Map map, ObjectInput in) throws IOException, ClassNotFoundException{
+ int size = MarshallUtil.readUnsignedInt(in);
+ for (int i = 0; i < size; i++) map.put(in.readObject(), in.readObject());
+ }
+
+ /**
+ * Writes a long in a variable-length format. Writes between one and nine bytes. Smaller values take fewer bytes.
+ * Negative numbers are not supported.
+ *
+ * @param i int to write
+ */
+ protected static void writeUnsignedLong(ObjectOutput out, long i) throws IOException {
+ while ((i & ~0x7F) != 0) {
+ out.writeByte((byte) ((i & 0x7f) | 0x80));
+ i >>>= 7;
+ }
+ out.writeByte((byte) i);
+ }
+
+ /**
+ * Reads a long stored in variable-length format. Reads between one and nine bytes. Smaller values take fewer
+ * bytes. Negative numbers are not supported.
+ */
+ protected static long readUnsignedLong(ObjectInput in) throws IOException {
+ byte b = in.readByte();
+ long i = b & 0x7F;
+ for (int shift = 7; (b & 0x80) != 0; shift += 7) {
+ b = in.readByte();
+ i |= (b & 0x7FL) << shift;
+ }
+ return i;
+ }
+}
Added: trunk/core/src/main/java/org/infinispan/marshall/jboss/MarshalledValueExternalizer.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/jboss/MarshalledValueExternalizer.java (rev 0)
+++ trunk/core/src/main/java/org/infinispan/marshall/jboss/MarshalledValueExternalizer.java 2009-04-14 18:09:18 UTC (rev 113)
@@ -0,0 +1,60 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.marshall.jboss;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+
+import net.jcip.annotations.Immutable;
+
+import org.infinispan.marshall.MarshalledValue;
+import org.jboss.marshalling.Creator;
+import org.jboss.marshalling.Externalizer;
+
+/**
+ * MarshalledValueExternalizer.
+ *
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+ at Immutable
+public class MarshalledValueExternalizer implements Externalizer {
+
+ /** The serialVersionUID */
+ private static final long serialVersionUID = 8473423584918714661L;
+
+ public void writeExternal(Object subject, ObjectOutput output) throws IOException {
+ ((MarshalledValue) subject).writeExternal(output);
+ }
+
+ public Object createExternal(Class<?> subjectType, ObjectInput input, Creator defaultCreator)
+ throws IOException, ClassNotFoundException {
+ return new MarshalledValue();
+ }
+
+ public void readExternal(Object subject, ObjectInput input) throws IOException,
+ ClassNotFoundException {
+ ((MarshalledValue) subject).readExternal(input);
+ }
+
+}
Added: trunk/core/src/main/java/org/infinispan/marshall/jboss/ReplicableCommandExternalizer.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/jboss/ReplicableCommandExternalizer.java (rev 0)
+++ trunk/core/src/main/java/org/infinispan/marshall/jboss/ReplicableCommandExternalizer.java 2009-04-14 18:09:18 UTC (rev 113)
@@ -0,0 +1,85 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.marshall.jboss;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+
+import net.jcip.annotations.Immutable;
+
+import org.infinispan.CacheException;
+import org.infinispan.commands.ReplicableCommand;
+import org.infinispan.util.Util;
+import org.jboss.marshalling.Creator;
+import org.jboss.marshalling.Externalizer;
+
+/**
+ * ReplicableCommandExternalizer.
+ *
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+ at Immutable
+public class ReplicableCommandExternalizer implements Externalizer {
+
+ /** The serialVersionUID */
+ private static final long serialVersionUID = 6915200269446867084L;
+
+ public void writeExternal(Object subject, ObjectOutput output) throws IOException {
+ ReplicableCommand command = (ReplicableCommand) subject;
+ output.writeShort(command.getCommandId());
+ Object[] args = command.getParameters();
+ byte numArgs = (byte) (args == null ? 0 : args.length);
+ output.writeByte(numArgs);
+ for (int i = 0; i < numArgs; i++) {
+ output.writeObject(args[i]);
+ }
+ }
+
+ /**
+ * In this case, subjectType will contain the class name of the ReplicableCommand subclass to
+ * create. Note that StateTransferControlCommand might need to be treated differently!!!
+ */
+ public Object createExternal(Class<?> subjectType, ObjectInput input, Creator defaultCreator)
+ throws IOException, ClassNotFoundException {
+ try {
+ ReplicableCommand command = (ReplicableCommand) Util.getInstance(subjectType);
+ return command;
+ } catch(Exception e) {
+ throw new CacheException("Unable to create new instance of ReplicableCommand", e);
+ }
+ }
+
+ public void readExternal(Object subject, ObjectInput input) throws IOException,
+ ClassNotFoundException {
+ ReplicableCommand command = (ReplicableCommand) subject;
+ short methodId = input.readShort();
+ byte numArgs = input.readByte();
+ Object[] args = null;
+ if (numArgs > 0) {
+ args = new Object[numArgs];
+ for (int i = 0; i < numArgs; i++) args[i] = input.readObject();
+ }
+ command.setParameters(methodId, args);
+ }
+}
\ No newline at end of file
Added: trunk/core/src/main/java/org/infinispan/marshall/jboss/SetExternalizer.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/jboss/SetExternalizer.java (rev 0)
+++ trunk/core/src/main/java/org/infinispan/marshall/jboss/SetExternalizer.java 2009-04-14 18:09:18 UTC (rev 113)
@@ -0,0 +1,68 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.marshall.jboss;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.util.Collection;
+import java.util.Set;
+
+import net.jcip.annotations.Immutable;
+
+import org.infinispan.CacheException;
+import org.infinispan.util.Util;
+import org.jboss.marshalling.Creator;
+import org.jboss.marshalling.Externalizer;
+
+/**
+ * Set externalizer for all set implementations, i.e. HashSet and TreeSet
+ *
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+ at Immutable
+public class SetExternalizer implements Externalizer {
+
+ /** The serialVersionUID */
+ private static final long serialVersionUID = -3147427397000304867L;
+
+ public void writeExternal(Object subject, ObjectOutput output) throws IOException {
+ MarshallUtil.marshallCollection((Collection) subject, output);
+ }
+
+ public Object createExternal(Class<?> subjectType, ObjectInput input, Creator defaultCreator)
+ throws IOException, ClassNotFoundException {
+ try {
+ return Util.getInstance(subjectType);
+ } catch(Exception e) {
+ throw new CacheException("Unable to create new instance of ReplicableCommand", e);
+ }
+ }
+
+ public void readExternal(Object subject, ObjectInput input) throws IOException,
+ ClassNotFoundException {
+ Set set = (Set) subject;
+ int size = MarshallUtil.readUnsignedInt(input);
+ for (int i = 0; i < size; i++) set.add(input.readObject());
+ }
+}
\ No newline at end of file
Added: trunk/core/src/main/java/org/infinispan/marshall/jboss/SingletonListExternalizer.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/jboss/SingletonListExternalizer.java (rev 0)
+++ trunk/core/src/main/java/org/infinispan/marshall/jboss/SingletonListExternalizer.java 2009-04-14 18:09:18 UTC (rev 113)
@@ -0,0 +1,61 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.marshall.jboss;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.util.Collections;
+import java.util.List;
+
+import net.jcip.annotations.Immutable;
+
+import org.jboss.marshalling.Creator;
+import org.jboss.marshalling.Externalizer;
+
+/**
+ * SingletonListExternalizer.
+ *
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+ at Immutable
+public class SingletonListExternalizer implements Externalizer {
+
+ /** The serialVersionUID */
+ private static final long serialVersionUID = -714785461531351642L;
+
+ public void writeExternal(Object subject, ObjectOutput output) throws IOException {
+ output.writeObject(((List) subject).get(0));
+ }
+
+ public Object createExternal(Class<?> subjectType, ObjectInput input, Creator defaultCreator)
+ throws IOException, ClassNotFoundException {
+ return Collections.singletonList(input.readObject());
+ }
+
+ public void readExternal(Object subject, ObjectInput input) throws IOException,
+ ClassNotFoundException {
+ // No-op since all the work is done during create.
+ }
+
+}
Added: trunk/core/src/main/java/org/infinispan/marshall/jboss/StateTransferControlCommandExternalizer.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/jboss/StateTransferControlCommandExternalizer.java (rev 0)
+++ trunk/core/src/main/java/org/infinispan/marshall/jboss/StateTransferControlCommandExternalizer.java 2009-04-14 18:09:18 UTC (rev 113)
@@ -0,0 +1,61 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.marshall.jboss;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+
+import org.infinispan.commands.control.StateTransferControlCommand;
+import org.infinispan.remoting.RpcManager;
+import org.jboss.marshalling.Creator;
+
+/**
+ * StateTransferControlCommandExternalizer.
+ *
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+public class StateTransferControlCommandExternalizer extends ReplicableCommandExternalizer {
+
+ /** The serialVersionUID */
+ private static final long serialVersionUID = -3743458410265076691L;
+
+ private RpcManager rpcManager;
+
+ public void init(RpcManager rpcManager) {
+ this.rpcManager = rpcManager;
+ }
+
+ /**
+ * In this case, subjectType will contain the class name of the ReplicableCommand subclass to
+ * create.
+ *
+ * Note that StateTransferControlCommand might need to be treated differently!!!
+ * Todo: check outcome of email sent to dev list.
+ */
+ public Object createExternal(Class<?> subjectType, ObjectInput input, Creator defaultCreator)
+ throws IOException, ClassNotFoundException {
+ StateTransferControlCommand command = new StateTransferControlCommand();
+ command.init(rpcManager);
+ return command;
+ }
+}
\ No newline at end of file
Added: trunk/core/src/main/java/org/infinispan/marshall/jboss/TransactionLogExternalizer.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/jboss/TransactionLogExternalizer.java (rev 0)
+++ trunk/core/src/main/java/org/infinispan/marshall/jboss/TransactionLogExternalizer.java 2009-04-14 18:09:18 UTC (rev 113)
@@ -0,0 +1,70 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.marshall.jboss;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+
+import net.jcip.annotations.Immutable;
+
+import org.infinispan.commands.write.WriteCommand;
+import org.infinispan.transaction.GlobalTransaction;
+import org.infinispan.transaction.TransactionLog;
+import org.jboss.marshalling.Creator;
+import org.jboss.marshalling.Externalizer;
+
+/**
+ * TransactionLogExternalizer.
+ *
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+ at Immutable
+public class TransactionLogExternalizer implements Externalizer {
+
+ /** The serialVersionUID */
+ private static final long serialVersionUID = -7341096933735222157L;
+
+ public void writeExternal(Object subject, ObjectOutput output) throws IOException {
+ TransactionLog.LogEntry le = (TransactionLog.LogEntry) subject;
+ output.writeObject(le.getTransaction());
+ WriteCommand[] cmds = le.getModifications();
+ MarshallUtil.writeUnsignedInt(output, cmds.length);
+ for (WriteCommand c : cmds)
+ output.writeObject(c);
+ }
+
+ public Object createExternal(Class<?> subjectType, ObjectInput input, Creator defaultCreator)
+ throws IOException, ClassNotFoundException {
+ GlobalTransaction gtx = (GlobalTransaction) input.readObject();
+ int numCommands = MarshallUtil.readUnsignedInt(input);
+ WriteCommand[] cmds = new WriteCommand[numCommands];
+ for (int i = 0; i < numCommands; i++) cmds[i] = (WriteCommand) input.readObject();
+ return new TransactionLog.LogEntry(gtx, cmds);
+ }
+
+ public void readExternal(Object subject, ObjectInput input) throws IOException,
+ ClassNotFoundException {
+ // No-op since the initialisation the creation and read happens during the create phase.
+ }
+}
Modified: trunk/core/src/main/java/org/infinispan/statetransfer/StateTransferManagerImpl.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/statetransfer/StateTransferManagerImpl.java 2009-04-14 17:00:56 UTC (rev 112)
+++ trunk/core/src/main/java/org/infinispan/statetransfer/StateTransferManagerImpl.java 2009-04-14 18:09:18 UTC (rev 113)
@@ -52,7 +52,9 @@
import java.io.IOException;
import java.io.InputStream;
+import java.io.ObjectInput;
import java.io.ObjectInputStream;
+import java.io.ObjectOutput;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.util.Arrays;
@@ -130,22 +132,22 @@
}
public void generateState(OutputStream out) throws StateTransferException {
- ObjectOutputStream oos = null;
+ ObjectOutput oo = null;
boolean txLogActivated = false;
try {
boolean canProvideState = (transientState || persistentState)
&& (txLogActivated = transactionLog.activate());
if (log.isDebugEnabled()) log.debug("Generating state. Can provide? {0}", canProvideState);
- oos = new ObjectOutputStream(out);
- marshaller.objectToObjectStream(canProvideState, oos);
+ oo = marshaller.startObjectOutput(out);
+ marshaller.objectToObjectStream(canProvideState, oo);
if (canProvideState) {
- delimit(oos);
- if (transientState) generateInMemoryState(oos);
- delimit(oos);
- if (persistentState) generatePersistentState(oos);
- delimit(oos);
- generateTransactionLog(oos);
+ delimit(oo);
+ if (transientState) generateInMemoryState(oo);
+ delimit(oo);
+ if (persistentState) generatePersistentState(oo);
+ delimit(oo);
+ generateTransactionLog(oo);
if (log.isDebugEnabled()) log.debug("State generated, closing object stream");
} else {
@@ -157,12 +159,12 @@
} catch (Exception e) {
throw new StateTransferException(e);
} finally {
- Util.flushAndCloseStream(oos);
+ marshaller.finishObjectOutput(oo);
if (txLogActivated) transactionLog.deactivate();
}
}
- private void generateTransactionLog(ObjectOutputStream oos) throws Exception {
+ private void generateTransactionLog(ObjectOutput oo) throws Exception {
// todo this should be configurable
int maxNonProgressingLogWrites = 100;
int flushTimeout = 60000;
@@ -173,7 +175,7 @@
if (trace) log.trace("Transaction log size is {0}", transactionLog.size());
for (int nonProgress = 0, size = transactionLog.size(); size > 0;) {
if (trace) log.trace("Tx Log remaining entries = " + size);
- transactionLog.writeCommitLog(marshaller, oos);
+ transactionLog.writeCommitLog(marshaller, oo);
int newSize = transactionLog.size();
// If size did not decrease then we did not make progress, and could be wasting
@@ -190,29 +192,29 @@
// Signal to sender that we need a flush to get a consistent view
// of the remaining transactions.
- delimit(oos);
- oos.flush();
+ delimit(oo);
+ oo.flush();
if (trace) log.trace("Waiting for a distributed sync block");
distributedSync.blockUntilAcquired(flushTimeout, MILLISECONDS);
if (trace) log.trace("Distributed sync block received, proceeding with writing commit log");
// Write remaining transactions
- transactionLog.writeCommitLog(marshaller, oos);
- delimit(oos);
+ transactionLog.writeCommitLog(marshaller, oo);
+ delimit(oo);
// Write all non-completed prepares
- transactionLog.writePendingPrepares(marshaller, oos);
- delimit(oos);
- oos.flush();
+ transactionLog.writePendingPrepares(marshaller, oo);
+ delimit(oo);
+ oo.flush();
}
finally {
distributedSync.releaseProcessingLock();
}
}
- private void processCommitLog(ObjectInputStream ois) throws Exception {
+ private void processCommitLog(ObjectInput oi) throws Exception {
if (trace) log.trace("Applying commit log");
- Object object = marshaller.objectFromObjectStream(ois);
+ Object object = marshaller.objectFromObjectStream(oi);
while (object instanceof TransactionLog.LogEntry) {
WriteCommand[] mods = ((TransactionLog.LogEntry) object).getModifications();
if (trace) log.trace("Mods = {0}", Arrays.toString(mods));
@@ -224,17 +226,17 @@
interceptorChain.invoke(ctx, mod);
}
- object = marshaller.objectFromObjectStream(ois);
+ object = marshaller.objectFromObjectStream(oi);
}
assertDelimited(object);
if (trace) log.trace("Finished applying commit log");
}
- private void applyTransactionLog(ObjectInputStream ois) throws Exception {
+ private void applyTransactionLog(ObjectInput oi) throws Exception {
if (trace) log.trace("Integrating transaction log");
- processCommitLog(ois);
+ processCommitLog(oi);
stateSender = rpcManager.getCurrentStateTransferSource();
mimicPartialFlushViaRPC(stateSender, true);
needToUnblockRPC = true;
@@ -242,11 +244,11 @@
try {
if (trace)
log.trace("Retrieving/Applying post-flush commits");
- processCommitLog(ois);
+ processCommitLog(oi);
if (trace)
log.trace("Retrieving/Applying pending prepares");
- Object object = marshaller.objectFromObjectStream(ois);
+ Object object = marshaller.objectFromObjectStream(oi);
while (object instanceof PrepareCommand) {
PrepareCommand command = (PrepareCommand) object;
@@ -260,7 +262,7 @@
} else {
if (trace) log.trace("Prepare {0} not in tx log; not applying", command);
}
- object = marshaller.objectFromObjectStream(ois);
+ object = marshaller.objectFromObjectStream(oi);
}
assertDelimited(object);
} catch (Exception e) {
@@ -288,17 +290,17 @@
public void applyState(InputStream in) throws StateTransferException {
if (log.isDebugEnabled()) log.debug("Applying state");
- ObjectInputStream ois = null;
+ ObjectInput oi = null;
try {
- ois = new ObjectInputStream(in);
- boolean canProvideState = (Boolean) marshaller.objectFromObjectStream(ois);
+ oi = marshaller.startObjectInput(in);
+ boolean canProvideState = (Boolean) marshaller.objectFromObjectStream(oi);
if (canProvideState) {
- assertDelimited(ois);
- if (transientState) applyInMemoryState(ois);
- assertDelimited(ois);
- if (persistentState) applyPersistentState(ois);
- assertDelimited(ois);
- applyTransactionLog(ois);
+ assertDelimited(oi);
+ if (transientState) applyInMemoryState(oi);
+ assertDelimited(oi);
+ if (persistentState) applyPersistentState(oi);
+ assertDelimited(oi);
+ applyTransactionLog(oi);
if (log.isDebugEnabled()) log.debug("State applied, closing object stream");
} else {
String msg = "Provider cannot provide state!";
@@ -311,11 +313,11 @@
throw new StateTransferException(e);
} finally {
// just close the object stream but do NOT close the underlying stream
- Util.closeStream(ois);
+ marshaller.finishObjectInput(oi);
}
}
- private void applyInMemoryState(ObjectInputStream i) throws StateTransferException {
+ private void applyInMemoryState(ObjectInput i) throws StateTransferException {
dataContainer.clear();
try {
Set<InternalCacheEntry> set = (Set<InternalCacheEntry>) marshaller.objectFromObjectStream(i);
@@ -327,7 +329,7 @@
}
}
- private void generateInMemoryState(ObjectOutputStream o) throws StateTransferException {
+ private void generateInMemoryState(ObjectOutput oo) throws StateTransferException {
// write all StoredEntries to the stream using the marshaller.
// TODO is it safe enough to get these from the data container directly?
try {
@@ -336,13 +338,13 @@
if (!e.isExpired()) entries.add(e);
}
if (log.isDebugEnabled()) log.debug("Writing {0} StoredEntries to stream", entries.size());
- marshaller.objectToObjectStream(entries, o);
+ marshaller.objectToObjectStream(entries, oo);
} catch (Exception e) {
throw new StateTransferException(e);
}
}
- private void applyPersistentState(ObjectInputStream i) throws StateTransferException {
+ private void applyPersistentState(ObjectInput i) throws StateTransferException {
try {
// always use the unclosable stream delegate to ensure the impl doesn't close the stream
cs.fromStream(new UnclosableObjectInputStream(i));
@@ -351,20 +353,20 @@
}
}
- private void generatePersistentState(ObjectOutputStream o) throws StateTransferException {
+ private void generatePersistentState(ObjectOutput oo) throws StateTransferException {
try {
// always use the unclosable stream delegate to ensure the impl doesn't close the stream
- cs.toStream(new UnclosableObjectOutputStream(o));
+ cs.toStream(new UnclosableObjectOutputStream(oo));
} catch (CacheLoaderException cle) {
throw new StateTransferException(cle);
}
}
- private void delimit(ObjectOutputStream o) throws IOException {
- marshaller.objectToObjectStream(DELIMITER, o);
+ private void delimit(ObjectOutput oo) throws IOException {
+ marshaller.objectToObjectStream(DELIMITER, oo);
}
- private void assertDelimited(ObjectInputStream i) throws StateTransferException {
+ private void assertDelimited(ObjectInput i) throws StateTransferException {
Object o;
try {
o = marshaller.objectFromObjectStream(i);
Modified: trunk/core/src/main/java/org/infinispan/transaction/TransactionLog.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/transaction/TransactionLog.java 2009-04-14 17:00:56 UTC (rev 112)
+++ trunk/core/src/main/java/org/infinispan/transaction/TransactionLog.java 2009-04-14 18:09:18 UTC (rev 113)
@@ -27,6 +27,7 @@
import org.infinispan.logging.LogFactory;
import org.infinispan.marshall.Marshaller;
+import java.io.ObjectOutput;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.List;
@@ -128,7 +129,7 @@
return entries.size();
}
- public void writeCommitLog(Marshaller marshaller, ObjectOutputStream out) throws Exception {
+ public void writeCommitLog(Marshaller marshaller, ObjectOutput out) throws Exception {
List<LogEntry> buffer = new ArrayList<LogEntry>(10);
while (entries.drainTo(buffer, 10) > 0) {
@@ -139,7 +140,7 @@
}
}
- public void writePendingPrepares(Marshaller marshaller, ObjectOutputStream out) throws Exception {
+ public void writePendingPrepares(Marshaller marshaller, ObjectOutput out) throws Exception {
if (log.isTraceEnabled()) log.trace("Writing {0} pending prepares to the stream", pendingPrepares.size());
for (PrepareCommand entry : pendingPrepares.values()) marshaller.objectToObjectStream(entry, out);
}
Modified: trunk/core/src/main/java/org/infinispan/util/Util.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/util/Util.java 2009-04-14 17:00:56 UTC (rev 112)
+++ trunk/core/src/main/java/org/infinispan/util/Util.java 2009-04-14 18:09:18 UTC (rev 113)
@@ -22,6 +22,8 @@
package org.infinispan.util;
import java.io.InputStream;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
import java.io.OutputStream;
import java.lang.reflect.Method;
import java.text.NumberFormat;
@@ -32,6 +34,7 @@
* General utility methods used throughout the JBC code base.
*
* @author <a href="brian.stansberry at jboss.com">Brian Stansberry</a>
+ * @author Galder Zamarreño
* @since 4.0
*/
public final class Util {
@@ -165,6 +168,15 @@
}
}
+ public static void closeInput(ObjectInput i) {
+ if (i == null) return;
+ try {
+ i.close();
+ } catch (Exception e) {
+
+ }
+ }
+
public static void flushAndCloseStream(OutputStream o) {
if (o == null) return;
try {
@@ -179,4 +191,20 @@
}
}
+
+ public static void flushAndCloseOutput(ObjectOutput o) {
+ if (o == null) return;
+ try {
+ o.flush();
+ } catch (Exception e) {
+
+ }
+
+ try {
+ o.close();
+ } catch (Exception e) {
+
+ }
+ }
+
}
Modified: trunk/core/src/test/java/org/infinispan/marshall/ObjectStreamMarshaller.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/marshall/ObjectStreamMarshaller.java 2009-04-14 17:00:56 UTC (rev 112)
+++ trunk/core/src/test/java/org/infinispan/marshall/ObjectStreamMarshaller.java 2009-04-14 18:09:18 UTC (rev 113)
@@ -1,6 +1,7 @@
package org.infinispan.marshall;
import org.infinispan.io.ByteBuffer;
+import org.infinispan.util.Util;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
@@ -10,6 +11,7 @@
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;
+import java.io.OutputStream;
import java.io.Serializable;
/**
@@ -18,6 +20,15 @@
* @author Manik Surtani
*/
public class ObjectStreamMarshaller implements Marshaller, Serializable {
+
+ public ObjectOutput startObjectOutput(OutputStream os) throws IOException {
+ return new ObjectOutputStream(os);
+ }
+
+ public void finishObjectOutput(ObjectOutput oo) {
+ Util.flushAndCloseOutput(oo);
+ }
+
public void objectToObjectStream(Object obj, ObjectOutput out) throws IOException {
out.writeObject(obj);
}
@@ -26,6 +37,14 @@
return in.readObject();
}
+ public ObjectInput startObjectInput(InputStream is) throws IOException {
+ return new ObjectInputStream(is);
+ }
+
+ public void finishObjectInput(ObjectInput oi) {
+ Util.closeInput(oi);
+ }
+
public Object objectFromStream(InputStream is) throws IOException, ClassNotFoundException {
if (is instanceof ObjectInputStream)
return objectFromObjectStream((ObjectInputStream) is);
@@ -57,5 +76,4 @@
public Object objectFromByteBuffer(byte[] buf) throws IOException, ClassNotFoundException {
return objectFromObjectStream(new ObjectInputStream(new ByteArrayInputStream(buf)));
}
-
}
Added: trunk/core/src/test/java/org/infinispan/marshall/jboss/JBossMarshallerTest.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/marshall/jboss/JBossMarshallerTest.java (rev 0)
+++ trunk/core/src/test/java/org/infinispan/marshall/jboss/JBossMarshallerTest.java 2009-04-14 18:09:18 UTC (rev 113)
@@ -0,0 +1,272 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.marshall.jboss;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
+
+import org.infinispan.commands.ReplicableCommand;
+import org.infinispan.commands.control.StateTransferControlCommand;
+import org.infinispan.commands.read.GetKeyValueCommand;
+import org.infinispan.commands.remote.ClusteredGetCommand;
+import org.infinispan.commands.remote.MultipleRpcCommand;
+import org.infinispan.commands.tx.CommitCommand;
+import org.infinispan.commands.tx.PrepareCommand;
+import org.infinispan.commands.tx.RollbackCommand;
+import org.infinispan.commands.write.ClearCommand;
+import org.infinispan.commands.write.InvalidateCommand;
+import org.infinispan.commands.write.PutKeyValueCommand;
+import org.infinispan.commands.write.PutMapCommand;
+import org.infinispan.commands.write.RemoveCommand;
+import org.infinispan.commands.write.ReplaceCommand;
+import org.infinispan.container.entries.ImmortalCacheEntry;
+import org.infinispan.container.entries.InternalEntryFactory;
+import org.infinispan.container.entries.MortalCacheEntry;
+import org.infinispan.container.entries.TransientCacheEntry;
+import org.infinispan.container.entries.TransientMortalCacheEntry;
+import org.infinispan.marshall.MarshalledValue;
+import org.infinispan.remoting.transport.Address;
+import org.infinispan.remoting.transport.jgroups.ExtendedResponse;
+import org.infinispan.remoting.transport.jgroups.JGroupsAddress;
+import org.infinispan.remoting.transport.jgroups.RequestIgnoredResponse;
+import org.infinispan.transaction.GlobalTransaction;
+import org.infinispan.transaction.TransactionLog;
+import org.infinispan.util.FastCopyHashMap;
+import org.infinispan.util.Immutables;
+import org.jgroups.stack.IpAddress;
+import org.testng.annotations.AfterTest;
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.Test;
+
+/**
+ * JBossMarshallingMarshallerTest.
+ *
+ * Todo: AtomicHashMap missing.
+ *
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+ at Test(groups = "functional", testName = "marshall.jboss.JBossMarshallerTest")
+public class JBossMarshallerTest {
+
+ private final JBossMarshaller marshaller = new JBossMarshaller();
+
+ @BeforeTest
+ public void setUp() {
+ marshaller.init(Thread.currentThread().getContextClassLoader(), null);
+ }
+
+ @AfterTest
+ public void tearDown() {
+ marshaller.stop();
+ }
+
+ public void testJGroupsAddressMarshalling() throws Exception {
+ JGroupsAddress address = new JGroupsAddress(new IpAddress(12345));
+ marshallAndAssertEquality(address);
+ }
+
+ public void testGlobalTransactionMarshalling() throws Exception {
+ GlobalTransaction gtx = GlobalTransaction.create(new JGroupsAddress(new IpAddress(12345)));
+ marshallAndAssertEquality(gtx);
+ }
+
+ public void testListMarshalling() throws Exception {
+ List l1 = new ArrayList();
+ List l2 = new LinkedList();
+ for (int i = 0; i < 10; i++) {
+ GlobalTransaction gtx = GlobalTransaction.create(new JGroupsAddress(new IpAddress(1000 * i)));
+ l1.add(gtx);
+ l2.add(gtx);
+ }
+ marshallAndAssertEquality(l1);
+ marshallAndAssertEquality(l2);
+ }
+
+ public void testMapMarshalling() throws Exception {
+ Map m1 = new HashMap();
+ Map m2 = new TreeMap();
+ Map m3 = new HashMap();
+ Map<Integer, GlobalTransaction> m4 = new FastCopyHashMap<Integer, GlobalTransaction>();
+ for (int i = 0; i < 10; i++) {
+ GlobalTransaction gtx = GlobalTransaction.create(new JGroupsAddress(new IpAddress(1000 * i)));
+ m1.put(1000 * i, gtx);
+ m2.put(1000 * i, gtx);
+ m4.put(1000 * i, gtx);
+ }
+ Map m5 = Immutables.immutableMapWrap(m3);
+ marshallAndAssertEquality(m1);
+ marshallAndAssertEquality(m2);
+ byte[] bytes = marshaller.objectToByteBuffer(m4);
+ Map<Integer, GlobalTransaction> m4Read = (Map<Integer, GlobalTransaction>) marshaller.objectFromByteBuffer(bytes);
+ for (Map.Entry<Integer, GlobalTransaction> entry : m4.entrySet()) {
+ assert m4Read.get(entry.getKey()).equals(entry.getValue()) : "Writen[" + entry.getValue() + "] and read[" + m4Read.get(entry.getKey()) +"] objects should be the same";
+ }
+
+ marshallAndAssertEquality(m5);
+ }
+
+ public void testSetMarshalling() throws Exception {
+ Set s1 = new HashSet();
+ Set s2 = new TreeSet();
+ for (int i = 0; i < 10; i++) {
+ Integer integ = new Integer(1000 * i);
+ s1.add(integ);
+ s2.add(integ);
+ }
+ marshallAndAssertEquality(s1);
+ marshallAndAssertEquality(s2);
+ }
+
+ public void testMarshalledValueMarshalling() throws Exception {
+ GlobalTransaction gtx = GlobalTransaction.create(new JGroupsAddress(new IpAddress(12345)));
+ MarshalledValue mv = new MarshalledValue(gtx, true);
+ marshallAndAssertEquality(mv);
+ }
+
+ public void testSingletonListMarshalling() throws Exception {
+ GlobalTransaction gtx = GlobalTransaction.create(new JGroupsAddress(new IpAddress(12345)));
+ List l = Collections.singletonList(gtx);
+ marshallAndAssertEquality(l);
+ }
+
+ public void testTransactionLogMarshalling() throws Exception {
+ GlobalTransaction gtx = GlobalTransaction.create(new JGroupsAddress(new IpAddress(12345)));
+ PutKeyValueCommand command = new PutKeyValueCommand("k", "v", false, null, 0, 0);
+ TransactionLog.LogEntry entry = new TransactionLog.LogEntry(gtx, command);
+ byte[] bytes = marshaller.objectToByteBuffer(entry);
+ TransactionLog.LogEntry readObj = (TransactionLog.LogEntry) marshaller.objectFromByteBuffer(bytes);
+ assert Arrays.equals(readObj.getModifications(), entry.getModifications()) :
+ "Writen[" + entry.getModifications() + "] and read[" + readObj.getModifications() +"] objects should be the same";
+ assert readObj.getTransaction().equals(entry.getTransaction()) :
+ "Writen[" + entry.getModifications() + "] and read[" + readObj.getModifications() +"] objects should be the same";
+ }
+
+ public void testRequestIgnoredResponseMarshalling() throws Exception {
+ marshallAndAssertEquality(RequestIgnoredResponse.INSTANCE);
+ }
+
+ public void testExtendedResponseMarshalling() throws Exception {
+ PutKeyValueCommand command = new PutKeyValueCommand("k", "v", false, null, 0, 0);
+ ExtendedResponse extended = new ExtendedResponse(command, false);
+ byte[] bytes = marshaller.objectToByteBuffer(extended);
+ ExtendedResponse readObj = (ExtendedResponse) marshaller.objectFromByteBuffer(bytes);
+ assert extended.getResponse().equals(readObj.getResponse()) :
+ "Writen[" + extended.getResponse() + "] and read[" + readObj.getResponse() +"] objects should be the same";
+ assert extended.isReplayIgnoredRequests() == readObj.isReplayIgnoredRequests() :
+ "Writen[" + extended.isReplayIgnoredRequests() + "] and read[" + readObj.isReplayIgnoredRequests() +"] objects should be the same";
+ }
+
+ public void testReplicableCommandsMarshalling() throws Exception {
+ StateTransferControlCommand c1 = new StateTransferControlCommand(true);
+ byte[] bytes = marshaller.objectToByteBuffer(c1);
+ StateTransferControlCommand rc1 = (StateTransferControlCommand)marshaller.objectFromByteBuffer(bytes);
+ assert rc1.getCommandId() == c1.getCommandId() : "Writen[" + c1.getCommandId() + "] and read[" + rc1.getCommandId() +"] objects should be the same";
+ assert Arrays.equals(rc1.getParameters(), c1.getParameters()) : "Writen[" + c1.getParameters() + "] and read[" + rc1.getParameters() +"] objects should be the same";
+
+ ClusteredGetCommand c2 = new ClusteredGetCommand("key", "mycache");
+ marshallAndAssertEquality(c2);
+
+ // SizeCommand does not have an empty constructor, so doesn't look to be one that is marshallable.
+
+ GetKeyValueCommand c4 = new GetKeyValueCommand("key", null);
+ bytes = marshaller.objectToByteBuffer(c4);
+ GetKeyValueCommand rc4 = (GetKeyValueCommand)marshaller.objectFromByteBuffer(bytes);
+ assert rc4.getCommandId() == c4.getCommandId() : "Writen[" + c4.getCommandId() + "] and read[" + rc4.getCommandId() +"] objects should be the same";
+ assert Arrays.equals(rc4.getParameters(), c4.getParameters()) : "Writen[" + c4.getParameters() + "] and read[" + rc4.getParameters() +"] objects should be the same";
+
+ PutKeyValueCommand c5 = new PutKeyValueCommand("k", "v", false, null, 0, 0);
+ marshallAndAssertEquality(c5);
+
+ RemoveCommand c6 = new RemoveCommand("key", null, null);
+ marshallAndAssertEquality(c6);
+
+ // EvictCommand does not have an empty constructor, so doesn't look to be one that is marshallable.
+
+ InvalidateCommand c7 = new InvalidateCommand(null, "key1", "key2");
+ bytes = marshaller.objectToByteBuffer(c7);
+ InvalidateCommand rc7 = (InvalidateCommand)marshaller.objectFromByteBuffer(bytes);
+ assert rc7.getCommandId() == c7.getCommandId() : "Writen[" + c7.getCommandId() + "] and read[" + rc7.getCommandId() +"] objects should be the same";
+ assert Arrays.equals(rc7.getParameters(), c7.getParameters()) : "Writen[" + c7.getParameters() + "] and read[" + rc7.getParameters() +"] objects should be the same";
+
+ ReplaceCommand c8 = new ReplaceCommand("key", "oldvalue", "newvalue", 0, 0);
+ marshallAndAssertEquality(c8);
+
+ ClearCommand c9 = new ClearCommand();
+ bytes = marshaller.objectToByteBuffer(c9);
+ ClearCommand rc9 = (ClearCommand)marshaller.objectFromByteBuffer(bytes);
+ assert rc9.getCommandId() == c9.getCommandId() : "Writen[" + c9.getCommandId() + "] and read[" + rc9.getCommandId() +"] objects should be the same";
+ assert Arrays.equals(rc9.getParameters(), c9.getParameters()) : "Writen[" + c9.getParameters() + "] and read[" + rc9.getParameters() +"] objects should be the same";
+
+ Map m1 = new HashMap();
+ for (int i = 0; i < 10; i++) {
+ GlobalTransaction gtx = GlobalTransaction.create(new JGroupsAddress(new IpAddress(1000 * i)));
+ m1.put(1000 * i, gtx);
+ }
+ PutMapCommand c10 = new PutMapCommand(m1, null, 0, 0);
+ marshallAndAssertEquality(c10);
+
+ Address local = new JGroupsAddress(new IpAddress(12345));
+ GlobalTransaction gtx = GlobalTransaction.create(local);
+ PrepareCommand c11 = new PrepareCommand(gtx, local, true, c5, c6, c8, c10);
+ marshallAndAssertEquality(c11);
+
+ CommitCommand c12 = new CommitCommand(gtx);
+ marshallAndAssertEquality(c12);
+
+ RollbackCommand c13 = new RollbackCommand(gtx);
+ marshallAndAssertEquality(c13);
+
+ MultipleRpcCommand c99 = new MultipleRpcCommand(Arrays.asList(new ReplicableCommand[] {c2, c5, c6, c8, c10, c12, c13}), "mycache");
+ marshallAndAssertEquality(c99);
+ }
+
+ public void testInternalCacheEntryMarshalling() throws Exception {
+ ImmortalCacheEntry entry1 = (ImmortalCacheEntry) InternalEntryFactory.create("key", "value", System.currentTimeMillis() - 1000, -1, System.currentTimeMillis(), -1);
+ marshallAndAssertEquality(entry1);
+
+ MortalCacheEntry entry2 = (MortalCacheEntry) InternalEntryFactory.create("key", "value", System.currentTimeMillis() - 1000, 200000, System.currentTimeMillis(), -1);
+ marshallAndAssertEquality(entry2);
+
+ TransientCacheEntry entry3 = (TransientCacheEntry) InternalEntryFactory.create("key", "value", System.currentTimeMillis() - 1000, -1, System.currentTimeMillis(), 4000000);
+ marshallAndAssertEquality(entry3);
+
+ TransientMortalCacheEntry entry4 = (TransientMortalCacheEntry) InternalEntryFactory.create("key", "value", System.currentTimeMillis() - 1000, 200000, System.currentTimeMillis(), 4000000);
+ marshallAndAssertEquality(entry4);
+ }
+
+ protected void marshallAndAssertEquality(Object writeObj) throws Exception {
+ byte[] bytes = marshaller.objectToByteBuffer(writeObj);
+ Object readObj = marshaller.objectFromByteBuffer(bytes);
+ assert readObj.equals(writeObj) : "Writen[" + writeObj + "] and read[" + readObj +"] objects should be the same";
+ }
+
+}
Modified: trunk/core/src/test/java/org/infinispan/test/fwk/TestCacheManagerFactory.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/test/fwk/TestCacheManagerFactory.java 2009-04-14 17:00:56 UTC (rev 112)
+++ trunk/core/src/test/java/org/infinispan/test/fwk/TestCacheManagerFactory.java 2009-04-14 18:09:18 UTC (rev 113)
@@ -5,6 +5,7 @@
import org.infinispan.manager.CacheManager;
import org.infinispan.manager.DefaultCacheManager;
import org.infinispan.remoting.transport.jgroups.JGroupsTransport;
+import org.infinispan.util.Util;
import java.util.Properties;
@@ -12,14 +13,18 @@
* CacheManagers in unit tests should be created with this factory, in order to avoit resource clashes.
*
* @author Mircea.Markus at jboss.com
+ * @author Galder Zamarreño
*/
public class TestCacheManagerFactory {
+
+ public static final String MARSHALLER = System.getProperties().getProperty("infinispan.marshaller.class");
/**
* Creates an cache manager that does not support clustering.
*/
public static CacheManager createLocalCacheManager() {
GlobalConfiguration globalConfiguration = GlobalConfiguration.getNonClusteredDefault();
+ amendMarshaller(globalConfiguration);
// amendJmx(globalConfiguration);
return new DefaultCacheManager(globalConfiguration);
}
@@ -29,6 +34,7 @@
*/
public static CacheManager createClusteredCacheManager() {
GlobalConfiguration globalConfiguration = GlobalConfiguration.getClusteredDefault();
+ amendMarshaller(globalConfiguration);
// amendJmx(globalConfiguration);
Properties newTransportProps = new Properties();
newTransportProps.put(JGroupsTransport.CONFIGURATION_STRING, JGroupsConfigBuilder.getJGroupsConfig());
@@ -41,6 +47,7 @@
* during running tests in parallel.
*/
public static CacheManager createCacheManager(GlobalConfiguration configuration) {
+ amendMarshaller(configuration);
amendTransport(configuration);
// amendJmx(configuration);
return new DefaultCacheManager(configuration);
@@ -52,11 +59,13 @@
*/
public static CacheManager createCacheManager(Configuration defaultCacheConfig) {
GlobalConfiguration globalConfiguration = GlobalConfiguration.getNonClusteredDefault();
+ amendMarshaller(globalConfiguration);
// amendJmx(globalConfiguration);
return new DefaultCacheManager(globalConfiguration, defaultCacheConfig);
}
public static DefaultCacheManager createCacheManager(GlobalConfiguration configuration, Configuration defaultCfg) {
+ amendMarshaller(configuration);
amendTransport(configuration);
// amendJmx(configuration);
return new DefaultCacheManager(configuration, defaultCfg);
@@ -74,4 +83,15 @@
configuration.setTransportProperties(newTransportProps);
}
}
+
+ private static void amendMarshaller(GlobalConfiguration configuration) {
+ if (MARSHALLER != null) {
+ try {
+ Util.loadClass(MARSHALLER);
+ configuration.setMarshallerClass(MARSHALLER);
+ } catch (ClassNotFoundException e) {
+ // No-op, stick to GlobalConfiguration default.
+ }
+ }
+ }
}
Modified: trunk/core/src/test/java/org/infinispan/test/testng/SuiteResourcesAndLogTest.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/test/testng/SuiteResourcesAndLogTest.java 2009-04-14 17:00:56 UTC (rev 112)
+++ trunk/core/src/test/java/org/infinispan/test/testng/SuiteResourcesAndLogTest.java 2009-04-14 18:09:18 UTC (rev 113)
@@ -13,6 +13,7 @@
* This class makes sure that all files are being deleted after each test run. It also logs testsuite information.
*
* @author Mircea.Markus at jboss.com
+ * @author Galder Zamarreño
*/
@Test(groups = "functional", testName = "test.testng.SuiteResourcesAndLogTest")
public class SuiteResourcesAndLogTest {
@@ -53,6 +54,7 @@
log("sun.arch.data.model = " + System.getProperty("sun.arch.data.model"));
log("sun.cpu.endian = " + System.getProperty("sun.cpu.endian"));
log("jgroups.stack = " + System.getProperty("jgroups.stack"));
+ log("infinispan.marshaller.class = " + System.getProperty("infinispan.marshaller.class"));
log("~~~~~~~~~~~~~~~~~~~~~~~~~ ENVIRONMENT INFO ~~~~~~~~~~~~~~~~~~~~~~~~~~");
}
More information about the infinispan-commits
mailing list