Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
package com.dyuproject.protostuff.runtime;
import java.io.IOException;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;
import java.util.Map.Entry;
import com.dyuproject.protostuff.CollectionSchema;
import com.dyuproject.protostuff.GraphInput;
import com.dyuproject.protostuff.Input;
import com.dyuproject.protostuff.MapSchema;
import com.dyuproject.protostuff.MapSchema.MapWrapper;
import com.dyuproject.protostuff.Message;
import com.dyuproject.protostuff.Output;
import com.dyuproject.protostuff.Pipe;
import com.dyuproject.protostuff.ProtostuffException;
import com.dyuproject.protostuff.Schema;
import com.dyuproject.protostuff.runtime.MappedSchema.Field;
/***
* This base class handles all the IO for reading and writing polymorphic fields.
* When a field's type is polymorphic/dynamic (e.g interface/abstract/object),
* the type (id) needs to be written (ahead) before its value/content to be able to
* deserialize it correctly.
*
* The underlying impl will determine how the type (id) should be written.
*
* An {@link IdStrategy} is standalone if the {@link #primaryGroup} is not set.
*
* @author Leo Romanoff
* @author David Yu
*
*/
public abstract class IdStrategy
{
public final IdStrategy primaryGroup;
public final int groupId;
protected IdStrategy(IdStrategy primaryGroup, int groupId)
{
if(primaryGroup != null)
{
if(groupId <= 0 || 0 != (groupId & (groupId-1)))
{
throw new RuntimeException(
"The groupId must be a power of two (1,2,4,8,etc).");
}
}
else if(groupId != 0)
{
throw new RuntimeException("An IdStrategy without a primaryGroup " +
"(standalone) must have a groupId of zero.");
}
this.primaryGroup = primaryGroup;
this.groupId = groupId;
}
/**
* Generates a schema from the given class. If this strategy is part of a group,
* the existing fields of that group's schema will be re-used.
*/
protected Schema newSchema(Class typeClass)
{
// check if this is part of a group
if(primaryGroup != null)
{
// only pojos created by runtime schema support groups
final Schema s = primaryGroup.getSchemaWrapper(
typeClass, true).getSchema();
if(s instanceof RuntimeSchema)
{
final RuntimeSchema rs = (RuntimeSchema)s;
final ArrayList> fields = new ArrayList>(
rs.fields.length);
for(Field f : rs.fields)
{
final int groupFilter = f.groupFilter;
if(groupFilter != 0)
{
final int set; // set for exclusion
if(groupFilter > 0)
{
// inclusion
set = ~groupFilter & 0x7FFFFFFF;
}
else
{
// exclusion
set = -groupFilter;
}
if(0 != (groupId & set))
{
// this field is excluded on the current group id
continue;
}
}
fields.add(f);
}
final int size = fields.size();
if(size == rs.fields.length)
{
// nothing is excluded
return rs;
}
if(size == 0)
{
throw new RuntimeException("All fields were excluded for " +
rs.messageFullName() + " on group " + groupId);
}
return new RuntimeSchema(typeClass, fields,
// the last field
fields.get(size-1).number, rs.instantiator);
}
return s;
}
return RuntimeSchema.createFrom(typeClass, this);
}
/**
* Thrown when a type is not known by the IdStrategy.
* The DefaultIdStrategy will never throw this exception though.
*/
public static class UnknownTypeException extends RuntimeException
{
private static final long serialVersionUID = 1L;
public UnknownTypeException(String msg)
{
super(msg);
}
}
/**
* Responsible for instantiating custom {@link IdStrategy} impls.
*/
public interface Factory
{
/**
* Creates a new {@link IdStrategy} instance (impl).
*/
public IdStrategy create();
/**
* Called after the method {@link #create()} has been called.
* This is used to prevent classloader issues.
* RuntimeEnv's {@link RuntimeEnv#ID_STRATEGY} need to be set first.
*/
public void postCreate();
}
/**
* Returns true if there is a {@link Delegate} explicitly registered for the
* {@code typeClass}.
*/
public abstract boolean isDelegateRegistered(Class> typeClass);
/**
* Returns the {@link Delegate delegate}.
*/
public abstract Delegate getDelegate(Class super T> typeClass);
/**
* Returns true if the {@code typeClass} is explicitly registered.
*/
public abstract boolean isRegistered(Class> typeClass);
/**
* Returns the {@link HasSchema schema wrapper}.
* The caller is responsible that the typeClass is a pojo (e.g not an enum/array/etc).
*/
public abstract HasSchema getSchemaWrapper(Class typeClass,
boolean create);
/**
* Returns the {@link EnumIO}.
* The callers (internal field factories) are responsible that the class provided
* is an enum class.
*/
protected abstract EnumIO extends Enum>> getEnumIO(Class> enumClass);
/**
* Returns the {@link CollectionSchema.MessageFactory}.
* The callers (internal field factories) are responsible that the class provided
* implements {@link Collection}.
*/
protected abstract CollectionSchema.MessageFactory getCollectionFactory(Class> clazz);
/**
* Returns the {@link MapSchema.MessageFactory}.
* The callers (internal field factories}) are responsible that the class provided
* implements {@Map}.
*/
protected abstract MapSchema.MessageFactory getMapFactory(Class> clazz);
// collection
protected abstract void writeCollectionIdTo(Output output, int fieldNumber,
Class> clazz) throws IOException;
protected abstract void transferCollectionId(Input input, Output output,
int fieldNumber) throws IOException;
protected abstract CollectionSchema.MessageFactory resolveCollectionFrom(
Input input) throws IOException;
// map
protected abstract void writeMapIdTo(Output output, int fieldNumber,
Class> clazz) throws IOException;
protected abstract void transferMapId(Input input, Output output,
int fieldNumber) throws IOException;
protected abstract MapSchema.MessageFactory resolveMapFrom(
Input input) throws IOException;
// enum
protected abstract void writeEnumIdTo(Output output, int fieldNumber,
Class> clazz) throws IOException;
protected abstract void transferEnumId(Input input, Output output,
int fieldNumber) throws IOException;
protected abstract EnumIO> resolveEnumFrom(Input input) throws IOException;
// pojo
protected abstract Schema writePojoIdTo(Output output, int fieldNumber,
Class clazz) throws IOException;
protected abstract HasSchema transferPojoId(Input input, Output output,
int fieldNumber) throws IOException;
protected abstract HasSchema resolvePojoFrom(Input input, int fieldNumber)
throws IOException;
protected abstract Schema writeMessageIdTo(Output output, int fieldNumber,
Message message) throws IOException;
// delegate
/**
* If this method returns null, the clazz was not registered as a delegate.
*/
protected abstract Delegate tryWriteDelegateIdTo(Output output,
int fieldNumber, Class clazz) throws IOException;
protected abstract Delegate transferDelegateId(Input input, Output output,
int fieldNumber) throws IOException;
protected abstract Delegate resolveDelegateFrom(Input input) throws IOException;
// array
protected abstract void writeArrayIdTo(Output output, Class> componentType)
throws IOException;
protected abstract void transferArrayId(Input input, Output output, int fieldNumber,
boolean mapped) throws IOException;
protected abstract Class> resolveArrayComponentTypeFrom(Input input,
boolean mapped) throws IOException;
// class
protected abstract void writeClassIdTo(Output output, Class> componentType,
boolean array) throws IOException;
protected abstract void transferClassId(Input input, Output output, int fieldNumber,
boolean mapped, boolean array) throws IOException;
protected abstract Class> resolveClassFrom(Input input,
boolean mapped, boolean array) throws IOException;
// polymorphic requirements
final DerivativeSchema POLYMORPHIC_POJO_ELEMENT_SCHEMA =
new DerivativeSchema(this)
{
@SuppressWarnings("unchecked")
protected void doMergeFrom(Input input, Schema