You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2017/03/15 21:41:02 UTC
[1/3] camel git commit: CAMEL-10799: camel-connector - Generate
spring boot auto configuration
Repository: camel
Updated Branches:
refs/heads/master 7aeb3b769 -> 12ddb0fc8
CAMEL-10799: camel-connector - Generate spring boot auto configuration
Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/f897d468
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/f897d468
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/f897d468
Branch: refs/heads/master
Commit: f897d46870baf9eacf8d32d704f4bfaf13df3fd9
Parents: 7aeb3b7
Author: Claus Ibsen <da...@apache.org>
Authored: Wed Mar 15 20:15:44 2017 +0100
Committer: Claus Ibsen <da...@apache.org>
Committed: Wed Mar 15 20:33:49 2017 +0100
----------------------------------------------------------------------
connectors/camel-connector-maven-plugin/pom.xml | 22 +
.../camel/maven/connector/ConnectorMojo.java | 2 -
.../SpringBootAutoConfigurationMojo.java | 416 +++++++++++++++++++
.../camel/maven/connector/StringHelper.java | 27 ++
.../maven/connector/model/ComponentModel.java | 201 +++++++++
.../connector/model/ComponentOptionModel.java | 146 +++++++
.../src/main/resources/license-header-java.txt | 16 +
.../src/main/resources/license-header.txt | 16 +
connectors/camel-connector/pom.xml | 15 +
9 files changed, 859 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/camel/blob/f897d468/connectors/camel-connector-maven-plugin/pom.xml
----------------------------------------------------------------------
diff --git a/connectors/camel-connector-maven-plugin/pom.xml b/connectors/camel-connector-maven-plugin/pom.xml
index 524b1be..48a8bc8 100644
--- a/connectors/camel-connector-maven-plugin/pom.xml
+++ b/connectors/camel-connector-maven-plugin/pom.xml
@@ -61,6 +61,28 @@
<version>${jackson2-version}</version>
</dependency>
+ <!-- roaster to create java source for Spring Boot auto configuration support -->
+ <dependency>
+ <groupId>org.jboss.forge.roaster</groupId>
+ <artifactId>roaster-api</artifactId>
+ <version>${roaster-version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.forge.roaster</groupId>
+ <artifactId>roaster-jdt</artifactId>
+ <version>${roaster-version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot</artifactId>
+ <version>${spring-boot-version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-autoconfigure</artifactId>
+ <version>${spring-boot-version}</version>
+ </dependency>
+
<!-- logging -->
<dependency>
<groupId>org.slf4j</groupId>
http://git-wip-us.apache.org/repos/asf/camel/blob/f897d468/connectors/camel-connector-maven-plugin/src/main/java/org/apache/camel/maven/connector/ConnectorMojo.java
----------------------------------------------------------------------
diff --git a/connectors/camel-connector-maven-plugin/src/main/java/org/apache/camel/maven/connector/ConnectorMojo.java b/connectors/camel-connector-maven-plugin/src/main/java/org/apache/camel/maven/connector/ConnectorMojo.java
index ce089d8..a9958a6 100644
--- a/connectors/camel-connector-maven-plugin/src/main/java/org/apache/camel/maven/connector/ConnectorMojo.java
+++ b/connectors/camel-connector-maven-plugin/src/main/java/org/apache/camel/maven/connector/ConnectorMojo.java
@@ -268,8 +268,6 @@ public class ConnectorMojo extends AbstractJarMojo {
Map values = (Map) dto.get("endpointValues");
Map overrides = (Map) dto.get("endpointOverrides");
- ObjectMapper mapper = new ObjectMapper();
-
StringBuilder sb = new StringBuilder();
sb.append(" \"properties\": {\n");
http://git-wip-us.apache.org/repos/asf/camel/blob/f897d468/connectors/camel-connector-maven-plugin/src/main/java/org/apache/camel/maven/connector/SpringBootAutoConfigurationMojo.java
----------------------------------------------------------------------
diff --git a/connectors/camel-connector-maven-plugin/src/main/java/org/apache/camel/maven/connector/SpringBootAutoConfigurationMojo.java b/connectors/camel-connector-maven-plugin/src/main/java/org/apache/camel/maven/connector/SpringBootAutoConfigurationMojo.java
new file mode 100644
index 0000000..a6dbd84
--- /dev/null
+++ b/connectors/camel-connector-maven-plugin/src/main/java/org/apache/camel/maven/connector/SpringBootAutoConfigurationMojo.java
@@ -0,0 +1,416 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.
+ */
+package org.apache.camel.maven.connector;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.apache.camel.maven.connector.model.ComponentModel;
+import org.apache.camel.maven.connector.model.ComponentOptionModel;
+import org.apache.commons.io.FileUtils;
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugins.annotations.LifecyclePhase;
+import org.apache.maven.plugins.annotations.Mojo;
+import org.apache.maven.plugins.annotations.Parameter;
+import org.jboss.forge.roaster.Roaster;
+import org.jboss.forge.roaster.model.source.AnnotationSource;
+import org.jboss.forge.roaster.model.source.Import;
+import org.jboss.forge.roaster.model.source.JavaClassSource;
+import org.jboss.forge.roaster.model.source.MethodSource;
+import org.jboss.forge.roaster.model.source.PropertySource;
+import org.jboss.forge.roaster.model.util.Formatter;
+import org.jboss.forge.roaster.model.util.Strings;
+import org.springframework.boot.autoconfigure.AutoConfigureAfter;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.context.properties.DeprecatedConfigurationProperty;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import static org.apache.camel.maven.connector.FileHelper.loadText;
+import static org.apache.camel.maven.connector.StringHelper.getSafeValue;
+
+/**
+ * Generate Spring Boot auto configuration files for Camel connectors.
+ */
+@Mojo(name = "prepare-spring-boot-auto-configuration",
+ defaultPhase = LifecyclePhase.PACKAGE,
+ requiresProject = true, threadSafe = true)
+public class SpringBootAutoConfigurationMojo extends AbstractMojo {
+
+ @Parameter(defaultValue = "${project.build.outputDirectory}", required = true)
+ private File classesDirectory;
+
+ @Parameter(defaultValue = "${basedir}", required = true)
+ private File baseDir;
+
+ @Parameter(defaultValue = "true")
+ private boolean includeLicenseHeader;
+
+ @Override
+ public void execute() throws MojoExecutionException, MojoFailureException {
+ try {
+ executeConnector();
+ } catch (Exception e) {
+ throw new MojoFailureException("Error generating Spring-Boot auto configuration for connector", e);
+ }
+ }
+
+ private void executeConnector() throws Exception {
+
+ String javaType = null;
+ String connectorScheme = null;
+
+ File file = new File(classesDirectory, "camel-connector.json");
+ if (file.exists()) {
+ ObjectMapper mapper = new ObjectMapper();
+ Map dto = mapper.readValue(file, Map.class);
+
+ javaType = (String) dto.get("javaType");
+ connectorScheme = (String) dto.get("scheme");
+ }
+
+ // find the component dependency and get its .json file
+ file = new File(classesDirectory, "camel-component-schema.json");
+ if (file.exists() && javaType != null && connectorScheme != null) {
+ String json = loadText(new FileInputStream(file));
+ ComponentModel model = generateComponentModel(json);
+
+ // resolvePropertyPlaceholders is an option which only make sense to use if the component has other options
+ boolean hasOptions = model.getComponentOptions().stream().anyMatch(o -> !o.getName().equals("resolvePropertyPlaceholders"));
+
+ // use springboot as sub package name so the code is not in normal
+ // package so the Spring Boot JARs can be optional at runtime
+ int pos = javaType.lastIndexOf(".");
+ String pkg = javaType.substring(0, pos) + ".springboot";
+
+ getLog().info("Generating Spring Boot AutoConfiguration for Connector: " + model.getScheme());
+
+ if (hasOptions) {
+ createConnectorConfigurationSource(pkg, model, javaType, connectorScheme);
+ }
+ createConnectorAutoConfigurationSource(pkg, model, hasOptions, javaType, connectorScheme);
+ createConnectorSpringFactorySource(pkg, model);
+ } else {
+ getLog().warn("Cannot generate Spring Boot AutoConfiguration as camel-component-schema.json file missing");
+ }
+ }
+
+ private void createConnectorSpringFactorySource(String packageName, ComponentModel model) throws MojoFailureException {
+ int pos = model.getJavaType().lastIndexOf(".");
+ String name = model.getJavaType().substring(pos + 1);
+ name = name.replace("Component", "ConnectorAutoConfiguration");
+
+ writeComponentSpringFactorySource(packageName, name);
+ }
+
+ private void writeComponentSpringFactorySource(String packageName, String name) throws MojoFailureException {
+ StringBuilder sb = new StringBuilder();
+ sb.append("org.springframework.boot.autoconfigure.EnableAutoConfiguration=\\\n");
+
+ String lineToAdd = packageName + "." + name + "\n";
+ sb.append(lineToAdd);
+
+ String fileName = "src/main/resources/META-INF/spring.factories";
+ File target = new File(baseDir, fileName);
+
+ // create new file
+ try {
+ String header = "";
+ if (includeLicenseHeader) {
+ InputStream is = getClass().getClassLoader().getResourceAsStream("license-header.txt");
+ header = loadText(is);
+ }
+ String code = sb.toString();
+ // add empty new line after header
+ code = header + "\n" + code;
+ getLog().debug("Source code generated:\n" + code);
+
+ FileUtils.write(target, code);
+ getLog().info("Created file: " + target);
+ } catch (Exception e) {
+ throw new MojoFailureException("IOError with file " + target, e);
+ }
+ }
+
+ private void createConnectorConfigurationSource(String packageName, ComponentModel model, String javaType, String connectorScheme) throws MojoFailureException {
+ final JavaClassSource javaClass = Roaster.create(JavaClassSource.class);
+
+ int pos = javaType.lastIndexOf(".");
+ String name = javaType.substring(pos + 1);
+ name = name.replace("Component", "ConnectorConfiguration");
+ javaClass.setPackage(packageName).setName(name);
+
+ String doc = "Generated by camel-connector-maven-plugin - do not edit this file!";
+ if (!Strings.isBlank(model.getDescription())) {
+ doc = model.getDescription() + "\n\n" + doc;
+ }
+ // replace Component with Connector
+ doc = doc.replaceAll("Component", "Connector");
+ doc = doc.replaceAll("component", "connector");
+ javaClass.getJavaDoc().setFullText(doc);
+
+ String prefix = "camel.connector." + model.getScheme();
+ // make sure prefix is in lower case
+ prefix = connectorScheme.toLowerCase(Locale.US);
+ javaClass.addAnnotation("org.springframework.boot.context.properties.ConfigurationProperties").setStringValue("prefix", prefix);
+
+ for (ComponentOptionModel option : model.getComponentOptions()) {
+ String type = option.getJavaType();
+ PropertySource<JavaClassSource> prop = javaClass.addProperty(type, option.getName());
+
+ // TODO: only include the global options so we can configure them
+
+ if ("true".equals(option.getDeprecated())) {
+ prop.getField().addAnnotation(Deprecated.class);
+ prop.getAccessor().addAnnotation(Deprecated.class);
+ prop.getMutator().addAnnotation(Deprecated.class);
+ // DeprecatedConfigurationProperty must be on getter when deprecated
+ prop.getAccessor().addAnnotation(DeprecatedConfigurationProperty.class);
+ }
+ if (!Strings.isBlank(option.getDescription())) {
+ prop.getField().getJavaDoc().setFullText(option.getDescription());
+ }
+ if (!Strings.isBlank(option.getDefaultValue())) {
+ if ("java.lang.String".equals(option.getJavaType())) {
+ prop.getField().setStringInitializer(option.getDefaultValue());
+ } else if ("long".equals(option.getJavaType()) || "java.lang.Long".equals(option.getJavaType())) {
+ // the value should be a Long number
+ String value = option.getDefaultValue() + "L";
+ prop.getField().setLiteralInitializer(value);
+ } else if ("integer".equals(option.getType()) || "boolean".equals(option.getType())) {
+ prop.getField().setLiteralInitializer(option.getDefaultValue());
+ } else if (!Strings.isBlank(option.getEnums())) {
+ String enumShortName = type.substring(type.lastIndexOf(".") + 1);
+ prop.getField().setLiteralInitializer(enumShortName + "." + option.getDefaultValue());
+ javaClass.addImport(model.getJavaType());
+ }
+ }
+ }
+
+
+ sortImports(javaClass);
+
+ String fileName = packageName.replaceAll("\\.", "\\/") + "/" + name + ".java";
+
+ writeSourceIfChanged(javaClass, fileName);
+ }
+
+ private void createConnectorAutoConfigurationSource(String packageName, ComponentModel model, boolean hasOptions,
+ String javaType, String connectorScheme) throws MojoFailureException {
+
+ final JavaClassSource javaClass = Roaster.create(JavaClassSource.class);
+
+ int pos = javaType.lastIndexOf(".");
+ String name = javaType.substring(pos + 1);
+ name = name.replace("Component", "ConnectorAutoConfiguration");
+
+ javaClass.setPackage(packageName).setName(name);
+
+ String doc = "Generated by camel-connector-maven-plugin - do not edit this file!";
+ javaClass.getJavaDoc().setFullText(doc);
+
+ javaClass.addAnnotation(Configuration.class);
+ javaClass.addAnnotation(ConditionalOnBean.class).setStringValue("type", "org.apache.camel.spring.boot.CamelAutoConfiguration");
+ javaClass.addAnnotation(AutoConfigureAfter.class).setStringValue("name", "org.apache.camel.spring.boot.CamelAutoConfiguration");
+
+ String configurationName = name.replace("ConnectorAutoConfiguration", "ConnectorConfiguration");
+ if (hasOptions) {
+ AnnotationSource<JavaClassSource> ann = javaClass.addAnnotation(EnableConfigurationProperties.class);
+ ann.setLiteralValue("value", configurationName + ".class");
+
+ javaClass.addImport("java.util.HashMap");
+ javaClass.addImport("java.util.Map");
+ javaClass.addImport("org.apache.camel.util.IntrospectionSupport");
+ }
+
+ javaClass.addImport(model.getJavaType());
+ javaClass.addImport("org.apache.camel.CamelContext");
+
+ // add method for auto configure
+ String body = createComponentBody(model.getShortJavaType(), hasOptions);
+ String methodName = "configure" + model.getShortJavaType();
+
+ MethodSource<JavaClassSource> method = javaClass.addMethod()
+ .setName(methodName)
+ .setPublic()
+ .setBody(body)
+ .setReturnType(model.getShortJavaType())
+ .addThrows(Exception.class);
+
+ method.addParameter("CamelContext", "camelContext");
+
+ if (hasOptions) {
+ method.addParameter(configurationName, "configuration");
+ }
+
+ method.addAnnotation(Bean.class).setStringValue("name", connectorScheme.toLowerCase(Locale.US) + "-connector");
+ method.addAnnotation(ConditionalOnClass.class).setLiteralValue("value", "CamelContext.class");
+ method.addAnnotation(ConditionalOnMissingBean.class).setLiteralValue("value", model.getShortJavaType() + ".class");
+
+ sortImports(javaClass);
+
+ String fileName = packageName.replaceAll("\\.", "\\/") + "/" + name + ".java";
+ writeSourceIfChanged(javaClass, fileName);
+ }
+
+ private void writeSourceIfChanged(JavaClassSource source, String fileName) throws MojoFailureException {
+ File target = new File(".", "src/main/java/" + fileName);
+
+ try {
+ String header = "";
+ if (includeLicenseHeader) {
+ InputStream is = getClass().getClassLoader().getResourceAsStream("license-header-java.txt");
+ header = loadText(is);
+ }
+ String code = sourceToString(source);
+ code = header + code;
+ getLog().debug("Source code generated:\n" + code);
+
+ if (target.exists()) {
+ String existing = FileUtils.readFileToString(target);
+ if (!code.equals(existing)) {
+ FileUtils.write(target, code, false);
+ getLog().info("Updated existing file: " + target);
+ } else {
+ getLog().debug("No changes to existing file: " + target);
+ }
+ } else {
+ FileUtils.write(target, code);
+ getLog().info("Created file: " + target);
+ }
+ } catch (Exception e) {
+ throw new MojoFailureException("IOError with file " + target, e);
+ }
+ }
+
+ private static String createComponentBody(String shortJavaType, boolean hasOptions) {
+ StringBuilder sb = new StringBuilder();
+ sb.append(shortJavaType).append(" connector = new ").append(shortJavaType).append("();").append("\n");
+ sb.append("connector.setCamelContext(camelContext);\n");
+ sb.append("\n");
+ if (hasOptions) {
+ sb.append("Map<String, Object> parameters = new HashMap<>();\n");
+ sb.append("IntrospectionSupport.getProperties(configuration, parameters, null, false);\n");
+ sb.append("IntrospectionSupport.setProperties(camelContext, camelContext.getTypeConverter(), connector, parameters);\n");
+ }
+ sb.append("\n");
+ sb.append("return connector;");
+ return sb.toString();
+ }
+
+ private static void sortImports(JavaClassSource javaClass) {
+ // sort imports
+ List<Import> imports = javaClass.getImports();
+
+ // sort imports
+ List<String> names = new ArrayList<>();
+ for (Import imp : imports) {
+ names.add(imp.getQualifiedName());
+ }
+ // sort
+ Collections.sort(names, (s1, s2) -> {
+ // java comes first
+ if (s1.startsWith("java.")) {
+ s1 = "___" + s1;
+ }
+ if (s2.startsWith("java.")) {
+ s2 = "___" + s2;
+ }
+ // then javax comes next
+ if (s1.startsWith("javax.")) {
+ s1 = "__" + s1;
+ }
+ if (s2.startsWith("javax.")) {
+ s2 = "__" + s2;
+ }
+ // org.w3c is for some odd reason also before others
+ if (s1.startsWith("org.w3c.")) {
+ s1 = "_" + s1;
+ }
+ if (s2.startsWith("org.w3c.")) {
+ s2 = "_" + s2;
+ }
+ return s1.compareTo(s2);
+ });
+
+ // remove all imports first
+ for (String name : names) {
+ javaClass.removeImport(name);
+ }
+ // and add them back in correct order
+ for (String name : names) {
+ javaClass.addImport(name);
+ }
+ }
+
+ private static String sourceToString(JavaClassSource javaClass) {
+ String code = Formatter.format(javaClass);
+ // convert tabs to 4 spaces
+ code = code.replaceAll("\\t", " ");
+ return code;
+ }
+
+ private static ComponentModel generateComponentModel(String json) {
+ List<Map<String, String>> rows = JSonSchemaHelper.parseJsonSchema("component", json, false);
+
+ ComponentModel component = new ComponentModel(true);
+ component.setScheme(getSafeValue("scheme", rows));
+ component.setSyntax(getSafeValue("syntax", rows));
+ component.setAlternativeSyntax(getSafeValue("alternativeSyntax", rows));
+ component.setTitle(getSafeValue("title", rows));
+ component.setDescription(getSafeValue("description", rows));
+ component.setFirstVersion(getSafeValue("firstVersion", rows));
+ component.setLabel(getSafeValue("label", rows));
+ component.setDeprecated(getSafeValue("deprecated", rows));
+ component.setConsumerOnly(getSafeValue("consumerOnly", rows));
+ component.setProducerOnly(getSafeValue("producerOnly", rows));
+ component.setJavaType(getSafeValue("javaType", rows));
+ component.setGroupId(getSafeValue("groupId", rows));
+ component.setArtifactId(getSafeValue("artifactId", rows));
+ component.setVersion(getSafeValue("version", rows));
+
+ rows = JSonSchemaHelper.parseJsonSchema("componentProperties", json, true);
+ for (Map<String, String> row : rows) {
+ ComponentOptionModel option = new ComponentOptionModel();
+ option.setName(getSafeValue("name", row));
+ option.setDisplayName(getSafeValue("displayName", row));
+ option.setKind(getSafeValue("kind", row));
+ option.setType(getSafeValue("type", row));
+ option.setJavaType(getSafeValue("javaType", row));
+ option.setDeprecated(getSafeValue("deprecated", row));
+ option.setDescription(getSafeValue("description", row));
+ option.setDefaultValue(getSafeValue("defaultValue", row));
+ option.setEnums(getSafeValue("enum", row));
+ component.addComponentOption(option);
+ }
+
+ return component;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/f897d468/connectors/camel-connector-maven-plugin/src/main/java/org/apache/camel/maven/connector/StringHelper.java
----------------------------------------------------------------------
diff --git a/connectors/camel-connector-maven-plugin/src/main/java/org/apache/camel/maven/connector/StringHelper.java b/connectors/camel-connector-maven-plugin/src/main/java/org/apache/camel/maven/connector/StringHelper.java
index b69de06..556cc59 100644
--- a/connectors/camel-connector-maven-plugin/src/main/java/org/apache/camel/maven/connector/StringHelper.java
+++ b/connectors/camel-connector-maven-plugin/src/main/java/org/apache/camel/maven/connector/StringHelper.java
@@ -16,6 +16,9 @@
*/
package org.apache.camel.maven.connector;
+import java.util.List;
+import java.util.Map;
+
/**
* Utility methods for String.
*/
@@ -172,4 +175,28 @@ public final class StringHelper {
return sb.toString().trim();
}
+ /**
+ * Gets the value with the key in a safe way, eg returning an empty string if there was no value for the key.
+ */
+ public static String getSafeValue(String key, List<Map<String, String>> rows) {
+ for (Map<String, String> row : rows) {
+ String value = row.get(key);
+ if (value != null) {
+ return value;
+ }
+ }
+ return "";
+ }
+
+ /**
+ * Gets the value with the key in a safe way, eg returning an empty string if there was no value for the key.
+ */
+ public static String getSafeValue(String key, Map<String, String> rows) {
+ String value = rows.get(key);
+ if (value != null) {
+ return value;
+ }
+ return "";
+ }
+
}
http://git-wip-us.apache.org/repos/asf/camel/blob/f897d468/connectors/camel-connector-maven-plugin/src/main/java/org/apache/camel/maven/connector/model/ComponentModel.java
----------------------------------------------------------------------
diff --git a/connectors/camel-connector-maven-plugin/src/main/java/org/apache/camel/maven/connector/model/ComponentModel.java b/connectors/camel-connector-maven-plugin/src/main/java/org/apache/camel/maven/connector/model/ComponentModel.java
new file mode 100644
index 0000000..126ffb2
--- /dev/null
+++ b/connectors/camel-connector-maven-plugin/src/main/java/org/apache/camel/maven/connector/model/ComponentModel.java
@@ -0,0 +1,201 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.
+ */
+package org.apache.camel.maven.connector.model;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ComponentModel {
+
+ private final boolean coreOnly;
+
+ private String kind;
+ private String scheme;
+ private String syntax;
+ private String alternativeSyntax;
+ private String alternativeSchemes;
+ private String title;
+ private String description;
+ private String firstVersion;
+ private String label;
+ private String deprecated;
+ private String consumerOnly;
+ private String producerOnly;
+ private String javaType;
+ private String groupId;
+ private String artifactId;
+ private String version;
+ private final List<ComponentOptionModel> componentOptions = new ArrayList<ComponentOptionModel>();
+
+ public ComponentModel(boolean coreOnly) {
+ this.coreOnly = coreOnly;
+ }
+
+ public String getKind() {
+ return kind;
+ }
+
+ public void setKind(String kind) {
+ this.kind = kind;
+ }
+
+ public String getScheme() {
+ return scheme;
+ }
+
+ public void setScheme(String scheme) {
+ this.scheme = scheme;
+ }
+
+ public String getSyntax() {
+ return syntax;
+ }
+
+ public void setSyntax(String syntax) {
+ this.syntax = syntax;
+ }
+
+ public String getAlternativeSyntax() {
+ return alternativeSyntax;
+ }
+
+ public void setAlternativeSyntax(String alternativeSyntax) {
+ this.alternativeSyntax = alternativeSyntax;
+ }
+
+ public String getAlternativeSchemes() {
+ return alternativeSchemes;
+ }
+
+ public void setAlternativeSchemes(String alternativeSchemes) {
+ this.alternativeSchemes = alternativeSchemes;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public String getFirstVersion() {
+ return firstVersion;
+ }
+
+ public void setFirstVersion(String firstVersion) {
+ this.firstVersion = firstVersion;
+ }
+
+ public String getLabel() {
+ return label;
+ }
+
+ public void setLabel(String label) {
+ this.label = label;
+ }
+
+ public String getDeprecated() {
+ return deprecated;
+ }
+
+ public void setDeprecated(String deprecated) {
+ this.deprecated = deprecated;
+ }
+
+ public String getConsumerOnly() {
+ return consumerOnly;
+ }
+
+ public void setConsumerOnly(String consumerOnly) {
+ this.consumerOnly = consumerOnly;
+ }
+
+ public String getProducerOnly() {
+ return producerOnly;
+ }
+
+ public void setProducerOnly(String producerOnly) {
+ this.producerOnly = producerOnly;
+ }
+
+ public String getJavaType() {
+ return javaType;
+ }
+
+ public void setJavaType(String javaType) {
+ this.javaType = javaType;
+ }
+
+ public String getGroupId() {
+ return groupId;
+ }
+
+ public void setGroupId(String groupId) {
+ this.groupId = groupId;
+ }
+
+ public String getArtifactId() {
+ return artifactId;
+ }
+
+ public void setArtifactId(String artifactId) {
+ this.artifactId = artifactId;
+ }
+
+ public String getVersion() {
+ return version;
+ }
+
+ public void setVersion(String version) {
+ this.version = version;
+ }
+
+ public List<ComponentOptionModel> getComponentOptions() {
+ return componentOptions;
+ }
+
+ public void addComponentOption(ComponentOptionModel option) {
+ componentOptions.add(option);
+ }
+
+ public String getShortJavaType() {
+ if (javaType.startsWith("java.util.Map")) {
+ return "Map";
+ } else if (javaType.startsWith("java.util.Set")) {
+ return "Set";
+ } else if (javaType.startsWith("java.util.List")) {
+ return "List";
+ }
+ int pos = javaType.lastIndexOf(".");
+ if (pos != -1) {
+ return javaType.substring(pos + 1);
+ } else {
+ return javaType;
+ }
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/f897d468/connectors/camel-connector-maven-plugin/src/main/java/org/apache/camel/maven/connector/model/ComponentOptionModel.java
----------------------------------------------------------------------
diff --git a/connectors/camel-connector-maven-plugin/src/main/java/org/apache/camel/maven/connector/model/ComponentOptionModel.java b/connectors/camel-connector-maven-plugin/src/main/java/org/apache/camel/maven/connector/model/ComponentOptionModel.java
new file mode 100644
index 0000000..2a717ab
--- /dev/null
+++ b/connectors/camel-connector-maven-plugin/src/main/java/org/apache/camel/maven/connector/model/ComponentOptionModel.java
@@ -0,0 +1,146 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.
+ */
+package org.apache.camel.maven.connector.model;
+
+public class ComponentOptionModel {
+
+ private String name;
+ private String displayName;
+ private String kind;
+ private String group;
+ private String required;
+ private String type;
+ private String javaType;
+ private String deprecated;
+ private String secret;
+ private String description;
+ private String defaultValue;
+ private String enums;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getDisplayName() {
+ return displayName;
+ }
+
+ public void setDisplayName(String displayName) {
+ this.displayName = displayName;
+ }
+
+ public String getKind() {
+ return kind;
+ }
+
+ public void setKind(String kind) {
+ this.kind = kind;
+ }
+
+ public String getGroup() {
+ return group;
+ }
+
+ public void setGroup(String group) {
+ this.group = group;
+ }
+
+ public String getRequired() {
+ return required;
+ }
+
+ public void setRequired(String required) {
+ this.required = required;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public String getJavaType() {
+ return javaType;
+ }
+
+ public void setJavaType(String javaType) {
+ this.javaType = javaType;
+ }
+
+ public String getDeprecated() {
+ return deprecated;
+ }
+
+ public void setDeprecated(String deprecated) {
+ this.deprecated = deprecated;
+ }
+
+ public String getSecret() {
+ return secret;
+ }
+
+ public void setSecret(String secret) {
+ this.secret = secret;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public String getDefaultValue() {
+ return defaultValue;
+ }
+
+ public void setDefaultValue(String defaultValue) {
+ this.defaultValue = defaultValue;
+ }
+
+ public String getEnums() {
+ return enums;
+ }
+
+ public void setEnums(String enums) {
+ this.enums = enums;
+ }
+
+ public String getShortJavaType() {
+ if (javaType.startsWith("java.util.Map")) {
+ return "Map";
+ } else if (javaType.startsWith("java.util.Set")) {
+ return "Set";
+ } else if (javaType.startsWith("java.util.List")) {
+ return "List";
+ }
+ int pos = javaType.lastIndexOf(".");
+ if (pos != -1) {
+ return javaType.substring(pos + 1);
+ } else {
+ return javaType;
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/f897d468/connectors/camel-connector-maven-plugin/src/main/resources/license-header-java.txt
----------------------------------------------------------------------
diff --git a/connectors/camel-connector-maven-plugin/src/main/resources/license-header-java.txt b/connectors/camel-connector-maven-plugin/src/main/resources/license-header-java.txt
new file mode 100644
index 0000000..0f49ea9
--- /dev/null
+++ b/connectors/camel-connector-maven-plugin/src/main/resources/license-header-java.txt
@@ -0,0 +1,16 @@
+/**
+ * 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.
+ */
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/camel/blob/f897d468/connectors/camel-connector-maven-plugin/src/main/resources/license-header.txt
----------------------------------------------------------------------
diff --git a/connectors/camel-connector-maven-plugin/src/main/resources/license-header.txt b/connectors/camel-connector-maven-plugin/src/main/resources/license-header.txt
new file mode 100644
index 0000000..12bdf0d
--- /dev/null
+++ b/connectors/camel-connector-maven-plugin/src/main/resources/license-header.txt
@@ -0,0 +1,16 @@
+#
+# 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.
+#
http://git-wip-us.apache.org/repos/asf/camel/blob/f897d468/connectors/camel-connector/pom.xml
----------------------------------------------------------------------
diff --git a/connectors/camel-connector/pom.xml b/connectors/camel-connector/pom.xml
index 6f99578..e709823 100644
--- a/connectors/camel-connector/pom.xml
+++ b/connectors/camel-connector/pom.xml
@@ -35,6 +35,8 @@
</properties>
<dependencies>
+
+ <!-- camel -->
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-core</artifactId>
@@ -43,6 +45,19 @@
<groupId>org.apache.camel</groupId>
<artifactId>camel-catalog</artifactId>
</dependency>
+
+ <!-- to support spring-boot auto configuration in the connectors -->
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot</artifactId>
+ <version>${spring-boot-version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-autoconfigure</artifactId>
+ <version>${spring-boot-version}</version>
+ </dependency>
+
</dependencies>
</project>
[2/3] camel git commit: CAMEL-10799: camel-connector - Generate
spring boot auto configuration
Posted by da...@apache.org.
CAMEL-10799: camel-connector - Generate spring boot auto configuration
Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/788572aa
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/788572aa
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/788572aa
Branch: refs/heads/master
Commit: 788572aac3a0a83947dc81d82e991ee404115272
Parents: f897d46
Author: Claus Ibsen <da...@apache.org>
Authored: Wed Mar 15 20:49:03 2017 +0100
Committer: Claus Ibsen <da...@apache.org>
Committed: Wed Mar 15 21:15:41 2017 +0100
----------------------------------------------------------------------
.../maven/connector/CollectionStringBuffer.java | 58 ---
.../camel/maven/connector/ConnectorMojo.java | 4 +
.../camel/maven/connector/FileHelper.java | 140 ------
.../apache/camel/maven/connector/GitHelper.java | 132 ------
.../camel/maven/connector/JSonSchemaHelper.java | 427 -------------------
.../SpringBootAutoConfigurationMojo.java | 43 +-
.../camel/maven/connector/StringHelper.java | 202 ---------
.../maven/connector/model/ComponentModel.java | 1 -
.../connector/util/CollectionStringBuffer.java | 58 +++
.../camel/maven/connector/util/FileHelper.java | 140 ++++++
.../camel/maven/connector/util/GitHelper.java | 132 ++++++
.../maven/connector/util/JSonSchemaHelper.java | 427 +++++++++++++++++++
.../maven/connector/util/StringHelper.java | 219 ++++++++++
13 files changed, 1003 insertions(+), 980 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/camel/blob/788572aa/connectors/camel-connector-maven-plugin/src/main/java/org/apache/camel/maven/connector/CollectionStringBuffer.java
----------------------------------------------------------------------
diff --git a/connectors/camel-connector-maven-plugin/src/main/java/org/apache/camel/maven/connector/CollectionStringBuffer.java b/connectors/camel-connector-maven-plugin/src/main/java/org/apache/camel/maven/connector/CollectionStringBuffer.java
deleted file mode 100644
index d98779d..0000000
--- a/connectors/camel-connector-maven-plugin/src/main/java/org/apache/camel/maven/connector/CollectionStringBuffer.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/**
- * 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.
- */
-package org.apache.camel.maven.connector;
-
-/**
- * A little helper class for converting a collection of values to a (usually comma separated) string.
- */
-public class CollectionStringBuffer {
-
- private final StringBuilder buffer = new StringBuilder();
- private String separator;
- private boolean first = true;
-
- public CollectionStringBuffer() {
- this(", ");
- }
-
- public CollectionStringBuffer(String separator) {
- this.separator = separator;
- }
-
- @Override
- public String toString() {
- return buffer.toString();
- }
-
- public void append(Object value) {
- if (first) {
- first = false;
- } else {
- buffer.append(separator);
- }
- buffer.append(value);
- }
-
- public String getSeparator() {
- return separator;
- }
-
- public void setSeparator(String separator) {
- this.separator = separator;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/camel/blob/788572aa/connectors/camel-connector-maven-plugin/src/main/java/org/apache/camel/maven/connector/ConnectorMojo.java
----------------------------------------------------------------------
diff --git a/connectors/camel-connector-maven-plugin/src/main/java/org/apache/camel/maven/connector/ConnectorMojo.java b/connectors/camel-connector-maven-plugin/src/main/java/org/apache/camel/maven/connector/ConnectorMojo.java
index a9958a6..59c91d8 100644
--- a/connectors/camel-connector-maven-plugin/src/main/java/org/apache/camel/maven/connector/ConnectorMojo.java
+++ b/connectors/camel-connector-maven-plugin/src/main/java/org/apache/camel/maven/connector/ConnectorMojo.java
@@ -32,6 +32,10 @@ import java.util.stream.Collectors;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
+import org.apache.camel.maven.connector.util.FileHelper;
+import org.apache.camel.maven.connector.util.GitHelper;
+import org.apache.camel.maven.connector.util.JSonSchemaHelper;
+import org.apache.camel.maven.connector.util.StringHelper;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.LifecyclePhase;
http://git-wip-us.apache.org/repos/asf/camel/blob/788572aa/connectors/camel-connector-maven-plugin/src/main/java/org/apache/camel/maven/connector/FileHelper.java
----------------------------------------------------------------------
diff --git a/connectors/camel-connector-maven-plugin/src/main/java/org/apache/camel/maven/connector/FileHelper.java b/connectors/camel-connector-maven-plugin/src/main/java/org/apache/camel/maven/connector/FileHelper.java
deleted file mode 100644
index ae01138..0000000
--- a/connectors/camel-connector-maven-plugin/src/main/java/org/apache/camel/maven/connector/FileHelper.java
+++ /dev/null
@@ -1,140 +0,0 @@
-/**
- * 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.
- */
-package org.apache.camel.maven.connector;
-
-import java.io.BufferedReader;
-import java.io.Closeable;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.FileReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.LineNumberReader;
-import java.nio.channels.FileChannel;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Utility methods for files.
- */
-public final class FileHelper {
-
- private FileHelper() {
- }
-
- /**
- * Loads the entire stream into memory as a String and returns it.
- * <p/>
- * <b>Notice:</b> This implementation appends a <tt>\n</tt> as line
- * terminator at the of the text.
- * <p/>
- * Warning, don't use for crazy big streams :)
- */
- public static String loadText(InputStream in) throws IOException {
- StringBuilder builder = new StringBuilder();
- InputStreamReader isr = new InputStreamReader(in);
- try {
- BufferedReader reader = new LineNumberReader(isr);
- while (true) {
- String line = reader.readLine();
- if (line != null) {
- builder.append(line);
- builder.append("\n");
- } else {
- break;
- }
- }
- return builder.toString();
- } finally {
- isr.close();
- in.close();
- }
- }
-
- /**
- * Loads the file
- */
- public static List<String> loadFile(File file) throws Exception {
- List<String> lines = new ArrayList<>();
- LineNumberReader reader = new LineNumberReader(new FileReader(file));
-
- String line;
- do {
- line = reader.readLine();
- if (line != null) {
- lines.add(line);
- }
- } while (line != null);
- reader.close();
-
- return lines;
- }
-
- /**
- * Loads the file
- */
- public static List<String> loadFile(InputStream fis) throws Exception {
- List<String> lines = new ArrayList<>();
- LineNumberReader reader = new LineNumberReader(new InputStreamReader(fis));
-
- String line;
- do {
- line = reader.readLine();
- if (line != null) {
- lines.add(line);
- }
- } while (line != null);
- reader.close();
-
- return lines;
- }
-
- public static void copyFile(File from, File to) throws IOException {
- FileChannel in = null;
- FileChannel out = null;
- try {
- in = new FileInputStream(from).getChannel();
- out = new FileOutputStream(to).getChannel();
-
- long size = in.size();
- long position = 0;
- while (position < size) {
- position += in.transferTo(position, 4096, out);
- }
- } finally {
- close(in);
- close(out);
- }
- }
-
- /**
- * Closes the given resource if it is available, logging any closing exceptions to the given log.
- */
- public static void close(Closeable closeable) {
- if (closeable != null) {
- try {
- closeable.close();
- } catch (IOException e) {
- // ignore
- }
- }
- }
-
-
-}
http://git-wip-us.apache.org/repos/asf/camel/blob/788572aa/connectors/camel-connector-maven-plugin/src/main/java/org/apache/camel/maven/connector/GitHelper.java
----------------------------------------------------------------------
diff --git a/connectors/camel-connector-maven-plugin/src/main/java/org/apache/camel/maven/connector/GitHelper.java b/connectors/camel-connector-maven-plugin/src/main/java/org/apache/camel/maven/connector/GitHelper.java
deleted file mode 100644
index bd879f7..0000000
--- a/connectors/camel-connector-maven-plugin/src/main/java/org/apache/camel/maven/connector/GitHelper.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/**
- * 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.
- */
-package org.apache.camel.maven.connector;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.StringReader;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Utility methods for git.
- */
-public final class GitHelper {
-
- private GitHelper() {
- }
-
- /**
- * Finds the folder where <tt>.git</tt> is located in the project
- */
- public static File findGitFolder() {
- File baseDir = new File("").getAbsoluteFile();
- return findGitFolder(baseDir);
- }
-
- private static File findGitFolder(File basedir) {
- File gitDir = new File(basedir, ".git");
- if (gitDir.exists() && gitDir.isDirectory()) {
- return gitDir;
- }
-
- File parent = basedir.getParentFile();
- if (parent != null) {
- return findGitFolder(parent);
- } else {
- return null;
- }
- }
-
- /**
- * Returns the remote git URL for the given folder; looking for the .git/config file in the current directory or a parent directory
- */
- public static String extractGitUrl(File basedir) throws IOException {
- if (basedir == null) {
- return null;
- }
- if (basedir.exists() && basedir.isDirectory()) {
- File gitConfig = new File(basedir, ".git/config");
- if (gitConfig.isFile() && gitConfig.exists()) {
- String text = FileHelper.loadText(new FileInputStream(gitConfig));
- return extractGitUrl(text);
- }
- }
- File parentFile = basedir.getParentFile();
- if (parentFile != null) {
- return extractGitUrl(parentFile);
- }
- return null;
- }
-
- /**
- * Returns the remote git URL for the given git config file text lets extract the
- */
- private static String extractGitUrl(String configText) {
- String remote = null;
- String lastUrl = null;
- String firstUrl = null;
- BufferedReader reader = new BufferedReader(new StringReader(configText));
- Map<String, String> remoteUrls = new HashMap<>();
- while (true) {
- String line = null;
- try {
- line = reader.readLine();
- } catch (IOException e) {
- // ignore should never happen!
- }
- if (line == null) {
- break;
- }
- if (line.startsWith("[remote ")) {
- String[] parts = line.split("\"");
- if (parts.length > 1) {
- remote = parts[1];
- }
- } else if (line.startsWith("[")) {
- remote = null;
- } else if (remote != null && line.length() > 0 && Character.isWhitespace(line.charAt(0))) {
- String trimmed = line.trim();
- if (trimmed.startsWith("url ")) {
- String[] parts = trimmed.split("=", 2);
- if (parts.length > 1) {
- lastUrl = parts[1].trim();
- if (firstUrl == null) {
- firstUrl = lastUrl;
- }
- remoteUrls.put(remote, lastUrl);
- }
- }
-
- }
- }
- String answer = null;
- if (remoteUrls.size() == 1) {
- return lastUrl;
- } else if (remoteUrls.size() > 1) {
- answer = remoteUrls.get("origin");
- if (answer == null) {
- answer = firstUrl;
- }
- }
- return answer;
- }
-
-
-}
http://git-wip-us.apache.org/repos/asf/camel/blob/788572aa/connectors/camel-connector-maven-plugin/src/main/java/org/apache/camel/maven/connector/JSonSchemaHelper.java
----------------------------------------------------------------------
diff --git a/connectors/camel-connector-maven-plugin/src/main/java/org/apache/camel/maven/connector/JSonSchemaHelper.java b/connectors/camel-connector-maven-plugin/src/main/java/org/apache/camel/maven/connector/JSonSchemaHelper.java
deleted file mode 100644
index c78d79c..0000000
--- a/connectors/camel-connector-maven-plugin/src/main/java/org/apache/camel/maven/connector/JSonSchemaHelper.java
+++ /dev/null
@@ -1,427 +0,0 @@
-/**
- * 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.
- */
-package org.apache.camel.maven.connector;
-
-import java.io.File;
-import java.net.URI;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * A helper class for <a href="http://json-schema.org/">JSON schema</a>.
- */
-public final class JSonSchemaHelper {
-
- private static final String VALID_CHARS = ".-='/\\!&():;";
- // 0 = text, 1 = enum, 2 = boolean, 3 = integer or number
- private static final Pattern PATTERN = Pattern.compile("\"(.+?)\"|\\[(.+)\\]|(true|false)|(-?\\d+\\.?\\d*)");
- private static final String QUOT = """;
-
- private JSonSchemaHelper() {
- }
-
- public static String toJson(String name, String displayName, String kind, Boolean required, String type, String defaultValue, String description,
- Boolean deprecated, Boolean secret, String group, String label, boolean enumType, Set<String> enums,
- boolean oneOfType, Set<String> oneOffTypes, boolean asPredicate, String optionalPrefix, String prefix, boolean multiValue) {
- String typeName = getType(type, enumType);
-
- StringBuilder sb = new StringBuilder();
- sb.append(StringHelper.doubleQuote(name));
- sb.append(": { \"kind\": ");
- sb.append(StringHelper.doubleQuote(kind));
-
- // compute a display name if we don't have anything
- if (StringHelper.isNullOrEmpty(displayName)) {
- displayName = StringHelper.asTitle(name);
- }
- // we want display name early so its easier to spot
- sb.append(", \"displayName\": ");
- sb.append(StringHelper.doubleQuote(displayName));
-
- // we want group early so its easier to spot
- if (!StringHelper.isNullOrEmpty(group)) {
- sb.append(", \"group\": ");
- sb.append(StringHelper.doubleQuote(group));
- }
-
- // we want label early so its easier to spot
- if (!StringHelper.isNullOrEmpty(label)) {
- sb.append(", \"label\": ");
- sb.append(StringHelper.doubleQuote(label));
- }
-
- if (required != null) {
- // boolean type
- sb.append(", \"required\": ");
- sb.append(required.toString());
- }
-
- sb.append(", \"type\": ");
- if ("enum".equals(typeName)) {
- String actualType = getType(type, false);
- sb.append(StringHelper.doubleQuote(actualType));
- sb.append(", \"javaType\": \"" + type + "\"");
- CollectionStringBuffer enumValues = new CollectionStringBuffer();
- for (Object value : enums) {
- enumValues.append(StringHelper.doubleQuote(value.toString()));
- }
- sb.append(", \"enum\": [ ");
- sb.append(enumValues.toString());
- sb.append(" ]");
- } else if (oneOfType) {
- sb.append(StringHelper.doubleQuote(typeName));
- sb.append(", \"javaType\": \"" + type + "\"");
- CollectionStringBuffer oneOfValues = new CollectionStringBuffer();
- for (Object value : oneOffTypes) {
- oneOfValues.append(StringHelper.doubleQuote(value.toString()));
- }
- sb.append(", \"oneOf\": [ ");
- sb.append(oneOfValues.toString());
- sb.append(" ]");
- } else if ("array".equals(typeName)) {
- sb.append(StringHelper.doubleQuote("array"));
- sb.append(", \"javaType\": \"" + type + "\"");
- } else {
- sb.append(StringHelper.doubleQuote(typeName));
- sb.append(", \"javaType\": \"" + type + "\"");
- }
-
- if (!StringHelper.isNullOrEmpty(optionalPrefix)) {
- sb.append(", \"optionalPrefix\": ");
- String text = safeDefaultValue(optionalPrefix);
- sb.append(StringHelper.doubleQuote(text));
- }
-
- if (!StringHelper.isNullOrEmpty(prefix)) {
- sb.append(", \"prefix\": ");
- String text = safeDefaultValue(prefix);
- sb.append(StringHelper.doubleQuote(text));
- }
- if (multiValue) {
- // boolean value
- sb.append(", \"multiValue\": true");
- }
-
- if (deprecated != null) {
- sb.append(", \"deprecated\": ");
- // boolean value
- sb.append(deprecated.toString());
- }
-
- if (secret != null) {
- sb.append(", \"secret\": ");
- // boolean value
- sb.append(secret.toString());
- }
-
- if (!StringHelper.isNullOrEmpty(defaultValue)) {
- sb.append(", \"defaultValue\": ");
- String text = safeDefaultValue(defaultValue);
- // the type can either be boolean, integer, number or text based
- if ("boolean".equals(typeName) || "integer".equals(typeName) || "number".equals(typeName)) {
- sb.append(text);
- } else {
- // text should be quoted
- sb.append(StringHelper.doubleQuote(text));
- }
- }
-
- // for expressions we want to know if it must be used as predicate or not
- boolean predicate = "expression".equals(kind) || asPredicate;
- if (predicate) {
- sb.append(", \"asPredicate\": ");
- if (asPredicate) {
- sb.append("true");
- } else {
- sb.append("false");
- }
- }
-
- if (!StringHelper.isNullOrEmpty(description)) {
- sb.append(", \"description\": ");
- String text = sanitizeDescription(description, false);
- sb.append(StringHelper.doubleQuote(text));
- }
-
- sb.append(" }");
- return sb.toString();
- }
-
- /**
- * Gets the JSon schema type.
- *
- * @param type the java type
- * @return the json schema type, is never null, but returns <tt>object</tt> as the generic type
- */
- public static String getType(String type, boolean enumType) {
- if (enumType) {
- return "enum";
- } else if (type == null) {
- // return generic type for unknown type
- return "object";
- } else if (type.equals(URI.class.getName()) || type.equals(URL.class.getName())) {
- return "string";
- } else if (type.equals(File.class.getName())) {
- return "string";
- } else if (type.equals(Date.class.getName())) {
- return "string";
- } else if (type.startsWith("java.lang.Class")) {
- return "string";
- } else if (type.startsWith("java.util.List") || type.startsWith("java.util.Collection")) {
- return "array";
- }
-
- String primitive = getPrimitiveType(type);
- if (primitive != null) {
- return primitive;
- }
-
- return "object";
- }
-
- /**
- * Gets the JSon schema primitive type.
- *
- * @param name the java type
- * @return the json schema primitive type, or <tt>null</tt> if not a primitive
- */
- public static String getPrimitiveType(String name) {
-
- // special for byte[] or Object[] as its common to use
- if ("java.lang.byte[]".equals(name) || "byte[]".equals(name)) {
- return "string";
- } else if ("java.lang.Byte[]".equals(name) || "Byte[]".equals(name)) {
- return "array";
- } else if ("java.lang.Object[]".equals(name) || "Object[]".equals(name)) {
- return "array";
- } else if ("java.lang.String[]".equals(name) || "String[]".equals(name)) {
- return "array";
- } else if ("java.lang.Character".equals(name) || "Character".equals(name) || "char".equals(name)) {
- return "string";
- } else if ("java.lang.String".equals(name) || "String".equals(name)) {
- return "string";
- } else if ("java.lang.Boolean".equals(name) || "Boolean".equals(name) || "boolean".equals(name)) {
- return "boolean";
- } else if ("java.lang.Integer".equals(name) || "Integer".equals(name) || "int".equals(name)) {
- return "integer";
- } else if ("java.lang.Long".equals(name) || "Long".equals(name) || "long".equals(name)) {
- return "integer";
- } else if ("java.lang.Short".equals(name) || "Short".equals(name) || "short".equals(name)) {
- return "integer";
- } else if ("java.lang.Byte".equals(name) || "Byte".equals(name) || "byte".equals(name)) {
- return "integer";
- } else if ("java.lang.Float".equals(name) || "Float".equals(name) || "float".equals(name)) {
- return "number";
- } else if ("java.lang.Double".equals(name) || "Double".equals(name) || "double".equals(name)) {
- return "number";
- }
-
- return null;
- }
-
- /**
- * Sanitizes the javadoc to removed invalid characters so it can be used as json description
- *
- * @param javadoc the javadoc
- * @return the text that is valid as json
- */
- public static String sanitizeDescription(String javadoc, boolean summary) {
- if (StringHelper.isNullOrEmpty(javadoc)) {
- return null;
- }
-
- // lets just use what java accepts as identifiers
- StringBuilder sb = new StringBuilder();
-
- // split into lines
- String[] lines = javadoc.split("\n");
-
- boolean first = true;
- for (String line : lines) {
- line = line.trim();
-
- // terminate if we reach @param, @return or @deprecated as we only want the javadoc summary
- if (line.startsWith("@param") || line.startsWith("@return") || line.startsWith("@deprecated")) {
- break;
- }
-
- // skip lines that are javadoc references
- if (line.startsWith("@")) {
- continue;
- }
-
- // remove all XML tags
- line = line.replaceAll("<.*?>", "");
-
- // remove all inlined javadoc links, eg such as {@link org.apache.camel.spi.Registry}
- line = line.replaceAll("\\{\\@\\w+\\s([\\w.]+)\\}", "$1");
-
- // we are starting from a new line, so add a whitespace
- if (!first) {
- sb.append(' ');
- }
-
- // create a new line
- StringBuilder cb = new StringBuilder();
- for (char c : line.toCharArray()) {
- if (Character.isJavaIdentifierPart(c) || VALID_CHARS.indexOf(c) != -1) {
- cb.append(c);
- } else if (Character.isWhitespace(c)) {
- // always use space as whitespace, also for line feeds etc
- cb.append(' ');
- }
- }
-
- // append data
- String s = cb.toString().trim();
- sb.append(s);
-
- boolean empty = StringHelper.isNullOrEmpty(s);
- boolean endWithDot = s.endsWith(".");
- boolean haveText = sb.length() > 0;
-
- if (haveText && summary && (empty || endWithDot)) {
- // if we only want a summary, then skip at first empty line we encounter, or if the sentence ends with a dot
- break;
- }
-
- first = false;
- }
-
- // remove double whitespaces, and trim
- String s = sb.toString();
- s = s.replaceAll("\\s+", " ");
- return s.trim();
- }
-
- /**
- * Parses the json schema to split it into a list or rows, where each row contains key value pairs with the metadata
- *
- * @param group the group to parse from such as <tt>component</tt>, <tt>componentProperties</tt>, or <tt>properties</tt>.
- * @param json the json
- * @return a list of all the rows, where each row is a set of key value pairs with metadata
- */
- public static List<Map<String, String>> parseJsonSchema(String group, String json, boolean parseProperties) {
- List<Map<String, String>> answer = new ArrayList<Map<String, String>>();
- if (json == null) {
- return answer;
- }
-
- boolean found = false;
-
- // parse line by line
- String[] lines = json.split("\n");
- for (String line : lines) {
- // we need to find the group first
- if (!found) {
- String s = line.trim();
- found = s.startsWith("\"" + group + "\":") && s.endsWith("{");
- continue;
- }
-
- // we should stop when we end the group
- if (line.equals(" },") || line.equals(" }")) {
- break;
- }
-
- // need to safe encode \" so we can parse the line
- line = line.replaceAll("\"\\\\\"\"", '"' + QUOT + '"');
-
- Map<String, String> row = new LinkedHashMap<String, String>();
- Matcher matcher = PATTERN.matcher(line);
-
- String key;
- if (parseProperties) {
- // when parsing properties the first key is given as name, so the first parsed token is the value of the name
- key = "name";
- } else {
- key = null;
- }
- while (matcher.find()) {
- if (key == null) {
- key = matcher.group(1);
- } else {
- String value = matcher.group(1);
- if (value != null) {
- // its text based
- value = value.trim();
- // decode
- value = value.replaceAll(QUOT, "\"");
- value = decodeJson(value);
- }
- if (value == null) {
- // not text then its maybe an enum?
- value = matcher.group(2);
- if (value != null) {
- // its an enum so strip out " and trim spaces after comma
- value = value.replaceAll("\"", "");
- value = value.replaceAll(", ", ",");
- value = value.trim();
- }
- }
- if (value == null) {
- // not text then its maybe a boolean?
- value = matcher.group(3);
- }
- if (value == null) {
- // not text then its maybe a integer?
- value = matcher.group(4);
- }
- if (value != null) {
- row.put(key, value);
- }
- // reset
- key = null;
- }
- }
- if (!row.isEmpty()) {
- answer.add(row);
- }
- }
-
- return answer;
- }
-
- private static String decodeJson(String value) {
- // json encodes a \ as \\ so we need to decode from \\ back to \
- if ("\\\\".equals(value)) {
- value = "\\";
- }
- return value;
- }
-
- /**
- * The default value may need to be escaped to be safe for json
- */
- private static String safeDefaultValue(String value) {
- if ("\"".equals(value)) {
- return "\\\"";
- } else if ("\\".equals(value)) {
- return "\\\\";
- } else {
- return value;
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/camel/blob/788572aa/connectors/camel-connector-maven-plugin/src/main/java/org/apache/camel/maven/connector/SpringBootAutoConfigurationMojo.java
----------------------------------------------------------------------
diff --git a/connectors/camel-connector-maven-plugin/src/main/java/org/apache/camel/maven/connector/SpringBootAutoConfigurationMojo.java b/connectors/camel-connector-maven-plugin/src/main/java/org/apache/camel/maven/connector/SpringBootAutoConfigurationMojo.java
index a6dbd84..e276992 100644
--- a/connectors/camel-connector-maven-plugin/src/main/java/org/apache/camel/maven/connector/SpringBootAutoConfigurationMojo.java
+++ b/connectors/camel-connector-maven-plugin/src/main/java/org/apache/camel/maven/connector/SpringBootAutoConfigurationMojo.java
@@ -28,6 +28,7 @@ import java.util.Map;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.camel.maven.connector.model.ComponentModel;
import org.apache.camel.maven.connector.model.ComponentOptionModel;
+import org.apache.camel.maven.connector.util.JSonSchemaHelper;
import org.apache.commons.io.FileUtils;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
@@ -52,8 +53,9 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
-import static org.apache.camel.maven.connector.FileHelper.loadText;
-import static org.apache.camel.maven.connector.StringHelper.getSafeValue;
+import static org.apache.camel.maven.connector.util.FileHelper.loadText;
+import static org.apache.camel.maven.connector.util.StringHelper.getSafeValue;
+import static org.apache.camel.maven.connector.util.StringHelper.getShortJavaType;
/**
* Generate Spring Boot auto configuration files for Camel connectors.
@@ -66,9 +68,6 @@ public class SpringBootAutoConfigurationMojo extends AbstractMojo {
@Parameter(defaultValue = "${project.build.outputDirectory}", required = true)
private File classesDirectory;
- @Parameter(defaultValue = "${basedir}", required = true)
- private File baseDir;
-
@Parameter(defaultValue = "true")
private boolean includeLicenseHeader;
@@ -114,16 +113,16 @@ public class SpringBootAutoConfigurationMojo extends AbstractMojo {
if (hasOptions) {
createConnectorConfigurationSource(pkg, model, javaType, connectorScheme);
}
- createConnectorAutoConfigurationSource(pkg, model, hasOptions, javaType, connectorScheme);
- createConnectorSpringFactorySource(pkg, model);
+ createConnectorAutoConfigurationSource(pkg, hasOptions, javaType, connectorScheme);
+ createConnectorSpringFactorySource(pkg, javaType);
} else {
getLog().warn("Cannot generate Spring Boot AutoConfiguration as camel-component-schema.json file missing");
}
}
- private void createConnectorSpringFactorySource(String packageName, ComponentModel model) throws MojoFailureException {
- int pos = model.getJavaType().lastIndexOf(".");
- String name = model.getJavaType().substring(pos + 1);
+ private void createConnectorSpringFactorySource(String packageName, String javaType) throws MojoFailureException {
+ int pos = javaType.lastIndexOf(".");
+ String name = javaType.substring(pos + 1);
name = name.replace("Component", "ConnectorAutoConfiguration");
writeComponentSpringFactorySource(packageName, name);
@@ -136,8 +135,10 @@ public class SpringBootAutoConfigurationMojo extends AbstractMojo {
String lineToAdd = packageName + "." + name + "\n";
sb.append(lineToAdd);
+ // project root folder
+ File root = classesDirectory.getParentFile().getParentFile();
String fileName = "src/main/resources/META-INF/spring.factories";
- File target = new File(baseDir, fileName);
+ File target = new File(root, fileName);
// create new file
try {
@@ -177,7 +178,7 @@ public class SpringBootAutoConfigurationMojo extends AbstractMojo {
String prefix = "camel.connector." + model.getScheme();
// make sure prefix is in lower case
- prefix = connectorScheme.toLowerCase(Locale.US);
+ prefix = "camel.connector." + connectorScheme.toLowerCase(Locale.US);
javaClass.addAnnotation("org.springframework.boot.context.properties.ConfigurationProperties").setStringValue("prefix", prefix);
for (ComponentOptionModel option : model.getComponentOptions()) {
@@ -217,11 +218,10 @@ public class SpringBootAutoConfigurationMojo extends AbstractMojo {
sortImports(javaClass);
String fileName = packageName.replaceAll("\\.", "\\/") + "/" + name + ".java";
-
writeSourceIfChanged(javaClass, fileName);
}
- private void createConnectorAutoConfigurationSource(String packageName, ComponentModel model, boolean hasOptions,
+ private void createConnectorAutoConfigurationSource(String packageName, boolean hasOptions,
String javaType, String connectorScheme) throws MojoFailureException {
final JavaClassSource javaClass = Roaster.create(JavaClassSource.class);
@@ -249,18 +249,19 @@ public class SpringBootAutoConfigurationMojo extends AbstractMojo {
javaClass.addImport("org.apache.camel.util.IntrospectionSupport");
}
- javaClass.addImport(model.getJavaType());
+ javaClass.addImport(javaType);
javaClass.addImport("org.apache.camel.CamelContext");
// add method for auto configure
- String body = createComponentBody(model.getShortJavaType(), hasOptions);
- String methodName = "configure" + model.getShortJavaType();
+ String shortJavaType = getShortJavaType(javaType);
+ String body = createComponentBody(shortJavaType, hasOptions);
+ String methodName = "configure" + shortJavaType;
MethodSource<JavaClassSource> method = javaClass.addMethod()
.setName(methodName)
.setPublic()
.setBody(body)
- .setReturnType(model.getShortJavaType())
+ .setReturnType(shortJavaType)
.addThrows(Exception.class);
method.addParameter("CamelContext", "camelContext");
@@ -271,7 +272,7 @@ public class SpringBootAutoConfigurationMojo extends AbstractMojo {
method.addAnnotation(Bean.class).setStringValue("name", connectorScheme.toLowerCase(Locale.US) + "-connector");
method.addAnnotation(ConditionalOnClass.class).setLiteralValue("value", "CamelContext.class");
- method.addAnnotation(ConditionalOnMissingBean.class).setLiteralValue("value", model.getShortJavaType() + ".class");
+ method.addAnnotation(ConditionalOnMissingBean.class).setLiteralValue("value", javaType + ".class");
sortImports(javaClass);
@@ -280,7 +281,9 @@ public class SpringBootAutoConfigurationMojo extends AbstractMojo {
}
private void writeSourceIfChanged(JavaClassSource source, String fileName) throws MojoFailureException {
- File target = new File(".", "src/main/java/" + fileName);
+ // project root folder
+ File root = classesDirectory.getParentFile().getParentFile();
+ File target = new File(root, "src/main/java/" + fileName);
try {
String header = "";
http://git-wip-us.apache.org/repos/asf/camel/blob/788572aa/connectors/camel-connector-maven-plugin/src/main/java/org/apache/camel/maven/connector/StringHelper.java
----------------------------------------------------------------------
diff --git a/connectors/camel-connector-maven-plugin/src/main/java/org/apache/camel/maven/connector/StringHelper.java b/connectors/camel-connector-maven-plugin/src/main/java/org/apache/camel/maven/connector/StringHelper.java
deleted file mode 100644
index 556cc59..0000000
--- a/connectors/camel-connector-maven-plugin/src/main/java/org/apache/camel/maven/connector/StringHelper.java
+++ /dev/null
@@ -1,202 +0,0 @@
-/**
- * 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.
- */
-package org.apache.camel.maven.connector;
-
-import java.util.List;
-import java.util.Map;
-
-/**
- * Utility methods for String.
- */
-public final class StringHelper {
-
- private StringHelper() {
- }
-
- /**
- * Converts the value to use dash style instead of upper cased
- */
- public static String camelCaseToDash(String value) {
- StringBuilder sb = new StringBuilder(value.length());
- boolean dash = false;
-
- for (char c : value.toCharArray()) {
- // skip dash in start
- if (sb.length() > 0 & Character.isUpperCase(c)) {
- dash = true;
- }
- if (dash) {
- sb.append('-');
- sb.append(Character.toLowerCase(c));
- } else {
- // lower case first
- if (sb.length() == 0) {
- sb.append(Character.toLowerCase(c));
- } else {
- sb.append(c);
- }
- }
- dash = false;
- }
- return sb.toString();
- }
-
- /**
- * Returns the string value (uses empty string for <tt>null</tt> values)
- */
- public static String nullSafe(String text) {
- return text != null ? text : "";
- }
-
- /**
- * Returns true if the given text is null or empty string or has <tt>null</tt> as the value
- */
- public static boolean isNullOrEmpty(String text) {
- return text == null || text.length() == 0 || "null".equals(text);
- }
-
- public static String safeNull(String text) {
- if (isNullOrEmpty(text)) {
- return "";
- } else {
- return text;
- }
- }
-
- /**
- * Returns the value or the defaultValue if it is null
- */
- public static String getOrElse(String text, String defaultValue) {
- return (text != null) ? text : defaultValue;
- }
-
- /**
- * Returns the string after the given token
- *
- * @param text the text
- * @param after the token
- * @return the text after the token, or <tt>null</tt> if text does not contain the token
- */
- public static String after(String text, String after) {
- if (!text.contains(after)) {
- return null;
- }
- return text.substring(text.indexOf(after) + after.length());
- }
-
- /**
- * Returns the canonical class name by removing any generic type information.
- */
- public static String canonicalClassName(String className) {
- // remove generics
- int pos = className.indexOf('<');
- if (pos != -1) {
- return className.substring(0, pos);
- } else {
- return className;
- }
- }
-
- /**
- * Returns the text wrapped double quotes
- */
- public static String doubleQuote(String text) {
- return quote(text, "\"");
- }
-
- /**
- * Returns the text wrapped single quotes
- */
- public static String singleQuote(String text) {
- return quote(text, "'");
- }
-
- /**
- * Wraps the text in the given quote text
- *
- * @param text the text to wrap in quotes
- * @param quote the quote text added to the prefix and postfix of the text
- *
- * @return the text wrapped in the given quotes
- */
- public static String quote(String text, String quote) {
- return quote + text + quote;
- }
-
- /**
- * Clips the text between the start and end markers
- */
- public static String between(String text, String start, String end) {
- int pos = text.indexOf(start);
- if (pos > 0) {
- text = text.substring(pos + 1);
- }
- int pos2 = text.lastIndexOf(end);
- if (pos2 > 0) {
- text = text.substring(0, pos2);
- }
- return text;
- }
-
- /**
- * Capitalizes the name as a title
- *
- * @param name the name
- * @return as a title
- */
- public static String asTitle(String name) {
- StringBuilder sb = new StringBuilder();
- for (char c : name.toCharArray()) {
- boolean upper = Character.isUpperCase(c);
- boolean first = sb.length() == 0;
- if (first) {
- sb.append(Character.toUpperCase(c));
- } else if (upper) {
- sb.append(' ');
- sb.append(c);
- } else {
- sb.append(Character.toLowerCase(c));
- }
- }
- return sb.toString().trim();
- }
-
- /**
- * Gets the value with the key in a safe way, eg returning an empty string if there was no value for the key.
- */
- public static String getSafeValue(String key, List<Map<String, String>> rows) {
- for (Map<String, String> row : rows) {
- String value = row.get(key);
- if (value != null) {
- return value;
- }
- }
- return "";
- }
-
- /**
- * Gets the value with the key in a safe way, eg returning an empty string if there was no value for the key.
- */
- public static String getSafeValue(String key, Map<String, String> rows) {
- String value = rows.get(key);
- if (value != null) {
- return value;
- }
- return "";
- }
-
-}
http://git-wip-us.apache.org/repos/asf/camel/blob/788572aa/connectors/camel-connector-maven-plugin/src/main/java/org/apache/camel/maven/connector/model/ComponentModel.java
----------------------------------------------------------------------
diff --git a/connectors/camel-connector-maven-plugin/src/main/java/org/apache/camel/maven/connector/model/ComponentModel.java b/connectors/camel-connector-maven-plugin/src/main/java/org/apache/camel/maven/connector/model/ComponentModel.java
index 126ffb2..fad13aa 100644
--- a/connectors/camel-connector-maven-plugin/src/main/java/org/apache/camel/maven/connector/model/ComponentModel.java
+++ b/connectors/camel-connector-maven-plugin/src/main/java/org/apache/camel/maven/connector/model/ComponentModel.java
@@ -197,5 +197,4 @@ public class ComponentModel {
}
}
-
}
http://git-wip-us.apache.org/repos/asf/camel/blob/788572aa/connectors/camel-connector-maven-plugin/src/main/java/org/apache/camel/maven/connector/util/CollectionStringBuffer.java
----------------------------------------------------------------------
diff --git a/connectors/camel-connector-maven-plugin/src/main/java/org/apache/camel/maven/connector/util/CollectionStringBuffer.java b/connectors/camel-connector-maven-plugin/src/main/java/org/apache/camel/maven/connector/util/CollectionStringBuffer.java
new file mode 100644
index 0000000..e4c88e2
--- /dev/null
+++ b/connectors/camel-connector-maven-plugin/src/main/java/org/apache/camel/maven/connector/util/CollectionStringBuffer.java
@@ -0,0 +1,58 @@
+/**
+ * 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.
+ */
+package org.apache.camel.maven.connector.util;
+
+/**
+ * A little helper class for converting a collection of values to a (usually comma separated) string.
+ */
+public class CollectionStringBuffer {
+
+ private final StringBuilder buffer = new StringBuilder();
+ private String separator;
+ private boolean first = true;
+
+ public CollectionStringBuffer() {
+ this(", ");
+ }
+
+ public CollectionStringBuffer(String separator) {
+ this.separator = separator;
+ }
+
+ @Override
+ public String toString() {
+ return buffer.toString();
+ }
+
+ public void append(Object value) {
+ if (first) {
+ first = false;
+ } else {
+ buffer.append(separator);
+ }
+ buffer.append(value);
+ }
+
+ public String getSeparator() {
+ return separator;
+ }
+
+ public void setSeparator(String separator) {
+ this.separator = separator;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/788572aa/connectors/camel-connector-maven-plugin/src/main/java/org/apache/camel/maven/connector/util/FileHelper.java
----------------------------------------------------------------------
diff --git a/connectors/camel-connector-maven-plugin/src/main/java/org/apache/camel/maven/connector/util/FileHelper.java b/connectors/camel-connector-maven-plugin/src/main/java/org/apache/camel/maven/connector/util/FileHelper.java
new file mode 100644
index 0000000..5e974d1
--- /dev/null
+++ b/connectors/camel-connector-maven-plugin/src/main/java/org/apache/camel/maven/connector/util/FileHelper.java
@@ -0,0 +1,140 @@
+/**
+ * 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.
+ */
+package org.apache.camel.maven.connector.util;
+
+import java.io.BufferedReader;
+import java.io.Closeable;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.LineNumberReader;
+import java.nio.channels.FileChannel;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Utility methods for files.
+ */
+public final class FileHelper {
+
+ private FileHelper() {
+ }
+
+ /**
+ * Loads the entire stream into memory as a String and returns it.
+ * <p/>
+ * <b>Notice:</b> This implementation appends a <tt>\n</tt> as line
+ * terminator at the of the text.
+ * <p/>
+ * Warning, don't use for crazy big streams :)
+ */
+ public static String loadText(InputStream in) throws IOException {
+ StringBuilder builder = new StringBuilder();
+ InputStreamReader isr = new InputStreamReader(in);
+ try {
+ BufferedReader reader = new LineNumberReader(isr);
+ while (true) {
+ String line = reader.readLine();
+ if (line != null) {
+ builder.append(line);
+ builder.append("\n");
+ } else {
+ break;
+ }
+ }
+ return builder.toString();
+ } finally {
+ isr.close();
+ in.close();
+ }
+ }
+
+ /**
+ * Loads the file
+ */
+ public static List<String> loadFile(File file) throws Exception {
+ List<String> lines = new ArrayList<>();
+ LineNumberReader reader = new LineNumberReader(new FileReader(file));
+
+ String line;
+ do {
+ line = reader.readLine();
+ if (line != null) {
+ lines.add(line);
+ }
+ } while (line != null);
+ reader.close();
+
+ return lines;
+ }
+
+ /**
+ * Loads the file
+ */
+ public static List<String> loadFile(InputStream fis) throws Exception {
+ List<String> lines = new ArrayList<>();
+ LineNumberReader reader = new LineNumberReader(new InputStreamReader(fis));
+
+ String line;
+ do {
+ line = reader.readLine();
+ if (line != null) {
+ lines.add(line);
+ }
+ } while (line != null);
+ reader.close();
+
+ return lines;
+ }
+
+ public static void copyFile(File from, File to) throws IOException {
+ FileChannel in = null;
+ FileChannel out = null;
+ try {
+ in = new FileInputStream(from).getChannel();
+ out = new FileOutputStream(to).getChannel();
+
+ long size = in.size();
+ long position = 0;
+ while (position < size) {
+ position += in.transferTo(position, 4096, out);
+ }
+ } finally {
+ close(in);
+ close(out);
+ }
+ }
+
+ /**
+ * Closes the given resource if it is available, logging any closing exceptions to the given log.
+ */
+ public static void close(Closeable closeable) {
+ if (closeable != null) {
+ try {
+ closeable.close();
+ } catch (IOException e) {
+ // ignore
+ }
+ }
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/788572aa/connectors/camel-connector-maven-plugin/src/main/java/org/apache/camel/maven/connector/util/GitHelper.java
----------------------------------------------------------------------
diff --git a/connectors/camel-connector-maven-plugin/src/main/java/org/apache/camel/maven/connector/util/GitHelper.java b/connectors/camel-connector-maven-plugin/src/main/java/org/apache/camel/maven/connector/util/GitHelper.java
new file mode 100644
index 0000000..7b2fdb6
--- /dev/null
+++ b/connectors/camel-connector-maven-plugin/src/main/java/org/apache/camel/maven/connector/util/GitHelper.java
@@ -0,0 +1,132 @@
+/**
+ * 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.
+ */
+package org.apache.camel.maven.connector.util;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Utility methods for git.
+ */
+public final class GitHelper {
+
+ private GitHelper() {
+ }
+
+ /**
+ * Finds the folder where <tt>.git</tt> is located in the project
+ */
+ public static File findGitFolder() {
+ File baseDir = new File("").getAbsoluteFile();
+ return findGitFolder(baseDir);
+ }
+
+ private static File findGitFolder(File basedir) {
+ File gitDir = new File(basedir, ".git");
+ if (gitDir.exists() && gitDir.isDirectory()) {
+ return gitDir;
+ }
+
+ File parent = basedir.getParentFile();
+ if (parent != null) {
+ return findGitFolder(parent);
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Returns the remote git URL for the given folder; looking for the .git/config file in the current directory or a parent directory
+ */
+ public static String extractGitUrl(File basedir) throws IOException {
+ if (basedir == null) {
+ return null;
+ }
+ if (basedir.exists() && basedir.isDirectory()) {
+ File gitConfig = new File(basedir, ".git/config");
+ if (gitConfig.isFile() && gitConfig.exists()) {
+ String text = FileHelper.loadText(new FileInputStream(gitConfig));
+ return extractGitUrl(text);
+ }
+ }
+ File parentFile = basedir.getParentFile();
+ if (parentFile != null) {
+ return extractGitUrl(parentFile);
+ }
+ return null;
+ }
+
+ /**
+ * Returns the remote git URL for the given git config file text lets extract the
+ */
+ private static String extractGitUrl(String configText) {
+ String remote = null;
+ String lastUrl = null;
+ String firstUrl = null;
+ BufferedReader reader = new BufferedReader(new StringReader(configText));
+ Map<String, String> remoteUrls = new HashMap<>();
+ while (true) {
+ String line = null;
+ try {
+ line = reader.readLine();
+ } catch (IOException e) {
+ // ignore should never happen!
+ }
+ if (line == null) {
+ break;
+ }
+ if (line.startsWith("[remote ")) {
+ String[] parts = line.split("\"");
+ if (parts.length > 1) {
+ remote = parts[1];
+ }
+ } else if (line.startsWith("[")) {
+ remote = null;
+ } else if (remote != null && line.length() > 0 && Character.isWhitespace(line.charAt(0))) {
+ String trimmed = line.trim();
+ if (trimmed.startsWith("url ")) {
+ String[] parts = trimmed.split("=", 2);
+ if (parts.length > 1) {
+ lastUrl = parts[1].trim();
+ if (firstUrl == null) {
+ firstUrl = lastUrl;
+ }
+ remoteUrls.put(remote, lastUrl);
+ }
+ }
+
+ }
+ }
+ String answer = null;
+ if (remoteUrls.size() == 1) {
+ return lastUrl;
+ } else if (remoteUrls.size() > 1) {
+ answer = remoteUrls.get("origin");
+ if (answer == null) {
+ answer = firstUrl;
+ }
+ }
+ return answer;
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/788572aa/connectors/camel-connector-maven-plugin/src/main/java/org/apache/camel/maven/connector/util/JSonSchemaHelper.java
----------------------------------------------------------------------
diff --git a/connectors/camel-connector-maven-plugin/src/main/java/org/apache/camel/maven/connector/util/JSonSchemaHelper.java b/connectors/camel-connector-maven-plugin/src/main/java/org/apache/camel/maven/connector/util/JSonSchemaHelper.java
new file mode 100644
index 0000000..2bc95b7
--- /dev/null
+++ b/connectors/camel-connector-maven-plugin/src/main/java/org/apache/camel/maven/connector/util/JSonSchemaHelper.java
@@ -0,0 +1,427 @@
+/**
+ * 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.
+ */
+package org.apache.camel.maven.connector.util;
+
+import java.io.File;
+import java.net.URI;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * A helper class for <a href="http://json-schema.org/">JSON schema</a>.
+ */
+public final class JSonSchemaHelper {
+
+ private static final String VALID_CHARS = ".-='/\\!&():;";
+ // 0 = text, 1 = enum, 2 = boolean, 3 = integer or number
+ private static final Pattern PATTERN = Pattern.compile("\"(.+?)\"|\\[(.+)\\]|(true|false)|(-?\\d+\\.?\\d*)");
+ private static final String QUOT = """;
+
+ private JSonSchemaHelper() {
+ }
+
+ public static String toJson(String name, String displayName, String kind, Boolean required, String type, String defaultValue, String description,
+ Boolean deprecated, Boolean secret, String group, String label, boolean enumType, Set<String> enums,
+ boolean oneOfType, Set<String> oneOffTypes, boolean asPredicate, String optionalPrefix, String prefix, boolean multiValue) {
+ String typeName = getType(type, enumType);
+
+ StringBuilder sb = new StringBuilder();
+ sb.append(StringHelper.doubleQuote(name));
+ sb.append(": { \"kind\": ");
+ sb.append(StringHelper.doubleQuote(kind));
+
+ // compute a display name if we don't have anything
+ if (StringHelper.isNullOrEmpty(displayName)) {
+ displayName = StringHelper.asTitle(name);
+ }
+ // we want display name early so its easier to spot
+ sb.append(", \"displayName\": ");
+ sb.append(StringHelper.doubleQuote(displayName));
+
+ // we want group early so its easier to spot
+ if (!StringHelper.isNullOrEmpty(group)) {
+ sb.append(", \"group\": ");
+ sb.append(StringHelper.doubleQuote(group));
+ }
+
+ // we want label early so its easier to spot
+ if (!StringHelper.isNullOrEmpty(label)) {
+ sb.append(", \"label\": ");
+ sb.append(StringHelper.doubleQuote(label));
+ }
+
+ if (required != null) {
+ // boolean type
+ sb.append(", \"required\": ");
+ sb.append(required.toString());
+ }
+
+ sb.append(", \"type\": ");
+ if ("enum".equals(typeName)) {
+ String actualType = getType(type, false);
+ sb.append(StringHelper.doubleQuote(actualType));
+ sb.append(", \"javaType\": \"" + type + "\"");
+ CollectionStringBuffer enumValues = new CollectionStringBuffer();
+ for (Object value : enums) {
+ enumValues.append(StringHelper.doubleQuote(value.toString()));
+ }
+ sb.append(", \"enum\": [ ");
+ sb.append(enumValues.toString());
+ sb.append(" ]");
+ } else if (oneOfType) {
+ sb.append(StringHelper.doubleQuote(typeName));
+ sb.append(", \"javaType\": \"" + type + "\"");
+ CollectionStringBuffer oneOfValues = new CollectionStringBuffer();
+ for (Object value : oneOffTypes) {
+ oneOfValues.append(StringHelper.doubleQuote(value.toString()));
+ }
+ sb.append(", \"oneOf\": [ ");
+ sb.append(oneOfValues.toString());
+ sb.append(" ]");
+ } else if ("array".equals(typeName)) {
+ sb.append(StringHelper.doubleQuote("array"));
+ sb.append(", \"javaType\": \"" + type + "\"");
+ } else {
+ sb.append(StringHelper.doubleQuote(typeName));
+ sb.append(", \"javaType\": \"" + type + "\"");
+ }
+
+ if (!StringHelper.isNullOrEmpty(optionalPrefix)) {
+ sb.append(", \"optionalPrefix\": ");
+ String text = safeDefaultValue(optionalPrefix);
+ sb.append(StringHelper.doubleQuote(text));
+ }
+
+ if (!StringHelper.isNullOrEmpty(prefix)) {
+ sb.append(", \"prefix\": ");
+ String text = safeDefaultValue(prefix);
+ sb.append(StringHelper.doubleQuote(text));
+ }
+ if (multiValue) {
+ // boolean value
+ sb.append(", \"multiValue\": true");
+ }
+
+ if (deprecated != null) {
+ sb.append(", \"deprecated\": ");
+ // boolean value
+ sb.append(deprecated.toString());
+ }
+
+ if (secret != null) {
+ sb.append(", \"secret\": ");
+ // boolean value
+ sb.append(secret.toString());
+ }
+
+ if (!StringHelper.isNullOrEmpty(defaultValue)) {
+ sb.append(", \"defaultValue\": ");
+ String text = safeDefaultValue(defaultValue);
+ // the type can either be boolean, integer, number or text based
+ if ("boolean".equals(typeName) || "integer".equals(typeName) || "number".equals(typeName)) {
+ sb.append(text);
+ } else {
+ // text should be quoted
+ sb.append(StringHelper.doubleQuote(text));
+ }
+ }
+
+ // for expressions we want to know if it must be used as predicate or not
+ boolean predicate = "expression".equals(kind) || asPredicate;
+ if (predicate) {
+ sb.append(", \"asPredicate\": ");
+ if (asPredicate) {
+ sb.append("true");
+ } else {
+ sb.append("false");
+ }
+ }
+
+ if (!StringHelper.isNullOrEmpty(description)) {
+ sb.append(", \"description\": ");
+ String text = sanitizeDescription(description, false);
+ sb.append(StringHelper.doubleQuote(text));
+ }
+
+ sb.append(" }");
+ return sb.toString();
+ }
+
+ /**
+ * Gets the JSon schema type.
+ *
+ * @param type the java type
+ * @return the json schema type, is never null, but returns <tt>object</tt> as the generic type
+ */
+ public static String getType(String type, boolean enumType) {
+ if (enumType) {
+ return "enum";
+ } else if (type == null) {
+ // return generic type for unknown type
+ return "object";
+ } else if (type.equals(URI.class.getName()) || type.equals(URL.class.getName())) {
+ return "string";
+ } else if (type.equals(File.class.getName())) {
+ return "string";
+ } else if (type.equals(Date.class.getName())) {
+ return "string";
+ } else if (type.startsWith("java.lang.Class")) {
+ return "string";
+ } else if (type.startsWith("java.util.List") || type.startsWith("java.util.Collection")) {
+ return "array";
+ }
+
+ String primitive = getPrimitiveType(type);
+ if (primitive != null) {
+ return primitive;
+ }
+
+ return "object";
+ }
+
+ /**
+ * Gets the JSon schema primitive type.
+ *
+ * @param name the java type
+ * @return the json schema primitive type, or <tt>null</tt> if not a primitive
+ */
+ public static String getPrimitiveType(String name) {
+
+ // special for byte[] or Object[] as its common to use
+ if ("java.lang.byte[]".equals(name) || "byte[]".equals(name)) {
+ return "string";
+ } else if ("java.lang.Byte[]".equals(name) || "Byte[]".equals(name)) {
+ return "array";
+ } else if ("java.lang.Object[]".equals(name) || "Object[]".equals(name)) {
+ return "array";
+ } else if ("java.lang.String[]".equals(name) || "String[]".equals(name)) {
+ return "array";
+ } else if ("java.lang.Character".equals(name) || "Character".equals(name) || "char".equals(name)) {
+ return "string";
+ } else if ("java.lang.String".equals(name) || "String".equals(name)) {
+ return "string";
+ } else if ("java.lang.Boolean".equals(name) || "Boolean".equals(name) || "boolean".equals(name)) {
+ return "boolean";
+ } else if ("java.lang.Integer".equals(name) || "Integer".equals(name) || "int".equals(name)) {
+ return "integer";
+ } else if ("java.lang.Long".equals(name) || "Long".equals(name) || "long".equals(name)) {
+ return "integer";
+ } else if ("java.lang.Short".equals(name) || "Short".equals(name) || "short".equals(name)) {
+ return "integer";
+ } else if ("java.lang.Byte".equals(name) || "Byte".equals(name) || "byte".equals(name)) {
+ return "integer";
+ } else if ("java.lang.Float".equals(name) || "Float".equals(name) || "float".equals(name)) {
+ return "number";
+ } else if ("java.lang.Double".equals(name) || "Double".equals(name) || "double".equals(name)) {
+ return "number";
+ }
+
+ return null;
+ }
+
+ /**
+ * Sanitizes the javadoc to removed invalid characters so it can be used as json description
+ *
+ * @param javadoc the javadoc
+ * @return the text that is valid as json
+ */
+ public static String sanitizeDescription(String javadoc, boolean summary) {
+ if (StringHelper.isNullOrEmpty(javadoc)) {
+ return null;
+ }
+
+ // lets just use what java accepts as identifiers
+ StringBuilder sb = new StringBuilder();
+
+ // split into lines
+ String[] lines = javadoc.split("\n");
+
+ boolean first = true;
+ for (String line : lines) {
+ line = line.trim();
+
+ // terminate if we reach @param, @return or @deprecated as we only want the javadoc summary
+ if (line.startsWith("@param") || line.startsWith("@return") || line.startsWith("@deprecated")) {
+ break;
+ }
+
+ // skip lines that are javadoc references
+ if (line.startsWith("@")) {
+ continue;
+ }
+
+ // remove all XML tags
+ line = line.replaceAll("<.*?>", "");
+
+ // remove all inlined javadoc links, eg such as {@link org.apache.camel.spi.Registry}
+ line = line.replaceAll("\\{\\@\\w+\\s([\\w.]+)\\}", "$1");
+
+ // we are starting from a new line, so add a whitespace
+ if (!first) {
+ sb.append(' ');
+ }
+
+ // create a new line
+ StringBuilder cb = new StringBuilder();
+ for (char c : line.toCharArray()) {
+ if (Character.isJavaIdentifierPart(c) || VALID_CHARS.indexOf(c) != -1) {
+ cb.append(c);
+ } else if (Character.isWhitespace(c)) {
+ // always use space as whitespace, also for line feeds etc
+ cb.append(' ');
+ }
+ }
+
+ // append data
+ String s = cb.toString().trim();
+ sb.append(s);
+
+ boolean empty = StringHelper.isNullOrEmpty(s);
+ boolean endWithDot = s.endsWith(".");
+ boolean haveText = sb.length() > 0;
+
+ if (haveText && summary && (empty || endWithDot)) {
+ // if we only want a summary, then skip at first empty line we encounter, or if the sentence ends with a dot
+ break;
+ }
+
+ first = false;
+ }
+
+ // remove double whitespaces, and trim
+ String s = sb.toString();
+ s = s.replaceAll("\\s+", " ");
+ return s.trim();
+ }
+
+ /**
+ * Parses the json schema to split it into a list or rows, where each row contains key value pairs with the metadata
+ *
+ * @param group the group to parse from such as <tt>component</tt>, <tt>componentProperties</tt>, or <tt>properties</tt>.
+ * @param json the json
+ * @return a list of all the rows, where each row is a set of key value pairs with metadata
+ */
+ public static List<Map<String, String>> parseJsonSchema(String group, String json, boolean parseProperties) {
+ List<Map<String, String>> answer = new ArrayList<Map<String, String>>();
+ if (json == null) {
+ return answer;
+ }
+
+ boolean found = false;
+
+ // parse line by line
+ String[] lines = json.split("\n");
+ for (String line : lines) {
+ // we need to find the group first
+ if (!found) {
+ String s = line.trim();
+ found = s.startsWith("\"" + group + "\":") && s.endsWith("{");
+ continue;
+ }
+
+ // we should stop when we end the group
+ if (line.equals(" },") || line.equals(" }")) {
+ break;
+ }
+
+ // need to safe encode \" so we can parse the line
+ line = line.replaceAll("\"\\\\\"\"", '"' + QUOT + '"');
+
+ Map<String, String> row = new LinkedHashMap<String, String>();
+ Matcher matcher = PATTERN.matcher(line);
+
+ String key;
+ if (parseProperties) {
+ // when parsing properties the first key is given as name, so the first parsed token is the value of the name
+ key = "name";
+ } else {
+ key = null;
+ }
+ while (matcher.find()) {
+ if (key == null) {
+ key = matcher.group(1);
+ } else {
+ String value = matcher.group(1);
+ if (value != null) {
+ // its text based
+ value = value.trim();
+ // decode
+ value = value.replaceAll(QUOT, "\"");
+ value = decodeJson(value);
+ }
+ if (value == null) {
+ // not text then its maybe an enum?
+ value = matcher.group(2);
+ if (value != null) {
+ // its an enum so strip out " and trim spaces after comma
+ value = value.replaceAll("\"", "");
+ value = value.replaceAll(", ", ",");
+ value = value.trim();
+ }
+ }
+ if (value == null) {
+ // not text then its maybe a boolean?
+ value = matcher.group(3);
+ }
+ if (value == null) {
+ // not text then its maybe a integer?
+ value = matcher.group(4);
+ }
+ if (value != null) {
+ row.put(key, value);
+ }
+ // reset
+ key = null;
+ }
+ }
+ if (!row.isEmpty()) {
+ answer.add(row);
+ }
+ }
+
+ return answer;
+ }
+
+ private static String decodeJson(String value) {
+ // json encodes a \ as \\ so we need to decode from \\ back to \
+ if ("\\\\".equals(value)) {
+ value = "\\";
+ }
+ return value;
+ }
+
+ /**
+ * The default value may need to be escaped to be safe for json
+ */
+ private static String safeDefaultValue(String value) {
+ if ("\"".equals(value)) {
+ return "\\\"";
+ } else if ("\\".equals(value)) {
+ return "\\\\";
+ } else {
+ return value;
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/788572aa/connectors/camel-connector-maven-plugin/src/main/java/org/apache/camel/maven/connector/util/StringHelper.java
----------------------------------------------------------------------
diff --git a/connectors/camel-connector-maven-plugin/src/main/java/org/apache/camel/maven/connector/util/StringHelper.java b/connectors/camel-connector-maven-plugin/src/main/java/org/apache/camel/maven/connector/util/StringHelper.java
new file mode 100644
index 0000000..5aa8542
--- /dev/null
+++ b/connectors/camel-connector-maven-plugin/src/main/java/org/apache/camel/maven/connector/util/StringHelper.java
@@ -0,0 +1,219 @@
+/**
+ * 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.
+ */
+package org.apache.camel.maven.connector.util;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Utility methods for String.
+ */
+public final class StringHelper {
+
+ private StringHelper() {
+ }
+
+ /**
+ * Converts the value to use dash style instead of upper cased
+ */
+ public static String camelCaseToDash(String value) {
+ StringBuilder sb = new StringBuilder(value.length());
+ boolean dash = false;
+
+ for (char c : value.toCharArray()) {
+ // skip dash in start
+ if (sb.length() > 0 & Character.isUpperCase(c)) {
+ dash = true;
+ }
+ if (dash) {
+ sb.append('-');
+ sb.append(Character.toLowerCase(c));
+ } else {
+ // lower case first
+ if (sb.length() == 0) {
+ sb.append(Character.toLowerCase(c));
+ } else {
+ sb.append(c);
+ }
+ }
+ dash = false;
+ }
+ return sb.toString();
+ }
+
+ /**
+ * Returns the string value (uses empty string for <tt>null</tt> values)
+ */
+ public static String nullSafe(String text) {
+ return text != null ? text : "";
+ }
+
+ /**
+ * Returns true if the given text is null or empty string or has <tt>null</tt> as the value
+ */
+ public static boolean isNullOrEmpty(String text) {
+ return text == null || text.length() == 0 || "null".equals(text);
+ }
+
+ public static String safeNull(String text) {
+ if (isNullOrEmpty(text)) {
+ return "";
+ } else {
+ return text;
+ }
+ }
+
+ /**
+ * Returns the value or the defaultValue if it is null
+ */
+ public static String getOrElse(String text, String defaultValue) {
+ return (text != null) ? text : defaultValue;
+ }
+
+ /**
+ * Returns the string after the given token
+ *
+ * @param text the text
+ * @param after the token
+ * @return the text after the token, or <tt>null</tt> if text does not contain the token
+ */
+ public static String after(String text, String after) {
+ if (!text.contains(after)) {
+ return null;
+ }
+ return text.substring(text.indexOf(after) + after.length());
+ }
+
+ /**
+ * Returns the canonical class name by removing any generic type information.
+ */
+ public static String canonicalClassName(String className) {
+ // remove generics
+ int pos = className.indexOf('<');
+ if (pos != -1) {
+ return className.substring(0, pos);
+ } else {
+ return className;
+ }
+ }
+
+ /**
+ * Returns the text wrapped double quotes
+ */
+ public static String doubleQuote(String text) {
+ return quote(text, "\"");
+ }
+
+ /**
+ * Returns the text wrapped single quotes
+ */
+ public static String singleQuote(String text) {
+ return quote(text, "'");
+ }
+
+ /**
+ * Wraps the text in the given quote text
+ *
+ * @param text the text to wrap in quotes
+ * @param quote the quote text added to the prefix and postfix of the text
+ *
+ * @return the text wrapped in the given quotes
+ */
+ public static String quote(String text, String quote) {
+ return quote + text + quote;
+ }
+
+ /**
+ * Clips the text between the start and end markers
+ */
+ public static String between(String text, String start, String end) {
+ int pos = text.indexOf(start);
+ if (pos > 0) {
+ text = text.substring(pos + 1);
+ }
+ int pos2 = text.lastIndexOf(end);
+ if (pos2 > 0) {
+ text = text.substring(0, pos2);
+ }
+ return text;
+ }
+
+ /**
+ * Capitalizes the name as a title
+ *
+ * @param name the name
+ * @return as a title
+ */
+ public static String asTitle(String name) {
+ StringBuilder sb = new StringBuilder();
+ for (char c : name.toCharArray()) {
+ boolean upper = Character.isUpperCase(c);
+ boolean first = sb.length() == 0;
+ if (first) {
+ sb.append(Character.toUpperCase(c));
+ } else if (upper) {
+ sb.append(' ');
+ sb.append(c);
+ } else {
+ sb.append(Character.toLowerCase(c));
+ }
+ }
+ return sb.toString().trim();
+ }
+
+ /**
+ * Gets the value with the key in a safe way, eg returning an empty string if there was no value for the key.
+ */
+ public static String getSafeValue(String key, List<Map<String, String>> rows) {
+ for (Map<String, String> row : rows) {
+ String value = row.get(key);
+ if (value != null) {
+ return value;
+ }
+ }
+ return "";
+ }
+
+ /**
+ * Gets the value with the key in a safe way, eg returning an empty string if there was no value for the key.
+ */
+ public static String getSafeValue(String key, Map<String, String> rows) {
+ String value = rows.get(key);
+ if (value != null) {
+ return value;
+ }
+ return "";
+ }
+
+ public static String getShortJavaType(String javaType) {
+ if (javaType.startsWith("java.util.Map")) {
+ return "Map";
+ } else if (javaType.startsWith("java.util.Set")) {
+ return "Set";
+ } else if (javaType.startsWith("java.util.List")) {
+ return "List";
+ }
+ int pos = javaType.lastIndexOf(".");
+ if (pos != -1) {
+ return javaType.substring(pos + 1);
+ } else {
+ return javaType;
+ }
+ }
+
+
+}
[3/3] camel git commit: CAMEL-10799: camel-connector - Generate
spring boot auto configuration
Posted by da...@apache.org.
CAMEL-10799: camel-connector - Generate spring boot auto configuration
Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/12ddb0fc
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/12ddb0fc
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/12ddb0fc
Branch: refs/heads/master
Commit: 12ddb0fc8147b0e5491134a078f3e44579a7651c
Parents: 788572a
Author: Claus Ibsen <da...@apache.org>
Authored: Wed Mar 15 21:56:47 2017 +0100
Committer: Claus Ibsen <da...@apache.org>
Committed: Wed Mar 15 22:40:48 2017 +0100
----------------------------------------------------------------------
.../SpringBootAutoConfigurationMojo.java | 18 +++++---
.../component/connector/ConnectorComponent.java | 10 +++++
.../connector/DefaultConnectorComponent.java | 47 ++++++++++++++++++++
3 files changed, 68 insertions(+), 7 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/camel/blob/12ddb0fc/connectors/camel-connector-maven-plugin/src/main/java/org/apache/camel/maven/connector/SpringBootAutoConfigurationMojo.java
----------------------------------------------------------------------
diff --git a/connectors/camel-connector-maven-plugin/src/main/java/org/apache/camel/maven/connector/SpringBootAutoConfigurationMojo.java b/connectors/camel-connector-maven-plugin/src/main/java/org/apache/camel/maven/connector/SpringBootAutoConfigurationMojo.java
index e276992..1529696 100644
--- a/connectors/camel-connector-maven-plugin/src/main/java/org/apache/camel/maven/connector/SpringBootAutoConfigurationMojo.java
+++ b/connectors/camel-connector-maven-plugin/src/main/java/org/apache/camel/maven/connector/SpringBootAutoConfigurationMojo.java
@@ -52,6 +52,7 @@ import org.springframework.boot.context.properties.DeprecatedConfigurationProper
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Lazy;
import static org.apache.camel.maven.connector.util.FileHelper.loadText;
import static org.apache.camel.maven.connector.util.StringHelper.getSafeValue;
@@ -108,15 +109,14 @@ public class SpringBootAutoConfigurationMojo extends AbstractMojo {
int pos = javaType.lastIndexOf(".");
String pkg = javaType.substring(0, pos) + ".springboot";
- getLog().info("Generating Spring Boot AutoConfiguration for Connector: " + model.getScheme());
-
+ // we only create spring boot auto configuration if there is options to configure
if (hasOptions) {
+ getLog().info("Generating Spring Boot AutoConfiguration for Connector: " + model.getScheme());
+
createConnectorConfigurationSource(pkg, model, javaType, connectorScheme);
+ createConnectorAutoConfigurationSource(pkg, hasOptions, javaType, connectorScheme);
+ createConnectorSpringFactorySource(pkg, javaType);
}
- createConnectorAutoConfigurationSource(pkg, hasOptions, javaType, connectorScheme);
- createConnectorSpringFactorySource(pkg, javaType);
- } else {
- getLog().warn("Cannot generate Spring Boot AutoConfiguration as camel-component-schema.json file missing");
}
}
@@ -270,7 +270,10 @@ public class SpringBootAutoConfigurationMojo extends AbstractMojo {
method.addParameter(configurationName, "configuration");
}
- method.addAnnotation(Bean.class).setStringValue("name", connectorScheme.toLowerCase(Locale.US) + "-connector");
+ // must be named -component because camel-spring-boot uses that to lookup components
+ String beanName = connectorScheme + "-component";
+ method.addAnnotation(Lazy.class);
+ method.addAnnotation(Bean.class).setStringValue("name", beanName);
method.addAnnotation(ConditionalOnClass.class).setLiteralValue("value", "CamelContext.class");
method.addAnnotation(ConditionalOnMissingBean.class).setLiteralValue("value", javaType + ".class");
@@ -321,6 +324,7 @@ public class SpringBootAutoConfigurationMojo extends AbstractMojo {
sb.append("Map<String, Object> parameters = new HashMap<>();\n");
sb.append("IntrospectionSupport.getProperties(configuration, parameters, null, false);\n");
sb.append("IntrospectionSupport.setProperties(camelContext, camelContext.getTypeConverter(), connector, parameters);\n");
+ sb.append("connector.setComponentOptions(parameters);\n");
}
sb.append("\n");
sb.append("return connector;");
http://git-wip-us.apache.org/repos/asf/camel/blob/12ddb0fc/connectors/camel-connector/src/main/java/org/apache/camel/component/connector/ConnectorComponent.java
----------------------------------------------------------------------
diff --git a/connectors/camel-connector/src/main/java/org/apache/camel/component/connector/ConnectorComponent.java b/connectors/camel-connector/src/main/java/org/apache/camel/component/connector/ConnectorComponent.java
index 6c4f12f..4a7dbce 100644
--- a/connectors/camel-connector/src/main/java/org/apache/camel/component/connector/ConnectorComponent.java
+++ b/connectors/camel-connector/src/main/java/org/apache/camel/component/connector/ConnectorComponent.java
@@ -66,4 +66,14 @@ public interface ConnectorComponent extends Component {
*/
String getCamelConnectorJSon();
+ /**
+ * A set of additional component options to use for the base component when creating connector endpoints.
+ */
+ Map<String, Object> getComponentOptions();
+
+ /**
+ * A set of additional component options to use for the base component when creating connector endpoints.
+ */
+ void setComponentOptions(Map<String, Object> baseComponentOptions);
+
}
http://git-wip-us.apache.org/repos/asf/camel/blob/12ddb0fc/connectors/camel-connector/src/main/java/org/apache/camel/component/connector/DefaultConnectorComponent.java
----------------------------------------------------------------------
diff --git a/connectors/camel-connector/src/main/java/org/apache/camel/component/connector/DefaultConnectorComponent.java b/connectors/camel-connector/src/main/java/org/apache/camel/component/connector/DefaultConnectorComponent.java
index 536a224..18f6c52 100644
--- a/connectors/camel-connector/src/main/java/org/apache/camel/component/connector/DefaultConnectorComponent.java
+++ b/connectors/camel-connector/src/main/java/org/apache/camel/component/connector/DefaultConnectorComponent.java
@@ -16,9 +16,13 @@
*/
package org.apache.camel.component.connector;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Modifier;
import java.net.URISyntaxException;
+import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
+import java.util.Set;
import org.apache.camel.Component;
import org.apache.camel.ComponentVerifier;
@@ -42,6 +46,7 @@ public abstract class DefaultConnectorComponent extends DefaultComponent impleme
private final String componentName;
private final ConnectorModel model;
+ private Map<String, Object> componentOptions;
protected DefaultConnectorComponent(String componentName, String className) {
this.componentName = componentName;
@@ -60,6 +65,31 @@ public abstract class DefaultConnectorComponent extends DefaultComponent impleme
parameters.clear();
String scheme = model.getBaseScheme();
+
+ // if we have component options then we need to create a new instance of the component
+ // which we then configure before it create the endpoint
+ if (componentOptions != null && !componentOptions.isEmpty()) {
+ String baseClassName = model.getBaseJavaType();
+ if (baseClassName != null) {
+ Class<?> type = Class.forName(baseClassName);
+ Constructor ctr = getPublicDefaultConstructor(type);
+ if (ctr != null) {
+ // call default no-arg constructor
+ Object base = ctr.newInstance();
+ // configure component with extra options
+ Map<String, Object> copy = new HashMap<>(componentOptions);
+ IntrospectionSupport.setProperties(getCamelContext(), getCamelContext().getTypeConverter(), base, copy);
+
+ if (base instanceof Component) {
+ Component old = getCamelContext().removeComponent(scheme);
+ // ensure component is started and stopped when Camel shutdown
+ getCamelContext().addService(base, true, true);
+ getCamelContext().addComponent(scheme, (Component) base);
+ }
+ }
+ }
+ }
+
String delegateUri = createEndpointUri(scheme, options);
log.debug("Connector resolved: {} -> {}", uri, delegateUri);
@@ -67,6 +97,15 @@ public abstract class DefaultConnectorComponent extends DefaultComponent impleme
return new DefaultConnectorEndpoint(uri, this, delegate, model.getInputDataType(), model.getOutputDataType());
}
+ private static Constructor getPublicDefaultConstructor(Class<?> clazz) {
+ for (Constructor ctr : clazz.getConstructors()) {
+ if (Modifier.isPublic(ctr.getModifiers()) && ctr.getParameterCount() == 0) {
+ return ctr;
+ }
+ }
+ return null;
+ }
+
@Override
public String createEndpointUri(String scheme, Map<String, String> options) throws URISyntaxException {
log.trace("Creating endpoint uri with scheme: {}", scheme);
@@ -99,6 +138,14 @@ public abstract class DefaultConnectorComponent extends DefaultComponent impleme
return componentName;
}
+ public Map<String, Object> getComponentOptions() {
+ return componentOptions;
+ }
+
+ public void setComponentOptions(Map<String, Object> baseComponentOptions) {
+ this.componentOptions = baseComponentOptions;
+ }
+
@SuppressWarnings("unchecked")
@Override
public ComponentVerifier getVerifier() {