Repository: camel Updated Branches: refs/heads/camel-2.16.x b234404c4 -> 609c21366 refs/heads/master 348e1bcc2 -> c74fdf5cc
CAMEL-9472: Add multi value to component docs Project: http://git-wip-us.apache.org/repos/asf/camel/repo Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/409a5380 Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/409a5380 Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/409a5380 Branch: refs/heads/master Commit: 409a5380fde8d16202cd7ec7668cd9452fbde9fb Parents: 348e1bc Author: Claus Ibsen <davscl...@apache.org> Authored: Mon Jan 4 12:18:50 2016 +0100 Committer: Claus Ibsen <davscl...@apache.org> Committed: Mon Jan 4 12:22:14 2016 +0100 ---------------------------------------------------------------------- .../camel/impl/ScheduledPollEndpoint.java | 2 +- .../camel/catalog/DefaultCamelCatalog.java | 30 ++++++++--- .../apache/camel/catalog/JSonSchemaHelper.java | 52 ++++++++++++++++++++ .../apache/camel/catalog/CamelCatalogTest.java | 4 ++ .../camel/tools/apt/EipAnnotationProcessor.java | 2 +- .../tools/apt/EndpointAnnotationProcessor.java | 25 +++++++--- .../tools/apt/helper/JsonSchemaHelper.java | 12 ++++- .../camel/tools/apt/model/EndpointOption.java | 15 +++++- .../tools/apt/EndpointOptionComparatorTest.java | 8 +-- .../java/org/apache/camel/spi/UriParam.java | 12 +++++ 10 files changed, 139 insertions(+), 23 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/camel/blob/409a5380/camel-core/src/main/java/org/apache/camel/impl/ScheduledPollEndpoint.java ---------------------------------------------------------------------- diff --git a/camel-core/src/main/java/org/apache/camel/impl/ScheduledPollEndpoint.java b/camel-core/src/main/java/org/apache/camel/impl/ScheduledPollEndpoint.java index 13335c9..6d1b938 100644 --- a/camel-core/src/main/java/org/apache/camel/impl/ScheduledPollEndpoint.java +++ b/camel-core/src/main/java/org/apache/camel/impl/ScheduledPollEndpoint.java @@ -76,7 +76,7 @@ public abstract class ScheduledPollEndpoint extends DefaultEndpoint { defaultValue = "none", label = "consumer,scheduler", description = "To use a cron scheduler from either camel-spring or camel-quartz2 component") private ScheduledPollConsumerScheduler scheduler; private String schedulerName = "none"; // used when configuring scheduler using a string value - @UriParam(optionalPrefix = "consumer.", label = "consumer,scheduler", + @UriParam(prefix = "scheduler.", multiValue = true, label = "consumer,scheduler", description = "To configure additional properties when using a custom scheduler or any of the Quartz2, Spring based scheduler.") private Map<String, Object> schedulerProperties; @UriParam(optionalPrefix = "consumer.", label = "consumer,scheduler", http://git-wip-us.apache.org/repos/asf/camel/blob/409a5380/platforms/catalog/src/main/java/org/apache/camel/catalog/DefaultCamelCatalog.java ---------------------------------------------------------------------- diff --git a/platforms/catalog/src/main/java/org/apache/camel/catalog/DefaultCamelCatalog.java b/platforms/catalog/src/main/java/org/apache/camel/catalog/DefaultCamelCatalog.java index a4e638a..79a50bf 100644 --- a/platforms/catalog/src/main/java/org/apache/camel/catalog/DefaultCamelCatalog.java +++ b/platforms/catalog/src/main/java/org/apache/camel/catalog/DefaultCamelCatalog.java @@ -47,9 +47,12 @@ import static org.apache.camel.catalog.JSonSchemaHelper.getNames; import static org.apache.camel.catalog.JSonSchemaHelper.getPropertyDefaultValue; import static org.apache.camel.catalog.JSonSchemaHelper.getPropertyEnum; import static org.apache.camel.catalog.JSonSchemaHelper.getPropertyKind; +import static org.apache.camel.catalog.JSonSchemaHelper.getPropertyNameFromNameWithPrefix; +import static org.apache.camel.catalog.JSonSchemaHelper.getPropertyPrefix; import static org.apache.camel.catalog.JSonSchemaHelper.getRow; import static org.apache.camel.catalog.JSonSchemaHelper.isPropertyBoolean; import static org.apache.camel.catalog.JSonSchemaHelper.isPropertyInteger; +import static org.apache.camel.catalog.JSonSchemaHelper.isPropertyMultiValue; import static org.apache.camel.catalog.JSonSchemaHelper.isPropertyNumber; import static org.apache.camel.catalog.JSonSchemaHelper.isPropertyObject; import static org.apache.camel.catalog.JSonSchemaHelper.isPropertyRequired; @@ -752,13 +755,25 @@ public class DefaultCamelCatalog implements CamelCatalog { // validate all the options for (Map.Entry<String, String> property : properties.entrySet()) { + String value = property.getValue(); + + String originalName = property.getKey(); String name = property.getKey(); // the name may be using an optional prefix, so lets strip that because the options // in the schema are listed without the prefix name = stripOptionalPrefixFromName(rows, name); - String value = property.getValue(); + // the name may be using a prefix, so lets see if we can find the real property name + String propertyName = getPropertyNameFromNameWithPrefix(rows, name); + if (propertyName != null) { + name = propertyName; + } + + String prefix = getPropertyPrefix(rows, name); + String kind = getPropertyKind(rows, name); boolean placeholder = value.startsWith("{{") || value.startsWith("${") || value.startsWith("$simple{"); boolean lookup = value.startsWith("#") && value.length() > 1; + // we cannot evaluate multi values as strict as the others, as we don't know their expected types + boolean mulitValue = prefix != null && originalName.startsWith(prefix) && isPropertyMultiValue(rows, name); Map<String, String> row = getRow(rows, name); if (row == null) { @@ -786,7 +801,7 @@ public class DefaultCamelCatalog implements CamelCatalog { // is enum but the value is not within the enum range // but we can only check if the value is not a placeholder String enums = getPropertyEnum(rows, name); - if (!placeholder && !lookup && enums != null) { + if (!mulitValue && !placeholder && !lookup && enums != null) { String[] choices = enums.split(","); boolean found = false; for (String s : choices) { @@ -801,9 +816,8 @@ public class DefaultCamelCatalog implements CamelCatalog { } } - // is reference lookup of bean (not applicable for @UriPath) - String kind = getPropertyKind(rows, name); - if (!"path".equals(kind) && isPropertyObject(rows, name)) { + // is reference lookup of bean (not applicable for @UriPath, or multi-valued) + if (!mulitValue && !"path".equals(kind) && isPropertyObject(rows, name)) { // must start with # and be at least 2 characters if (!value.startsWith("#") || value.length() <= 1) { result.addInvalidReference(name, value); @@ -811,7 +825,7 @@ public class DefaultCamelCatalog implements CamelCatalog { } // is boolean - if (!placeholder && !lookup && isPropertyBoolean(rows, name)) { + if (!mulitValue && !placeholder && !lookup && isPropertyBoolean(rows, name)) { // value must be a boolean boolean bool = "true".equalsIgnoreCase(value) || "false".equalsIgnoreCase(value); if (!bool) { @@ -820,7 +834,7 @@ public class DefaultCamelCatalog implements CamelCatalog { } // is integer - if (!placeholder && !lookup && isPropertyInteger(rows, name)) { + if (!mulitValue && !placeholder && !lookup && isPropertyInteger(rows, name)) { // value must be an integer boolean valid = validateInteger(value); if (!valid) { @@ -829,7 +843,7 @@ public class DefaultCamelCatalog implements CamelCatalog { } // is number - if (!placeholder && !lookup && isPropertyNumber(rows, name)) { + if (!mulitValue && !placeholder && !lookup && isPropertyNumber(rows, name)) { // value must be an number boolean valid = false; try { http://git-wip-us.apache.org/repos/asf/camel/blob/409a5380/platforms/catalog/src/main/java/org/apache/camel/catalog/JSonSchemaHelper.java ---------------------------------------------------------------------- diff --git a/platforms/catalog/src/main/java/org/apache/camel/catalog/JSonSchemaHelper.java b/platforms/catalog/src/main/java/org/apache/camel/catalog/JSonSchemaHelper.java index 2293a7a..4e4624a 100644 --- a/platforms/catalog/src/main/java/org/apache/camel/catalog/JSonSchemaHelper.java +++ b/platforms/catalog/src/main/java/org/apache/camel/catalog/JSonSchemaHelper.java @@ -273,6 +273,58 @@ public final class JSonSchemaHelper { return null; } + public static String getPropertyPrefix(List<Map<String, String>> rows, String name) { + for (Map<String, String> row : rows) { + String prefix = null; + boolean found = false; + if (row.containsKey("name")) { + found = name.equals(row.get("name")); + } + if (row.containsKey("prefix")) { + prefix = row.get("prefix"); + } + if (found) { + return prefix; + } + } + return null; + } + + public static boolean isPropertyMultiValue(List<Map<String, String>> rows, String name) { + for (Map<String, String> row : rows) { + boolean multiValue = false; + boolean found = false; + if (row.containsKey("name")) { + found = name.equals(row.get("name")); + } + if (row.containsKey("multiValue")) { + multiValue = "true".equals(row.get("multiValue")); + } + if (found) { + return multiValue; + } + } + return false; + } + + public static String getPropertyNameFromNameWithPrefix(List<Map<String, String>> rows, String name) { + for (Map<String, String> row : rows) { + String propertyName = null; + boolean found = false; + if (row.containsKey("name")) { + propertyName = row.get("name"); + } + if (row.containsKey("prefix")) { + String preifx = row.get("prefix"); + found = name.startsWith(preifx); + } + if (found) { + return propertyName; + } + } + return null; + } + public static Map<String, String> getRow(List<Map<String, String>> rows, String key) { for (Map<String, String> row : rows) { if (key.equals(row.get("name"))) { http://git-wip-us.apache.org/repos/asf/camel/blob/409a5380/platforms/catalog/src/test/java/org/apache/camel/catalog/CamelCatalogTest.java ---------------------------------------------------------------------- diff --git a/platforms/catalog/src/test/java/org/apache/camel/catalog/CamelCatalogTest.java b/platforms/catalog/src/test/java/org/apache/camel/catalog/CamelCatalogTest.java index 0b8923f..28c8cef 100644 --- a/platforms/catalog/src/test/java/org/apache/camel/catalog/CamelCatalogTest.java +++ b/platforms/catalog/src/test/java/org/apache/camel/catalog/CamelCatalogTest.java @@ -480,6 +480,10 @@ public class CamelCatalogTest { // mixed optional without consumer. prefix result = catalog.validateEndpointProperties("file:inbox?delay=5000&consumer.greedy=true"); assertTrue(result.isSuccess()); + + // prefix + result = catalog.validateEndpointProperties("file:inbox?delay=5000&scheduler.foo=123&scheduler.bar=456"); + assertTrue(result.isSuccess()); } @Test http://git-wip-us.apache.org/repos/asf/camel/blob/409a5380/tooling/apt/src/main/java/org/apache/camel/tools/apt/EipAnnotationProcessor.java ---------------------------------------------------------------------- diff --git a/tooling/apt/src/main/java/org/apache/camel/tools/apt/EipAnnotationProcessor.java b/tooling/apt/src/main/java/org/apache/camel/tools/apt/EipAnnotationProcessor.java index 294804c..eadb6fe 100644 --- a/tooling/apt/src/main/java/org/apache/camel/tools/apt/EipAnnotationProcessor.java +++ b/tooling/apt/src/main/java/org/apache/camel/tools/apt/EipAnnotationProcessor.java @@ -207,7 +207,7 @@ public class EipAnnotationProcessor extends AbstractAnnotationProcessor { String doc = entry.getDocumentation(); doc = sanitizeDescription(doc, false); buffer.append(JsonSchemaHelper.toJson(entry.getName(), entry.getKind(), entry.isRequired(), entry.getType(), entry.getDefaultValue(), doc, - entry.isDeprecated(), null, null, entry.isEnumType(), entry.getEnums(), entry.isOneOf(), entry.getOneOfTypes(), null)); + entry.isDeprecated(), null, null, entry.isEnumType(), entry.getEnums(), entry.isOneOf(), entry.getOneOfTypes(), null, null, false)); } buffer.append("\n }"); http://git-wip-us.apache.org/repos/asf/camel/blob/409a5380/tooling/apt/src/main/java/org/apache/camel/tools/apt/EndpointAnnotationProcessor.java ---------------------------------------------------------------------- diff --git a/tooling/apt/src/main/java/org/apache/camel/tools/apt/EndpointAnnotationProcessor.java b/tooling/apt/src/main/java/org/apache/camel/tools/apt/EndpointAnnotationProcessor.java index 3dc29af..93c6022 100644 --- a/tooling/apt/src/main/java/org/apache/camel/tools/apt/EndpointAnnotationProcessor.java +++ b/tooling/apt/src/main/java/org/apache/camel/tools/apt/EndpointAnnotationProcessor.java @@ -249,11 +249,14 @@ public class EndpointAnnotationProcessor extends AbstractAnnotationProcessor { defaultValue = "false"; } - // component options do not have optional prefix + // component options do not have prefix String optionalPrefix = ""; + String prefix = ""; + boolean multiValue = false; buffer.append(JsonSchemaHelper.toJson(entry.getName(), "property", required, entry.getType(), defaultValue, doc, - entry.isDeprecated(), entry.getGroup(), entry.getLabel(), entry.isEnumType(), entry.getEnums(), false, null, optionalPrefix)); + entry.isDeprecated(), entry.getGroup(), entry.getLabel(), entry.isEnumType(), entry.getEnums(), false, null, + optionalPrefix, prefix, multiValue)); } buffer.append("\n },"); @@ -297,11 +300,14 @@ public class EndpointAnnotationProcessor extends AbstractAnnotationProcessor { defaultValue = "false"; } - // @UriPath options do not have optional prefix + // @UriPath options do not have prefix String optionalPrefix = ""; + String prefix = ""; + boolean multiValue = false; buffer.append(JsonSchemaHelper.toJson(entry.getName(), "path", required, entry.getType(), defaultValue, doc, - entry.isDeprecated(), entry.getGroup(), entry.getLabel(), entry.isEnumType(), entry.getEnums(), false, null, optionalPrefix)); + entry.isDeprecated(), entry.getGroup(), entry.getLabel(), entry.isEnumType(), entry.getEnums(), false, null, + optionalPrefix, prefix, multiValue)); } // sort the endpoint options in the standard order we prefer @@ -341,9 +347,12 @@ public class EndpointAnnotationProcessor extends AbstractAnnotationProcessor { defaultValue = "false"; } String optionalPrefix = entry.getOptionalPrefix(); + String prefix = entry.getPrefix(); + boolean multiValue = entry.isMultiValue(); buffer.append(JsonSchemaHelper.toJson(entry.getName(), "parameter", required, entry.getType(), defaultValue, - doc, entry.isDeprecated(), entry.getGroup(), entry.getLabel(), entry.isEnumType(), entry.getEnums(), false, null, optionalPrefix)); + doc, entry.isDeprecated(), entry.getGroup(), entry.getLabel(), entry.isEnumType(), entry.getEnums(), false, null, + optionalPrefix, prefix, multiValue)); } buffer.append("\n }"); @@ -672,7 +681,9 @@ public class EndpointAnnotationProcessor extends AbstractAnnotationProcessor { } name = prefix + name; - String optionalPrefix = param.optionalPrefix(); + String paramOptionalPrefix = param.optionalPrefix(); + String paramPrefix = param.prefix(); + boolean multiValue = param.multiValue(); String defaultValue = param.defaultValue(); if (defaultValue == null && metadata != null) { defaultValue = metadata.defaultValue(); @@ -737,7 +748,7 @@ public class EndpointAnnotationProcessor extends AbstractAnnotationProcessor { String group = EndpointHelper.labelAsGroupName(label, componentModel.isConsumerOnly(), componentModel.isProducerOnly()); EndpointOption option = new EndpointOption(name, fieldTypeName, required, defaultValue, defaultValueNote, - docComment.trim(), optionalPrefix, deprecated, group, label, isEnum, enums); + docComment.trim(), paramOptionalPrefix, paramPrefix, multiValue, deprecated, group, label, isEnum, enums); endpointOptions.add(option); } } http://git-wip-us.apache.org/repos/asf/camel/blob/409a5380/tooling/apt/src/main/java/org/apache/camel/tools/apt/helper/JsonSchemaHelper.java ---------------------------------------------------------------------- diff --git a/tooling/apt/src/main/java/org/apache/camel/tools/apt/helper/JsonSchemaHelper.java b/tooling/apt/src/main/java/org/apache/camel/tools/apt/helper/JsonSchemaHelper.java index 51cf907..21ba792 100644 --- a/tooling/apt/src/main/java/org/apache/camel/tools/apt/helper/JsonSchemaHelper.java +++ b/tooling/apt/src/main/java/org/apache/camel/tools/apt/helper/JsonSchemaHelper.java @@ -42,7 +42,7 @@ public final class JsonSchemaHelper { public static String toJson(String name, String kind, Boolean required, String type, String defaultValue, String description, Boolean deprecated, String group, String label, boolean enumType, Set<String> enums, - boolean oneOfType, Set<String> oneOffTypes, String optionalPrefix) { + boolean oneOfType, Set<String> oneOffTypes, String optionalPrefix, String prefix, boolean multiValue) { String typeName = JsonSchemaHelper.getType(type, enumType); StringBuilder sb = new StringBuilder(); @@ -102,6 +102,16 @@ public final class JsonSchemaHelper { sb.append(Strings.doubleQuote(text)); } + if (!Strings.isNullOrEmpty(prefix)) { + sb.append(", \"prefix\": "); + String text = safeDefaultValue(prefix); + sb.append(Strings.doubleQuote(text)); + } + if (multiValue) { + sb.append(", \"multiValue\": "); + sb.append(Strings.doubleQuote("true")); + } + if (deprecated != null) { sb.append(", \"deprecated\": "); sb.append(Strings.doubleQuote(deprecated.toString())); http://git-wip-us.apache.org/repos/asf/camel/blob/409a5380/tooling/apt/src/main/java/org/apache/camel/tools/apt/model/EndpointOption.java ---------------------------------------------------------------------- diff --git a/tooling/apt/src/main/java/org/apache/camel/tools/apt/model/EndpointOption.java b/tooling/apt/src/main/java/org/apache/camel/tools/apt/model/EndpointOption.java index 3a367cf..7a45547 100644 --- a/tooling/apt/src/main/java/org/apache/camel/tools/apt/model/EndpointOption.java +++ b/tooling/apt/src/main/java/org/apache/camel/tools/apt/model/EndpointOption.java @@ -31,6 +31,8 @@ public final class EndpointOption { private String defaultValueNote; private String documentation; private String optionalPrefix; + private String prefix; + private boolean multiValue; private boolean deprecated; private String group; private String label; @@ -38,7 +40,8 @@ public final class EndpointOption { private Set<String> enums; public EndpointOption(String name, String type, String required, String defaultValue, String defaultValueNote, - String documentation, String optionalPrefix, boolean deprecated, String group, String label, + String documentation, String optionalPrefix, String prefix, boolean multiValue, + boolean deprecated, String group, String label, boolean enumType, Set<String> enums) { this.name = name; this.type = type; @@ -47,6 +50,8 @@ public final class EndpointOption { this.defaultValueNote = defaultValueNote; this.documentation = documentation; this.optionalPrefix = optionalPrefix; + this.prefix = prefix; + this.multiValue = multiValue; this.deprecated = deprecated; this.group = group; this.label = label; @@ -78,6 +83,14 @@ public final class EndpointOption { return optionalPrefix; } + public String getPrefix() { + return prefix; + } + + public boolean isMultiValue() { + return multiValue; + } + public boolean isDeprecated() { return deprecated; } http://git-wip-us.apache.org/repos/asf/camel/blob/409a5380/tooling/apt/src/test/java/org/apache/camel/tools/apt/EndpointOptionComparatorTest.java ---------------------------------------------------------------------- diff --git a/tooling/apt/src/test/java/org/apache/camel/tools/apt/EndpointOptionComparatorTest.java b/tooling/apt/src/test/java/org/apache/camel/tools/apt/EndpointOptionComparatorTest.java index 3d4a4fe..660dc56 100644 --- a/tooling/apt/src/test/java/org/apache/camel/tools/apt/EndpointOptionComparatorTest.java +++ b/tooling/apt/src/test/java/org/apache/camel/tools/apt/EndpointOptionComparatorTest.java @@ -39,10 +39,10 @@ public class EndpointOptionComparatorTest { String group3 = EndpointHelper.labelAsGroupName(label3, false, false); String group4 = EndpointHelper.labelAsGroupName(label4, false, false); - EndpointOption op1 = new EndpointOption("first", "string", "true", "", "", "blah", null, false, group1, label1, false, null); - EndpointOption op2 = new EndpointOption("synchronous", "string", "true", "", "", "blah", null, false, group2, label2, false, null); - EndpointOption op3 = new EndpointOption("second", "string", "true", "", "", "blah", null, false, group3, label3, false, null); - EndpointOption op4 = new EndpointOption("country", "string", "true", "", "", "blah", null, false, group4, label4, false, null); + EndpointOption op1 = new EndpointOption("first", "string", "true", "", "", "blah", null, null, false, false, group1, label1, false, null); + EndpointOption op2 = new EndpointOption("synchronous", "string", "true", "", "", "blah", null, null, false, false, group2, label2, false, null); + EndpointOption op3 = new EndpointOption("second", "string", "true", "", "", "blah", null, null, false, false, group3, label3, false, null); + EndpointOption op4 = new EndpointOption("country", "string", "true", "", "", "blah", null, null, false, false, group4, label4, false, null); List<EndpointOption> list = new ArrayList<EndpointOption>(); list.add(op1); http://git-wip-us.apache.org/repos/asf/camel/blob/409a5380/tooling/spi-annotations/src/main/java/org/apache/camel/spi/UriParam.java ---------------------------------------------------------------------- diff --git a/tooling/spi-annotations/src/main/java/org/apache/camel/spi/UriParam.java b/tooling/spi-annotations/src/main/java/org/apache/camel/spi/UriParam.java index ef45b2f..51760c3 100644 --- a/tooling/spi-annotations/src/main/java/org/apache/camel/spi/UriParam.java +++ b/tooling/spi-annotations/src/main/java/org/apache/camel/spi/UriParam.java @@ -85,6 +85,18 @@ public @interface UriParam { String javaType() default ""; /** + * If the parameter can be configured multiple times, such as configuring options to a <tt>Map</tt> type. + */ + boolean multiValue() default false; + + /** + * If the parameter must be configured with a prefix. + * <p/> + * For example to configure scheduler options, the parameters is prefixed with <tt>scheduler.foo=bar</tt> + */ + String prefix() default ""; + + /** * If the parameter can be configured with an optional prefix. * <p/> * For example to configure consumer options, the parameters can be prefixed with <tt>consumer.</tt>, eg <tt>consumer.delay=5000</tt>