public HollowObjectTypeMapper()

in hollow/src/main/java/com/netflix/hollow/core/write/objectmapper/HollowObjectTypeMapper.java [63:144]


    public HollowObjectTypeMapper(HollowObjectMapper parentMapper, Class<?> clazz, String declaredTypeName, Set<Type> visited) {
        this.parentMapper = parentMapper;
        this.clazz = clazz;
        this.typeName = declaredTypeName != null ? declaredTypeName : getDefaultTypeName(clazz);
        this.mappedFields = new ArrayList<MappedField>();

        boolean hasAssignedOrdinalField = false;
        long assignedOrdinalFieldOffset = -1;
        if(clazz == String.class) {
            try {
                mappedFields.add(new MappedField(clazz.getDeclaredField("value")));
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        } else if(clazz == Date.class) {
            try {
                mappedFields.add(new MappedField(MappedFieldType.DATE_TIME));
            } catch(Exception e) {
                throw new RuntimeException(e);
            }
        } else {
            /// gather fields from type hierarchy
            Class<?> currentClass = clazz;

            while(currentClass != Object.class && currentClass != Enum.class) {
                if(currentClass.isInterface()) {
                    throw new IllegalArgumentException("Unexpected interface " + currentClass.getSimpleName() + " passed as field.");
                } if (currentClass.isArray()) {
                    throw new IllegalArgumentException("Unexpected array " + currentClass.getSimpleName() + " passed as field. Consider using collections or marking as transient.");
                }
                Field[] declaredFields = currentClass.getDeclaredFields();

                for(int i=0;i<declaredFields.length;i++) {
                    Field declaredField = declaredFields[i];
                    int modifiers = declaredField.getModifiers();
                    if(!Modifier.isTransient(modifiers) && !Modifier.isStatic(modifiers) &&
                            !"__assigned_ordinal".equals(declaredField.getName()) &&
                            !declaredField.isAnnotationPresent(HollowTransient.class)) {

                        mappedFields.add(new MappedField(declaredField, visited));
                    } else if("__assigned_ordinal".equals(declaredField.getName()) &&
                            currentClass == clazz) {
                        // If there is a field of name __assigned_ordinal on clazz
                        if(declaredField.getType() == long.class) {
                            assignedOrdinalFieldOffset = unsafe.objectFieldOffset(declaredField);
                            hasAssignedOrdinalField = true;;
                        }
                    }
                }

                if(currentClass.isEnum())
                    mappedFields.add(new MappedField(MappedFieldType.ENUM_NAME));
                
                currentClass = currentClass.getSuperclass();
            }
        }

        this.schema = new HollowObjectSchema(typeName, mappedFields.size(), getKeyFieldPaths(clazz));

        Set<String> fieldNamesSeen = new HashSet<>();
        for(MappedField field : mappedFields) {
            if(!fieldNamesSeen.add(field.getFieldName()))
                throw new IllegalArgumentException("Duplicate field name '" + field.getFieldName() + "' found in class hierarchy for class " + clazz.getName());

            if(field.getFieldType() == MappedFieldType.REFERENCE) {
                schema.addField(field.getFieldName(), field.getFieldType().getSchemaFieldType(), field.getReferencedTypeName());
            } else {
                schema.addField(field.getFieldName(), field.getFieldType().getSchemaFieldType());
            }
        }

        HollowObjectTypeWriteState existingWriteState = (HollowObjectTypeWriteState) parentMapper.getStateEngine().getTypeState(typeName);
        if (existingWriteState != null) {
            this.writeState = existingWriteState;
        } else {
            int numShardsByAnnotation = getNumShardsByAnnotation(clazz);
            this.writeState = new HollowObjectTypeWriteState(schema, numShardsByAnnotation);
        }

        this.assignedOrdinalFieldOffset = assignedOrdinalFieldOffset;
        this.hasAssignedOrdinalField = hasAssignedOrdinalField;
    }