/** * Serialize the node of a PropertyBox serialization tree. * @param context Serialization context * @param obj Json object to use * @param propertyBox PropertyBox to serialize * @param node The PropertyBox node to serialize * @throws JsonSerializationException If an error occurred */ private static void serializePropertyBoxNode(JsonSerializationContext context, JsonObject obj, PropertyBox propertyBox, PropertySetSerializationNode node) throws JsonSerializationException { if (node.getProperty().isPresent()) { serializePropertyBoxProperty(context, obj, propertyBox, node.getProperty().get(), node.getName()); } else { try { // add nested object JsonObject nested = new JsonObject(); obj.add(node.getName(), nested); // serialize nested object serializePropertyBoxNodes(context, nested, propertyBox, node.getChildren()); } catch (JsonSerializationException se) { throw se; } catch (Exception e) { throw new JsonSerializationException( "Failed to serialize PropertyBox [" + propertyBox + "] for field name [" + node.getName() + "]", e); } } }
/** * Encode a {@link PropertySetSerializationNode} into a document fragment. * @param context Resolution context * @param propertyBox The PropertyBox to encode * @param node The property set serialization node * @param parentPath Parent nodes path * @return The document fragment field-value map * @throws InvalidExpressionException If an error occurred */ private static Map<String, Object> encodePropertyBoxNode(MongoDocumentContext<?> context, PropertyBox propertyBox, PropertySetSerializationNode node, String parentPath, boolean forUpdate) throws InvalidExpressionException { return isValidNodeProperty(node) .map(p -> encodeProperty(context, propertyBox, p, node.getName(), parentPath, forUpdate)) .orElseGet(() -> { // nested String parent = composeFieldPath(parentPath, node.getName()); Map<String, Object> nested = encodePropertyBoxNodes(context, propertyBox, node.getChildren(), parent, forUpdate); return forUpdate ? nested : Collections.singletonMap(node.getName(), nested); }); }
/** * Checks whether a node represents a property and the property is valid, i.e. it is a {@link Path}. * @param node The node * @return <code>true</code> if the node represents a valid property */ private static Optional<Property<?>> isValidNodeProperty(PropertySetSerializationNode node) { return node.getProperty().filter(p -> Path.class.isAssignableFrom(p.getClass())); }
Optional<Property<?>> property = isValidNodeProperty(node); if (property.isPresent()) { modelProperty = resolveSchemaProperty(model, property.get(), node.getName(), resolver, includeReadOnly); } else { modelProperty = modelToProperty( resolvePropertyBoxNodes(model, node.getChildren(), resolver, includeReadOnly)); properties.put(node.getName(), modelProperty);
/** * Checks if a {@link PropertySetSerializationNode} property is valid, i.e. it is a {@link Path} type property. * @param <T> Property type * @param <P> Path & Property type * @param node The node to check * @return If valid, returns the property as a {@link Path} and {@link Property} type, otherwise an empty Optional * is returned */ @SuppressWarnings("unchecked") private static <T, P extends Path<T> & Property<T>> Optional<P> isValidNodeProperty( PropertySetSerializationNode node) { return node.getProperty().filter(p -> Path.class.isAssignableFrom(p.getClass())).map(p -> (P) p); }
node.getChildren().forEach(c -> c.getProperty().ifPresent(p -> properties.remove(p))); return Optional.of(node);