private Optional<SimplePropertyDefinition> findDefinition(final Collection<SimplePropertyDefinition> props, final String key) { final String lookupKey = getLookupKey(key); return props.stream().filter(it -> it.getPath().equals(lookupKey)).findFirst(); }
private Stream<SimplePropertyDefinition> filterRoots(final Collection<SimplePropertyDefinition> props) { return ofNullable(props) .map(p -> p.stream().filter(it -> it.getName().equals(it.getPath()))) .orElseGet(Stream::empty); }
private Optional<SimplePropertyDefinition> findDefinition(final String key) { final String lookupKey = getLookupKey(key); return definitions.stream().filter(it -> it.getPath().equals(lookupKey)).findFirst(); }
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 JsonObject unflatten(final String prefix, final Collection<SimplePropertyDefinition> definitions, final Map<String, String> config) { final List<SimplePropertyDefinition> defs = new ArrayList<>(definitions); defs.sort(comparing(SimplePropertyDefinition::getPath)); final JsonObjectBuilder json = factory.createObjectBuilder(); final Collection<String> matched = new HashSet<>(); new ArrayList<>(definitions) .stream() .filter(it -> it.getPath().equals(prefix + it.getName())) .peek(it -> matched.add(it.getPath())) .forEach(prop -> onProperty(prefix, definitions, config, json, prop)); // handle virtual *properties* ($xxx) which are not spec-ed, ex: foo.$maxBatchSize config .entrySet() .stream() .filter(it -> it.getKey().startsWith("$") && !it.getKey().contains(".")) .filter(it -> matched.add(prefix + it.getKey())) // if matched from the def (w/ type) don't override it .forEach(e -> json.add(e.getKey(), e.getValue())); return json.build(); }
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)); }); }
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); }); }); }
public ConfigTypeNode enforceFormIdInTriggersIfPresent(final ConfigTypeNode it) { final Optional<SimplePropertyDefinition> idPropOpt = findFormId(it); if (!idPropOpt.isPresent()) { enrichTriggers(it, "$formId"); return it; } // H: we assume the id uses a simple path (no array etc), should be the case generally final String idProp = idPropOpt.get().getPath(); enrichTriggers(it, idProp + ",$formId\n\n"); return it; }
private void processObject(final Collection<SimplePropertyDefinition> definitions, final SimplePropertyDefinition prop, final Map<String, String> config, final JsonObjectBuilder json, final String name, final String currentPath) { final Map<String, String> subConfig = extractSubConfig(config, name); if (!subConfig.isEmpty()) { json.add(name, unflatten(currentPath, definitions, subConfig)); } else { new ArrayList<>(definitions) .stream() .filter(it -> isNested(it.getPath(), prop.getPath())) .forEach(p -> onProperty(currentPath, definitions, extractSubConfig(config, p.getName() + '.'), json, p)); } }
/** * Converts a component form to a uiSpec. * * @param detail the component model. * @param context an optional custom context to propagate some parameters. * @return the uiSpec corresponding to the model. */ public CompletionStage<Ui> convert(final ComponentDetail detail, final String lang, final T context) { return convert(detail::getDisplayName, detail.getId()::getFamily, detail::getProperties, detail::getActions, p -> p.getName().equals(p.getPath()), context, lang); }
protected JsonSchema findJsonSchema(final PropertyContext<?> cs) { final String[] segments = cs.getProperty().getPath().split("\\."); JsonSchema schema = jsonSchema; for (final String current : segments) { if (current.endsWith("[]")) { schema = schema.getProperties().get(current.substring(0, current.length() - "[]".length())).getItems(); } else { schema = schema.getProperties().get(current); } if (schema != null && "array".equals(schema.getType()) && schema.getItems() != null) { schema = schema.getItems(); } if (schema == null) { // unexpected log.warn("Didn't find json schema for {}", cs.getProperty().getPath()); return null; } } return schema; } }
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()); }
@CacheResult(cacheName = "org.talend.sdk.component.proxy.validation.jsonschema") public CompletionStage<JsonSchemaValidator> getValidator(final RequestContext context, final String formId) { return configurations.getDetails(context.language(), formId, context::findPlaceholder).thenCompose(config -> { final JsonSchema jsonSchema = new JsonSchema(); final JsonSchemaConverter converter = new JsonSchemaConverter(jsonb, jsonSchema, config.getProperties()); return CompletableFuture .allOf(config .getProperties() .stream() .filter(Objects::nonNull) .filter(p -> p.getName().equals(p.getPath())) .map(it -> new PropertyContext<>(it, context, LIGHT_CONTEXT_CONFIGURATION)) .map(CompletionStages::toStage) .map(converter::convert) .toArray(CompletableFuture[]::new)) .thenApply(r -> jsonSchema); }).thenApply(schema -> jsonb.fromJson(jsonb.toJson(schema), JsonObject.class)).thenApply(factory::newInstance); } }
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 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)); } }
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; }
@Override public CompletionStage<PropertyContext<?>> convert(final CompletionStage<PropertyContext<?>> cs) { return cs.thenCompose(context -> { final UiSchema arraySchema = newUiSchema(context); final SimplePropertyDefinition original = context.getProperty(); arraySchema.setTitle(original.getDisplayName()); arraySchema.setItems(new ArrayList<>()); arraySchema.setItemWidget("collapsibleFieldset"); final UiSchemaConverter converter = new UiSchemaConverter(gridLayoutFilter, family, arraySchema.getItems(), new ArrayList<>(), client, jsonSchema, properties, actions, lang, customPropertyConverters); return converter .convertObject(new PropertyContext<>( new SimplePropertyDefinition(original.getPath() + "[]", original.getName(), null, original.getType(), original.getDefaultValue(), original.getValidation(), metaToPropagate, original.getPlaceholder(), original.getProposalDisplayNames()), context.getRootContext(), context.getConfiguration()), metaToPropagate, arraySchema); }); } }