@Override @PublicEvolving public <X> TypeInformation<X> getTypeAt(int pos) { if (pos < 0 || pos >= this.fields.length) { throw new IndexOutOfBoundsException(); } @SuppressWarnings("unchecked") TypeInformation<X> typed = (TypeInformation<X>) fields[pos].getTypeInformation(); return typed; }
@Override public String toString() { List<String> fieldStrings = new ArrayList<String>(); for (PojoField field : fields) { fieldStrings.add(field.getField().getName() + ": " + field.getTypeInformation().toString()); } return "PojoType<" + getTypeClass().getName() + ", fields = [" + StringUtils.join(fieldStrings, ", ") + "]" + ">"; }
private static TypeInformation<?> getTypeOfPojoField(TypeInformation<?> pojoInfo, Field field) { for (int j = 0; j < pojoInfo.getArity(); j++) { PojoField pf = ((PojoTypeInfo<?>) pojoInfo).getPojoFieldAt(j); if (pf.getField().getName().equals(field.getName())) { return pf.getTypeInformation(); } } return null; }
@PublicEvolving public PojoTypeInfo(Class<T> typeClass, List<PojoField> fields) { super(typeClass); checkArgument(Modifier.isPublic(typeClass.getModifiers()), "POJO %s is not public", typeClass); this.fields = fields.toArray(new PojoField[fields.size()]); Arrays.sort(this.fields, new Comparator<PojoField>() { @Override public int compare(PojoField o1, PojoField o2) { return o1.getField().getName().compareTo(o2.getField().getName()); } }); int counterFields = 0; for(PojoField field : fields) { counterFields += field.getTypeInformation().getTotalFields(); } totalFields = counterFields; }
public PojoSerializer<T> createPojoSerializer(ExecutionConfig config) { TypeSerializer<?>[] fieldSerializers = new TypeSerializer<?>[fields.length]; Field[] reflectiveFields = new Field[fields.length]; for (int i = 0; i < fields.length; i++) { fieldSerializers[i] = fields[i].getTypeInformation().createSerializer(config); reflectiveFields[i] = fields[i].getField(); } return new PojoSerializer<T>(getTypeClass(), fieldSerializers, reflectiveFields, config); }
if (fields[i].getField().getName().equals(field)) { fieldPos = i; fieldType = fields[i].getTypeInformation(); break;
@SuppressWarnings("unchecked") @Internal private static <T extends SpecificRecordBase> List<PojoField> generateFieldsFromAvroSchema(Class<T> typeClass) { PojoTypeExtractor pte = new PojoTypeExtractor(); ArrayList<Type> typeHierarchy = new ArrayList<>(); typeHierarchy.add(typeClass); TypeInformation ti = pte.analyzePojo(typeClass, typeHierarchy, null, null, null); if (!(ti instanceof PojoTypeInfo)) { throw new IllegalStateException("Expecting type to be a PojoTypeInfo"); } PojoTypeInfo pti = (PojoTypeInfo) ti; List<PojoField> newFields = new ArrayList<>(pti.getTotalFields()); for (int i = 0; i < pti.getArity(); i++) { PojoField f = pti.getPojoFieldAt(i); TypeInformation newType = f.getTypeInformation(); // check if type is a CharSequence if (newType instanceof GenericTypeInfo) { if ((newType).getTypeClass().equals(CharSequence.class)) { // replace the type by a org.apache.avro.util.Utf8 newType = new GenericTypeInfo(org.apache.avro.util.Utf8.class); } } PojoField newField = new PojoField(f.getField(), newType); newFields.add(newField); } return newFields; }
@Test public void testRecursivePojo3() { TypeInformation<?> ti = TypeExtractor.createTypeInfo(RecursivePojo3.class); Assert.assertTrue(ti instanceof PojoTypeInfo); PojoField pf = ((PojoTypeInfo) ti).getPojoFieldAt(0); Assert.assertTrue(pf.getTypeInformation() instanceof PojoTypeInfo); Assert.assertEquals(GenericTypeInfo.class, ((PojoTypeInfo) pf.getTypeInformation()).getPojoFieldAt(0).getTypeInformation().getClass()); }
@Test public void testPojosWithMutualRecursion() { TypeInformation<?> ti = TypeExtractor.createTypeInfo(MutualPojoB.class); Assert.assertTrue(ti instanceof PojoTypeInfo); TypeInformation<?> pti = ((PojoTypeInfo) ti).getPojoFieldAt(0).getTypeInformation(); Assert.assertTrue(pti instanceof PojoTypeInfo); Assert.assertEquals(GenericTypeInfo.class, ((PojoTypeInfo) pti).getPojoFieldAt(0).getTypeInformation().getClass()); }
@Test public void testPojoWithGenerics() { TypeInformation<?> typeForClass = TypeExtractor.createTypeInfo(ParentSettingGenerics.class); Assert.assertTrue(typeForClass instanceof PojoTypeInfo<?>); PojoTypeInfo<?> pojoTypeForClass = (PojoTypeInfo<?>) typeForClass; for(int i = 0; i < pojoTypeForClass.getArity(); i++) { PojoField field = pojoTypeForClass.getPojoFieldAt(i); String name = field.getField().getName(); if(name.equals("field1")) { Assert.assertEquals(BasicTypeInfo.INT_TYPE_INFO, field.getTypeInformation()); } else if (name.equals("field2")) { Assert.assertEquals(BasicTypeInfo.LONG_TYPE_INFO, field.getTypeInformation()); } else if (name.equals("field3")) { Assert.assertEquals(BasicTypeInfo.STRING_TYPE_INFO, field.getTypeInformation()); } else if (name.equals("key")) { Assert.assertEquals(BasicTypeInfo.INT_TYPE_INFO, field.getTypeInformation()); } else { Assert.fail("Unexpected field "+field); } } }
private void checkFromTuplePojo(TypeInformation<?> typeInformation) { Assert.assertTrue(typeInformation instanceof PojoTypeInfo<?>); Assert.assertEquals(4, typeInformation.getTotalFields()); PojoTypeInfo<?> pojoTypeForClass = (PojoTypeInfo<?>) typeInformation; for(int i = 0; i < pojoTypeForClass.getArity(); i++) { PojoField field = pojoTypeForClass.getPojoFieldAt(i); String name = field.getField().getName(); if(name.equals("special")) { Assert.assertEquals(BasicTypeInfo.INT_TYPE_INFO, field.getTypeInformation()); } else if(name.equals("f0") || name.equals("f1")) { Assert.assertEquals(BasicTypeInfo.STRING_TYPE_INFO, field.getTypeInformation()); } else if(name.equals("f2")) { Assert.assertEquals(BasicTypeInfo.LONG_TYPE_INFO, field.getTypeInformation()); } else { Assert.fail("unexpected field"); } } }
@Test public void testRecursivePojoWithTypeVariable() { TypeInformation<?> ti = TypeExtractor.createTypeInfo(MyType.class); Assert.assertTrue(ti instanceof PojoTypeInfo); TypeInformation<?> pti = ((PojoTypeInfo) ti).getPojoFieldAt(0).getTypeInformation(); Assert.assertTrue(pti instanceof PojoTypeInfo); Assert.assertEquals(GenericTypeInfo.class, ((PojoTypeInfo) pti).getPojoFieldAt(0).getTypeInformation().getClass()); }
@Test public void testRecursivePojo2() { TypeInformation<?> ti = TypeExtractor.createTypeInfo(RecursivePojo2.class); Assert.assertTrue(ti instanceof PojoTypeInfo); PojoField pf = ((PojoTypeInfo) ti).getPojoFieldAt(0); Assert.assertTrue(pf.getTypeInformation() instanceof TupleTypeInfo); Assert.assertEquals(GenericTypeInfo.class, ((TupleTypeInfo) pf.getTypeInformation()).getTypeAt(0).getClass()); }
@Test public void testPojoWithComplexHierarchy() { TypeInformation<?> typeForClass = TypeExtractor.createTypeInfo(ComplexHierarchyTop.class); Assert.assertTrue(typeForClass instanceof PojoTypeInfo<?>); PojoTypeInfo<?> pojoTypeForClass = (PojoTypeInfo<?>) typeForClass; for(int i = 0; i < pojoTypeForClass.getArity(); i++) { PojoField field = pojoTypeForClass.getPojoFieldAt(i); String name = field.getField().getName(); if(name.equals("field1")) { Assert.assertTrue(field.getTypeInformation() instanceof PojoTypeInfo<?>); // From tuple is pojo (not tuple type!) } else if (name.equals("field2")) { Assert.assertTrue(field.getTypeInformation() instanceof TupleTypeInfo<?>); Assert.assertTrue( ((TupleTypeInfo<?>)field.getTypeInformation()).getTypeAt(0).equals(BasicTypeInfo.STRING_TYPE_INFO) ); } else if (name.equals("key")) { Assert.assertEquals(BasicTypeInfo.INT_TYPE_INFO, field.getTypeInformation()); } else { Assert.fail("Unexpected field "+field); } } }
@SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testGenericPojoTypeInference2() { MyMapper2<Boolean, Character> function = new MyMapper2<>(); TypeInformation<?> ti = TypeExtractor.getMapReturnTypes( function, TypeInformation.of(new TypeHint<Tuple2<Character,Boolean>>(){})); Assert.assertTrue(ti instanceof PojoTypeInfo<?>); PojoTypeInfo<?> pti = (PojoTypeInfo<?>) ti; for(int i = 0; i < pti.getArity(); i++) { PojoField field = pti.getPojoFieldAt(i); String name = field.getField().getName(); if(name.equals("extraField")) { Assert.assertEquals(BasicTypeInfo.CHAR_TYPE_INFO, field.getTypeInformation()); } else if (name.equals("f0")) { Assert.assertEquals(BasicTypeInfo.BOOLEAN_TYPE_INFO, field.getTypeInformation()); } else if (name.equals("f1")) { Assert.assertEquals(BasicTypeInfo.BOOLEAN_TYPE_INFO, field.getTypeInformation()); } else if (name.equals("f2")) { Assert.assertEquals(BasicTypeInfo.LONG_TYPE_INFO, field.getTypeInformation()); } else { Assert.fail("Unexpected field "+field); } } }
@Test public void testRecursivePojo1() { TypeInformation<?> ti = TypeExtractor.createTypeInfo(RecursivePojo1.class); Assert.assertTrue(ti instanceof PojoTypeInfo); Assert.assertEquals(GenericTypeInfo.class, ((PojoTypeInfo) ti).getPojoFieldAt(0).getTypeInformation().getClass()); }
@Test public void testPojoWithRecursiveGenericField() { TypeInformation<?> ti = TypeExtractor.createTypeInfo(PojoWithRecursiveGenericField.class); Assert.assertTrue(ti instanceof PojoTypeInfo); Assert.assertEquals(GenericTypeInfo.class, ((PojoTypeInfo) ti).getPojoFieldAt(0).getTypeInformation().getClass()); }
@Test public void testGenericPojoTypeInference1() { MyMapper<String> function = new MyMapper<>(); TypeInformation<?> ti = TypeExtractor.getMapReturnTypes( function, TypeInformation.of(new TypeHint<PojoWithGenerics<Long, String>>(){})); Assert.assertTrue(ti instanceof PojoTypeInfo<?>); PojoTypeInfo<?> pti = (PojoTypeInfo<?>) ti; for(int i = 0; i < pti.getArity(); i++) { PojoField field = pti.getPojoFieldAt(i); String name = field.getField().getName(); if(name.equals("field1")) { Assert.assertEquals(BasicTypeInfo.STRING_TYPE_INFO, field.getTypeInformation()); } else if (name.equals("field2")) { Assert.assertEquals(BasicTypeInfo.STRING_TYPE_INFO, field.getTypeInformation()); } else if (name.equals("key")) { Assert.assertEquals(BasicTypeInfo.INT_TYPE_INFO, field.getTypeInformation()); } else { Assert.fail("Unexpected field "+field); } } }
/** * Test if the TypeExtractor is accepting untyped generics, * making them GenericTypes */ @Test public void testPojoWithGenericsSomeFieldsGeneric() { TypeInformation<?> typeForClass = TypeExtractor.createTypeInfo(PojoWithGenerics.class); Assert.assertTrue(typeForClass instanceof PojoTypeInfo<?>); PojoTypeInfo<?> pojoTypeForClass = (PojoTypeInfo<?>) typeForClass; for(int i = 0; i < pojoTypeForClass.getArity(); i++) { PojoField field = pojoTypeForClass.getPojoFieldAt(i); String name = field.getField().getName(); if(name.equals("field1")) { Assert.assertEquals(new GenericTypeInfo<Object>(Object.class), field.getTypeInformation()); } else if (name.equals("field2")) { Assert.assertEquals(new GenericTypeInfo<Object>(Object.class), field.getTypeInformation()); } else if (name.equals("key")) { Assert.assertEquals(BasicTypeInfo.INT_TYPE_INFO, field.getTypeInformation()); } else { Assert.fail("Unexpected field "+field); } } }
@Test public void testExtractAsPartOfPojo() { PojoTypeInfo<PojoWithWritable> pojoInfo = (PojoTypeInfo<PojoWithWritable>) TypeExtractor.getForClass(PojoWithWritable.class); boolean foundWritable = false; for (int i = 0; i < pojoInfo.getArity(); i++) { PojoField field = pojoInfo.getPojoFieldAt(i); String name = field.getField().getName(); if (name.equals("hadoopCitizen")) { if (foundWritable) { fail("already seen"); } foundWritable = true; assertEquals(new WritableTypeInfo<>(DirectWritable.class), field.getTypeInformation()); assertEquals(DirectWritable.class, field.getTypeInformation().getTypeClass()); } } assertTrue("missed the writable type", foundWritable); }