Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  //========================================================================
  //Copyright 2007-2010 David Yu dyuproject@gmail.com
  //------------------------------------------------------------------------
  //Licensed under the Apache License, Version 2.0 (the "License");
  //you may not use this file except in compliance with the License.
  //You may obtain a copy of the License at 
  //http://www.apache.org/licenses/LICENSE-2.0
  //Unless required by applicable law or agreed to in writing, software
  //distributed under the License is distributed on an "AS IS" BASIS,
 //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 //See the License for the specific language governing permissions and
 //limitations under the License.
 //========================================================================
 
 package io.protostuff.runtime;
 
 import static io.protostuff.runtime.RuntimeEnv.ENUMS_BY_NAME;
 
 import java.util.Map;
 
Determines how enums are serialized/deserialized. Default is BY_NUMBER. To enable BY_NAME, set the property "protostuff.runtime.enums_by_name=true".

Author(s):
David Yu
Created:
Oct 20, 2010
 
 public abstract class EnumIO<E extends Enum<E>> implements
         PolymorphicSchema.Factory
 {
 
     // Used by ObjectSchema to ser/deser both EnumMap and EnumSet.
     private static final java.lang.reflect.Field __keyTypeFromEnumMap;
     private static final java.lang.reflect.Field __elementTypeFromEnumSet;
 
     static
     {
         boolean success = false;
         java.lang.reflect.Field keyTypeFromMap = nullvalueTypeFromSet = null;
         try
         {
             keyTypeFromMap = EnumMap.class.getDeclaredField("keyType");
             keyTypeFromMap.setAccessible(true);
             valueTypeFromSet = EnumSet.class.getDeclaredField("elementType");
             valueTypeFromSet.setAccessible(true);
             success = true;
         }
         catch (Exception e)
         {
             // ignore
         }
 
          = success ? keyTypeFromMap : null;
          = success ? valueTypeFromSet : null;
     }

    
Retrieves the enum key type from the EnumMap via reflection. This is used by ObjectSchema.
 
     static Class<?> getKeyTypeFromEnumMap(Object enumMap)
     {
         if ( == null)
         {
             throw new RuntimeException(
                     "Could not access (reflection) the private "
                             + "field *keyType* (enumClass) from: class java.util.EnumMap");
         }
 
         try
         {
             return (Class<?>) .get(enumMap);
         }
         catch (IllegalArgumentException | IllegalAccessException e)
         {
             throw new RuntimeException(e);
         }
     }

    
Retrieves the enum key type from the EnumMap via reflection. This is used by ObjectSchema.
 
     static Class<?> getElementTypeFromEnumSet(Object enumSet)
     {
         if ( == null)
         {
            throw new RuntimeException(
                    "Could not access (reflection) the private "
                            + "field *elementType* (enumClass) from: class java.util.EnumSet");
        }
        try
        {
            return (Class<?>) .get(enumSet);
        }
        catch (IllegalArgumentException | IllegalAccessException e)
        {
            throw new RuntimeException(e);
        }
    }
    @SuppressWarnings({ "unchecked""rawtypes" })
    static EnumIO<? extends Enum<?>> newEnumIO(Class<?> enumClass)
    {
        return  ? new ByName(enumClass) : new ByNumber(enumClass);
    }

    
Writes the java.lang.Enum to the output.
    public void writeTo(Output outputint numberboolean repeated,
            Enum<?> ethrows IOException
    {
        if ()
        {
            output.writeString(numbergetAlias(e), repeated);
        }
        else
        {
            output.writeEnum(numbergetTag(e), repeated);
        }
    }

    
Transfers the java.lang.Enum from the input to the output.
    public static void transfer(Pipe pipeInput inputOutput output,
            int numberboolean repeatedthrows IOException
    {
        if ()
            input.transferByteRangeTo(outputtruenumberrepeated);
        else
            output.writeEnum(numberinput.readEnum(), repeated);
    }
    private static <E extends Enum<E>> CollectionSchema.MessageFactory newEnumSetFactory(
            final EnumIO<E> eio)
    {
        return new CollectionSchema.MessageFactory()
        {
            @Override
            @SuppressWarnings("unchecked")
            public <V> Collection<V> newMessage()
            {
                return (Collection<V>) eio.newEnumSet();
            }
            @Override
            public Class<?> typeClass()
            {
                return EnumSet.class;
            }
        };
    }
    private static <E extends Enum<E>> MapSchema.MessageFactory newEnumMapFactory(
            final EnumIO<E> eio)
    {
        return new MapSchema.MessageFactory()
        {
            @Override
            @SuppressWarnings("unchecked")
            public <K, V> Map<K, V> newMessage()
            {
                return (Map<K, V>) eio.newEnumMap();
            }
            @Override
            public Class<?> typeClass()
            {
                return EnumMap.class;
            }
        };
    }

    
The enum class.
    public final Class<E> enumClass;
    private volatile MapSchema.MessageFactory enumMapFactory;
            nullthis);
    private final String[] alias;
    private final int[] tag;
    private final Map<String, E> valueByAliasMap;
    private final Map<Integer, E> valueByTagMap;
    public EnumIO(Class<E> enumClass)
    {
        this. = enumClass;
        Field[] fields = enumClass.getFields();
        int n = fields.length;
         = new String[n];
         = new int[n];
         = new HashMap<>(n * 2);
         = new HashMap<>(n * 2);
        for (E instance : enumClass.getEnumConstants())
        {
            int ordinal = instance.ordinal();
            try
            {
                Field field = enumClass.getField(instance.name());
                if (field.isAnnotationPresent(Tag.class))
                {
                    Tag annotation = field.getAnnotation(Tag.class);
                    [ordinal] = annotation.value();
                    [ordinal] = annotation.alias();
                    .put(annotation.value(), instance);
                    .put(annotation.alias(), instance);
                }
                else
                {
                    [ordinal] = ordinal;
                    [ordinal] = field.getName();
                    .put(ordinalinstance);
                    .put(field.getName(), instance);
                }
            }
            catch (NoSuchFieldException e)
            {
                throw new IllegalStateException(e);
            }
        }
    }
    @Override
    public PolymorphicSchema newSchema(Class<?> typeClassIdStrategy strategy,
            Handler handler)
    {
        return new ArraySchemas.EnumArray(handlerthis);
    }
    public int getTag(Enum<?> element)
    {
        return [element.ordinal()];
    }
    public String getAlias(Enum<?> element)
    {
        return [element.ordinal()];
    }
    public E getByTag(int tag)
    {
        return .get(tag);
    }
    public E getByAlias(String alias)
    {
        return .get(alias);
    }

    
Returns the factory for an EnumSet (lazy).
    {
        CollectionSchema.MessageFactory enumSetFactory = this.;
        if (enumSetFactory == null)
        {
            synchronized (this)
            {
                if ((enumSetFactory = this.) == null)
                    this. = enumSetFactory = newEnumSetFactory(this);
            }
        }
        return enumSetFactory;
    }

    
Returns the factory for an EnumMap (lazy).
    {
        MapSchema.MessageFactory enumMapFactory = this.;
        if (enumMapFactory == null)
        {
            synchronized (this)
            {
                if ((enumMapFactory = this.) == null)
                    this. = enumMapFactory = newEnumMapFactory(this);
            }
        }
        return enumMapFactory;
    }

    
Returns an empty java.util.EnumSet.
    public EnumSet<E> newEnumSet()
    {
        return EnumSet.noneOf();
    }

    
Returns an empty java.util.EnumMap.
    public <V> EnumMap<E, V> newEnumMap()
    {
        return new EnumMap<>();
    }

    
Read the enum from the input.
    public abstract E readFrom(Input inputthrows IOException;

    
Reads the enum by its name.
    public static final class ByName<E extends Enum<E>> extends EnumIO<E>
    {
        public ByName(Class<E> enumClass)
        {
            super(enumClass);
        }
        @Override
        public E readFrom(Input inputthrows IOException
        {
            String alias = input.readString();
            return getByAlias(alias);
        }
    }

    
Reads the enum by its number.
    public static final class ByNumber<E extends Enum<E>> extends EnumIO<E>
    {
        public ByNumber(Class<E> enumClass)
        {
            super(enumClass);
        }
        @Override
        public E readFrom(Input inputthrows IOException
        {
            int tag = input.readEnum();
            return getByTag(tag);
        }
    }
New to GrepCode? Check out our FAQ X