@@ -92,6 +92,9 @@ class MessageSerializerGenerator {
9292 /** Collection of message-specific imports. */
9393 private final Set <String > imports = new TreeSet <>();
9494
95+ /** Collection of Serializer class fields containing mappers for message enum fields. */
96+ private final Set <String > mapperFields = new TreeSet <>();
97+
9598 /** */
9699 private final ProcessingEnvironment env ;
97100
@@ -142,6 +145,8 @@ private String generateSerializerCode(String serClsName) throws IOException {
142145 try (Writer writer = new StringWriter ()) {
143146 writeClassHeader (writer , PKG_NAME , serClsName );
144147
148+ writeClassFields (writer );
149+
145150 // Write #writeTo method.
146151 for (String w : write )
147152 writer .write (w + NL );
@@ -238,10 +243,6 @@ private void processField(VariableElement field, int opt) throws Exception {
238243 if (assignableFrom (field .asType (), type (Throwable .class .getName ())))
239244 throw new UnsupportedOperationException ("You should use ErrorMessage for serialization of throwables." );
240245
241- if (enumType (erasedType (field .asType ())))
242- throw new IllegalArgumentException ("Unsupported enum type: " + field .asType () +
243- ". The enum must be wrapped into a Message (see, for example, TransactionIsolationMessage)." );
244-
245246 writeField (field , opt );
246247 readField (field , opt );
247248 }
@@ -335,7 +336,7 @@ private void returnFalseIfWriteFailed(VariableElement field) throws Exception {
335336
336337 imports .add ("org.apache.ignite.plugin.extensions.communication.MessageCollectionItemType" );
337338
338- returnFalseIfWriteFailed (write , "writer.writeObjectArray" , getExpr ,
339+ returnFalseIfEnumWriteFailed (write , "writer.writeObjectArray" , getExpr ,
339340 "MessageCollectionItemType." + messageCollectionItemType (componentType ));
340341
341342 return ;
@@ -388,10 +389,31 @@ else if (assignableFrom(erasedType(type), type(Collection.class.getName()))) {
388389
389390 imports .add ("org.apache.ignite.plugin.extensions.communication.MessageCollectionItemType" );
390391
391- returnFalseIfWriteFailed (write , "writer.writeCollection" , getExpr ,
392+ returnFalseIfEnumWriteFailed (write , "writer.writeCollection" , getExpr ,
392393 "MessageCollectionItemType." + messageCollectionItemType (typeArgs .get (0 )));
393394 }
394395
396+ else if (enumType (type )) {
397+ //TODO check CustomMapper annotation
398+ imports .add ("org.apache.ignite.plugin.extensions.communication.mappers.EnumMapper" );
399+ imports .add ("org.apache.ignite.plugin.extensions.communication.mappers.DefaultEnumMapper" );
400+
401+ Element element = env .getTypeUtils ().asElement (type );
402+
403+ imports .add (element .toString ());
404+
405+ String enumName = element .getSimpleName ().toString ();
406+
407+ char [] chars = enumName .toCharArray ();
408+ chars [0 ] = Character .toLowerCase (chars [0 ]);
409+
410+ String enumMapperSerializerFieldName = new String (chars ) + "Mapper" ;
411+
412+ mapperFields .add ("private final EnumMapper<" + enumName + "> " + enumMapperSerializerFieldName + " = new DefaultEnumMapper<>(" + enumName + ".values());" );
413+
414+ returnFalseIfEnumWriteFailed (write , "writer.writeByte" , enumMapperSerializerFieldName + ".encode" , getExpr );
415+ }
416+
395417 else
396418 throw new IllegalArgumentException ("Unsupported declared type: " + type );
397419
@@ -420,6 +442,23 @@ private void returnFalseIfWriteFailed(Collection<String> code, String accessor,
420442 indent --;
421443 }
422444
445+ /**
446+ * Generate code of writing single enum field mapped with EnumMapper:
447+ * <pre>
448+ * if (!writer.writeByte(myEnumMapper.encode(msg.myEnum()))
449+ * return false;
450+ * </pre>
451+ */
452+ private void returnFalseIfEnumWriteFailed (Collection <String > code , String writerCall , String mapperCall , String fieldGetterCall ) {
453+ code .add (line ("if (!%s(%s(msg.%s)))" , writerCall , mapperCall , fieldGetterCall ));
454+
455+ indent ++;
456+
457+ code .add (line ("return false;" ));
458+
459+ indent --;
460+ }
461+
423462 /**
424463 * Discover access read methods, like {@code readInt}.
425464 *
@@ -530,6 +569,18 @@ else if (assignableFrom(erasedType(type), type(Collection.class.getName()))) {
530569 "MessageCollectionItemType." + messageCollectionItemType (typeArgs .get (0 )));
531570 }
532571
572+ else if (enumType (type )) {
573+ //TODO check CustomMapper annotation
574+ String enumName = env .getTypeUtils ().asElement (type ).getSimpleName ().toString ();
575+
576+ char [] chars = enumName .toCharArray ();
577+ chars [0 ] = Character .toLowerCase (chars [0 ]);
578+
579+ String enumMapperSerializerFieldName = new String (chars ) + "Mapper" ;
580+
581+ returnFalseIfEnumReadFailed (name , enumMapperSerializerFieldName + ".decode" );
582+ }
583+
533584 else
534585 throw new IllegalArgumentException ("Unsupported declared type: " + type );
535586
@@ -643,6 +694,32 @@ private void returnFalseIfReadFailed(String var, String mtd, String... args) {
643694 indent --;
644695 }
645696
697+ /**
698+ * Generate code of reading single field:
699+ * <pre>
700+ * msg.id(reader.readInt());
701+ *
702+ * if (!reader.isLastRead())
703+ * return false;
704+ * </pre>
705+ *
706+ * @param msgSetterName Variable name.
707+ * @param mapperDecodeCall Method name.
708+ */
709+ private void returnFalseIfEnumReadFailed (String msgSetterName , String mapperDecodeCall ) {
710+ read .add (line ("msg.%s(%s(reader.readByte()));" , msgSetterName , mapperDecodeCall ));
711+
712+ read .add (EMPTY );
713+
714+ read .add (line ("if (!reader.isLastRead())" ));
715+
716+ indent ++;
717+
718+ read .add (line ("return false;" ));
719+
720+ indent --;
721+ }
722+
646723 /** */
647724 private void finish (List <String > code ) {
648725 String lastLine = code .get (code .size () - 1 );
@@ -672,6 +749,21 @@ private String line(String format, Object... args) {
672749 return sb .toString ();
673750 }
674751
752+ /** Write header of serializer class: license, imports, class declaration. */
753+ private void writeClassFields (Writer writer ) throws IOException {
754+ indent = 1 ;
755+
756+ for (String field : mapperFields ) {
757+ writer .write (line (METHOD_JAVADOC ));
758+ writer .write (NL );
759+ writer .write (line (field ));
760+ writer .write (NL );
761+ }
762+ writer .write (NL );
763+
764+ indent = 0 ;
765+ }
766+
675767 /** Write header of serializer class: license, imports, class declaration. */
676768 private void writeClassHeader (Writer writer , String pkgName , String serClsName ) throws IOException {
677769 try (InputStream in = getClass ().getClassLoader ().getResourceAsStream ("license.txt" );
@@ -719,13 +811,9 @@ private boolean assignableFrom(TypeMirror type, TypeMirror superType) {
719811
720812 /** */
721813 private boolean enumType (TypeMirror type ) {
722- if (type .getKind () == TypeKind .DECLARED ) {
723- Element element = env .getTypeUtils ().asElement (type );
724-
725- return element != null && element .getKind () == ElementKind .ENUM ;
726- }
814+ Element element = env .getTypeUtils ().asElement (type );
727815
728- return false ;
816+ return element != null && element . getKind () == ElementKind . ENUM ;
729817 }
730818
731819 /** */
0 commit comments