package io.github.ibuildthecloud.gdapi.id; import io.github.ibuildthecloud.gdapi.factory.SchemaFactory; import io.github.ibuildthecloud.gdapi.model.Field; import io.github.ibuildthecloud.gdapi.model.FieldType; import io.github.ibuildthecloud.gdapi.model.Schema; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; public class IdFormatterUtils { public static Object formatReference(Field field, IdFormatter formatter, Object value, SchemaFactory schemaFactory) { return formatReference(field.getTypeEnum(), field.getType(), field.getSubTypeEnums(), field.getSubTypes(), formatter, value, schemaFactory); } private static Object formatReference(FieldType fieldType, String schemaType, List<FieldType> subTypeEnums, List<String> subTypes, IdFormatter formatter, Object value, SchemaFactory schemaFactory) { if (value == null) { return value; } switch (fieldType) { case REFERENCE: String type = subTypes.get(0); return formatter.formatId(type, value); case ARRAY: return formatList(subTypeEnums, subTypes, formatter, value, schemaFactory); case MAP: return formatMap(subTypeEnums, subTypes, formatter, value, schemaFactory); case TYPE: if (schemaType == null || schemaFactory == null) { return value; } return formatType(formatter, value, schemaFactory, schemaType); default: return value; } } private static Object formatType(IdFormatter formatter, Object value, SchemaFactory schemaFactory, String schemaType) { if (value == null || !(value instanceof Map)) { return value; } if (schemaFactory == null || schemaType == null) { return value; } Map<?, ?> inputs = (Map<?, ?>)value; Map<Object, Object> result = new LinkedHashMap<Object, Object>(); Schema fieldSchema = schemaFactory.getSchema(schemaType); if (!result.containsKey("type")) { result.put("type", fieldSchema.getId()); } for (Map.Entry<String, Field> entry : fieldSchema.getResourceFields().entrySet()) { String fieldName = entry.getKey(); if (inputs.containsKey(fieldName)) { Object subFieldValue = inputs.get(fieldName); if (subFieldValue != null) { Field subField = entry.getValue(); Object formattedValue = formatReference(subField.getTypeEnum(), subField.getType(), subField.getSubTypeEnums(), subField.getSubTypes(), formatter, subFieldValue, schemaFactory); result.put(fieldName, formattedValue); } else { result.put(fieldName, subFieldValue); } } } return result; } private static Object formatList(List<FieldType> subTypeEnums, List<String> subTypes, IdFormatter formatter, Object value, SchemaFactory schemaFactory) { if (value == null || subTypeEnums.size() == 0) { return value; } if (!(value instanceof List)) { return value; } List<?> inputs = (List<?>)value; List<Object> result = new ArrayList<Object>(inputs.size()); FieldType fieldType = subTypeEnums.get(0); String schemaType = null; if (subTypes.size() > 1) { schemaType = subTypes.get(1); } else { schemaType = subTypes.get(0); } subTypeEnums = subTypeEnums.subList(1, subTypeEnums.size()); subTypes = subTypes.subList(1, subTypes.size()); for (Object input : inputs) { result.add(formatReference(fieldType, schemaType, subTypeEnums, subTypes, formatter, input, schemaFactory)); } return result; } private static Object formatMap(List<FieldType> subTypeEnums, List<String> subTypes, IdFormatter formatter, Object value, SchemaFactory schemaFactory) { if (value == null || subTypeEnums.size() == 0) { return value; } if (!(value instanceof Map)) { return value; } Map<?, ?> inputs = (Map<?, ?>)value; Map<Object, Object> result = new LinkedHashMap<Object, Object>(); FieldType fieldType = subTypeEnums.get(0); String schemaType = null; if (subTypes.size() > 1) { schemaType = subTypes.get(1); } else { schemaType = subTypes.get(0); } subTypeEnums = subTypeEnums.subList(1, subTypeEnums.size()); subTypes = subTypes.subList(1, subTypes.size()); for (Map.Entry<?, ?> entry : inputs.entrySet()) { result.put(entry.getKey(), formatReference(fieldType, schemaType, subTypeEnums, subTypes, formatter, entry.getValue(), schemaFactory)); } return result; } }