Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  package io.protostuff.runtime;
  
  import static io.protostuff.runtime.RuntimeFieldFactory.ID_BOOL;
  import static io.protostuff.runtime.RuntimeFieldFactory.ID_BYTE;
  import static io.protostuff.runtime.RuntimeFieldFactory.ID_CHAR;
  import static io.protostuff.runtime.RuntimeFieldFactory.ID_DOUBLE;
  import static io.protostuff.runtime.RuntimeFieldFactory.ID_FLOAT;
  import static io.protostuff.runtime.RuntimeFieldFactory.ID_INT32;
  import static io.protostuff.runtime.RuntimeFieldFactory.ID_INT64;
 import static io.protostuff.runtime.RuntimeFieldFactory.ID_SHORT;
 
 import java.util.Map;
 
The FQCN(fully qualified class name) will serve as the id (string). Does not need any registration in the user-code (works out-of-the-box). The size of serialized representation may be not very efficient.

Author(s):
Leo Romanoff
David Yu
 
 public final class DefaultIdStrategy extends IdStrategy
 {
 
     final ConcurrentHashMap<StringHasSchema<?>> pojoMapping = new ConcurrentHashMap<>();
 
     final ConcurrentHashMap<StringEnumIO<?>> enumMapping = new ConcurrentHashMap<>();
 
 
 
 
     public DefaultIdStrategy()
     {
         super(null, 0);
     }
 
     public DefaultIdStrategy(IdStrategy primaryGroupint groupId)
     {
         super(primaryGroupgroupId);
     }

    
Registers a pojo. Returns true if registration is successful or if the same exact schema was previously registered. Used by RuntimeSchema.register(java.lang.Class,io.protostuff.Schema).
 
     public <T> boolean registerPojo(Class<T> typeClassSchema<T> schema)
     {
         assert typeClass != null && schema != null;
 
         final HasSchema<?> last = .putIfAbsent(typeClass.getName(),
                 new Registered<>(schema));
 
         return last == null
                 || (last instanceof Registered<?> && ((Registered<?>) last). == schema);
     }

    
Registers an enum. Returns true if registration is successful.
 
     public <T extends Enum<T>> boolean registerEnum(Class<T> enumClass)
     {
         return null == .putIfAbsent(enumClass.getName(),
                 EnumIO.newEnumIO(enumClass));
     }

    
Registers a delegate. Returns true if registration is successful.
 
     public <T> boolean registerDelegate(Delegate<T> delegate)
     {
         return null == .putIfAbsent(delegate.typeClass()
                 .getName(), new HasDelegate<>(delegate));
     }

    
Registers a collection. Returns true if registration is successful.
 
     public boolean registerCollection(CollectionSchema.MessageFactory factory)
     {
         return null == .putIfAbsent(factory.typeClass()
                 .getName(), factory);
     }

    
Registers a map. Returns true if registration is successful.
    public boolean registerMap(MapSchema.MessageFactory factory)
    {
        return null == .putIfAbsent(factory.typeClass().getName(),
                factory);
    }

    
    public <T> boolean map(Class<? super T> baseClassClass<T> typeClass)
    {
        assert baseClass != null && typeClass != null;
        if (typeClass.isInterface()
                || Modifier.isAbstract(typeClass.getModifiers()))
        {
            throw new IllegalArgumentException(typeClass
                    + " cannot be an interface/abstract class.");
        }
        final HasSchema<?> last = .putIfAbsent(baseClass.getName(),
                new Mapped<>(baseClasstypeClassthis));
        return last == null
                || (last instanceof Mapped<?> && ((Mapped<?>) last). == typeClass);
    }
    @Override
    public boolean isDelegateRegistered(Class<?> typeClass)
    {
        return .containsKey(typeClass.getName());
    }
    @Override
    @SuppressWarnings("unchecked")
    public <T> HasDelegate<T> getDelegateWrapper(Class<? super T> typeClass)
    {
        return (HasDelegate<T>) .get(typeClass.getName());
    }
    @Override
    @SuppressWarnings("unchecked")
    public <T> Delegate<T> getDelegate(Class<? super T> typeClass)
    {
        final HasDelegate<T> last = (HasDelegate<T>) 
                .get(typeClass.getName());
        return last == null ? null : last.delegate;
    }
    @Override
    public boolean isRegistered(Class<?> typeClass)
    {
        final HasSchema<?> last = .get(typeClass.getName());
        return last != null && !(last instanceof Lazy<?>);
    }
    @SuppressWarnings("unchecked")
    private <T> HasSchema<T> getSchemaWrapper(String classNameboolean load)
    {
        HasSchema<T> hs = (HasSchema<T>) .get(className);
        if (hs == null)
        {
            if (!load)
                return null;
            final Class<T> typeClass = RuntimeEnv.loadClass(className);
            hs = new Lazy<>(typeClassthis);
            final HasSchema<T> last = (HasSchema<T>) .putIfAbsent(
                    typeClass.getName(), hs);
            if (last != null)
                hs = last;
        }
        return hs;
    }
    @Override
    @SuppressWarnings("unchecked")
    public <T> HasSchema<T> getSchemaWrapper(Class<T> typeClassboolean create)
    {
        HasSchema<T> hs = (HasSchema<T>) .get(typeClass.getName());
        if (hs == null && create)
        {
            hs = new Lazy<>(typeClassthis);
            final HasSchema<T> last = (HasSchema<T>) .putIfAbsent(
                    typeClass.getName(), hs);
            if (last != null)
                hs = last;
        }
        return hs;
    }
    private EnumIO<? extends Enum<?>> getEnumIO(String classNameboolean load)
    {
        EnumIO<?> eio = .get(className);
        if (eio == null)
        {
            if (!load)
                return null;
            final Class<?> enumClass = RuntimeEnv.loadClass(className);
            eio = EnumIO.newEnumIO(enumClass);
            final EnumIO<?> existing = .putIfAbsent(
                    enumClass.getName(), eio);
            if (existing != null)
                eio = existing;
        }
        return eio;
    }
    @Override
    protected EnumIO<? extends Enum<?>> getEnumIO(Class<?> enumClass)
    {
        EnumIO<?> eio = .get(enumClass.getName());
        if (eio == null)
        {
            eio = EnumIO.newEnumIO(enumClass);
            final EnumIO<?> existing = .putIfAbsent(
                    enumClass.getName(), eio);
            if (existing != null)
                eio = existing;
        }
        return eio;
    }
    @Override
            Class<?> clazz)
    {
        final String className = clazz.getName();
                .get(className);
        if (factory == null)
        {
            if (className.startsWith("java.util"))
            {
                factory = CollectionSchema.MessageFactories.valueOf(clazz
                        .getSimpleName());
            }
            else
            {
                factory = new RuntimeCollectionFactory(clazz);
                CollectionSchema.MessageFactory f = 
                        .putIfAbsent(classNamefactory);
                if (f != null)
                    factory = f;
            }
        }
        return factory;
    }
    @Override
    protected MapSchema.MessageFactory getMapFactory(Class<?> clazz)
    {
        final String className = clazz.getName();
        MapSchema.MessageFactory factory = .get(className);
        if (factory == null)
        {
            if (className.startsWith("java.util"))
            {
                factory = MapSchema.MessageFactories.valueOf(clazz
                        .getSimpleName());
            }
            else
            {
                factory = new RuntimeMapFactory(clazz);
                MapSchema.MessageFactory f = .putIfAbsent(className,
                        factory);
                if (f != null)
                    factory = f;
            }
        }
        return factory;
    }
    @Override
    protected void writeCollectionIdTo(Output outputint fieldNumber,
            Class<?> clazzthrows IOException
    {
        final CollectionSchema.MessageFactory factory = 
                .get(clazz);
        if (factory == null && clazz.getName().startsWith("java.util"))
        {
            // jdk collection
            // better not to register the jdk collection if using this strategy
            // as it saves space by not writing the full package
            output.writeString(fieldNumberclazz.getSimpleName(), false);
        }
        else
        {
            output.writeString(fieldNumberclazz.getName(), false);
        }
    }
    @Override
    protected void transferCollectionId(Input inputOutput output,
            int fieldNumberthrows IOException
    {
        input.transferByteRangeTo(outputtruefieldNumberfalse);
    }
    @Override
            throws IOException
    {
        final String className = input.readString();
                .get(className);
        if (factory == null)
        {
            if (className.indexOf('.') == -1)
            {
                factory = CollectionSchema.MessageFactories.valueOf(className);
            }
            else
            {
                factory = new RuntimeCollectionFactory(
                        RuntimeEnv.loadClass(className));
                CollectionSchema.MessageFactory f = 
                        .putIfAbsent(classNamefactory);
                if (f != null)
                    factory = f;
            }
        }
        return factory;
    }
    @Override
    protected void writeMapIdTo(Output outputint fieldNumberClass<?> clazz)
            throws IOException
    {
        final MapSchema.MessageFactory factory = .get(clazz);
        if (factory == null && clazz.getName().startsWith("java.util"))
        {
            // jdk map
            // better not to register the jdk map if using this strategy
            // as it saves space by not writing the full package
            output.writeString(fieldNumberclazz.getSimpleName(), false);
        }
        else
        {
            output.writeString(fieldNumberclazz.getName(), false);
        }
    }
    @Override
    protected void transferMapId(Input inputOutput outputint fieldNumber)
            throws IOException
    {
        input.transferByteRangeTo(outputtruefieldNumberfalse);
    }
    @Override
    protected MapSchema.MessageFactory resolveMapFrom(Input input)
            throws IOException
    {
        final String className = input.readString();
        MapSchema.MessageFactory factory = .get(className);
        if (factory == null)
        {
            if (className.indexOf('.') == -1)
            {
                factory = MapSchema.MessageFactories.valueOf(className);
            }
            else
            {
                factory = new RuntimeMapFactory(RuntimeEnv.loadClass(className));
                MapSchema.MessageFactory f = .putIfAbsent(className,
                        factory);
                if (f != null)
                    factory = f;
            }
        }
        return factory;
    }
    @Override
    protected void writeEnumIdTo(Output outputint fieldNumberClass<?> clazz)
            throws IOException
    {
        output.writeString(fieldNumberclazz.getName(), false);
    }
    @Override
    protected void transferEnumId(Input inputOutput outputint fieldNumber)
            throws IOException
    {
        input.transferByteRangeTo(outputtruefieldNumberfalse);
    }
    @Override
    protected EnumIO<?> resolveEnumFrom(Input inputthrows IOException
    {
        return getEnumIO(input.readString(), true);
    }
    @Override
    @SuppressWarnings("unchecked")
    protected <T> HasDelegate<T> tryWriteDelegateIdTo(Output output,
            int fieldNumberClass<T> clazzthrows IOException
    {
        final HasDelegate<T> hd = (HasDelegate<T>) .get(clazz
                .getName());
        if (hd == null)
            return null;
        output.writeString(fieldNumberclazz.getName(), false);
        return hd;
    }
    @Override
    @SuppressWarnings("unchecked")
    protected <T> HasDelegate<T> transferDelegateId(Input inputOutput output,
            int fieldNumberthrows IOException
    {
        final String className = input.readString();
        final HasDelegate<T> hd = (HasDelegate<T>) 
                .get(className);
        if (hd == null)
            throw new UnknownTypeException("delegate: " + className
                    + " (Outdated registry)");
        output.writeString(fieldNumberclassNamefalse);
        return hd;
    }
    @Override
    @SuppressWarnings("unchecked")
    protected <T> HasDelegate<T> resolveDelegateFrom(Input input)
            throws IOException
    {
        final String className = input.readString();
        final HasDelegate<T> hd = (HasDelegate<T>) 
                .get(className);
        if (hd == null)
            throw new UnknownTypeException("delegate: " + className
                    + " (Outdated registry)");
        return hd;
    }
    @Override
    protected <T> HasSchema<T> writePojoIdTo(Output outputint fieldNumber,
            Class<T> clazzthrows IOException
    {
        output.writeString(fieldNumberclazz.getName(), false);
        // it is important to return the schema initialized (if it hasn't been).
        return getSchemaWrapper(clazztrue);
    }
    @Override
    protected <T> HasSchema<T> transferPojoId(Input inputOutput output,
            int fieldNumberthrows IOException
    {
        final String className = input.readString();
        final HasSchema<T> wrapper = getSchemaWrapper(className,
                .);
        if (wrapper == null)
        {
            throw new ProtostuffException("polymorphic pojo not registered: "
                    + className);
        }
        output.writeString(fieldNumberclassNamefalse);
        return wrapper;
    }
    @Override
    protected <T> HasSchema<T> resolvePojoFrom(Input inputint fieldNumber)
            throws IOException
    {
        final String className = input.readString();
        final HasSchema<T> wrapper = getSchemaWrapper(className,
                .);
        if (wrapper == null)
            throw new ProtostuffException("polymorphic pojo not registered: "
                    + className);
        return wrapper;
    }
    @Override
    protected <T> Schema<T> writeMessageIdTo(Output outputint fieldNumber,
            Message<T> messagethrows IOException
    {
        output.writeString(fieldNumbermessage.getClass().getName(), false);
        return message.cachedSchema();
    }
    @Override
    protected void writeArrayIdTo(Output outputClass<?> componentType)
            throws IOException
    {
                componentType.getName(), false);
    }
    @Override
    protected void transferArrayId(Input inputOutput outputint fieldNumber,
            boolean mappedthrows IOException
    {
        input.transferByteRangeTo(outputtruefieldNumberfalse);
    }
    @Override
    protected Class<?> resolveArrayComponentTypeFrom(Input inputboolean mapped)
            throws IOException
    {
        return resolveClass(input.readString());
    }
    static Class<?> resolveClass(String className)
    {
        final RuntimeFieldFactory<Objectinline = RuntimeFieldFactory
                .getInline(className);
        if (inline == null)
            return RuntimeEnv.loadClass(className);
        if (className.indexOf('.') != -1)
            return inline.typeClass();
        switch (inline.id)
        {
            case :
                return boolean.class;
            case :
                return byte.class;
            case :
                return char.class;
            case :
                return short.class;
            case :
                return int.class;
            case :
                return long.class;
            case :
                return float.class;
            case :
                return double.class;
            default:
                throw new RuntimeException("Should never happen.");
        }
    }
    @Override
    protected void writeClassIdTo(Output outputClass<?> componentType,
            boolean arraythrows IOException
    {
        final int id = array ? .
                : .;
        output.writeString(idcomponentType.getName(), false);
    }
    @Override
    protected void transferClassId(Input inputOutput outputint fieldNumber,
            boolean mappedboolean arraythrows IOException
    {
        input.transferByteRangeTo(outputtruefieldNumberfalse);
    }
    @Override
    protected Class<?> resolveClassFrom(Input inputboolean mapped,
            boolean arraythrows IOException
    {
        return resolveClass(input.readString());
    }
    static final class RuntimeCollectionFactory implements
            CollectionSchema.MessageFactory
    {
        final Class<?> collectionClass;
        final RuntimeEnv.Instantiator<?> instantiator;
        public RuntimeCollectionFactory(Class<?> collectionClass)
        {
            this. = collectionClass;
             = RuntimeEnv.newInstantiator(collectionClass);
        }
        @Override
        @SuppressWarnings("unchecked")
        public <V> Collection<V> newMessage()
        {
            return (Collection<V>) .newInstance();
        }
        @Override
        public Class<?> typeClass()
        {
            return ;
        }
    }
    static final class RuntimeMapFactory implements MapSchema.MessageFactory
    {
        final Class<?> mapClass;
        final RuntimeEnv.Instantiator<?> instantiator;
        public RuntimeMapFactory(Class<?> mapClass)
        {
            this. = mapClass;
             = RuntimeEnv.newInstantiator(mapClass);
        }
        @Override
        @SuppressWarnings("unchecked")
        public <K, V> Map<K, V> newMessage()
        {
            return (Map<K, V>) .newInstance();
        }
        @Override
        public Class<?> typeClass()
        {
            return ;
        }
    }
    static final class Lazy<T> extends HasSchema<T>
    {
        final IdStrategy strategy;
        final Class<T> typeClass;
        private volatile Schema<T> schema;
        private volatile Pipe.Schema<T> pipeSchema;
        Lazy(Class<T> typeClassIdStrategy strategy)
        {
            this. = typeClass;
            this. = strategy;
        }
        @Override
        @SuppressWarnings("unchecked")
        public Schema<T> getSchema()
        {
            Schema<T> schema = this.;
            if (schema == null)
            {
                synchronized (this)
                {
                    if ((schema = this.) == null)
                    {
                        if (Message.class.isAssignableFrom())
                        {
                            // use the message's schema.
                            try
                            {
                                final Message<T> m = (Message<T>) 
                                        .newInstance();
                                this. = schema = m.cachedSchema();
                            }
                            catch (InstantiationException | IllegalAccessException e)
                            {
                                throw new RuntimeException(e);
                            }
                        }
                        else
                        {
                            // create new
                            this. = schema = 
                                    .newSchema();
                        }
                    }
                }
            }
            return schema;
        }
        @Override
        public Pipe.Schema<T> getPipeSchema()
        {
            Pipe.Schema<T> pipeSchema = this.;
            if (pipeSchema == null)
            {
                synchronized (this)
                {
                    if ((pipeSchema = this.) == null)
                    {
                        this. = pipeSchema = RuntimeSchema
                                .resolvePipeSchema(getSchema(), true);
                    }
                }
            }
            return pipeSchema;
        }
    }
    static final class Mapped<T> extends HasSchema<T>
    {
        final IdStrategy strategy;
        final Class<? super T> baseClass;
        final Class<T> typeClass;
        private volatile HasSchema<T> wrapper;
        Mapped(Class<? super T> baseClassClass<T> typeClass,
                IdStrategy strategy)
        {
            this. = baseClass;
            this. = typeClass;
            this. = strategy;
        }
        @Override
        public Schema<T> getSchema()
        {
            HasSchema<T> wrapper = this.;
            if (wrapper == null)
            {
                synchronized (this)
                {
                    if ((wrapper = this.) == null)
                    {
                        this. = wrapper = .getSchemaWrapper(
                                true);
                    }
                }
            }
            return wrapper.getSchema();
        }
        @Override
        public Pipe.Schema<T> getPipeSchema()
        {
            HasSchema<T> wrapper = this.;
            if (wrapper == null)
            {
                synchronized (this)
                {
                    if ((wrapper = this.) == null)
                    {
                        this. = wrapper = .getSchemaWrapper(
                                true);
                    }
                }
            }
            return wrapper.getPipeSchema();
        }
    }
    static final class Registered<T> extends HasSchema<T>
    {
        final Schema<T> schema;
        private volatile Pipe.Schema<T> pipeSchema;
        Registered(Schema<T> schema)
        {
            this. = schema;
        }
        @Override
        public Schema<T> getSchema()
        {
            return ;
        }
        @Override
        public Pipe.Schema<T> getPipeSchema()
        {
            Pipe.Schema<T> pipeSchema = this.;
            if (pipeSchema == null)
            {
                synchronized (this)
                {
                    if ((pipeSchema = this.) == null)
                    {
                        this. = pipeSchema = RuntimeSchema
                                .resolvePipeSchema(.typeClass(),
                                        true);
                    }
                }
            }
            return pipeSchema;
        }
    }
New to GrepCode? Check out our FAQ X