/** * Given a GenericRecord, this method will return the schema of the field specified by the path parameter. The * fieldLocation parameter is an ordered string specifying the location of the nested field to retrieve. For example, * field1.nestedField1 takes the the schema of the field "field1", and retrieves the schema "nestedField1" from it. * @param schema is the record to retrieve the schema from * @param fieldLocation is the location of the field * @return the schema of the field */ public static Optional<Schema> getFieldSchema(Schema schema, String fieldLocation) { Preconditions.checkNotNull(schema); Preconditions.checkArgument(!Strings.isNullOrEmpty(fieldLocation)); Splitter splitter = Splitter.on(FIELD_LOCATION_DELIMITER).omitEmptyStrings().trimResults(); List<String> pathList = Lists.newArrayList(splitter.split(fieldLocation)); if (pathList.size() == 0) { return Optional.absent(); } return AvroUtils.getFieldSchemaHelper(schema, pathList, 0); }
/** * Helper method that does the actual work for {@link #getFieldSchema(Schema, String)} * @param schema passed from {@link #getFieldSchema(Schema, String)} * @param pathList passed from {@link #getFieldSchema(Schema, String)} * @param field keeps track of the index used to access the list pathList * @return the schema of the field */ private static Optional<Schema> getFieldSchemaHelper(Schema schema, List<String> pathList, int field) { if (schema.getType() == Type.RECORD && schema.getField(pathList.get(field)) == null) { return Optional.absent(); } switch (schema.getType()) { case UNION: throw new AvroRuntimeException("Union of complex types cannot be handled : " + schema); case MAP: if ((field + 1) == pathList.size()) { return Optional.fromNullable(schema.getValueType()); } return AvroUtils.getFieldSchemaHelper(schema.getValueType(), pathList, ++field); case RECORD: if ((field + 1) == pathList.size()) { return Optional.fromNullable(schema.getField(pathList.get(field)).schema()); } return AvroUtils.getFieldSchemaHelper(schema.getField(pathList.get(field)).schema(), pathList, ++field); default: throw new AvroRuntimeException("Invalid type in schema : " + schema); } }