This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/camel.git
commit a6d02e0737f7de2017de746acc9999b415c81405 Author: Claus Ibsen <claus.ib...@gmail.com> AuthorDate: Fri Jun 21 10:25:00 2019 +0200 CAMEL-13663: camel-main-maven-plugin to generte spring-boot tooling metadata to fool Java editors to have code completions for Camel Main application.properties files. --- .../src/main/docs/camel-main-maven-plugin.adoc | 2 + .../java/org/apache/camel/maven/GenerateMojo.java | 61 +++++- .../META-INF/spring-configuration-metadata.json | 210 +++++++++++++++++++++ 3 files changed, 265 insertions(+), 8 deletions(-) diff --git a/catalog/camel-main-maven-plugin/src/main/docs/camel-main-maven-plugin.adoc b/catalog/camel-main-maven-plugin/src/main/docs/camel-main-maven-plugin.adoc index 97f6eca..34f9007 100644 --- a/catalog/camel-main-maven-plugin/src/main/docs/camel-main-maven-plugin.adoc +++ b/catalog/camel-main-maven-plugin/src/main/docs/camel-main-maven-plugin.adoc @@ -163,6 +163,8 @@ The maven plugin *generate* goal supports the following options which can be con |=== | Parameter | Default Value | Description +| autowireEnabled | true | Whether generating autowiring is enabled. +| springBootEnabled | true | Whether generating spring boot tooling support is enabled. | logClasspath | false | Whether to log the classpath when starting | logUnmapped | false | When autowiring has detected multiple implementations (2 or more) of a given interface, which cannot be mapped, should they be logged so you can see and add manual mapping if needed. | downloadVersion | true | Whether to allow downloading Camel catalog version from the internet. diff --git a/catalog/camel-main-maven-plugin/src/main/java/org/apache/camel/maven/GenerateMojo.java b/catalog/camel-main-maven-plugin/src/main/java/org/apache/camel/maven/GenerateMojo.java index c3e3b21..04d5567 100644 --- a/catalog/camel-main-maven-plugin/src/main/java/org/apache/camel/maven/GenerateMojo.java +++ b/catalog/camel-main-maven-plugin/src/main/java/org/apache/camel/maven/GenerateMojo.java @@ -21,6 +21,7 @@ import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; +import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.List; @@ -30,6 +31,7 @@ import java.util.stream.Collectors; import org.apache.camel.maven.model.AutowireData; import org.apache.camel.maven.model.SpringBootData; +import org.apache.camel.support.IntrospectionSupport; import org.apache.camel.support.PatternHelper; import org.apache.camel.util.IOHelper; import org.apache.camel.util.OrderedProperties; @@ -50,6 +52,18 @@ import static org.apache.camel.util.StringHelper.camelCaseToDash; public class GenerateMojo extends AbstractMainMojo { /** + * Whether generating autowiring is enabled. + */ + @Parameter(property = "camel.autowireEnabled", defaultValue = "true") + protected boolean autowireEnabled; + + /** + * Whether generating spring boot tooling support is enabled. + */ + @Parameter(property = "camel.springBootEnabled", defaultValue = "true") + protected boolean springBootEnabled; + + /** * When autowiring has detected multiple implementations (2 or more) of a given interface, which * cannot be mapped, should they be logged so you can see and add manual mapping if needed. */ @@ -126,10 +140,13 @@ public class GenerateMojo extends AbstractMainMojo { // we want to use dash in the name String dash = camelCaseToDash(name); String key = "camel.component." + componentName + "." + dash; - springBootData.add(new SpringBootData(key, springBootJavaType(javaType), description, defaultValue)); + if (springBootEnabled) { + getLog().debug("Spring Boot option: " + key); + springBootData.add(new SpringBootData(key, springBootJavaType(javaType), description, defaultValue)); + } // check if we can do automatic autowire to complex singleton objects from classes in the classpath - if ("object".equals(type)) { + if (autowireEnabled && "object".equals(type)) { if (!isValidAutowirePropertyName(componentName, name)) { getLog().debug("Skipping property name: " + name); return; @@ -148,14 +165,28 @@ public class GenerateMojo extends AbstractMainMojo { .collect(Collectors.toSet()); Class best = chooseBestKnownType(componentName, name, clazz, classes, mappingProperties); if (best != null) { - key = "camel.component." + componentName + "." + name; + key = "camel.component." + componentName + "." + dash; String value = "#class:" + best.getName(); - getLog().debug(key + "=" + value); + getLog().debug("Autowire: " + key + "=" + value); autowireData.add(new AutowireData(key, value)); - // TODO: get options from best class (getter/setter pairs) - // we dont have documentation - // add as spring boot options + if (springBootEnabled) { + // gather additional spring boot data for this class + // we dont have documentation or default values + List<Method> setters = new ArrayList<>(); + extraSetterMethods(best, setters); + // sort the setters + setters.sort((o1, o2) -> o1.getName().compareToIgnoreCase(o2.getName())); + for (Method m : setters) { + String shortHand = IntrospectionSupport.getSetterShorthandName(m); + String bootName = camelCaseToDash(shortHand); + String bootKey = "camel.component." + componentName + "." + dash + "." + bootName; + String bootJavaType = m.getParameterTypes()[0].getName(); + getLog().debug("Spring Boot option: " + bootKey); + String desc = "Auto discovered option from class: " + best.getName() + " to set the option via setter: " + m.getName(); + springBootData.add(new SpringBootData(bootKey, springBootJavaType(bootJavaType), desc, null)); + } + } } } @@ -183,7 +214,9 @@ public class GenerateMojo extends AbstractMainMojo { sb.append(" {\n"); sb.append(" \"name\": \"" + row.getName() + "\",\n"); sb.append(" \"type\": \"" + row.getJavaType() + "\",\n"); - sb.append(" \"description\": \"" + row.getDescription() + "\""); + if (row.getDescription() != null) { + sb.append(" \"description\": \"" + row.getDescription() + "\""); + } if (row.getDefaultValue() != null) { sb.append(",\n"); if (springBootDefaultValueQuotes(row.getJavaType())) { @@ -388,4 +421,16 @@ public class GenerateMojo extends AbstractMainMojo { return true; } + private static void extraSetterMethods(Class<?> clazz, List<Method> answer) { + if (clazz == null || clazz == Object.class) { + return; + } + Method[] methods = clazz.getMethods(); + for (Method m : methods) { + if (IntrospectionSupport.isSetter(m)) { + answer.add(m); + } + } + } + } diff --git a/examples/camel-example-main-artemis/src/main/resources/META-INF/spring-configuration-metadata.json b/examples/camel-example-main-artemis/src/main/resources/META-INF/spring-configuration-metadata.json index 03f8ff8..75835f7 100644 --- a/examples/camel-example-main-artemis/src/main/resources/META-INF/spring-configuration-metadata.json +++ b/examples/camel-example-main-artemis/src/main/resources/META-INF/spring-configuration-metadata.json @@ -662,6 +662,216 @@ "description": "The connection factory to be use. A connection factory must be configured either on the component or endpoint." }, { + "name": "camel.component.jms.connection-factory.auto-group", + "type": "java.lang.Boolean", + "description": "Auto discovered option from class: org.apache.activemq.artemis.jms.client.ActiveMQJMSConnectionFactory to set the option via setter: setAutoGroup" + }, + { + "name": "camel.component.jms.connection-factory.block-on-acknowledge", + "type": "java.lang.Boolean", + "description": "Auto discovered option from class: org.apache.activemq.artemis.jms.client.ActiveMQJMSConnectionFactory to set the option via setter: setBlockOnAcknowledge" + }, + { + "name": "camel.component.jms.connection-factory.block-on-durable-send", + "type": "java.lang.Boolean", + "description": "Auto discovered option from class: org.apache.activemq.artemis.jms.client.ActiveMQJMSConnectionFactory to set the option via setter: setBlockOnDurableSend" + }, + { + "name": "camel.component.jms.connection-factory.block-on-non-durable-send", + "type": "java.lang.Boolean", + "description": "Auto discovered option from class: org.apache.activemq.artemis.jms.client.ActiveMQJMSConnectionFactory to set the option via setter: setBlockOnNonDurableSend" + }, + { + "name": "camel.component.jms.connection-factory.cache-destinations", + "type": "java.lang.Boolean", + "description": "Auto discovered option from class: org.apache.activemq.artemis.jms.client.ActiveMQJMSConnectionFactory to set the option via setter: setCacheDestinations" + }, + { + "name": "camel.component.jms.connection-factory.cache-large-messages-client", + "type": "java.lang.Boolean", + "description": "Auto discovered option from class: org.apache.activemq.artemis.jms.client.ActiveMQJMSConnectionFactory to set the option via setter: setCacheLargeMessagesClient" + }, + { + "name": "camel.component.jms.connection-factory.call-failover-timeout", + "type": "java.lang.Long", + "description": "Auto discovered option from class: org.apache.activemq.artemis.jms.client.ActiveMQJMSConnectionFactory to set the option via setter: setCallFailoverTimeout" + }, + { + "name": "camel.component.jms.connection-factory.call-timeout", + "type": "java.lang.Long", + "description": "Auto discovered option from class: org.apache.activemq.artemis.jms.client.ActiveMQJMSConnectionFactory to set the option via setter: setCallTimeout" + }, + { + "name": "camel.component.jms.connection-factory.client-failure-check-period", + "type": "java.lang.Long", + "description": "Auto discovered option from class: org.apache.activemq.artemis.jms.client.ActiveMQJMSConnectionFactory to set the option via setter: setClientFailureCheckPeriod" + }, + { + "name": "camel.component.jms.connection-factory.client-id", + "type": "java.lang.String", + "description": "Auto discovered option from class: org.apache.activemq.artemis.jms.client.ActiveMQJMSConnectionFactory to set the option via setter: setClientID" + }, + { + "name": "camel.component.jms.connection-factory.compress-large-message", + "type": "java.lang.Boolean", + "description": "Auto discovered option from class: org.apache.activemq.artemis.jms.client.ActiveMQJMSConnectionFactory to set the option via setter: setCompressLargeMessage" + }, + { + "name": "camel.component.jms.connection-factory.confirmation-window-size", + "type": "java.lang.Integer", + "description": "Auto discovered option from class: org.apache.activemq.artemis.jms.client.ActiveMQJMSConnectionFactory to set the option via setter: setConfirmationWindowSize" + }, + { + "name": "camel.component.jms.connection-factory.connection-load-balancing-policy-class-name", + "type": "java.lang.String", + "description": "Auto discovered option from class: org.apache.activemq.artemis.jms.client.ActiveMQJMSConnectionFactory to set the option via setter: setConnectionLoadBalancingPolicyClassName" + }, + { + "name": "camel.component.jms.connection-factory.connection-ttl", + "type": "java.lang.Long", + "description": "Auto discovered option from class: org.apache.activemq.artemis.jms.client.ActiveMQJMSConnectionFactory to set the option via setter: setConnectionTTL" + }, + { + "name": "camel.component.jms.connection-factory.consumer-max-rate", + "type": "java.lang.Integer", + "description": "Auto discovered option from class: org.apache.activemq.artemis.jms.client.ActiveMQJMSConnectionFactory to set the option via setter: setConsumerMaxRate" + }, + { + "name": "camel.component.jms.connection-factory.consumer-window-size", + "type": "java.lang.Integer", + "description": "Auto discovered option from class: org.apache.activemq.artemis.jms.client.ActiveMQJMSConnectionFactory to set the option via setter: setConsumerWindowSize" + }, + { + "name": "camel.component.jms.connection-factory.deserialization-black-list", + "type": "java.lang.String", + "description": "Auto discovered option from class: org.apache.activemq.artemis.jms.client.ActiveMQJMSConnectionFactory to set the option via setter: setDeserializationBlackList" + }, + { + "name": "camel.component.jms.connection-factory.deserialization-white-list", + "type": "java.lang.String", + "description": "Auto discovered option from class: org.apache.activemq.artemis.jms.client.ActiveMQJMSConnectionFactory to set the option via setter: setDeserializationWhiteList" + }, + { + "name": "camel.component.jms.connection-factory.dups-ok-batch-size", + "type": "java.lang.Integer", + "description": "Auto discovered option from class: org.apache.activemq.artemis.jms.client.ActiveMQJMSConnectionFactory to set the option via setter: setDupsOKBatchSize" + }, + { + "name": "camel.component.jms.connection-factory.enable1x-prefixes", + "type": "java.lang.Boolean", + "description": "Auto discovered option from class: org.apache.activemq.artemis.jms.client.ActiveMQJMSConnectionFactory to set the option via setter: setEnable1xPrefixes" + }, + { + "name": "camel.component.jms.connection-factory.enable-shared-client-id", + "type": "java.lang.Boolean", + "description": "Auto discovered option from class: org.apache.activemq.artemis.jms.client.ActiveMQJMSConnectionFactory to set the option via setter: setEnableSharedClientID" + }, + { + "name": "camel.component.jms.connection-factory.failover-on-initial-connection", + "type": "java.lang.Boolean", + "description": "Auto discovered option from class: org.apache.activemq.artemis.jms.client.ActiveMQJMSConnectionFactory to set the option via setter: setFailoverOnInitialConnection" + }, + { + "name": "camel.component.jms.connection-factory.group-id", + "type": "java.lang.String", + "description": "Auto discovered option from class: org.apache.activemq.artemis.jms.client.ActiveMQJMSConnectionFactory to set the option via setter: setGroupID" + }, + { + "name": "camel.component.jms.connection-factory.ignore-jta", + "type": "java.lang.Boolean", + "description": "Auto discovered option from class: org.apache.activemq.artemis.jms.client.ActiveMQJMSConnectionFactory to set the option via setter: setIgnoreJTA" + }, + { + "name": "camel.component.jms.connection-factory.incoming-interceptor-list", + "type": "java.lang.String", + "description": "Auto discovered option from class: org.apache.activemq.artemis.jms.client.ActiveMQJMSConnectionFactory to set the option via setter: setIncomingInterceptorList" + }, + { + "name": "camel.component.jms.connection-factory.initial-connect-attempts", + "type": "java.lang.Integer", + "description": "Auto discovered option from class: org.apache.activemq.artemis.jms.client.ActiveMQJMSConnectionFactory to set the option via setter: setInitialConnectAttempts" + }, + { + "name": "camel.component.jms.connection-factory.initial-message-packet-size", + "type": "java.lang.Integer", + "description": "Auto discovered option from class: org.apache.activemq.artemis.jms.client.ActiveMQJMSConnectionFactory to set the option via setter: setInitialMessagePacketSize" + }, + { + "name": "camel.component.jms.connection-factory.max-retry-interval", + "type": "java.lang.Long", + "description": "Auto discovered option from class: org.apache.activemq.artemis.jms.client.ActiveMQJMSConnectionFactory to set the option via setter: setMaxRetryInterval" + }, + { + "name": "camel.component.jms.connection-factory.min-large-message-size", + "type": "java.lang.Integer", + "description": "Auto discovered option from class: org.apache.activemq.artemis.jms.client.ActiveMQJMSConnectionFactory to set the option via setter: setMinLargeMessageSize" + }, + { + "name": "camel.component.jms.connection-factory.outgoing-interceptor-list", + "type": "java.lang.String", + "description": "Auto discovered option from class: org.apache.activemq.artemis.jms.client.ActiveMQJMSConnectionFactory to set the option via setter: setOutgoingInterceptorList" + }, + { + "name": "camel.component.jms.connection-factory.pre-acknowledge", + "type": "java.lang.Boolean", + "description": "Auto discovered option from class: org.apache.activemq.artemis.jms.client.ActiveMQJMSConnectionFactory to set the option via setter: setPreAcknowledge" + }, + { + "name": "camel.component.jms.connection-factory.producer-max-rate", + "type": "java.lang.Integer", + "description": "Auto discovered option from class: org.apache.activemq.artemis.jms.client.ActiveMQJMSConnectionFactory to set the option via setter: setProducerMaxRate" + }, + { + "name": "camel.component.jms.connection-factory.producer-window-size", + "type": "java.lang.Integer", + "description": "Auto discovered option from class: org.apache.activemq.artemis.jms.client.ActiveMQJMSConnectionFactory to set the option via setter: setProducerWindowSize" + }, + { + "name": "camel.component.jms.connection-factory.protocol-manager-factory-str", + "type": "java.lang.String", + "description": "Auto discovered option from class: org.apache.activemq.artemis.jms.client.ActiveMQJMSConnectionFactory to set the option via setter: setProtocolManagerFactoryStr" + }, + { + "name": "camel.component.jms.connection-factory.reconnect-attempts", + "type": "java.lang.Integer", + "description": "Auto discovered option from class: org.apache.activemq.artemis.jms.client.ActiveMQJMSConnectionFactory to set the option via setter: setReconnectAttempts" + }, + { + "name": "camel.component.jms.connection-factory.retry-interval", + "type": "java.lang.Long", + "description": "Auto discovered option from class: org.apache.activemq.artemis.jms.client.ActiveMQJMSConnectionFactory to set the option via setter: setRetryInterval" + }, + { + "name": "camel.component.jms.connection-factory.retry-interval-multiplier", + "type": "double", + "description": "Auto discovered option from class: org.apache.activemq.artemis.jms.client.ActiveMQJMSConnectionFactory to set the option via setter: setRetryIntervalMultiplier" + }, + { + "name": "camel.component.jms.connection-factory.scheduled-thread-pool-max-size", + "type": "java.lang.Integer", + "description": "Auto discovered option from class: org.apache.activemq.artemis.jms.client.ActiveMQJMSConnectionFactory to set the option via setter: setScheduledThreadPoolMaxSize" + }, + { + "name": "camel.component.jms.connection-factory.thread-pool-max-size", + "type": "java.lang.Integer", + "description": "Auto discovered option from class: org.apache.activemq.artemis.jms.client.ActiveMQJMSConnectionFactory to set the option via setter: setThreadPoolMaxSize" + }, + { + "name": "camel.component.jms.connection-factory.transaction-batch-size", + "type": "java.lang.Integer", + "description": "Auto discovered option from class: org.apache.activemq.artemis.jms.client.ActiveMQJMSConnectionFactory to set the option via setter: setTransactionBatchSize" + }, + { + "name": "camel.component.jms.connection-factory.use-global-pools", + "type": "java.lang.Boolean", + "description": "Auto discovered option from class: org.apache.activemq.artemis.jms.client.ActiveMQJMSConnectionFactory to set the option via setter: setUseGlobalPools" + }, + { + "name": "camel.component.jms.connection-factory.use-topology-for-load-balancing", + "type": "java.lang.Boolean", + "description": "Auto discovered option from class: org.apache.activemq.artemis.jms.client.ActiveMQJMSConnectionFactory to set the option via setter: setUseTopologyForLoadBalancing" + }, + { "name": "camel.component.jms.username", "type": "java.lang.String", "description": "Username to use with the ConnectionFactory. You can also configure username/password directly on the ConnectionFactory."