private static <T> Field<T> createCollectionEnumV( int number, String name, final java.lang.reflect.Field f, final MessageFactory messageFactory, final Class<Object> genericType, IdStrategy strategy) { final EnumIO<?> eio = strategy.getEnumIO(genericType); return new Field<T>(FieldType.ENUM, number, name, true, f.getAnnotation(Tag.class)) { { f.setAccessible(true); } @SuppressWarnings("unchecked") protected void mergeFrom(Input input, T message) throws IOException { final Enum<?> value = eio.readFrom(input); try { final Collection<Enum<?>> existing = (Collection<Enum<?>>) f.get(message); if (existing == null) { final Collection<Enum<?>> collection = messageFactory.newMessage(); collection.add(value); f.set(message, collection); } else existing.add(value); } catch (IllegalArgumentException e) { throw new RuntimeException(e); } catch (IllegalAccessException e) { throw new RuntimeException(e); } } @SuppressWarnings("unchecked") protected void writeTo(Output output, T message) throws IOException { final Collection<Enum<?>> collection; try { collection = (Collection<Enum<?>>) f.get(message); } catch (IllegalArgumentException e) { throw new RuntimeException(e); } catch (IllegalAccessException e) { throw new RuntimeException(e); } if (collection != null && !collection.isEmpty()) { for (Enum<?> en : collection) EnumIO.writeTo(output, number, true, en); } } protected void transfer(Pipe pipe, Input input, Output output, boolean repeated) throws IOException { EnumIO.transfer(pipe, input, output, number, repeated); } }; }
@SuppressWarnings("unchecked") public <T> Field<T> create( int number, String name, final java.lang.reflect.Field f, IdStrategy strategy) { if (null != f.getAnnotation(Morph.class)) { // can be used to override the configured system property: // RuntimeEnv.COLLECTION_SCHEMA_ON_REPEATED_FIELDS // In this context, Morph annotation will force using a // collection // schema only for this particular field. return RuntimeCollectionFieldFactory.getFactory().create(number, name, f, strategy); } if (EnumSet.class.isAssignableFrom(f.getType())) { final Class<Object> enumType = (Class<Object>) getGenericType(f, 0); if (enumType == null) { // still handle the serialization of EnumSets even without // generics return RuntimeFieldFactory.OBJECT.create(number, name, f, strategy); } return createCollectionEnumV( number, name, f, strategy.getEnumIO(enumType).getEnumSetFactory(), enumType, strategy); } final MessageFactory messageFactory = strategy.getCollectionFactory(f.getType()); final Class<Object> genericType = (Class<Object>) getGenericType(f, 0); if (genericType == null) { // the value is not a simple parameterized type. return createCollectionObjectV( number, name, f, messageFactory, genericType, PolymorphicSchemaFactories.OBJECT, strategy); } final Delegate<Object> inline = getDelegateOrInline(genericType, strategy); if (inline != null) return createCollectionInlineV(number, name, f, messageFactory, inline); if (Message.class.isAssignableFrom(genericType)) return createCollectionPojoV(number, name, f, messageFactory, genericType, strategy); if (genericType.isEnum()) return createCollectionEnumV(number, name, f, messageFactory, genericType, strategy); final PolymorphicSchema.Factory factory = PolymorphicSchemaFactories.getFactoryFromRepeatedValueGenericType(genericType); if (factory != null) { return createCollectionObjectV( number, name, f, messageFactory, genericType, factory, strategy); } if (pojo(genericType, f.getAnnotation(Morph.class), strategy)) return createCollectionPojoV(number, name, f, messageFactory, genericType, strategy); if (genericType.isInterface()) { return createCollectionObjectV( number, name, f, messageFactory, genericType, PolymorphicSchemaFactories.OBJECT, strategy); } return createCollectionPolymorphicV( number, name, f, messageFactory, genericType, strategy); }