public ObjectSerializer(Class<O> clazz) { this.schemaRoot = new DescribeContext(DEFAULT).describeSchema(clazz); }
public void processMappings() { QueueItem<SubPath, TypeContext> currentItem; while ((currentItem = queue.poll()) != null) { registerMapping(currentItem.key, currentItem.value); } }
private ValueType setKeyPropertiesType() { PropertyPath elementPath = getElementPath(path, setKey.value()); ObjectType objectType = (ObjectType) context.describeNow(elementPath, new TypeContext(setType, elementType)); if (objectType.getIdentifier() != null) { throw new IllegalArgumentException("Element should not have both @SetKey and @Id: " + typeContext); } // Ensure that nested mappings are processed before accessing them context.processMappings(); List<Key> keys = new ArrayList<>(); for (String idProperty : setKey.value()) { IdentifiableType idType = requireIdentifiable(context.getValueType(elementPath.property(idProperty))); AccessibleProperty property = objectType.getProperties().get(idProperty); keys.add(new PropertyKey(property, idType)); } return newSetType(keys); }
public static ValueType describeReference(TypeDescriptor type, PropertyPath targetPath, DescribeContext context) { TypeContext typeContext = new TypeContext(type); context.describeAsync(targetPath.anyIndex(), typeContext); IdentifiableType identifiableType = (IdentifiableType) context.describeNow(targetPath.anyKey(), typeContext); return new ReferenceType(identifiableType, targetPath); } }
public Schema<ValueType> describeSchema(TypeDescriptor rootType) { schemaRoot = new Schema.Builder<>(); TypeContext typeContext = new TypeContext(rootType); schemaRoot.setValue(createValueType(PropertyPath.ROOT, typeContext)); processMappings(); return schemaRoot.build(); }
@Override public Optional<ValueType> describe(@Nullable PropertyPath path, TypeContext typeContext, DescribeContext context) { TypeDescriptor type = typeContext.type; MappingResolver mappingResolver = context.getMappingResolver(); MethodDescriptor valueMethod = getValueMethod(type, mappingResolver); if (valueMethod != null) { Class<?> rawDelegateType = valueMethod.getRawReturnType(); StaticExecutable creator = getCreator(type, rawDelegateType, mappingResolver); ValueType valueType = context.describeNow(path, new TypeContext(valueMethod)); return Optional.of(DelegateType.of(valueMethod, creator, valueType)); } return Optional.empty(); }
private void add(ConstructorDescriptor constructor) { Result<StaticExecutable> creator = context.getMappingResolver().creator(constructor); this.creator = MappingResolver.higherOf(this.creator, creator); }
private void add(String name, AccessibleProperty property, TypeContext typeContext) { if (!property.isWritable() && !creatorParameters.contains(name)) { throw new IllegalArgumentException(type.getSimpleName() + "." + name + " should have a matching setter or constructor parameter"); } SubPath subPath = path.property(name); if (!properties.containsKey(name)) { properties.put(name, property); context.describeAsync(subPath, typeContext); } }
private void setIdentifier(String name, AccessibleProperty property, TypeContext typeContext) { if (identifier != null) { throw new IllegalArgumentException(type.getSimpleName() + " should not have multiple @Id-properties"); } IdentifiableType idType; if (property.isWritable() || creatorParameters.contains(name)) { idType = (IdentifiableType) context.describeNow(path.property(name), typeContext); } else { idType = (IdentifiableType) context.describeNow(null, typeContext); } identifier = new ObjectIdentifier(property, idType, name); }
public Schema<ValueType> describeSchema(TypeToken rootType) { return describeSchema(typeMappings.getTypeDescriptor(rootType)); }
private ValueType registerMapping(PropertyPath path, TypeContext typeContext) { if (path == null) { return createValueType(null, typeContext); } Schema.Builder<ValueType> schema = schemaMappings.get(typeContext); if (schema == null) { schema = schemaRoot.getOrCreate(path); if (schema.getValue() == null) { ValueType valueType = createValueType(path, typeContext); schema.setValue(valueType); if (!valueType.isReference()) { schemaMappings.put(typeContext, schema); } } } else { schemaRoot.connect((SubPath) path, schema); } return schema.getValue(); }
@Override public ValueType describe(PropertyPath path, TypeDescriptor mapType, DescribeContext context) { TypeDescriptor keyType = mapType.resolveGenericParameter(Map.class, 0); TypeDescriptor valueType = mapType.resolveGenericParameter(Map.class, 1); context.describeAsync(path.any(), new TypeContext(mapType, valueType)); ValueType keyValueType = context.describeNow(null, new TypeContext(mapType, keyType)); if (!(keyValueType instanceof ScalarType)) { throw new IllegalArgumentException("Key of " + path + ": " + mapType + " is not a scalar (ScalarType)"); } return newMapType((ScalarType) keyValueType); }
private String getParameterName(ParameterDescriptor parameter) { return Check.notNull(context.getMappingResolver().name(parameter), type.getSimpleName() + " parameter name").value; }
@Override public ValueType describe(PropertyPath path, TypeDescriptor listType, DescribeContext context) { TypeDescriptor elementType = listType.resolveGenericParameter(List.class, 0); context.describeAsync(path.anyIndex(), new TypeContext(listType, elementType)); return new ListType(); }
private ValueType identifiableSetType() { ValueType valueType = context.describeNow(path.any(), new TypeContext(setType, elementType)); return newSetType(requireIdentifiable(valueType)); }
public Schema<ValueType> describeSchema(Class<?> rootClass) { return describeSchema(typeMappings.getTypeDescriptor(rootClass)); }
public ObjectSerializer(TypeToken<O> typeToken) { this.schemaRoot = new DescribeContext(DEFAULT).describeSchema(typeToken); }
private ValueType functionSetType() { context.describeAsync(path.any(), new TypeContext(setType, elementType)); TypeDescriptor functionType = setType.getTypeDescriptors().get(setKey.by()); TypeDescriptor input = functionType.resolveGenericParameter(Function.class, 0); TypeDescriptor output = functionType.resolveGenericParameter(Function.class, 1); if (!input.isSuperTypeOf(elementType)) { throw new IllegalArgumentException("Input type of Function provided by @SetKey(by=+" + input + ") should be super type of Set's element type " + elementType); } IdentifiableType delegate = requireIdentifiable(context.describeNow(null, new TypeContext(output))); return newSetType(ImmutableList.of((new FunctionKey((Function) functionType.newInstance(), delegate)))); }
@Override public Optional<ValueType> describe(PropertyPath path, TypeContext typeContext, DescribeContext context) { if (!applies(path, typeContext)) { return Optional.empty(); } MappingResolver mappingResolver = context.getMappingResolver(); Map<String, TypeDescriptor> typesByAlias = new LinkedHashMap<>(); TypeDescriptor type = typeContext.type; String alias = Check.notNull(mappingResolver.alias(type).value, "alias"); typesByAlias.put(alias, type); registerSubclasses(mappingResolver, typesByAlias, mappingResolver.subclasses(type)); ObjectTypeMapping objectTypeMapping = new ObjectTypeMapping(typesByAlias); return objectTypeMapping.describe(path, typeContext, context); }
@Override public ValueType describe(PropertyPath path, TypeDescriptor collectionType, DescribeContext context) { TypeDescriptor elementType = collectionType.resolveGenericParameter(Collection.class, 0); context.describeAsync(path.anyIndex(), new TypeContext(collectionType, elementType)); return new CollectionType(); }