This is an automated email from the ASF dual-hosted git repository. gnodet pushed a commit to branch endpoint-dsl in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/endpoint-dsl by this push: new 44e35b2 Clean up code a bit 44e35b2 is described below commit 44e35b26eaa6492232c65d6abb2a6b6534bfcc49 Author: Guillaume Nodet <gno...@gmail.com> AuthorDate: Fri Jun 7 08:39:07 2019 +0200 Clean up code a bit --- .../camel/maven/packaging/DynamicClassLoader.java | 63 +++++++ .../camel/maven/packaging/EndpointDslMojo.java | 185 +++++++++------------ .../packaging/SpringBootAutoConfigurationMojo.java | 35 +--- 3 files changed, 140 insertions(+), 143 deletions(-) diff --git a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/DynamicClassLoader.java b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/DynamicClassLoader.java new file mode 100644 index 0000000..adf4330 --- /dev/null +++ b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/DynamicClassLoader.java @@ -0,0 +1,63 @@ +/* + * 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.packaging; + +import java.io.File; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.Iterator; +import java.util.List; + +import org.objectweb.asm.ClassWriter; +import org.objectweb.asm.Opcodes; + +class DynamicClassLoader extends URLClassLoader { + + public DynamicClassLoader(URL[] urls, ClassLoader parent) { + super(urls, parent); + } + + public static DynamicClassLoader createDynamicClassLoader(List<String> classpathElements) { + final URL[] urls = new URL[classpathElements.size()]; + int i = 0; + for (Iterator<?> it = classpathElements.iterator(); it.hasNext(); i++) { + try { + urls[i] = new File((String)it.next()).toURI().toURL(); + } catch (MalformedURLException e) { + throw new RuntimeException(e.getMessage(), e); + } + } + final ClassLoader tccl = Thread.currentThread().getContextClassLoader(); + return new DynamicClassLoader(urls, tccl != null ? tccl : DynamicClassLoader.class.getClassLoader()); + } + + public Class defineClass(String name, byte[] data) { + return super.defineClass(name, data, 0, data.length); + } + + public Class generateDummyClass(String clazzName) { + try { + return loadClass(clazzName); + } catch (ClassNotFoundException e) { + ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES); + cw.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC, clazzName.replace('.', '/'), null, "java/lang/Object", null); + cw.visitEnd(); + return defineClass(clazzName, cw.toByteArray()); + } + } +} diff --git a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/EndpointDslMojo.java b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/EndpointDslMojo.java index deec1dc..b412fe5 100644 --- a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/EndpointDslMojo.java +++ b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/EndpointDslMojo.java @@ -23,13 +23,8 @@ import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Array; import java.lang.reflect.Field; -import java.net.MalformedURLException; -import java.net.URL; -import java.net.URLClassLoader; import java.util.ArrayList; -import java.util.Arrays; import java.util.HashMap; -import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; @@ -49,12 +44,10 @@ import org.apache.camel.maven.packaging.srcgen.GenericType; import org.apache.camel.maven.packaging.srcgen.GenericType.BoundType; import org.apache.camel.maven.packaging.srcgen.JavaClass; import org.apache.camel.maven.packaging.srcgen.Method; -import org.apache.camel.maven.packaging.srcgen.Property; import org.apache.camel.spi.UriEndpoint; import org.apache.camel.spi.UriParam; import org.apache.camel.spi.UriParams; import org.apache.camel.spi.UriPath; -import org.apache.camel.spi.annotations.Component; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; @@ -64,9 +57,6 @@ import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.plugins.annotations.ResolutionScope; import org.apache.maven.project.MavenProject; import org.jboss.forge.roaster.model.util.Strings; -import org.objectweb.asm.ClassWriter; -import org.objectweb.asm.Opcodes; -import org.springframework.boot.liquibase.SpringPackageScanClassResolver; import static org.apache.camel.maven.packaging.AbstractGeneratorMojo.updateResource; import static org.apache.camel.maven.packaging.JSonSchemaHelper.getSafeValue; @@ -80,23 +70,21 @@ import static org.apache.camel.maven.packaging.PackageHelper.loadText; @Mojo(name = "generate-endpoint-dsl", threadSafe = true, requiresDependencyResolution = ResolutionScope.COMPILE_PLUS_RUNTIME, defaultPhase = LifecyclePhase.PROCESS_CLASSES) public class EndpointDslMojo extends AbstractMojo { - private static final Map<String, String> PRIMITIVEMAP; + private static final Map<String, Class<?>> PRIMITIVEMAP; static { PRIMITIVEMAP = new HashMap<>(); - PRIMITIVEMAP.put("boolean", "java.lang.Boolean"); - PRIMITIVEMAP.put("char", "java.lang.Character"); - PRIMITIVEMAP.put("long", "java.lang.Long"); - PRIMITIVEMAP.put("int", "java.lang.Integer"); - PRIMITIVEMAP.put("integer", "java.lang.Integer"); - PRIMITIVEMAP.put("byte", "java.lang.Byte"); - PRIMITIVEMAP.put("short", "java.lang.Short"); - PRIMITIVEMAP.put("double", "java.lang.Double"); - PRIMITIVEMAP.put("float", "java.lang.Float"); + PRIMITIVEMAP.put("boolean", java.lang.Boolean.class); + PRIMITIVEMAP.put("char", java.lang.Character.class); + PRIMITIVEMAP.put("long", java.lang.Long.class); + PRIMITIVEMAP.put("int", java.lang.Integer.class); + PRIMITIVEMAP.put("integer", java.lang.Integer.class); + PRIMITIVEMAP.put("byte", java.lang.Byte.class); + PRIMITIVEMAP.put("short", java.lang.Short.class); + PRIMITIVEMAP.put("double", java.lang.Double.class); + PRIMITIVEMAP.put("float", java.lang.Float.class); } - private static final String[] IGNORE_MODULES = {/* Non-standard -> */ }; - /** * The maven project. */ @@ -119,19 +107,14 @@ public class EndpointDslMojo extends AbstractMojo { @Override public void execute() throws MojoExecutionException, MojoFailureException { - // Do not generate code for ignored module - if (Arrays.asList(IGNORE_MODULES).contains(project.getArtifactId())) { - getLog().info("Component auto-configuration will not be created: component contained in the ignore list"); - return; + try { + projectClassLoader = DynamicClassLoader.createDynamicClassLoader(project.getTestClasspathElements()); + } catch (org.apache.maven.artifact.DependencyResolutionRequiredException e) { + throw new RuntimeException(e.getMessage(), e); } - executeAll(); - } - - private void executeAll() throws MojoExecutionException, MojoFailureException { Map<File, Supplier<String>> files = PackageHelper.findJsonFiles(buildDir, p -> p.isDirectory() || p.getName().endsWith(".json")).stream() - .collect(Collectors.toMap(Function.identity(), s -> cache(() -> loadJson(s)))); - + .collect(Collectors.toMap(Function.identity(), s -> cache(() -> loadJson(s)))); executeComponent(files); } @@ -146,7 +129,6 @@ public class EndpointDslMojo extends AbstractMojo { private static <T> Supplier<T> cache(Supplier<T> supplier) { return new Supplier<T>() { T value; - @Override public T get() { if (value == null) { @@ -179,11 +161,10 @@ public class EndpointDslMojo extends AbstractMojo { Map<String, List<ComponentModel>> grModels = allModels.stream().collect(Collectors.groupingBy(ComponentModel::getJavaType)); for (String componentClass : grModels.keySet()) { List<ComponentModel> compModels = grModels.get(componentClass); - ComponentModel model = compModels.get(0); // They should be - // equivalent + ComponentModel model = compModels.get(0); // They should be equivalent List<String> aliases = compModels.stream().map(ComponentModel::getScheme).sorted().collect(Collectors.toList()); - String pkg = "org.apache.camel.model.endpoint"; + String pkg = "org.apache.camel.model.endpoint"; String overrideComponentName = null; if (aliases.size() > 1) { @@ -197,31 +178,24 @@ public class EndpointDslMojo extends AbstractMojo { } private void createEndpointDsl(String packageName, ComponentModel model, String overrideComponentName) throws MojoFailureException { - int pos = model.getJavaType().lastIndexOf("."); - String name = model.getJavaType().substring(pos + 1); - name = name.replace("Component", "Endpoint"); - - if (model.getJavaType().equals("org.apache.camel.component.atmosphere.websocket.WebsocketComponent")) { - name = "AtmosphereWebsocketEndpoint"; - } else if (model.getJavaType().equals("org.apache.camel.component.zookeepermaster.MasterComponent")) { - name = "ZooKeeperMasterEndpoint"; - } - - Class<?> realComponentClass = loadClass(model.getJavaType()); - Class<?> realEndpointClass = findEndpointClass(realComponentClass); + String componentClassName = model.getJavaType(); + String endpointName = getEndpointName(componentClassName); + Class<?> realComponentClass = loadClass(componentClassName); + Class<?> realEndpointClass = loadClass(findEndpointClassName(componentClassName)); final JavaClass javaClass = new JavaClass(getProjectClassLoader()); javaClass.setPackage(packageName); - javaClass.setName(name); + javaClass.setName(endpointName); javaClass.addImport("org.apache.camel.model.EndpointDefinition"); Map<String, JavaClass> enumClasses = new HashMap<>(); + String commonName = endpointName.replace("Endpoint", "Common"); JavaClass commonClass = javaClass.addNestedType().setPublic().setStatic(true); - commonClass.setName(name.replace("Endpoint", "Common") + "<T extends EndpointDefinition>"); + commonClass.setName(commonName + "<T extends EndpointDefinition>"); commonClass.extendSuperType("EndpointDefinition<T>"); commonClass.addMethod().setConstructor(true) - .setName(name.replace("Endpoint", "Common")) + .setName(commonName) .addParameter(String.class, "path") .setBody("super(\"" + model.getScheme() + "\", path);"); generateDummyClass(commonClass.getCanonicalName()); @@ -230,12 +204,13 @@ public class EndpointDslMojo extends AbstractMojo { if (realEndpointClass.getAnnotation(UriEndpoint.class).producerOnly()) { consumerClass = null; } else { + String consumerName = endpointName.replace("Endpoint", "Consumer"); consumerClass = javaClass.addNestedType().setPublic().setStatic(true); - consumerClass.setName(name.replace("Endpoint", "Consumer")); - consumerClass.extendSuperType(name.replace("Endpoint", "Common") + "<" + name.replace("Endpoint", "Consumer") + ">"); + consumerClass.setName(consumerName); + consumerClass.extendSuperType(commonName + "<" + consumerName + ">"); consumerClass.implementInterface("EndpointDefinition.Consumer"); consumerClass.addMethod().setConstructor(true).setPublic() - .setName(name.replace("Endpoint", "Consumer")) + .setName(consumerName) .addParameter(String.class, "path") .setBody("super(path);"); generateDummyClass(consumerClass.getCanonicalName()); @@ -245,12 +220,13 @@ public class EndpointDslMojo extends AbstractMojo { if (realEndpointClass.getAnnotation(UriEndpoint.class).consumerOnly()) { producerClass = null; } else { + String producerName = endpointName.replace("Endpoint", "Producer"); producerClass = javaClass.addNestedType().setPublic().setStatic(true); - producerClass.setName(name.replace("Endpoint", "Producer")); - producerClass.extendSuperType(name.replace("Endpoint", "Common") + "<" + name.replace("Endpoint", "Producer") + ">"); + producerClass.setName(producerName); + producerClass.extendSuperType(commonName + "<" + producerName + ">"); producerClass.implementInterface("EndpointDefinition.Producer"); producerClass.addMethod().setConstructor(true).setPublic() - .setName(name.replace("Endpoint", "Producer")) + .setName(producerName) .addParameter(String.class, "path") .setBody("super(path);"); generateDummyClass(producerClass.getCanonicalName()); @@ -267,7 +243,6 @@ public class EndpointDslMojo extends AbstractMojo { javaClass.addAnnotation(Generated.class.getName()) .setStringValue("value", EndpointDslMojo.class.getName()); - boolean pathSet = false; for (EndpointOptionModel option : model.getEndpointOptions()) { JavaClass target = commonClass; @@ -278,6 +253,9 @@ public class EndpointDslMojo extends AbstractMojo { target = consumerClass; } } + if (target == null) { + throw new IllegalArgumentException("Illegal label " + option.getLabel() + " for option " + option.getName()); + } GenericType ogtype; GenericType gtype; @@ -294,7 +272,7 @@ public class EndpointDslMojo extends AbstractMojo { String fluentBuilderTypeShortName = target == commonClass ? "T" : target.getName(); Method fluent = target.addMethod().setPublic().setName(option.getName()) .setReturnType(new GenericType(loadClass(fluentBuilderTypeName)) ) - .addParameter(PRIMITIVEMAP.containsKey(ogtype.toString()) ? ogtype : gtype, option.getName()) + .addParameter(isPrimitive(ogtype.toString()) ? ogtype : gtype, option.getName()) .setBody("this.properties.put(\"" + option.getName() + "\", " + option.getName() + ");\n" + "return (" + fluentBuilderTypeShortName + ") this;\n"); if ("true".equals(option.getDeprecated())) { @@ -312,20 +290,41 @@ public class EndpointDslMojo extends AbstractMojo { javaClass.removeImport("T"); - String fileName = packageName.replaceAll("\\.", "\\/") + "/" + name + ".java"; + String fileName = packageName.replaceAll("\\.", "\\/") + "/" + endpointName + ".java"; writeSourceIfChanged(javaClass, fileName, false); } - private Class<?> findEndpointClass(Class<?> componentClass) { - String endpointName = componentClass.getCanonicalName().replaceFirst("Component", "Endpoint"); - if ("org.apache.camel.component.disruptor.vm.DisruptorVmEndpoint".equals(endpointName)) { - endpointName = "org.apache.camel.component.disruptor.DisruptorEndpoint"; - } else if ("org.apache.camel.component.etcd.EtcdEndpoint".equals(endpointName)) { - endpointName = "org.apache.camel.component.etcd.AbstractEtcdPollingEndpoint"; - } else if ("org.apache.camel.websocket.jsr356.JSR356WebSocketEndpoint".equals(endpointName)) { - endpointName = "org.apache.camel.websocket.jsr356.JSR356Endpoint"; + private String getEndpointName(String type) { + int pos = type.lastIndexOf("."); + String name = type.substring(pos + 1).replace("Component", "Endpoint"); + // + // HACKS + // + switch (type) { + case "org.apache.camel.component.atmosphere.websocket.WebsocketComponent": + return "AtmosphereWebsocketEndpoint"; + case "org.apache.camel.component.zookeepermaster.MasterComponent": + return "ZooKeeperMasterEndpoint"; + default: + return name; + } + } + + private String findEndpointClassName(String type) { + String endpointName = type.replaceFirst("Component", "Endpoint"); + // + // HACKS + // + switch (type) { + case "org.apache.camel.component.disruptor.vm.DisruptorVmComponent": + return "org.apache.camel.component.disruptor.DisruptorEndpoint"; + case "org.apache.camel.component.etcd.EtcdComponent": + return "org.apache.camel.component.etcd.AbstractEtcdPollingEndpoint"; + case "org.apache.camel.websocket.jsr356.JSR356WebSocketComponent": + return "org.apache.camel.websocket.jsr356.JSR356Endpoint"; + default: + return endpointName; } - return loadClass(endpointName); } private Field findField(Class<?> realComponentClass, Class<?> realEndpointClass, EndpointOptionModel option) throws NoSuchFieldException { @@ -417,7 +416,7 @@ public class EndpointDslMojo extends AbstractMojo { } // Primitive if (isPrimitive(type)) { - return new GenericType(loadClass(PRIMITIVEMAP.get(type))); + return new GenericType(PRIMITIVEMAP.get(type)); } // Extends if (type.startsWith("? extends ")) { @@ -498,48 +497,12 @@ public class EndpointDslMojo extends AbstractMojo { || type.matches("org\\.apache\\.camel\\.(spi\\.)?([A-Za-z]+)"); } - protected DynamicClassLoader getProjectClassLoader() { - if (projectClassLoader == null) { - final List<?> classpathElements; - try { - classpathElements = project.getTestClasspathElements(); - } catch (org.apache.maven.artifact.DependencyResolutionRequiredException e) { - throw new RuntimeException(e.getMessage(), e); - } - final URL[] urls = new URL[classpathElements.size()]; - int i = 0; - for (Iterator<?> it = classpathElements.iterator(); it.hasNext(); i++) { - try { - urls[i] = new File((String)it.next()).toURI().toURL(); - } catch (MalformedURLException e) { - throw new RuntimeException(e.getMessage(), e); - } - } - final ClassLoader tccl = Thread.currentThread().getContextClassLoader(); - projectClassLoader = new DynamicClassLoader(urls, tccl != null ? tccl : getClass().getClassLoader()); - } - return projectClassLoader; - } - - static class DynamicClassLoader extends URLClassLoader { - public DynamicClassLoader(URL[] urls, ClassLoader parent) { - super(urls, parent); - } - - public Class defineClass(String name, byte[] data) { - return super.defineClass(name, data, 0, data.length); - } + private Class generateDummyClass(String clazzName) { + return getProjectClassLoader().generateDummyClass(clazzName); } - private Class generateDummyClass(String clazzName) { - try { - return getProjectClassLoader().loadClass(clazzName); - } catch (ClassNotFoundException e) { - ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES); - cw.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC, clazzName.replace('.', '/'), null, "java/lang/Object", null); - cw.visitEnd(); - return getProjectClassLoader().defineClass(clazzName, cw.toByteArray()); - } + private DynamicClassLoader getProjectClassLoader() { + return projectClassLoader; } private static String loadComponentJson(Map<File, Supplier<String>> jsonFiles, String componentName) { @@ -645,7 +608,7 @@ public class EndpointDslMojo extends AbstractMojo { } private void writeSourceIfChanged(String source, String fileName) throws MojoFailureException { - File core = findCamelCoreDirectory(project.getBasedir()); + File core = findCamelCoreDirectory(baseDir); File target = new File(new File(core, "src/main/java"), fileName); diff --git a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/SpringBootAutoConfigurationMojo.java b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/SpringBootAutoConfigurationMojo.java index 8d25d38..5839057 100644 --- a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/SpringBootAutoConfigurationMojo.java +++ b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/SpringBootAutoConfigurationMojo.java @@ -23,9 +23,6 @@ import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Modifier; import java.lang.reflect.Type; -import java.net.MalformedURLException; -import java.net.URL; -import java.net.URLClassLoader; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; @@ -34,7 +31,6 @@ import java.util.Arrays; import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; -import java.util.Iterator; import java.util.LinkedHashSet; import java.util.LinkedList; import java.util.List; @@ -78,8 +74,6 @@ import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.plugins.annotations.ResolutionScope; import org.apache.maven.project.MavenProject; import org.jboss.forge.roaster.model.util.Strings; -import org.objectweb.asm.ClassWriter; -import org.objectweb.asm.Opcodes; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.config.ConfigurableBeanFactory; import org.springframework.boot.autoconfigure.AutoConfigureAfter; @@ -1092,23 +1086,13 @@ public class SpringBootAutoConfigurationMojo extends AbstractMojo { protected DynamicClassLoader getProjectClassLoader() { if (projectClassLoader == null) { - final List<?> classpathElements; + final List<String> classpathElements; try { classpathElements = project.getTestClasspathElements(); } catch (org.apache.maven.artifact.DependencyResolutionRequiredException e) { throw new RuntimeException(e.getMessage(), e); } - final URL[] urls = new URL[classpathElements.size()]; - int i = 0; - for (Iterator<?> it = classpathElements.iterator(); it.hasNext(); i++) { - try { - urls[i] = new File((String)it.next()).toURI().toURL(); - } catch (MalformedURLException e) { - throw new RuntimeException(e.getMessage(), e); - } - } - final ClassLoader tccl = Thread.currentThread().getContextClassLoader(); - projectClassLoader = new DynamicClassLoader(urls, tccl != null ? tccl : getClass().getClassLoader()); + projectClassLoader = DynamicClassLoader.createDynamicClassLoader(classpathElements); } return projectClassLoader; } @@ -1523,16 +1507,6 @@ public class SpringBootAutoConfigurationMojo extends AbstractMojo { writeSourceIfChanged(javaClass, fileName, true); } - static class DynamicClassLoader extends URLClassLoader { - public DynamicClassLoader(URL[] urls, ClassLoader parent) { - super(urls, parent); - } - - public Class defineClass(String name, byte[] data) { - return super.defineClass(name, data, 0, data.length); - } - } - private void createComponentAutoConfigurationSource(String packageName, ComponentModel model, List<String> componentAliases, String overrideComponentName) throws MojoFailureException { @@ -1604,10 +1578,7 @@ public class SpringBootAutoConfigurationMojo extends AbstractMojo { } private Class generateDummyClass(String clazzName) { - ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES); - cw.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC, clazzName.replace('.', '/'), null, "java/lang/Object", null); - cw.visitEnd(); - return getProjectClassLoader().defineClass(clazzName, cw.toByteArray()); + return getProjectClassLoader().generateDummyClass(clazzName); } private void createDataFormatAutoConfigurationSource(String packageName, DataFormatModel model, List<String> dataFormatAliases, String overrideDataFormatName)