/*
* JBoss, Home of Professional Open Source.
* Copyright 2000 - 2008, 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.jboss.cache.marshall;
import org.jboss.cache.CacheException;
import org.jboss.cache.Fqn;
import org.jboss.cache.Region;
import org.jboss.cache.Region.Status;
import org.jboss.cache.buddyreplication.GravitateResult;
import org.jboss.cache.commands.CommandsFactory;
import org.jboss.cache.commands.ReplicableCommand;
import org.jboss.cache.commands.WriteCommand;
import org.jboss.cache.factories.annotations.Inject;
import org.jboss.cache.optimistic.DefaultDataVersion;
import org.jboss.cache.transaction.GlobalTransaction;
import org.jboss.cache.transaction.TransactionLog.LogEntry;
import org.jboss.cache.util.FastCopyHashMap;
import org.jboss.cache.util.Immutables;
import org.jgroups.Address;
import org.jgroups.stack.IpAddress;
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.*;
/**
* An enhanced marshaller for RPC calls between CacheImpl instances.
*
* @author Manik Surtani (manik AT jboss DOT org)
*/
public class CacheMarshaller200 extends AbstractMarshaller
{
// magic numbers
protected static final int MAGICNUMBER_METHODCALL = 1;
protected static final int MAGICNUMBER_FQN = 2;
protected static final int MAGICNUMBER_GTX = 3;
protected static final int MAGICNUMBER_IPADDRESS = 4;
protected static final int MAGICNUMBER_ARRAY_LIST = 5;
protected static final int MAGICNUMBER_INTEGER = 6;
protected static final int MAGICNUMBER_LONG = 7;
protected static final int MAGICNUMBER_BOOLEAN = 8;
protected static final int MAGICNUMBER_STRING = 9;
protected static final int MAGICNUMBER_DEFAULT_DATA_VERSION = 10;
protected static final int MAGICNUMBER_LINKED_LIST = 11;
protected static final int MAGICNUMBER_HASH_MAP = 12;
protected static final int MAGICNUMBER_TREE_MAP = 13;
protected static final int MAGICNUMBER_HASH_SET = 14;
protected static final int MAGICNUMBER_TREE_SET = 15;
protected static final int MAGICNUMBER_NODEDATA_MARKER = 16;
protected static final int MAGICNUMBER_NODEDATA_EXCEPTION_MARKER = 17;
protected static final int MAGICNUMBER_NODEDATA = 18;
protected static final int MAGICNUMBER_GRAVITATERESULT = 19;
protected static final int MAGICNUMBER_SHORT = 20;
protected static final int MAGICNUMBER_IMMUTABLE_MAPCOPY = 21;
protected static final int MAGICNUMBER_MARSHALLEDVALUE = 22;
protected static final int MAGICNUMBER_FASTCOPY_HASHMAP = 23;
protected static final int MAGICNUMBER_ARRAY = 24;
protected static final int MAGICNUMBER_BYTE = 25;
protected static final int MAGICNUMBER_CHAR = 26;
protected static final int MAGICNUMBER_FLOAT = 27;
protected static final int MAGICNUMBER_DOUBLE = 28;
protected static final int MAGICNUMBER_OBJECT = 29;
protected static final int MAGICNUMBER_TXLOG_ENTRY = 50;
protected static final int MAGICNUMBER_REQUEST_IGNORED_RESPONSE = 51;
protected static final int MAGICNUMBER_EXTENDED_RESPONSE = 52;
protected static final int MAGICNUMBER_NULL = 99;
protected static final int MAGICNUMBER_SERIALIZABLE = 100;
protected static final int MAGICNUMBER_REF = 101;
protected static final InactiveRegionException IRE = new InactiveRegionException("Cannot unmarshall to an inactive region");
public CacheMarshaller200()
{
initLogger();
// enabled, since this is always enabled in JBC 2.0.0.
useRefs = true;
}
protected CommandsFactory commandsFactory;
@Inject
public void injectCommandsFactory(CommandsFactory commandsFactory)
{
this.commandsFactory = commandsFactory;
}
// -------- AbstractMarshaller interface
public void objectToObjectStream(Object o, ObjectOutputStream out) throws Exception
{
if (useRegionBasedMarshalling)
{
Fqn region = null;
if (o instanceof RegionalizedReturnValue)
{
RegionalizedReturnValue rrv = (RegionalizedReturnValue) o;
region = rrv.region;
o = rrv.returnValue;
}
else if (o instanceof ReplicableCommand)
{
ReplicableCommand marshallableCommand = (ReplicableCommand) o;
region = extractFqnRegion(marshallableCommand);
}
if (trace) log.trace("Region based call. Using region " + region);
objectToObjectStream(o, out, region);
}
else
{
// not region based!
objectToObjectStream(o, out, null);
}
}
@Override
public RegionalizedMethodCall regionalizedMethodCallFromObjectStream(ObjectInputStream in) throws Exception
{
// parse the stream as per normal.
Object[] retVal = objectFromObjectStreamRegionBased(in);
RegionalizedMethodCall rmc = new RegionalizedMethodCall();
rmc.command = (ReplicableCommand) retVal[0];
rmc.region = (Fqn) retVal[1];
return rmc;
}
public Object objectFromObjectStream(ObjectInputStream in) throws Exception
{
if (useRegionBasedMarshalling)
{
return objectFromObjectStreamRegionBased(in)[0];
}
else
{
UnmarshalledReferences refMap = useRefs ? new UnmarshalledReferences() : null;
Object retValue = unmarshallObject(in, defaultClassLoader, refMap, false);
if (trace) log.trace("Unmarshalled object " + retValue);
return retValue;
}
}
public void objectToObjectStream(Object o, ObjectOutputStream out, Fqn region) throws Exception
{
if (trace) log.trace("Marshalling object " + o);
Map refMap = useRefs ? new IdentityHashMap() : null;
ClassLoader toUse = defaultClassLoader;
Thread current = Thread.currentThread();
ClassLoader old = current.getContextClassLoader();
if (old != null) toUse = old;
try
{
if (useRegionBasedMarshalling) // got to check again in case this meth is called directly
{
if (trace) log.trace("Writing region " + region + " to stream");
Region r = null;
if (region != null) r = regionManager.getRegion(region, false);
if (r != null && r.getClassLoader() != null) toUse = r.getClassLoader();
current.setContextClassLoader(toUse);
marshallObject(region, out, refMap);
}
else
{
current.setContextClassLoader(toUse);
}
marshallObject(o, out, refMap);
}
catch (Exception th)
{
if(log.isErrorEnabled()) log.error("Error while marshalling object: " + o, th);
throw th;
}
finally
{
if (log.isTraceEnabled()) log.trace("Done serializing object: " + o);
current.setContextClassLoader(old);
}
}
/**
* @param in
* @return a 2-object array. The first one is the unmarshalled object and the 2nd is an Fqn that relates to the region used. If region-based marshalling is not used, the 2nd value is null.
* @throws Exception
*/
protected Object[] objectFromObjectStreamRegionBased(ObjectInputStream in) throws Exception
{
UnmarshalledReferences refMap = useRefs ? new UnmarshalledReferences() : null;
Object o = unmarshallObject(in, refMap);
Fqn regionFqn = null;
if (o == null)
{
// a null region. Could happen. Use std marshalling.
log.trace("Unmarshalled region as null. Not using a context class loader to unmarshall.");
}
else
{
regionFqn = (Fqn) o;
}
if (trace) log.trace("Unmarshalled regionFqn " + regionFqn + " from stream");
Region region = null;
Object[] retValue = {null, null};
if (regionFqn != null)
{
region = findRegion(regionFqn);
}
if (region == null)
{
if (log.isDebugEnabled())
log.debug("Region does not exist for Fqn " + regionFqn + " - not using a context classloader.");
retValue[0] = unmarshallObject(in, defaultClassLoader, refMap, false);
}
else
{
retValue[0] = unmarshallObject(in, region.getClassLoader(), refMap, true);
retValue[1] = regionFqn;
}
if (trace) log.trace("Unmarshalled object " + retValue[0] + " with region " + retValue[1]);
return retValue;
}
private Region findRegion(Fqn fqn) throws InactiveRegionException
{
Region region = regionManager.getValidMarshallingRegion(fqn);
if (region != null)
{
Status status = region.getStatus();
if (status == Status.INACTIVATING || status == Status.INACTIVE)
{
if (log.isDebugEnabled())
{
throw new InactiveRegionException("Cannot unmarshall message for region " + fqn + ". This region is inactive.");
}
else
{
throw IRE;
}
}
}
else if (defaultInactive)
{
if (log.isDebugEnabled())
{
// No region but default inactive means region is inactive
throw new InactiveRegionException("Cannot unmarshall message for region " + fqn + ". By default region " + fqn
+ " is inactive.");
}
else
{
throw IRE;
}
}
return region;
}
private Fqn extractFqnRegion(ReplicableCommand cmd) throws Exception
{
Fqn fqn = extractFqn(cmd);
Region r = regionManager.getValidMarshallingRegion(fqn);
return r == null ? null : r.getFqn();
}
// --------- Marshalling methods
@SuppressWarnings("deprecation")
protected void marshallObject(Object o, ObjectOutputStream out, Map refMap) throws Exception
{
if (o == null)
{
out.writeByte(MAGICNUMBER_NULL);
}
else if (useRefs && refMap.containsKey(o))// see if this object has been marshalled before.
{
out.writeByte(MAGICNUMBER_REF);
writeReference(out, refMap.get(o));
}
else if (o instanceof ReplicableCommand)
{
ReplicableCommand command = (ReplicableCommand) o;
if (command.getCommandId() > -1)
{
out.writeByte(MAGICNUMBER_METHODCALL);
marshallCommand(command, out, refMap);
}
else
{
throw new IllegalArgumentException("MethodCall does not have a valid method id. Was this method call created with MethodCallFactory?");
}
}
else if (o instanceof org.jgroups.blocks.MethodCall)
{
throw new IllegalArgumentException("Usage of a legacy MethodCall object!!");
}
else if (o instanceof MarshalledValue)
{
out.writeByte(MAGICNUMBER_MARSHALLEDVALUE);
((MarshalledValue) o).writeExternal(out);
}
else if (o instanceof Fqn)
{
out.writeByte(MAGICNUMBER_FQN);
if (useRefs) writeReference(out, createReference(o, refMap));
marshallFqn((Fqn) o, out, refMap);
}
else if (o instanceof GlobalTransaction)
{
out.writeByte(MAGICNUMBER_GTX);
if (useRefs) writeReference(out, createReference(o, refMap));
marshallGlobalTransaction((GlobalTransaction) o, out, refMap);
}
else if (o instanceof LogEntry)
{
out.writeByte(MAGICNUMBER_TXLOG_ENTRY);
marshallLogEntry((LogEntry)o, out, refMap);
}
else if (o instanceof IpAddress)
{
out.writeByte(MAGICNUMBER_IPADDRESS);
marshallIpAddress((IpAddress) o, out);
}
else if (o instanceof DefaultDataVersion)
{
out.writeByte(MAGICNUMBER_DEFAULT_DATA_VERSION);
marshallDefaultDataVersion((DefaultDataVersion) o, out);
}
else if (o.getClass().equals(ArrayList.class))
{
out.writeByte(MAGICNUMBER_ARRAY_LIST);
marshallCollection((Collection) o, out, refMap);
}
else if (o.getClass().equals(LinkedList.class))
{
out.writeByte(MAGICNUMBER_LINKED_LIST);
marshallCollection((Collection) o, out, refMap);
}
else if (o.getClass().equals(HashMap.class))
{
out.writeByte(MAGICNUMBER_HASH_MAP);
marshallMap((Map) o, out, refMap);
}
else if (o.getClass().equals(TreeMap.class))
{
out.writeByte(MAGICNUMBER_TREE_MAP);
marshallMap((Map) o, out, refMap);
}
else if (o.getClass().equals(FastCopyHashMap.class))
{
out.writeByte(MAGICNUMBER_FASTCOPY_HASHMAP);
marshallMap((Map) o, out, refMap);
}
else if (o instanceof Map && Immutables.isImmutable(o))
{
out.writeByte(MAGICNUMBER_IMMUTABLE_MAPCOPY);
marshallMap((Map) o, out, refMap);
}
else if (o.getClass().equals(HashSet.class))
{
out.writeByte(MAGICNUMBER_HASH_SET);
marshallCollection((Collection) o, out, refMap);
}
else if (o.getClass().equals(TreeSet.class))
{
out.writeByte(MAGICNUMBER_TREE_SET);
marshallCollection((Collection) o, out, refMap);
}
else if (o instanceof Boolean)
{
out.writeByte(MAGICNUMBER_BOOLEAN);
out.writeBoolean(((Boolean) o).booleanValue());
}
else if (o instanceof Integer)
{
out.writeByte(MAGICNUMBER_INTEGER);
out.writeInt(((Integer) o).intValue());
}
else if (o instanceof Long)
{
out.writeByte(MAGICNUMBER_LONG);
out.writeLong(((Long) o).longValue());
}
else if (o instanceof Short)
{
out.writeByte(MAGICNUMBER_SHORT);
out.writeShort(((Short) o).shortValue());
}
else if (o instanceof String)
{
out.writeByte(MAGICNUMBER_STRING);
if (useRefs) writeReference(out, createReference(o, refMap));
marshallString((String) o, out);
}
else if (o instanceof NodeDataMarker)
{
out.writeByte(MAGICNUMBER_NODEDATA_MARKER);
((Externalizable) o).writeExternal(out);
}
else if (o instanceof NodeDataExceptionMarker)
{
out.writeByte(MAGICNUMBER_NODEDATA_EXCEPTION_MARKER);
((Externalizable) o).writeExternal(out);
}
else if (o instanceof NodeData)
{
out.writeByte(MAGICNUMBER_NODEDATA);
((Externalizable) o).writeExternal(out);
}
else if (o instanceof GravitateResult)
{
out.writeByte(MAGICNUMBER_GRAVITATERESULT);
marshallGravitateResult((GravitateResult) o, out, refMap);
}
else if (o instanceof RequestIgnoredResponse)
{
out.writeByte(MAGICNUMBER_REQUEST_IGNORED_RESPONSE);
}
else if (o instanceof ExtendedResponse)
{
out.writeByte(MAGICNUMBER_EXTENDED_RESPONSE);
marshallExtendedResponse((ExtendedResponse)o, out, refMap);
}
else if (o instanceof Serializable)
{
if (trace)
{
log.trace("Not optimum: using object serialization for " + o.getClass());
}
out.writeByte(MAGICNUMBER_SERIALIZABLE);
if (useRefs) writeReference(out, createReference(o, refMap));
out.writeObject(o);
}
else
{
throw new Exception("Don't know how to marshall object of type " + o.getClass());
}
}
private void marshallExtendedResponse(ExtendedResponse response, ObjectOutputStream out, Map refMap) throws Exception
{
out.writeBoolean(response.isReplayIgnoredRequests());
marshallObject(response.getResponse(), out, refMap);
}
private void marshallLogEntry(LogEntry log, ObjectOutputStream out, Map refMap) throws Exception
{
marshallObject(log.getTransaction(), out, refMap);
List mods = log.getModifications();
boolean isList = mods.size() > 1;
out.writeBoolean(isList);
if (isList)
marshallObject(log.getModifications(), out, refMap);
else
marshallObject(mods.get(0), out, refMap);
}
private void marshallGravitateResult(GravitateResult gravitateResult, ObjectOutputStream out, Map refMap) throws Exception
{
marshallObject(gravitateResult.isDataFound(), out, refMap);
if (gravitateResult.isDataFound())
{
marshallObject(gravitateResult.getNodeData(), out, refMap);
marshallObject(gravitateResult.getBuddyBackupFqn(), out, refMap);
}
}
private int createReference(Object o, Map refMap)
{
int reference = refMap.size();
refMap.put(o, reference);
return reference;
}
protected void marshallString(String s, ObjectOutputStream out) throws Exception
{
//StringUtil.saveString(out, s);
out.writeObject(s);
}
private void marshallCommand(ReplicableCommand command, ObjectOutputStream out, Map refMap) throws Exception
{
out.writeShort(command.getCommandId());
Object[] args = command.getParameters();
byte numArgs = (byte) (args == null ? 0 : args.length);
out.writeByte(numArgs);
for (int i = 0; i < numArgs; i++)
{
marshallObject(args[i], out, refMap);
}
}
private void marshallGlobalTransaction(GlobalTransaction globalTransaction, ObjectOutputStream out, Map refMap) throws Exception
{
out.writeLong(globalTransaction.getId());
marshallObject(globalTransaction.getAddress(), out, refMap);
}
protected void marshallFqn(Fqn fqn, ObjectOutputStream out, Map refMap) throws Exception
{
boolean isRoot = fqn.isRoot();
out.writeBoolean(isRoot);
if (!isRoot)
{
out.writeShort(fqn.size());
for (Object o : fqn.peekElements())
{
marshallObject(o, out, refMap);
}
}
}
private void marshallIpAddress(IpAddress ipAddress, ObjectOutputStream out) throws Exception
{
ipAddress.writeExternal(out);
}
@SuppressWarnings("unchecked")
private void marshallCollection(Collection c, ObjectOutputStream out, Map refMap) throws Exception
{
writeUnsignedInt(out, c.size());
for (Object o : c)
{
marshallObject(o, out, refMap);
}
}
@SuppressWarnings("unchecked")
private void marshallMap(Map map, ObjectOutputStream out, Map refMap) throws Exception
{
int mapSize = map.size();
writeUnsignedInt(out, mapSize);
if (mapSize == 0) return;
for (Map.Entry me : (Set) map.entrySet())
{
marshallObject(me.getKey(), out, refMap);
marshallObject(me.getValue(), out, refMap);
}
}
// --------- Unmarshalling methods
protected Object unmarshallObject(ObjectInputStream in, ClassLoader loader, UnmarshalledReferences refMap, boolean overrideContextClassloaderOnThread) throws Exception
{
if (loader == null)
{
return unmarshallObject(in, refMap);
}
else
{
Thread currentThread = Thread.currentThread();
ClassLoader old = currentThread.getContextClassLoader();
try
{
// only do this if we haven't already set a context class loader elsewhere.
if (overrideContextClassloaderOnThread || old == null) currentThread.setContextClassLoader(loader);
return unmarshallObject(in, refMap);
}
finally
{
if (overrideContextClassloaderOnThread || old == null) currentThread.setContextClassLoader(old);
}
}
}
protected Object unmarshallObject(ObjectInputStream in, UnmarshalledReferences refMap) throws Exception
{
byte magicNumber = in.readByte();
int reference = 0;
Object retVal;
switch (magicNumber)
{
case MAGICNUMBER_NULL:
return null;
case MAGICNUMBER_REF:
if (useRefs)
{
reference = readReference(in);
return refMap.getReferencedObject(reference);
}
else break;
case MAGICNUMBER_SERIALIZABLE:
if (useRefs) reference = readReference(in);
retVal = in.readObject();
if (useRefs) refMap.putReferencedObject(reference, retVal);
return retVal;
case MAGICNUMBER_MARSHALLEDVALUE:
MarshalledValue mv = new MarshalledValue();
mv.readExternal(in);
return mv;
case MAGICNUMBER_METHODCALL:
retVal = unmarshallCommand(in, refMap);
return retVal;
case MAGICNUMBER_FQN:
if (useRefs) reference = readReference(in);
retVal = unmarshallFqn(in, refMap);
if (useRefs) refMap.putReferencedObject(reference, retVal);
return retVal;
case MAGICNUMBER_GTX:
if (useRefs) reference = readReference(in);
retVal = unmarshallGlobalTransaction(in, refMap);
if (useRefs) refMap.putReferencedObject(reference, retVal);
return retVal;
case MAGICNUMBER_TXLOG_ENTRY:
return unmarshallLogEntry(in, refMap);
case MAGICNUMBER_IPADDRESS:
retVal = unmarshallIpAddress(in);
return retVal;
case MAGICNUMBER_DEFAULT_DATA_VERSION:
retVal = unmarshallDefaultDataVersion(in);
return retVal;
case MAGICNUMBER_ARRAY:
return unmarshallArray(in, refMap);
case MAGICNUMBER_ARRAY_LIST:
return unmarshallArrayList(in, refMap);
case MAGICNUMBER_LINKED_LIST:
return unmarshallLinkedList(in, refMap);
case MAGICNUMBER_HASH_MAP:
return unmarshallHashMap(in, refMap);
case MAGICNUMBER_TREE_MAP:
return unmarshallTreeMap(in, refMap);
case MAGICNUMBER_HASH_SET:
return unmarshallHashSet(in, refMap);
case MAGICNUMBER_TREE_SET:
return unmarshallTreeSet(in, refMap);
case MAGICNUMBER_IMMUTABLE_MAPCOPY:
return unmarshallMapCopy(in, refMap);
case MAGICNUMBER_FASTCOPY_HASHMAP:
return unmarshallFastCopyHashMap(in, refMap);
case MAGICNUMBER_BOOLEAN:
return in.readBoolean() ? Boolean.TRUE : Boolean.FALSE;
case MAGICNUMBER_INTEGER:
return in.readInt();
case MAGICNUMBER_LONG:
return in.readLong();
case MAGICNUMBER_SHORT:
return in.readShort();
case MAGICNUMBER_STRING:
if (useRefs) reference = readReference(in);
retVal = unmarshallString(in);
if (useRefs) refMap.putReferencedObject(reference, retVal);
return retVal;
case MAGICNUMBER_NODEDATA_MARKER:
retVal = new NodeDataMarker();
((NodeDataMarker) retVal).readExternal(in);
return retVal;
case MAGICNUMBER_NODEDATA_EXCEPTION_MARKER:
retVal = new NodeDataExceptionMarker();
((NodeDataExceptionMarker) retVal).readExternal(in);
return retVal;
case MAGICNUMBER_NODEDATA:
retVal = new NodeData();
((NodeData) retVal).readExternal(in);
return retVal;
case MAGICNUMBER_GRAVITATERESULT:
return unmarshallGravitateResult(in, refMap);
case MAGICNUMBER_REQUEST_IGNORED_RESPONSE:
return new RequestIgnoredResponse();
case MAGICNUMBER_EXTENDED_RESPONSE:
return unmarshallExtendedResponse(in, refMap);
default:
if (log.isErrorEnabled())
{
log.error("Unknown Magic Number " + magicNumber);
}
throw new Exception("Unknown magic number " + magicNumber);
}
throw new Exception("Unknown magic number " + magicNumber);
}
private ExtendedResponse unmarshallExtendedResponse(ObjectInputStream in, UnmarshalledReferences refMap) throws Exception
{
boolean replayIgnoredRequests = in.readBoolean();
ExtendedResponse response = new ExtendedResponse(unmarshallObject(in, refMap));
response.setReplayIgnoredRequests(replayIgnoredRequests);
return response;
}
@SuppressWarnings("unchecked")
private LogEntry unmarshallLogEntry(ObjectInputStream in, UnmarshalledReferences refMap) throws Exception
{
GlobalTransaction gtx = (GlobalTransaction)unmarshallObject(in, refMap);
boolean isList = in.readBoolean();
List mods;
if (isList)
mods = (List)unmarshallObject(in, refMap);
else
mods = Collections.singletonList(unmarshallObject(in, refMap));
return new LogEntry(gtx, mods);
}
private FastCopyHashMap unmarshallFastCopyHashMap(ObjectInputStream in, UnmarshalledReferences refMap) throws Exception
{
FastCopyHashMap map = new FastCopyHashMap();
populateFromStream(in, refMap, map);
return map;
}
@SuppressWarnings("unchecked")
private GravitateResult unmarshallGravitateResult(ObjectInputStream in, UnmarshalledReferences refMap) throws Exception
{
Boolean found = (Boolean) unmarshallObject(in, refMap);
if (found)
{
List stuff = (List) unmarshallObject(in, refMap);
Fqn fqn = (Fqn) unmarshallObject(in, refMap);
return GravitateResult.subtreeResult(stuff, fqn);
}
else
{
return GravitateResult.noDataFound();
}
}
protected String unmarshallString(ObjectInputStream in) throws Exception
{
return (String) in.readObject();
}
private ReplicableCommand unmarshallCommand(ObjectInputStream in, UnmarshalledReferences refMap) throws Exception
{
short methodId = in.readShort();
byte numArgs = in.readByte();
Object[] args = null;
if (numArgs > 0)
{
args = new Object[numArgs];
for (int i = 0; i < numArgs; i++) args[i] = unmarshallObject(in, refMap);
}
return commandsFactory.fromStream(methodId, args);
}
private GlobalTransaction unmarshallGlobalTransaction(ObjectInputStream in, UnmarshalledReferences refMap) throws Exception
{
GlobalTransaction gtx = new GlobalTransaction();
long id = in.readLong();
Object address = unmarshallObject(in, refMap);
gtx.setId(id);
gtx.setAddress((Address) address);
return gtx;
}
protected Fqn unmarshallFqn(ObjectInputStream in, UnmarshalledReferences refMap) throws Exception
{
boolean isRoot = in.readBoolean();
Fqn fqn;
if (!isRoot)
{
int numElements = in.readShort();
List elements = new ArrayList(numElements);
for (int i = 0; i < numElements; i++)
{
elements.add(unmarshallObject(in, refMap));
}
fqn = Fqn.fromList(elements, true);
}
else
{
fqn = Fqn.ROOT;
}
return fqn;
}
private IpAddress unmarshallIpAddress(ObjectInputStream in) throws Exception
{
IpAddress ipAddress = new IpAddress();
ipAddress.readExternal(in);
return ipAddress;
}
private List unmarshallArrayList(ObjectInputStream in, UnmarshalledReferences refMap) throws Exception
{
int listSize = readUnsignedInt(in);
List list = new ArrayList(listSize);
populateFromStream(in, refMap, list, listSize);
return list;
}
private List unmarshallLinkedList(ObjectInputStream in, UnmarshalledReferences refMap) throws Exception
{
List list = new LinkedList();
populateFromStream(in, refMap, list, readUnsignedInt(in));
return list;
}
private Map unmarshallHashMap(ObjectInputStream in, UnmarshalledReferences refMap) throws Exception
{
Map map = new HashMap();
populateFromStream(in, refMap, map);
return map;
}
@SuppressWarnings("unchecked")
private Map unmarshallMapCopy(ObjectInputStream in, UnmarshalledReferences refMap) throws Exception
{
// read in as a HashMap first
Map m = unmarshallHashMap(in, refMap);
return Immutables.immutableMapWrap(m);
}
private Map unmarshallTreeMap(ObjectInputStream in, UnmarshalledReferences refMap) throws Exception
{
Map map = new TreeMap();
populateFromStream(in, refMap, map);
return map;
}
private Set unmarshallHashSet(ObjectInputStream in, UnmarshalledReferences refMap) throws Exception
{
Set set = new HashSet();
populateFromStream(in, refMap, set);
return set;
}
private Set unmarshallTreeSet(ObjectInputStream in, UnmarshalledReferences refMap) throws Exception
{
Set set = new TreeSet();
populateFromStream(in, refMap, set);
return set;
}
@SuppressWarnings("unchecked")
private void populateFromStream(ObjectInputStream in, UnmarshalledReferences refMap, Map mapToPopulate) throws Exception
{
int size = readUnsignedInt(in);
for (int i = 0; i < size; i++) mapToPopulate.put(unmarshallObject(in, refMap), unmarshallObject(in, refMap));
}
@SuppressWarnings("unchecked")
private void populateFromStream(ObjectInputStream in, UnmarshalledReferences refMap, Set setToPopulate) throws Exception
{
int size = readUnsignedInt(in);
for (int i = 0; i < size; i++) setToPopulate.add(unmarshallObject(in, refMap));
}
@SuppressWarnings("unchecked")
private void populateFromStream(ObjectInputStream in, UnmarshalledReferences refMap, List listToPopulate, int listSize) throws Exception
{
for (int i = 0; i < listSize; i++) listToPopulate.add(unmarshallObject(in, refMap));
}
@SuppressWarnings("deprecation")
protected void marshallDefaultDataVersion(DefaultDataVersion ddv, ObjectOutputStream out) throws Exception
{
writeUnsignedLong(out, ddv.getRawVersion());
}
@SuppressWarnings("deprecation")
protected DefaultDataVersion unmarshallDefaultDataVersion(ObjectInputStream in) throws Exception
{
return new DefaultDataVersion(readUnsignedLong(in));
}
/**
* Reads a reference from a given stream.
*
* @param in the stream to read from
* @return an int representing a reference in RefMap.
* @throws IOException propagated from the OIS
*/
protected int readReference(ObjectInputStream in) throws IOException
{
return in.readShort();
}
/**
* Writes a reference to a given object output stream.
*
* @param out the stream to write to
* @param reference the reference to write
* @throws java.io.IOException propagated from the OOS
*/
protected void writeReference(ObjectOutputStream out, int reference) throws IOException
{
out.writeShort(reference);
}
protected int readUnsignedInt(ObjectInputStream in) throws IOException
{
return in.readInt();
}
protected void writeUnsignedInt(ObjectOutputStream out, int i) throws IOException
{
out.writeInt(i);
}
protected long readUnsignedLong(ObjectInputStream in) throws IOException
{
return in.readLong();
}
protected void writeUnsignedLong(ObjectOutputStream out, long i) throws IOException
{
out.writeLong(i);
}
protected Object unmarshallArray(ObjectInputStream in, UnmarshalledReferences refs) throws Exception
{
int sz = readUnsignedInt(in);
byte type = in.readByte();
switch (type)
{
case MAGICNUMBER_BOOLEAN:
{
boolean isPrim = in.readBoolean();
if (isPrim)
{
boolean[] a = new boolean[sz];
for (int i = 0; i < sz; i++) a[i] = in.readBoolean();
return a;
}
else
{
Boolean[] a = new Boolean[sz];
for (int i = 0; i < sz; i++) a[i] = in.readBoolean();
return a;
}
}
case MAGICNUMBER_INTEGER:
{
boolean isPrim = in.readBoolean();
if (isPrim)
{
int[] a = new int[sz];
for (int i = 0; i < sz; i++) a[i] = in.readInt();
return a;
}
else
{
Integer[] a = new Integer[sz];
for (int i = 0; i < sz; i++) a[i] = in.readInt();
return a;
}
}
case MAGICNUMBER_LONG:
{
boolean isPrim = in.readBoolean();
if (isPrim)
{
long[] a = new long[sz];
for (int i = 0; i < sz; i++) a[i] = in.readLong();
return a;
}
else
{
Long[] a = new Long[sz];
for (int i = 0; i < sz; i++) a[i] = in.readLong();
return a;
}
}
case MAGICNUMBER_CHAR:
{
boolean isPrim = in.readBoolean();
if (isPrim)
{
char[] a = new char[sz];
for (int i = 0; i < sz; i++) a[i] = in.readChar();
return a;
}
else
{
Character[] a = new Character[sz];
for (int i = 0; i < sz; i++) a[i] = in.readChar();
return a;
}
}
case MAGICNUMBER_BYTE:
{
boolean isPrim = in.readBoolean();
if (isPrim)
{
byte[] a = new byte[sz];
int bsize = 10240;
int offset = 0;
int bytesLeft = sz;
while (bytesLeft > 0)
{
int read = in.read(a, offset, Math.min(bsize, bytesLeft));
offset += read;
bytesLeft -= read;
}
return a;
}
else
{
Byte[] a = new Byte[sz];
for (int i = 0; i < sz; i++) a[i] = in.readByte();
return a;
}
}
case MAGICNUMBER_SHORT:
{
boolean isPrim = in.readBoolean();
if (isPrim)
{
short[] a = new short[sz];
for (int i = 0; i < sz; i++) a[i] = in.readShort();
return a;
}
else
{
Short[] a = new Short[sz];
for (int i = 0; i < sz; i++) a[i] = in.readShort();
return a;
}
}
case MAGICNUMBER_FLOAT:
{
boolean isPrim = in.readBoolean();
if (isPrim)
{
float[] a = new float[sz];
for (int i = 0; i < sz; i++) a[i] = in.readFloat();
return a;
}
else
{
Float[] a = new Float[sz];
for (int i = 0; i < sz; i++) a[i] = in.readFloat();
return a;
}
}
case MAGICNUMBER_DOUBLE:
{
boolean isPrim = in.readBoolean();
if (isPrim)
{
double[] a = new double[sz];
for (int i = 0; i < sz; i++) a[i] = in.readDouble();
return a;
}
else
{
Double[] a = new Double[sz];
for (int i = 0; i < sz; i++) a[i] = in.readDouble();
return a;
}
}
case MAGICNUMBER_OBJECT:
{
Object[] a = new Object[sz];
for (int i = 0; i < sz; i++) a[i] = unmarshallObject(in, refs);
return a;
}
default:
throw new CacheException("Unknown array type");
}
}
}