This is an automated email from the ASF dual-hosted git repository. nfilotto pushed a commit to branch CAMEL-17923/add-constant-name-to-header-model in repository https://gitbox.apache.org/repos/asf/camel.git
commit 1055f383000f9b476a883278a293b6e306805332 Author: Nicolas Filotto <[email protected]> AuthorDate: Fri Apr 8 14:54:07 2022 +0200 CAMEL-17923: Add the name of the constant to the header model --- .../java/org/apache/camel/spi/UriEndpoint.java | 4 +- docs/components/modules/ROOT/examples/js/camel.js | 42 ++++++++++++++++++ .../ROOT/partials/component-endpoint-headers.adoc | 5 +-- .../apache/camel/tooling/model/ComponentModel.java | 12 ++++++ .../org/apache/camel/tooling/model/JsonMapper.java | 3 ++ .../apache/camel/tooling/model/JsonMapperTest.java | 6 +++ .../packaging/EndpointSchemaGeneratorMojo.java | 50 ++++++++++++++-------- .../packaging/EndpointSchemaGeneratorMojoTest.java | 16 ++++++- .../java/org/apache/camel/spi/UriEndpoint.java | 4 +- 9 files changed, 116 insertions(+), 26 deletions(-) diff --git a/core/camel-api/src/generated/java/org/apache/camel/spi/UriEndpoint.java b/core/camel-api/src/generated/java/org/apache/camel/spi/UriEndpoint.java index e9c64483bd9..00f97990130 100644 --- a/core/camel-api/src/generated/java/org/apache/camel/spi/UriEndpoint.java +++ b/core/camel-api/src/generated/java/org/apache/camel/spi/UriEndpoint.java @@ -189,8 +189,8 @@ public @interface UriEndpoint { Class<?> headersClass() default void.class; /** - * The name of the field to get or the name of the method to invoke to get the name of the headers defined in an - * enum. + * The name of the field to get or the name of the method without parameters to invoke to get the name of the + * headers defined in an enum. * <p/> * Only took into account if and only if the class defined as {@code headersClass} is an enum. * <p/> diff --git a/docs/components/modules/ROOT/examples/js/camel.js b/docs/components/modules/ROOT/examples/js/camel.js new file mode 100644 index 00000000000..4e81b7195a8 --- /dev/null +++ b/docs/components/modules/ROOT/examples/js/camel.js @@ -0,0 +1,42 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +module.exports = { + extractConstantDisplayName: (name) => { + return name.split('#').pop().split('@').join('.') + }, + + extractConstantName: (name) => { + return name.split('#').pop().split('@').shift() + }, + + extractHeadersClass: (name) => { + return name.split('#').shift() + }, + + constantLink: (artifactId, name) => { + try { + return `https://javadoc.io/doc/org.apache.camel/${artifactId}/latest/` + + module.exports.extractHeadersClass(name).split('.').join('/') + '.html#' + + module.exports.extractConstantName(name) + + '[`' + module.exports.extractConstantDisplayName(name) + '`]' + } catch (e) { + console.log('error', e) + return e.msg() + } + }, +} \ No newline at end of file diff --git a/docs/components/modules/ROOT/partials/component-endpoint-headers.adoc b/docs/components/modules/ROOT/partials/component-endpoint-headers.adoc index 94b11e8f68d..d5d182f7e69 100644 --- a/docs/components/modules/ROOT/partials/component-endpoint-headers.adoc +++ b/docs/components/modules/ROOT/partials/component-endpoint-headers.adoc @@ -1,11 +1,10 @@ //component headers: START :tablespec: width="100%",cols="2,5a,^1,2",options="header" -:cellformats: 'util.boldLink(path[2], "endpoint_header", value.group) \ +:cellformats: 'util.boldLink(path[2], "endpoint_header", value.group) + "\n\nConstant: " + camel.constantLink("{artifactid}",value.constantName) \ |util.description(value) \ |util.valueAsString(value.defaultValue) \ |util.javaSimpleName(value.javaType)' -include::jsonpath$example$json/{shortname}.json[query='$.component',formats='name,scheme,pascalcasescheme=util.pascalCase(scheme),syntax,apiSyntax', requires={requires}] include::jsonpathcount$example$json/{shortname}.json[queries='headercount=nodes$.headers.*'] ifeval::[{headercount} != 0] @@ -18,7 +17,7 @@ The {doctitle} component supports {headercount} message header(s), which is/are | Name | Description | Default | Type |=== -jsonpathTable::example$json/{shortname}.json['nodes$.headers.*',{cellformats},{requires}] +jsonpathTable::example$json/{shortname}.json['nodes$.headers.*',{cellformats},'util=camel-website-util,camel=xref:js/camel.js'] endif::[] // component headers: END \ No newline at end of file diff --git a/tooling/camel-tooling-model/src/main/java/org/apache/camel/tooling/model/ComponentModel.java b/tooling/camel-tooling-model/src/main/java/org/apache/camel/tooling/model/ComponentModel.java index dfe31c0631e..d5df5019791 100644 --- a/tooling/camel-tooling-model/src/main/java/org/apache/camel/tooling/model/ComponentModel.java +++ b/tooling/camel-tooling-model/src/main/java/org/apache/camel/tooling/model/ComponentModel.java @@ -187,6 +187,18 @@ public class ComponentModel extends ArtifactModel<ComponentModel.ComponentOption public static class EndpointHeaderModel extends BaseOptionModel { + /** + * The name of the constant that defines the header. + */ + private String constantName; + + public String getConstantName() { + return constantName; + } + + public void setConstantName(String constantName) { + this.constantName = constantName; + } } public static class ComponentOptionModel extends BaseOptionModel { diff --git a/tooling/camel-tooling-model/src/main/java/org/apache/camel/tooling/model/JsonMapper.java b/tooling/camel-tooling-model/src/main/java/org/apache/camel/tooling/model/JsonMapper.java index d828168c4fb..0b3db6dbc5e 100644 --- a/tooling/camel-tooling-model/src/main/java/org/apache/camel/tooling/model/JsonMapper.java +++ b/tooling/camel-tooling-model/src/main/java/org/apache/camel/tooling/model/JsonMapper.java @@ -97,6 +97,7 @@ public final class JsonMapper { JsonObject mp = (JsonObject) entry.getValue(); EndpointHeaderModel header = new EndpointHeaderModel(); parseOption(mp, header, entry.getKey()); + header.setConstantName(mp.getString("constantName")); model.addEndpointHeader(header); } } @@ -531,6 +532,8 @@ public final class JsonMapper { prop.put("setterMethod", option.getSetterMethod()); if (option instanceof ComponentModel.ApiOptionModel) { prop.put("optional", ((ComponentModel.ApiOptionModel) option).isOptional()); + } else if (option instanceof ComponentModel.EndpointHeaderModel) { + prop.put("constantName", ((ComponentModel.EndpointHeaderModel) option).getConstantName()); } prop.entrySet().removeIf(e -> e.getValue() == null); prop.remove("prefix", ""); diff --git a/tooling/camel-tooling-model/src/test/java/org/apache/camel/tooling/model/JsonMapperTest.java b/tooling/camel-tooling-model/src/test/java/org/apache/camel/tooling/model/JsonMapperTest.java index fc03afa90a2..6beecb46742 100644 --- a/tooling/camel-tooling-model/src/test/java/org/apache/camel/tooling/model/JsonMapperTest.java +++ b/tooling/camel-tooling-model/src/test/java/org/apache/camel/tooling/model/JsonMapperTest.java @@ -45,6 +45,7 @@ class JsonMapperTest { EndpointHeaderModel header = new EndpointHeaderModel(); header.setName("Some Name"); header.setDescription("Some Description"); + header.setConstantName("Some constant Name"); model.addEndpointHeader(header); String json = JsonMapper.createParameterJsonSchema(model); ComponentModel model2 = JsonMapper.generateComponentModel(json); @@ -52,6 +53,7 @@ class JsonMapperTest { assertEquals(1, headers.size()); assertEquals(header.getName(), headers.get(0).getName()); assertEquals(header.getDescription(), headers.get(0).getDescription()); + assertEquals(header.getConstantName(), headers.get(0).getConstantName()); } @Test @@ -60,10 +62,12 @@ class JsonMapperTest { EndpointHeaderModel header1 = new EndpointHeaderModel(); header1.setName("Some Name"); header1.setDescription("Some Description"); + header1.setConstantName("Some constant Name"); model.addEndpointHeader(header1); EndpointHeaderModel header2 = new EndpointHeaderModel(); header2.setName("Some Name 2"); header2.setDescription("Some Description 2"); + header2.setConstantName("Some constant Name 2"); model.addEndpointHeader(header2); String json = JsonMapper.createParameterJsonSchema(model); ComponentModel model2 = JsonMapper.generateComponentModel(json); @@ -71,7 +75,9 @@ class JsonMapperTest { assertEquals(2, headers.size()); assertEquals(header1.getName(), headers.get(0).getName()); assertEquals(header1.getDescription(), headers.get(0).getDescription()); + assertEquals(header1.getConstantName(), headers.get(0).getConstantName()); assertEquals(header2.getName(), headers.get(1).getName()); assertEquals(header2.getDescription(), headers.get(1).getDescription()); + assertEquals(header2.getConstantName(), headers.get(1).getConstantName()); } } diff --git a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/EndpointSchemaGeneratorMojo.java b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/EndpointSchemaGeneratorMojo.java index d0890ce1dc2..4ea2bcea120 100644 --- a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/EndpointSchemaGeneratorMojo.java +++ b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/EndpointSchemaGeneratorMojo.java @@ -409,7 +409,7 @@ public class EndpointSchemaGeneratorMojo extends AbstractGeneratorMojo { getLog().debug(String.format("The java type %s could not be found", header.getJavaType()), e); } try { - header.setName(getHeaderName(field, headersNameProvider)); + setHeaderNames(header, field, headersNameProvider); componentModel.addEndpointHeader(header); } catch (Exception e) { getLog().debug(String.format("The name of the header corresponding to the field %s in class %s cannot be retrieved", @@ -420,31 +420,38 @@ public class EndpointSchemaGeneratorMojo extends AbstractGeneratorMojo { } /** - * The name of the header is: + * Set the name of the header and the name of the constant corresponding to the name of the header. + * <p/> + * The name of the header and the name of the constant are set as follows: * <ul> - * <li>In case of an interface or a class: The value of the field as we assume that it is a {@code String} - * constant</li> - * <li>In case of an enum: + * <li><u>In case of an interface or a class:</u> <b>The name of the header</b> is the value of the field as we + * assume that it is a {@code String} constant and <b>the name of the constant</b> is in the following format + * <i>${declaring-class-name}#${constant-name}</i></li> + * <li><u>In case of an enum:</u> * <ul> - * <li>If headers name provider is set to a name of field: The value of this particular field for the corresponding - * enum constant</li> - * <li>If headers name provider is set to a name of method: The returned value of this particular method for the - * corresponding enum constant</li> - * <li>By default: The name of the enum constant</li> + * <li><u>If {@code headersNameProvider} is set to a name of field:</u> <b>The name of the header</b> is the value + * of this particular field for the corresponding enum constant and <b>the name of the constant</b> is in the + * following format <i>${declaring-class-name}#${enum-constant-name}@${field-name}</i></li> + * <li><u>If {@code headersNameProvider} is set to a name of method:</u> <b>The name of the header</b> is the + * returned value of this particular method for the corresponding enum constant and <b>the name of the constant</b> + * is in the following format <i>${declaring-class-name}#${enum-constant-name}@${method-name}()</i></li> + * <li><u>Otherwise:</u> <b>The name of the header</b> is the name of the enum constant and <b>the name of the + * constant</b> is in the following format <i>${declaring-class-name}#${enum-constant-name}</i></li> * </ul> * </li> * </ul> * + * @param header the header in which the name of the header and its corresponding constant should be + * set. * @param field the field corresponding to the name of a header. * @param headersNameProvider the name of the field to get or the name of the method to invoke to get the name of * the headers. - * @return the name of the header corresponding to the given field. * @throws Exception if an error occurred while getting the name of the header */ - private String getHeaderName(Field field, String headersNameProvider) throws Exception { + private void setHeaderNames(EndpointHeaderModel header, Field field, String headersNameProvider) throws Exception { + final Class<?> declaringClass = field.getDeclaringClass(); if (field.getType().isEnum()) { if (!headersNameProvider.isEmpty()) { - final Class<?> declaringClass = field.getDeclaringClass(); final Optional<?> value = Arrays.stream(declaringClass.getEnumConstants()) .filter(c -> ((Enum<?>) c).name().equals(field.getName())) .findAny(); @@ -455,7 +462,10 @@ public class EndpointSchemaGeneratorMojo extends AbstractGeneratorMojo { .findAny(); if (headersNameProviderField.isPresent()) { getLog().debug("A field corresponding to the headers name provider has been found"); - return (String) headersNameProviderField.get().get(value.get()); + header.setConstantName( + String.format("%s#%s@%s", declaringClass.getName(), field.getName(), headersNameProvider)); + header.setName((String) headersNameProviderField.get().get(value.get())); + return; } getLog().debug( String.format("No field %s could be found in the class %s", headersNameProvider, declaringClass)); @@ -464,15 +474,21 @@ public class EndpointSchemaGeneratorMojo extends AbstractGeneratorMojo { .findAny(); if (headersNameProviderMethod.isPresent()) { getLog().debug("A method without parameters corresponding to the headers name provider has been found"); - return (String) headersNameProviderMethod.get().invoke(value.get()); + header.setConstantName( + String.format("%s#%s@%s()", declaringClass.getName(), field.getName(), headersNameProvider)); + header.setName((String) headersNameProviderMethod.get().invoke(value.get())); + return; } getLog().debug(String.format("No method %s without parameters could be found in the class %s", headersNameProvider, declaringClass)); } } - return field.getName(); + header.setConstantName(String.format("%s#%s", declaringClass.getName(), field.getName())); + header.setName(field.getName()); + return; } - return (String) field.get(null); + header.setConstantName(String.format("%s#%s", declaringClass.getName(), field.getName())); + header.setName((String) field.get(null)); } /** diff --git a/tooling/maven/camel-package-maven-plugin/src/test/java/org/apache/camel/maven/packaging/EndpointSchemaGeneratorMojoTest.java b/tooling/maven/camel-package-maven-plugin/src/test/java/org/apache/camel/maven/packaging/EndpointSchemaGeneratorMojoTest.java index 5e4fc847169..08da2b57c84 100644 --- a/tooling/maven/camel-package-maven-plugin/src/test/java/org/apache/camel/maven/packaging/EndpointSchemaGeneratorMojoTest.java +++ b/tooling/maven/camel-package-maven-plugin/src/test/java/org/apache/camel/maven/packaging/EndpointSchemaGeneratorMojoTest.java @@ -65,7 +65,8 @@ class EndpointSchemaGeneratorMojoTest { @ValueSource(classes = { SomeEndpoint.class, SomeEndpointUsingEnumConstants.class, SomeEndpointUsingInterfaceConstants.class }) void testCanRetrieveMetadataOfHeaders(Class<?> clazz) { - mojo.addEndpointHeaders(model, clazz.getAnnotation(UriEndpoint.class), "some"); + UriEndpoint endpoint = clazz.getAnnotation(UriEndpoint.class); + mojo.addEndpointHeaders(model, endpoint, "some"); List<EndpointHeaderModel> endpointHeaders = model.getEndpointHeaders(); assertEquals(3, endpointHeaders.size()); // Full @@ -83,6 +84,8 @@ class EndpointSchemaGeneratorMojoTest { assertEquals("my label", headerFull.getLabel()); assertEquals(3, headerFull.getEnums().size()); assertEquals("my label", headerFull.getGroup()); + assertEquals(String.format("%s#%s", endpoint.headersClass().getName(), headerFull.getName()), + headerFull.getConstantName()); // Empty EndpointHeaderModel headerEmpty = endpointHeaders.get(1); assertEquals("header", headerEmpty.getKind()); @@ -99,6 +102,8 @@ class EndpointSchemaGeneratorMojoTest { assertTrue(headerEmpty.getLabel().isEmpty()); assertNull(headerEmpty.getEnums()); assertEquals("common", headerEmpty.getGroup()); + assertEquals(String.format("%s#%s", endpoint.headersClass().getName(), headerEmpty.getName()), + headerEmpty.getConstantName()); // Empty with Javadoc as description EndpointHeaderModel headerEmptyWithJavadoc = endpointHeaders.get(2); assertEquals("header", headerEmptyWithJavadoc.getKind()); @@ -115,6 +120,8 @@ class EndpointSchemaGeneratorMojoTest { assertTrue(headerEmptyWithJavadoc.getLabel().isEmpty()); assertNull(headerEmptyWithJavadoc.getEnums()); assertEquals("common", headerEmptyWithJavadoc.getGroup()); + assertEquals(String.format("%s#%s", endpoint.headersClass().getName(), headerEmptyWithJavadoc.getName()), + headerEmptyWithJavadoc.getConstantName()); } @Test @@ -172,11 +179,16 @@ class EndpointSchemaGeneratorMojoTest { @ValueSource(classes = { SomeEndpointUsingEnumConstantsByField.class, SomeEndpointUsingEnumConstantsByMethod.class }) void testEndpointWithNameProvider(Class<?> clazz) { - mojo.addEndpointHeaders(model, clazz.getAnnotation(UriEndpoint.class), "some"); + UriEndpoint endpoint = clazz.getAnnotation(UriEndpoint.class); + mojo.addEndpointHeaders(model, endpoint, "some"); List<EndpointHeaderModel> endpointHeaders = model.getEndpointHeaders(); assertEquals(1, endpointHeaders.size()); EndpointHeaderModel header = endpointHeaders.get(0); assertEquals("header", header.getKind()); assertEquals("SomeName", header.getName()); + assertEquals( + String.format("%s#SOME_VALUE@%s", endpoint.headersClass().getName(), + endpoint.headersNameProvider() + (clazz.getName().contains("Method") ? "()" : "")), + header.getConstantName()); } } diff --git a/tooling/spi-annotations/src/main/java/org/apache/camel/spi/UriEndpoint.java b/tooling/spi-annotations/src/main/java/org/apache/camel/spi/UriEndpoint.java index e9c64483bd9..00f97990130 100644 --- a/tooling/spi-annotations/src/main/java/org/apache/camel/spi/UriEndpoint.java +++ b/tooling/spi-annotations/src/main/java/org/apache/camel/spi/UriEndpoint.java @@ -189,8 +189,8 @@ public @interface UriEndpoint { Class<?> headersClass() default void.class; /** - * The name of the field to get or the name of the method to invoke to get the name of the headers defined in an - * enum. + * The name of the field to get or the name of the method without parameters to invoke to get the name of the + * headers defined in an enum. * <p/> * Only took into account if and only if the class defined as {@code headersClass} is an enum. * <p/>
