/* * Hibernate OGM, Domain model persistence for NoSQL datastores * * License: GNU Lesser General Public License (LGPL), version 2.1 or later * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>. */ package org.hibernate.ogm.datastore.infinispanremote.impl.protobuf; import java.io.IOException; import org.infinispan.protostream.MessageMarshaller.ProtoStreamReader; import org.infinispan.protostream.MessageMarshaller.ProtoStreamWriter; /** * Protostream requires us to pass the actual type from the mapped Enum, * but OGM pre-maps these to String so se have to re-hydrate it from * String to map it to native enums. * See also: https://developers.google.com/protocol-buffers/docs/proto#enum * @author Sanne Grinovero */ public class EnumProtofieldAccessor implements ProtofieldAccessor<Enum> { private final int tag; private final String name; private final Class<? extends Enum> type; private final String columnName; private final boolean nullable; public EnumProtofieldAccessor(int tag, String name, boolean nullable, Class<? extends Enum> type, String columnName) { this.tag = tag; this.name = name; this.nullable = nullable; this.columnName = columnName; this.type = type; } @Override public void writeTo(ProtoStreamWriter outProtobuf, Enum value) throws IOException { outProtobuf.writeObject( name, value, type ); } @Override public Enum read(ProtoStreamReader reader) throws IOException { return reader.readObject( name, type ); } @Override public void collectTypeDefinitions(TypeDeclarationsCollector typesDefCollector) { typesDefCollector.createTypeDefinition( new EnumTypeDefinition( type ) ); }; @Override public void exportProtobufFieldDefinition(StringBuilder sb) { if ( nullable ) { sb.append( "\n\toptional " ); } else { sb.append( "\n\trequired " ); } sb.append( type.getSimpleName() ); sb.append( " " ); sb.append( name ); sb.append( " = " ); sb.append( tag ); sb.append( ";" ); } @Override public String getColumnName() { return columnName; } @Override public String getProtobufName() { return name; } private static final class EnumTypeDefinition implements TypeDefinition { private final Class<? extends Enum> type; public EnumTypeDefinition(Class<? extends Enum> type) { if ( type == null ) { throw new NullPointerException( "The 'type' parameter shall not be null" ); } this.type = type; } @Override public void exportProtobufTypeDefinition(StringBuilder sb) { Enum[] enumConstants = type.getEnumConstants(); sb.append( "\nenum " ); sb.append( type.getSimpleName() ); sb.append( " {" ); for ( int i = 0; i < enumConstants.length; i++ ) { sb.append( "\n\t" ); sb.append( enumConstants[i].name() ); sb.append( " = " ); sb.append( i ); sb.append( ";" ); } sb.append( "\n}\n" ); } @Override public String getTypeName() { return type.getSimpleName(); } @Override public int hashCode() { return type.hashCode(); } @Override public boolean equals(Object obj) { if ( this == obj ) { return true; } else if ( obj == null ) { return false; } else if ( EnumTypeDefinition.class != obj.getClass() ) { return false; } else { EnumTypeDefinition other = (EnumTypeDefinition) obj; return type.equals( other.type ); } } } }