private List<SimplePropertyDefinition> withTranslations(final ResourceBundle bundle, final Collection<SimplePropertyDefinition> props) { return props .stream() .map(p -> new SimplePropertyDefinition(p.getPath(), findTranslation(bundle, p.getName()), findTranslation(bundle, p.getDisplayName()), p.getType(), p.getDefaultValue(), p.getValidation(), ofNullable(p.getMetadata()) .map(m -> m .entrySet() .stream() .collect(toMap(Map.Entry::getKey, e -> findTranslation(bundle, e.getValue())))) .orElse(null), findTranslation(bundle, p.getPlaceholder()), ofNullable(p.getProposalDisplayNames()) .map(proposals -> proposals .entrySet() .stream() .collect(toMap(Map.Entry::getKey, e -> findTranslation(bundle, e.getValue()), (a, b) -> { throw new IllegalArgumentException("can't happen"); }, LinkedHashMap::new))) .orElse(null))) .collect(toList()); }
public String findPropertyPrefixForEnrichingProperty(final String configurationType) { return ofNullable(getPatch(configurationType)) .filter(it -> it.base != null) .map(patch -> Stream .of(patch.base.prependProperties, patch.base.appendProperties) .filter(Objects::nonNull) .flatMap(Collection::stream) .filter(it -> "OBJECT".equalsIgnoreCase(it.getType()) && it.getName() != null && it.getName().equals(it.getPath())) .findFirst()) .flatMap(identity()) .map(SimplePropertyDefinition::getName) .orElse(null); }
private void normalize(final SimplePropertyDefinition prop) { if (prop.getProposalDisplayNames() != null) { if (prop.getValidation() == null) { prop.setValidation(new PropertyValidation()); } if (prop.getValidation().getEnumValues() == null) { prop.getValidation().setEnumValues(prop.getProposalDisplayNames().keySet()); } } else if (prop.getValidation() != null && prop.getValidation().getEnumValues() != null && prop.getProposalDisplayNames() == null) { prop .setProposalDisplayNames(prop .getValidation() .getEnumValues() .stream() .collect(toMap(identity(), identity(), (a, b) -> { throw new IllegalArgumentException("Conflict is not possible here"); }, LinkedHashMap::new))); } if (prop.getMetadata() == null) { prop.setMetadata(emptyMap()); } if (prop.getName() == null) { prop.setName(prop.getPath().substring(prop.getPath().lastIndexOf('.') + 1)); } }
.stream() .filter(this::isConfiguration) .filter(it -> !it.getName().equals(it.getPath()) /* root is the one we convert */) .map(ref -> { final Map<String, String> enrichedMetadata = new HashMap<>(ref.getMetadata()); + ref.getMetadata().get("configurationtype::type") + "," + "name=" + ref.getMetadata().get("configurationtype::name") + ")"); return new SimplePropertyDefinition(ref.getPath(), ref.getName(), ref.getDisplayName(), "STRING", null, new PropertyValidation(true, null, null, null, null, null, null, null, null, emptySet()), .getAllConfigurations(context.getLanguage(), context.getPlaceholderProvider()) .thenApply(nodes -> nestedConfigurations.stream().map(it -> { final String type = it.getMetadata().getOrDefault("configurationtype::type", ""); final String name = it.getMetadata().getOrDefault("configurationtype::name", "default"); return nodes .getNodes() .orElseGet(() -> completedFuture(new LinkedHashMap<>())) .thenApply(potentialIdsAndNames -> { it.getValidation().setEnumValues(potentialIdsAndNames.keySet()); it.setProposalDisplayNames(potentialIdsAndNames); return null; }); .filter(it -> nestedConfigurations .stream()
return cs.thenCompose(context -> { final SimplePropertyDefinition property = context.getProperty(); if ("object".equalsIgnoreCase(property.getType())) { final Map<String, Object> childDefaults = new HashMap<>(); defaults.put(property.getName(), childDefaults); final PropertiesConverter propertiesConverter = new PropertiesConverter(jsonb, childDefaults, properties); ofNullable(property.getMetadata().getOrDefault("ui::defaultvalue::value", property.getDefaultValue())) .ifPresent(value -> { if ("number".equalsIgnoreCase(property.getType())) { defaults.put(property.getName(), Double.parseDouble(value)); } else if ("boolean".equalsIgnoreCase(property.getType())) { defaults.put(property.getName(), Boolean.parseBoolean(value)); } else if ("array".equalsIgnoreCase(property.getType())) { defaults.put(property.getName(), jsonb.fromJson(value, Object[].class)); } else if ("object".equalsIgnoreCase(property.getType())) { defaults.put(property.getName(), jsonb.fromJson(value, Map.class)); } else { if ("string".equalsIgnoreCase(property.getType()) && property .getMetadata() .keySet() .stream() .anyMatch(k -> k.equals("action::suggestions") || k.equalsIgnoreCase("action::dynamic_values"))) { defaults.putIfAbsent("$" + property.getPath() + "_name", value); defaults.put(property.getName(), value);
private Optional<UiSchema> addUpdate(final PropertyContext<?> root) { final SimplePropertyDefinition property = root.getProperty(); return ofNullable(property.getMetadata().get("action::update")) .flatMap(v -> (actions == null ? Stream.<ActionReference> empty() : actions.stream()) .filter(a -> a.getName().equals(v) && "update".equals(a.getType())) .findFirst()) .map(action -> { final UiSchema.Trigger trigger = toTrigger(properties, root.getProperty(), action); final String path = property.getPath(); trigger .setOptions(singletonList(new UiSchema.Option.Builder() .withPath(path.endsWith("[]") ? path.substring(0, path.length() - "[]".length()) : path) .withType(property.getType().toLowerCase(ROOT)) .build())); final UiSchema button = new UiSchema(); button .setTitle(action.getDisplayName() == null ? action.getName() + " (" + action.getType() + ')' : action.getDisplayName()); button.setWidget("button"); button.setTriggers(singletonList(trigger)); return button; }); }
private Patch forLang(final ResourceBundle bundle, final JsonProvider provider) { return patchPerLang.computeIfAbsent(bundle.getLocale().getLanguage(), k -> { final List<SimplePropertyDefinition> prependProperties = withTranslations(bundle, base.prependProperties); final List<SimplePropertyDefinition> appendProperties = withTranslations(bundle, base.appendProperties); return new Patch(prependProperties, appendProperties, Stream .of(prependProperties, appendProperties) .filter(Objects::nonNull) .flatMap(Collection::stream) .filter(it -> "true".equalsIgnoreCase(it.getMetadata().get("proxyserver::formId")) && !it.getPath().contains("${index}")) .findFirst() .map(it -> provider.createPointer('/' + it.getPath().replace('.', '/'))) .orElse(null)); }); }
protected UiSchema newOrphanSchema(final PropertyContext<?> ctx) { final UiSchema schema = new UiSchema(); schema.setTitle(ctx.getProperty().getDisplayName()); schema.setKey(ctx.getProperty().getPath()); if (ctx.isRequired()) { schema.setRequired(ctx.isRequired()); } schema.setPlaceholder(ctx.getProperty().getPlaceholder()); if (ctx.getConfiguration().isIncludeDocumentationMetadata()) { schema.setDescription(ctx.getProperty().getMetadata().get("documentation::value")); } if (actions != null) { final List<UiSchema.Trigger> triggers = Stream .concat(Stream .concat(Stream .concat(createValidationTrigger(ctx.getProperty()), createOtherActions(ctx.getProperty())), createSuggestionTriggers(ctx.getProperty())), createBuiltInSuggestionTriggers(ctx.getProperty())) .collect(toList()); if (!triggers.isEmpty()) { schema.setTriggers(triggers); } } schema.setCondition(createCondition(ctx)); return schema; }
final String defaultValue = context .getProperty() .getMetadata() .getOrDefault("ui::defaultvalue::value", context.getProperty().getDefaultValue()); convertDefaultValue(type, defaultValue).ifPresent(jsonSchema::setDefaultValue); final PropertyValidation validation = context.getProperty().getValidation(); if (validation != null) { ofNullable(validation.getMin()).ifPresent(m -> jsonSchema.setMinimum(m.doubleValue())); rootJsonSchema.setProperties(new HashMap<>()); rootJsonSchema.getProperties().put(context.getProperty().getName(), jsonSchema); final String order = context.getProperty().getMetadata().get("ui::optionsorder::value"); if (order != null) { jsonSchema.setProperties(new TreeMap<>(new Comparator<String>() {
return cs.thenCompose(context -> { final JsonSchema jsonSchema = new JsonSchema(); jsonSchema.setTitle(context.getProperty().getDisplayName()); final String type = context.getProperty().getType(); switch (type.toLowerCase(ROOT)) { case "enum": .thenCompose(c -> postHandling(context, jsonSchema, type)); default: if (context.getProperty().getPath().endsWith("[]")) { return CompletableFuture.completedFuture(context);
.stream() .filter(it -> it .getMetadata() .getOrDefault("configurationtype::name", "") .equals(parentFormSpec.getName()) && it .getMetadata() .getOrDefault("configurationtype::type", "") .equals(parentFormSpec.getConfigurationType())) configInstance.put(refProp.getPath() + ".$selfReference", refId); configInstance.put(refProp.getPath() + ".$selfReferenceType", node.getConfigurationType()); .get(it) .getValueType() == JsonValue.ValueType.OBJECT && node.getProperties().stream().noneMatch(prop -> prop.getName().equals(it))) .collect(Collector .of(builderFactory::createObjectBuilder,
private void enrichTriggers(final ConfigTypeNode it, final String appended) { it.getProperties().forEach(prop -> { final Map<String, String> metadata = prop.getMetadata(); metadata .keySet() .stream() .filter(k -> k.startsWith("action::") && k.split("::").length == 2) .forEach(act -> { final String key = act + "::parameters"; final String originalValue = metadata.get(key); final Map<String, String> newMetadata = new HashMap<>(metadata); final String newValue = (originalValue == null || originalValue.trim().isEmpty() ? ("action::healthcheck".equals(act) || "action::schema".equals(act) ? prop.getPath() + "," : "") + appended : (originalValue + ',' + appended)); newMetadata.put(key, newValue); prop.setMetadata(newMetadata); }); }); }
protected CompletionStage<PropertyContext<?>> fillProposalsAndReturn(final PropertyContext<?> context, final UiSchema schema, final JsonSchema jsonSchema) { if (context.getProperty().getValidation() != null && context.getProperty().getValidation().getEnumValues() != null) { schema .setTitleMap(context.getProperty().getProposalDisplayNames() != null ? context.getProperty().getProposalDisplayNames().entrySet().stream().map(v -> { final UiSchema.NameValue nameValue = new UiSchema.NameValue(); nameValue.setName(v.getValue()); return nameValue; }).collect(toList()) : context.getProperty().getValidation().getEnumValues().stream().sorted().map(v -> { final UiSchema.NameValue nameValue = new UiSchema.NameValue(); nameValue.setName(v); return nameValue; }).collect(toList())); jsonSchema.setEnumValues(context.getProperty().getValidation().getEnumValues()); } else { final String actionName = context.getProperty().getMetadata().get("action::dynamic_values"); if (client != null && actionName != null) { final CompletionStage<List<UiSchema.NameValue>> pairs =
private boolean isConfiguration(final SimplePropertyDefinition it) { return it.getMetadata().containsKey("configurationtype::name") && it.getMetadata().containsKey("configurationtype::type"); }
@Override public CompletionStage<PropertyContext<?>> convert(final CompletionStage<PropertyContext<?>> cs) { return cs.thenCompose(context -> { jsonSchema.setType(context.getProperty().getType().toLowerCase(ROOT)); final String prefix = context.getProperty().getPath() + "[]"; final List<SimplePropertyDefinition> arrayElements = properties.stream().filter(child -> child.getPath().startsWith(prefix)).collect(toList()); if (arrayElements.stream().anyMatch(e -> e.getPath().startsWith(prefix + '.'))) { // complex object final JsonSchema items = new JsonSchema(); items.setType("object"); .thenApply(done -> context); } else if (!arrayElements.isEmpty()) { // primitive final String type = arrayElements.get(0).getType(); final JsonSchema item = new JsonSchema(); item.setTitle(jsonSchema.getTitle());
private Function<String, Object> findStringValueMapper(final SimplePropertyDefinition definition) { if (definition == null) { return s -> s; } switch (definition.getType().toLowerCase(ROOT)) { case "boolean": return Boolean::parseBoolean; case "number": return Double::parseDouble; // assume object and array are not supported default: return s -> s; } }
public boolean isRequired() { return property.getValidation() != null && property.getValidation().getRequired() != null && property.getValidation().getRequired(); }
private SimplePropertyDefinition createChildrenChooserProperty(final List<ConfigTypeNode> childrenTypes, final String parentEntityId, final String locale, final String selectedItem, final String propertyPrefix) { final Map<String, String> metadata = new HashMap<>(); metadata .put("action::reloadFromParentEntityIdAndType", "builtin::root::reloadFromParentEntityIdAndType(" + "parentId=" + parentEntityId + ",type=" + childrenTypes.iterator().next().getConfigurationType() + ")"); metadata.put("action::reloadFromParentEntityIdAndType::parameters", ".."); final String simpleName = "childrenType"; final String path = ofNullable(propertyPrefix).filter(it -> !it.isEmpty()).map(p -> p + '.').orElse("") + simpleName; final LinkedHashMap<String, String> values = createConfigTypesValues(childrenTypes); return new SimplePropertyDefinition(path, simpleName, i18n.actionServiceChildrenTypePropertyDisplayName(new Locale(ofNullable(locale).orElse(""))), "enum", selectedItem, new PropertyValidation(true, null, null, null, null, null, null, null, null, values.keySet()), metadata, null, values); }