Search in sources :

Example 1 with AvroTypeException

use of org.apache.avro.AvroTypeException in project crunch by cloudera.

the class ScalaSafeReflectData method createSchema.

@Override
@SuppressWarnings(value = "unchecked")
protected Schema createSchema(Type type, Map<String, Schema> names) {
    if (type instanceof GenericArrayType) {
        // generic array
        Type component = ((GenericArrayType) type).getGenericComponentType();
        if (// byte array
        component == Byte.TYPE)
            return Schema.create(Schema.Type.BYTES);
        Schema result = Schema.createArray(createSchema(component, names));
        setElement(result, component);
        return result;
    } else if (type instanceof ParameterizedType) {
        ParameterizedType ptype = (ParameterizedType) type;
        Class raw = (Class) ptype.getRawType();
        Type[] params = ptype.getActualTypeArguments();
        if (java.util.Map.class.isAssignableFrom(raw) || scala.collection.Map.class.isAssignableFrom(raw)) {
            Type key = params[0];
            Type value = params[1];
            if (!(key == String.class))
                throw new AvroTypeException("Map key class not String: " + key);
            Schema schema = Schema.createMap(createSchema(value, names));
            schema.addProp(CLASS_PROP, raw.getName());
            return schema;
        } else if (Collection.class.isAssignableFrom(raw) || scala.collection.Iterable.class.isAssignableFrom(raw)) {
            // Collection
            if (params.length != 1)
                throw new AvroTypeException("No array type specified.");
            Schema schema = Schema.createArray(createSchema(params[0], names));
            schema.addProp(CLASS_PROP, raw.getName());
            return schema;
        } else {
            throw new AvroTypeException("Could not convert type: " + type);
        }
    } else if ((type == Short.class) || (type == Short.TYPE)) {
        Schema result = Schema.create(Schema.Type.INT);
        result.addProp(CLASS_PROP, Short.class.getName());
        return result;
    } else if (type instanceof Class) {
        // Class
        Class<?> c = (Class<?>) type;
        if (c.isPrimitive() || Number.class.isAssignableFrom(c) || c == Void.class || // primitive
        c == Boolean.class)
            return super.createSchema(type, names);
        if (c.isArray()) {
            // array
            Class component = c.getComponentType();
            if (// byte array
            component == Byte.TYPE)
                return Schema.create(Schema.Type.BYTES);
            Schema result = Schema.createArray(createSchema(component, names));
            setElement(result, component);
            return result;
        }
        if (// String
        CharSequence.class.isAssignableFrom(c))
            return Schema.create(Schema.Type.STRING);
        String fullName = c.getName();
        Schema schema = names.get(fullName);
        if (schema == null) {
            String name = getSimpleName(c);
            String space = c.getPackage() == null ? "" : c.getPackage().getName();
            if (// nested class
            c.getEnclosingClass() != null)
                space = c.getEnclosingClass().getName() + "$";
            Union union = c.getAnnotation(Union.class);
            if (union != null) {
                // union annotated
                return getAnnotatedUnion(union, names);
            } else if (c.isAnnotationPresent(Stringable.class)) {
                // Stringable
                Schema result = Schema.create(Schema.Type.STRING);
                result.addProp(CLASS_PROP, c.getName());
                return result;
            } else if (c.isEnum()) {
                // Enum
                List<String> symbols = new ArrayList<String>();
                Enum[] constants = (Enum[]) c.getEnumConstants();
                for (int i = 0; i < constants.length; i++) symbols.add(constants[i].name());
                schema = Schema.createEnum(name, null, /* doc */
                space, symbols);
            } else if (GenericFixed.class.isAssignableFrom(c)) {
                // fixed
                int size = c.getAnnotation(FixedSize.class).value();
                schema = Schema.createFixed(name, null, /* doc */
                space, size);
            } else if (IndexedRecord.class.isAssignableFrom(c)) {
                // specific
                return super.createSchema(type, names);
            } else {
                // record
                List<Schema.Field> fields = new ArrayList<Schema.Field>();
                boolean error = Throwable.class.isAssignableFrom(c);
                schema = Schema.createRecord(name, null, /* doc */
                space, error);
                names.put(c.getName(), schema);
                for (Field field : getFields(c)) if ((field.getModifiers() & (Modifier.TRANSIENT | Modifier.STATIC)) == 0) {
                    Schema fieldSchema = createFieldSchema(field, names);
                    JsonNode defaultValue = null;
                    if (fieldSchema.getType() == Schema.Type.UNION) {
                        Schema defaultType = fieldSchema.getTypes().get(0);
                        if (defaultType.getType() == Schema.Type.NULL) {
                            defaultValue = NullNode.getInstance();
                        }
                    }
                    fields.add(new Schema.Field(clean(field.getName()), fieldSchema, null, /* doc */
                    defaultValue));
                }
                if (// add Throwable message
                error)
                    fields.add(new Schema.Field("detailMessage", THROWABLE_MESSAGE, null, null));
                schema.setFields(fields);
            }
            names.put(fullName, schema);
        }
        return schema;
    }
    return super.createSchema(type, names);
}
Also used : IndexedRecord(org.apache.avro.generic.IndexedRecord) Schema(org.apache.avro.Schema) FixedSize(org.apache.avro.specific.FixedSize) JsonNode(org.codehaus.jackson.JsonNode) Union(org.apache.avro.reflect.Union) ParameterizedType(java.lang.reflect.ParameterizedType) Field(java.lang.reflect.Field) ArrayList(java.util.ArrayList) List(java.util.List) GenericArrayType(java.lang.reflect.GenericArrayType) GenericArrayType(java.lang.reflect.GenericArrayType) ParameterizedType(java.lang.reflect.ParameterizedType) Type(java.lang.reflect.Type) Collection(java.util.Collection) AvroTypeException(org.apache.avro.AvroTypeException)

Example 2 with AvroTypeException

use of org.apache.avro.AvroTypeException in project crunch by cloudera.

the class ScalaSafeReflectData method getFields.

// Return of this class and its superclasses to serialize.
// Not cached, since this is only used to create schemas, which are cached.
private Collection<Field> getFields(Class recordClass) {
    Map<String, Field> fields = new LinkedHashMap<String, Field>();
    Class c = recordClass;
    do {
        if (c.getPackage() != null && c.getPackage().getName().startsWith("java."))
            // skip java built-in classes
            break;
        for (Field field : c.getDeclaredFields()) if ((field.getModifiers() & (Modifier.TRANSIENT | Modifier.STATIC)) == 0)
            if (fields.put(field.getName(), field) != null)
                throw new AvroTypeException(c + " contains two fields named: " + field);
        c = c.getSuperclass();
    } while (c != null);
    return fields.values();
}
Also used : Field(java.lang.reflect.Field) LinkedHashMap(java.util.LinkedHashMap) AvroTypeException(org.apache.avro.AvroTypeException)

Aggregations

Field (java.lang.reflect.Field)2 AvroTypeException (org.apache.avro.AvroTypeException)2 GenericArrayType (java.lang.reflect.GenericArrayType)1 ParameterizedType (java.lang.reflect.ParameterizedType)1 Type (java.lang.reflect.Type)1 ArrayList (java.util.ArrayList)1 Collection (java.util.Collection)1 LinkedHashMap (java.util.LinkedHashMap)1 List (java.util.List)1 Schema (org.apache.avro.Schema)1 IndexedRecord (org.apache.avro.generic.IndexedRecord)1 Union (org.apache.avro.reflect.Union)1 FixedSize (org.apache.avro.specific.FixedSize)1 JsonNode (org.codehaus.jackson.JsonNode)1