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 2019/06/21 08:52:21 UTC

[camel] 06/08: CAMEL-13663: camel-main-maven-plugin to generte spring-boot tooling metadata to fool Java editors to have code completions for Camel Main application.properties files.

This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel.git

commit 6f01e564794cef5a3dad6365a86c3c335b2cedc5
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Fri Jun 21 09:51:40 2019 +0200

    CAMEL-13663: camel-main-maven-plugin to generte spring-boot tooling metadata to fool Java editors to have code completions for Camel Main application.properties files.
---
 .../java/org/apache/camel/maven/AutowireMojo.java  | 282 ---------------------
 .../apache/camel/maven/SpringBootToolingMojo.java  | 152 -----------
 2 files changed, 434 deletions(-)

diff --git a/catalog/camel-main-maven-plugin/src/main/java/org/apache/camel/maven/AutowireMojo.java b/catalog/camel-main-maven-plugin/src/main/java/org/apache/camel/maven/AutowireMojo.java
deleted file mode 100644
index a742f4a..0000000
--- a/catalog/camel-main-maven-plugin/src/main/java/org/apache/camel/maven/AutowireMojo.java
+++ /dev/null
@@ -1,282 +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;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.lang.reflect.Modifier;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Set;
-import java.util.stream.Collectors;
-
-import org.apache.camel.catalog.CamelCatalog;
-import org.apache.camel.catalog.JSonSchemaHelper;
-import org.apache.camel.maven.model.AutowireData;
-import org.apache.camel.support.PatternHelper;
-import org.apache.camel.util.IOHelper;
-import org.apache.camel.util.OrderedProperties;
-import org.apache.camel.util.StringHelper;
-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.apache.maven.plugins.annotations.ResolutionScope;
-import org.reflections.Reflections;
-
-/**
- * Pre scans your project and prepare autowiring by classpath scanning
- */
-@Mojo(name = "autowire", defaultPhase = LifecyclePhase.PROCESS_CLASSES, threadSafe = true, requiresDependencyResolution = ResolutionScope.COMPILE)
-@Deprecated
-public class AutowireMojo extends AbstractMainMojo {
-
-    /**
-     * When autowiring has detected multiple implementations (2 or more) of a given interface, which
-     * cannot be mapped, should they be logged so you can see and add manual mapping if needed.
-     */
-    @Parameter(property = "camel.logUnmapped", defaultValue = "false")
-    protected boolean logUnmapped;
-
-    /**
-     * The output directory for generated autowire file
-     */
-    @Parameter(readonly = true, defaultValue = "${project.build.directory}/classes/META-INF/services/org/apache/camel/")
-    protected File outFolder;
-
-    /**
-     * To exclude autowiring specific properties with these key names.
-     * You can also configure a single entry and separate the excludes with comma
-     */
-    @Parameter(property = "camel.exclude")
-    protected String[] exclude;
-
-    /**
-     * To include autowiring specific properties or component with these key names.
-     * You can also configure a single entry and separate the includes with comma
-     */
-    @Parameter(property = "camel.include")
-    protected String[] include;
-
-    /**
-     * To setup special mappings between known types as key=value pairs.
-     * You can also configure a single entry and separate the mappings with comma
-     */
-    @Parameter(property = "camel.mappings")
-    protected String[] mappings;
-
-    /**
-     * Optional mappings file loaded from classpath, with mapping that override any default mappings
-     */
-    @Parameter(defaultValue = "${project.build.directory}/classes/camel-main-mappings.properties")
-    protected File mappingsFile;
-
-    @Override
-    public void execute() throws MojoExecutionException, MojoFailureException {
-        // load default mappings
-        Properties mappingProperties = loadDefaultMappings();
-        getLog().debug("Loaded default-mappings: " + mappingProperties);
-        // add extra mappings
-        if (this.mappings != null) {
-            for (String m : this.mappings) {
-                String key = StringHelper.before(m, "=");
-                String value = StringHelper.after(m, "=");
-                if (key != null && value != null) {
-                    mappingProperties.setProperty(key, value);
-                    getLog().debug("Added mapping from pom.xml: " + key + "=" + value);
-                }
-            }
-        }
-        Properties mappingFileProperties = loadMappingsFile();
-        if (!mappingFileProperties.isEmpty()) {
-            getLog().debug("Loaded mappings file: " + mappingsFile + " with mappings: " + mappingFileProperties);
-            mappingProperties.putAll(mappingFileProperties);
-        }
-
-        final List<AutowireData> autowires = new ArrayList<>();
-        ComponentCallback callback = (componentName, name, type, javaType, description, defaultValue) -> {
-            if ("object".equals(type)) {
-                if (!isValidPropertyName(componentName, name)) {
-                    getLog().debug("Skipping property name: " + name);
-                    return;
-                }
-                try {
-                    Class clazz = classLoader.loadClass(javaType);
-                    if (clazz.isInterface() && isComplexUserType(clazz)) {
-                        Set<Class<?>> classes = reflections.getSubTypesOf(clazz);
-                        // filter classes (must not be interfaces, must be public, must not be abstract, must be top level) and also a valid autowire class
-                        classes = classes.stream().filter(
-                                c -> !c.isInterface()
-                                        && Modifier.isPublic(c.getModifiers())
-                                        && !Modifier.isAbstract(c.getModifiers())
-                                        && c.getEnclosingClass() == null
-                                        && isValidAutowireClass(c))
-                                .collect(Collectors.toSet());
-                        Class best = chooseBestKnownType(componentName, name, clazz, classes, mappingProperties);
-                        if (best != null) {
-                            String key = "camel.component." + componentName + "." + name;
-                            String value = "#class:" + best.getName();
-                            getLog().debug(key + "=" + value);
-                            autowires.add(new AutowireData(key, value));
-
-                            // TODO: get options from best class (getter/setter pairs)
-                            // we dont have documentation
-                            // add as spring boot options
-
-                        }
-                    }
-
-                } catch (Exception e) {
-                    // ignore
-                    getLog().debug("Cannot load class: " + name, e);
-                }
-            }
-        };
-
-        // perform the work with this callback
-        doExecute(callback);
-
-        if (!autowires.isEmpty()) {
-            outFolder.mkdirs();
-            File file = new File(outFolder, "autowire.properties");
-            try {
-                FileOutputStream fos = new FileOutputStream(file, false);
-                fos.write("# Generated by camel build tools\n".getBytes());
-                for (AutowireData data : autowires) {
-                    fos.write(data.getKey().getBytes());
-                    fos.write('=');
-                    fos.write(data.getValue().getBytes());
-                    fos.write('\n');
-                }
-                IOHelper.close(fos);
-                getLog().info("Created file: " + file + " (autowire by classpath: " + autowires.size() + ")");
-            } catch (Throwable e) {
-                throw new MojoFailureException("Cannot write to file " + file + " due " + e.getMessage(), e);
-            }
-        }
-    }
-
-    protected Properties loadDefaultMappings() throws MojoFailureException {
-        Properties mappings = new OrderedProperties();
-        try {
-            InputStream is = AutowireMojo.class.getResourceAsStream("/default-mappings.properties");
-            if (is != null) {
-                mappings.load(is);
-            }
-        } catch (IOException e) {
-            throw new MojoFailureException("Cannot load default-mappings.properties from classpath");
-        }
-        return mappings;
-    }
-
-    protected Properties loadMappingsFile() throws MojoFailureException {
-        Properties mappings = new OrderedProperties();
-        if (mappingsFile.exists() && mappingsFile.isFile()) {
-            try {
-                InputStream is = new FileInputStream(mappingsFile);
-                mappings.load(is);
-            } catch (IOException e) {
-                throw new MojoFailureException("Cannot load file: " + mappingsFile);
-            }
-        }
-        return mappings;
-    }
-
-    protected Class chooseBestKnownType(String componentName, String optionName, Class type, Set<Class<?>> candidates, Properties knownTypes) {
-        String known = knownTypes.getProperty(type.getName());
-        if (known != null) {
-            for (String k : known.split(";")) {
-                // special as we should skip this option
-                if ("#skip#".equals(k)) {
-                    return null;
-                }
-                Class found = candidates.stream().filter(c -> c.getName().equals(k)).findFirst().orElse(null);
-                if (found != null) {
-                    return found;
-                }
-            }
-        }
-
-        if (candidates.size() == 1) {
-            return candidates.iterator().next();
-        } else if (candidates.size() > 1) {
-            if (logUnmapped) {
-                getLog().debug("Cannot chose best type: " + type.getName() + " among " + candidates.size() + " implementations: " + candidates);
-                getLog().info("Cannot autowire option camel.component." + componentName + "." + optionName
-                        + " as the interface: " + type.getName() + " has " + candidates.size() + " implementations in the classpath:");
-                for (Class c : candidates) {
-                    getLog().info("\t\t" + c.getName());
-                }
-            }
-        }
-        return null;
-    }
-
-    protected boolean isValidPropertyName(String componentName, String name) {
-        // we want to regard names as the same if they are using dash or not, and also to be case insensitive.
-        String prefix = "camel.component." + componentName + ".";
-        name = StringHelper.dashToCamelCase(name);
-
-        if (exclude != null && exclude.length > 0) {
-            // works on components too
-            for (String pattern : exclude) {
-                pattern = pattern.trim();
-                pattern = StringHelper.dashToCamelCase(pattern);
-                if (PatternHelper.matchPattern(componentName, pattern)) {
-                    return false;
-                }
-                if (PatternHelper.matchPattern(name, pattern) || PatternHelper.matchPattern(prefix + name, pattern)) {
-                    return false;
-                }
-            }
-        }
-
-        if (include != null && include.length > 0) {
-            for (String pattern : include) {
-                pattern = pattern.trim();
-                pattern = StringHelper.dashToCamelCase(pattern);
-                if (PatternHelper.matchPattern(componentName, pattern)) {
-                    return true;
-                }
-                if (PatternHelper.matchPattern(name, pattern) || PatternHelper.matchPattern(prefix + name, pattern)) {
-                    return true;
-                }
-            }
-            // we have include enabled and none matched so it should be false
-            return false;
-        }
-
-        return true;
-    }
-
-    private static boolean isComplexUserType(Class type) {
-        // lets consider all non java, as complex types
-        return type != null && !type.isPrimitive() && !type.getName().startsWith("java.");
-    }
-
-    protected boolean isValidAutowireClass(Class clazz) {
-        // skip all from Apache Camel and regular JDK as they would be default anyway
-        return !clazz.getName().startsWith("org.apache.camel");
-    }
-
-}
diff --git a/catalog/camel-main-maven-plugin/src/main/java/org/apache/camel/maven/SpringBootToolingMojo.java b/catalog/camel-main-maven-plugin/src/main/java/org/apache/camel/maven/SpringBootToolingMojo.java
deleted file mode 100644
index 9691afc..0000000
--- a/catalog/camel-main-maven-plugin/src/main/java/org/apache/camel/maven/SpringBootToolingMojo.java
+++ /dev/null
@@ -1,152 +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;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.camel.maven.model.SpringBootData;
-import org.apache.camel.util.IOHelper;
-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.apache.maven.plugins.annotations.ResolutionScope;
-
-import static org.apache.camel.util.StringHelper.camelCaseToDash;
-
-/**
- * Pre scans your project and builds spring boot tooling metafiles which fools tools to
- * offer code completion for editing properties files.
- */
-@Mojo(name = "spring-boot-tooling", defaultPhase = LifecyclePhase.PROCESS_CLASSES, threadSafe = true, requiresDependencyResolution = ResolutionScope.COMPILE)
-@Deprecated
-public class SpringBootToolingMojo extends AbstractMainMojo {
-
-    /**
-     * The output directory for generated spring boot tooling file
-     */
-    @Parameter(readonly = true, defaultValue = "${project.build.directory}/../src/main/resources/META-INF/")
-    protected File outFolder;
-
-    @Override
-    public void execute() throws MojoExecutionException, MojoFailureException {
-
-        final List<SpringBootData> componentData = new ArrayList<>();
-        ComponentCallback callback = (componentName, name, type, javaType, description, defaultValue) -> {
-            // we want to use dash in the name
-            String dash = camelCaseToDash(name);
-            String key = "camel.component." + componentName + "." + dash;
-            componentData.add(new SpringBootData(key, springBootJavaType(javaType), description, defaultValue));
-        };
-
-        // perform the work with this callback
-        doExecute(callback);
-
-        if (!componentData.isEmpty()) {
-            StringBuilder sb = new StringBuilder();
-
-            for (int i = 0; i < componentData.size(); i++) {
-                SpringBootData row = componentData.get(i);
-                sb.append("    {\n");
-                sb.append("      \"name\": \"" + row.getName() + "\",\n");
-                sb.append("      \"type\": \"" + row.getJavaType() + "\",\n");
-                sb.append("      \"description\": \"" + row.getDescription() + "\"");
-                if (row.getDefaultValue() != null) {
-                    sb.append(",\n");
-                    if (springBootDefaultValueQuotes(row.getJavaType())) {
-                        sb.append("      \"defaultValue\": \"" + row.getDefaultValue() + "\"\n");
-                    } else {
-                        sb.append("      \"defaultValue\": " + row.getDefaultValue() + "\n");
-                    }
-                } else {
-                    sb.append("\n");
-                }
-                if (i < componentData.size() - 1) {
-                    sb.append("    },\n");
-                } else {
-                    sb.append("    }\n");
-                }
-            }
-            sb.append("  ]\n");
-            sb.append("}\n");
-
-            // okay then add the components into the main json at the end so they get merged together
-            // load camel-main metadata
-            String mainJson = loadCamelMainConfigurationMetadata();
-            if (mainJson == null) {
-                getLog().warn("Cannot load camel-main-configuration-metadata.json from within the camel-main JAR from the classpath."
-                        + " Not possible to build spring boot configuration file for this project");
-                return;
-            }
-            int pos = mainJson.lastIndexOf("    }");
-            String newJson = mainJson.substring(0, pos);
-            newJson = newJson + "    },\n";
-            newJson = newJson + sb.toString();
-
-            outFolder.mkdirs();
-            File file = new File(outFolder, "spring-configuration-metadata.json");
-            try {
-                FileOutputStream fos = new FileOutputStream(file, false);
-                fos.write(newJson.getBytes());
-                IOHelper.close(fos);
-                getLog().info("Created file: " + file);
-            } catch (Throwable e) {
-                throw new MojoFailureException("Cannot write to file " + file + " due " + e.getMessage(), e);
-            }
-        }
-    }
-    
-    private static String springBootJavaType(String javaType) {
-        if ("boolean".equalsIgnoreCase(javaType)) {
-            return "java.lang.Boolean";
-        } else if ("int".equalsIgnoreCase(javaType)) {
-            return "java.lang.Integer";
-        } else if ("long".equalsIgnoreCase(javaType)) {
-            return "java.lang.Long";
-        } else if ("string".equalsIgnoreCase(javaType)) {
-            return "java.lang.String";
-        }
-        return javaType;
-    }
-
-    private static boolean springBootDefaultValueQuotes(String javaType) {
-        if ("java.lang.Boolean".equalsIgnoreCase(javaType)) {
-            return false;
-        } else if ("java.lang.Integer".equalsIgnoreCase(javaType)) {
-            return false;
-        } else if ("java.lang.Long".equalsIgnoreCase(javaType)) {
-            return false;
-        }
-        return true;
-    }
-
-    protected String loadCamelMainConfigurationMetadata() throws MojoFailureException {
-        try {
-            InputStream is = classLoader.getResourceAsStream("META-INF/camel-main-configuration-metadata.json");
-            String text = IOHelper.loadText(is);
-            IOHelper.close(is);
-            return text;
-        } catch (Throwable e) {
-            throw new MojoFailureException("Error during discovering camel-main from classpath due " + e.getMessage(), e);
-        }
-    }
-}