Skip to content

Commit

Permalink
[FLINK-2874] Fix Avro getter/setter recognition
Browse files Browse the repository at this point in the history
This closes apache#1252
  • Loading branch information
Ulf Karlsson authored and fhueske committed Oct 22, 2015
1 parent 32b0dfd commit 17e7b42
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import java.util.List;

import org.apache.avro.specific.SpecificRecordBase;
import org.apache.commons.lang3.ClassUtils;
import org.apache.flink.api.common.functions.CoGroupFunction;
import org.apache.flink.api.common.functions.CrossFunction;
import org.apache.flink.api.common.functions.FlatJoinFunction;
Expand Down Expand Up @@ -1299,32 +1300,36 @@ private boolean isValidPojoField(Field f, Class<?> clazz, ArrayList<Type> typeHi
return true;
} else {
boolean hasGetter = false, hasSetter = false;
final String fieldNameLow = f.getName().toLowerCase();
final String fieldNameLow = f.getName().toLowerCase().replaceAll("_", "");

Type fieldType = f.getGenericType();
Class<?> fieldTypeWrapper = ClassUtils.primitiveToWrapper(f.getType());

TypeVariable<?> fieldTypeGeneric = null;
if(fieldType instanceof TypeVariable) {
fieldTypeGeneric = (TypeVariable<?>) fieldType;
fieldType = materializeTypeVariable(typeHierarchy, (TypeVariable<?>)fieldType);
}
for(Method m : clazz.getMethods()) {
final String methodNameLow = m.getName().toLowerCase().replaceAll("_", "");

// check for getter
if( // The name should be "get<FieldName>" or "<fieldName>" (for scala) or "is<fieldName>" for boolean fields.
(m.getName().toLowerCase().equals("get"+fieldNameLow) || m.getName().toLowerCase().equals("is"+fieldNameLow) || m.getName().toLowerCase().equals(fieldNameLow)) &&
(methodNameLow.equals("get"+fieldNameLow) || methodNameLow.equals("is"+fieldNameLow) || methodNameLow.equals(fieldNameLow)) &&
// no arguments for the getter
m.getParameterTypes().length == 0 &&
// return type is same as field type (or the generic variant of it)
(m.getGenericReturnType().equals( fieldType ) || (fieldTypeGeneric != null && m.getGenericReturnType().equals(fieldTypeGeneric)) )
(m.getGenericReturnType().equals( fieldType ) || (fieldTypeWrapper != null && m.getReturnType().equals( fieldTypeWrapper )) || (fieldTypeGeneric != null && m.getGenericReturnType().equals(fieldTypeGeneric)) )
) {
if(hasGetter) {
throw new IllegalStateException("Detected more than one getter");
}
hasGetter = true;
}
// check for setters (<FieldName>_$eq for scala)
if((m.getName().toLowerCase().equals("set"+fieldNameLow) || m.getName().toLowerCase().equals(fieldNameLow+"_$eq")) &&
if((methodNameLow.equals("set"+fieldNameLow) || methodNameLow.equals(fieldNameLow+"_$eq")) &&
m.getParameterTypes().length == 1 && // one parameter of the field's type
( m.getGenericParameterTypes()[0].equals( fieldType ) || (fieldTypeGeneric != null && m.getGenericParameterTypes()[0].equals(fieldTypeGeneric) ) )&&
(m.getGenericParameterTypes()[0].equals( fieldType ) || (fieldTypeWrapper != null && m.getParameterTypes()[0].equals( fieldTypeWrapper )) || (fieldTypeGeneric != null && m.getGenericParameterTypes()[0].equals(fieldTypeGeneric) ) )&&
// return type is void.
m.getReturnType().equals(Void.TYPE)
) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,11 +74,25 @@ public void testSerializabilityOfPojoTypeInfo() throws IOException, ClassNotFoun

assertEquals(pojoTypeInfo, deserializedPojoTypeInfo);
}


@Test
public void testPrimitivePojo() {
TypeInformation<PrimitivePojo> info1 = TypeExtractor.getForClass(PrimitivePojo.class);

assertTrue(info1 instanceof PojoTypeInfo);
}

@Test
public void testUnderscorePojo() {
TypeInformation<UnderscorePojo> info1 = TypeExtractor.getForClass(UnderscorePojo.class);

assertTrue(info1 instanceof PojoTypeInfo);
}

public static final class TestPojo {

public int someInt;

private String aString;

public Double[] doubleArray;
Expand Down Expand Up @@ -110,4 +124,30 @@ public String getaString() {
return aString;
}
}

public static final class PrimitivePojo {

private int someInt;

public void setSomeInt(Integer someInt) {
this.someInt = someInt;
}

public Integer getSomeInt() {
return this.someInt;
}
}

public static final class UnderscorePojo {

private int some_int;

public void setSomeInt(int some_int) {
this.some_int = some_int;
}

public Integer getSomeInt() {
return this.some_int;
}
}
}

0 comments on commit 17e7b42

Please sign in to comment.