/**
* Copyright 2016 Hortonworks.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
package com.hortonworks.registries.schemaregistry.avro;
import com.hortonworks.registries.schemaregistry.SchemaFieldInfo;
import org.apache.avro.Schema;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.List;
/**
*
*/
public class AvroFieldsGenerator {
private static final Logger LOG = LoggerFactory.getLogger(AvroFieldsGenerator.class);
public AvroFieldsGenerator() {
}
public List<SchemaFieldInfo> generateFields(Schema rootSchema) {
List<SchemaFieldInfo> schemaFieldInfos = new ArrayList<>();
parse(rootSchema, schemaFieldInfos);
return schemaFieldInfos;
}
private void parse(Schema schema, List<SchemaFieldInfo> schemaFieldInfos) {
if (schema.getType() != Schema.Type.RECORD) {
LOG.info("Given schema type [{}] is not record", schema.getType());
} else {
String fullName = schema.getFullName();
LOG.debug("Schema full name: [{}]", fullName);
List<Schema.Field> fields = schema.getFields();
for (Schema.Field field : fields) {
parseField(field, schemaFieldInfos);
}
}
}
private void parseField(Schema.Field field, List<SchemaFieldInfo> schemaFieldInfos) {
Schema schema = field.schema();
Schema.Type type = schema.getType();
String name = field.name();
LOG.debug("Visiting field: [{}]", field);
String namespace = null;
try {
namespace = schema.getNamespace();
} catch (Exception e) {
//ignore.
}
schemaFieldInfos.add(new SchemaFieldInfo(namespace, name, type.name()));
// todo check whether fields should be mapped to the root schema.
parseSchema(schema, schemaFieldInfos);
}
private void parseSchema(Schema schema, List<SchemaFieldInfo> schemaFieldInfos) {
Schema.Type type = schema.getType();
LOG.debug("Visiting type: [{}]", type);
switch (type) {
case RECORD:
// store fields of a record.
List<Schema.Field> fields = schema.getFields();
for (Schema.Field recordField : fields) {
parseField(recordField, schemaFieldInfos);
}
break;
case MAP:
Schema valueTypeSchema = schema.getValueType();
parseSchema(valueTypeSchema, schemaFieldInfos);
break;
case ENUM:
break;
case ARRAY:
Schema elementType = schema.getElementType();
parseSchema(elementType, schemaFieldInfos);
break;
case UNION:
List<Schema> unionTypes = schema.getTypes();
for (Schema typeSchema : unionTypes) {
parseSchema(typeSchema, schemaFieldInfos);
}
break;
case STRING:
case INT:
case LONG:
case FLOAT:
case DOUBLE:
case FIXED:
case BOOLEAN:
case BYTES:
case NULL:
break;
default:
throw new RuntimeException("Unsupported type: " + type);
}
}
}