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/03/14 06:53:23 UTC
[camel] 01/06: CAMEL-13313: Add support for generating type
converter loader source code to be able to load component type converters
in a faster way.
This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a commit to branch tc-loader
in repository https://gitbox.apache.org/repos/asf/camel.git
commit 9cf5e63f3aba656a2956f891f95a38ec49d0c473
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Thu Mar 14 05:44:45 2019 +0100
CAMEL-13313: Add support for generating type converter loader source code to be able to load component type converters in a faster way.
---
...nverter.java => InjectedTestTypeConverter.java} | 84 ++++++++--------
.../InjectedTypeConverterMultipleContextsTest.java | 4 +-
.../camel/cdi/test/InjectedTypeConverterTest.java | 4 +-
.../src/main/java/org/apache/camel/Converter.java | 8 ++
.../java/org/apache/camel/FallbackConverter.java | 9 ++
.../impl/converter/BaseTypeConverterRegistry.java | 1 +
.../java/org/apache/camel/util}/DoubleMap.java | 2 +-
.../camel/tools/apt/AnnotationProcessorHelper.java | 4 +-
...essor.java => ComponentConverterProcessor.java} | 110 ++++++++++++++++-----
...rProcessor.java => CoreConverterProcessor.java} | 3 +-
.../services/javax.annotation.processing.Processor | 6 +-
11 files changed, 161 insertions(+), 74 deletions(-)
diff --git a/components/camel-cdi/src/test/java/org/apache/camel/cdi/converter/InjectedTypeConverter.java b/components/camel-cdi/src/test/java/org/apache/camel/cdi/converter/InjectedTestTypeConverter.java
similarity index 91%
rename from components/camel-cdi/src/test/java/org/apache/camel/cdi/converter/InjectedTypeConverter.java
rename to components/camel-cdi/src/test/java/org/apache/camel/cdi/converter/InjectedTestTypeConverter.java
index ef0b245..2e7fc75 100644
--- a/components/camel-cdi/src/test/java/org/apache/camel/cdi/converter/InjectedTypeConverter.java
+++ b/components/camel-cdi/src/test/java/org/apache/camel/cdi/converter/InjectedTestTypeConverter.java
@@ -1,42 +1,42 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.camel.cdi.converter;
-
-import javax.inject.Inject;
-
-import org.apache.camel.CamelContext;
-import org.apache.camel.Converter;
-import org.apache.camel.cdi.pojo.TypeConverterInput;
-import org.apache.camel.cdi.pojo.TypeConverterOutput;
-
-@Converter
-public final class InjectedTypeConverter {
-
- private final CamelContext context;
-
- @Inject
- InjectedTypeConverter(CamelContext context) {
- this.context = context;
- }
-
- @Converter
- public TypeConverterOutput convert(TypeConverterInput input) throws Exception {
- TypeConverterOutput output = new TypeConverterOutput();
- output.setProperty(context.resolvePropertyPlaceholders(input.getProperty()));
- return output;
- }
-}
+/**
+ * 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.cdi.converter;
+
+import javax.inject.Inject;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.Converter;
+import org.apache.camel.cdi.pojo.TypeConverterInput;
+import org.apache.camel.cdi.pojo.TypeConverterOutput;
+
+@Converter
+public final class InjectedTestTypeConverter {
+
+ private final CamelContext context;
+
+ @Inject
+ InjectedTestTypeConverter(CamelContext context) {
+ this.context = context;
+ }
+
+ @Converter
+ public TypeConverterOutput convert(TypeConverterInput input) throws Exception {
+ TypeConverterOutput output = new TypeConverterOutput();
+ output.setProperty(context.resolvePropertyPlaceholders(input.getProperty()));
+ return output;
+ }
+}
diff --git a/components/camel-cdi/src/test/java/org/apache/camel/cdi/test/InjectedTypeConverterMultipleContextsTest.java b/components/camel-cdi/src/test/java/org/apache/camel/cdi/test/InjectedTypeConverterMultipleContextsTest.java
index ccd5796..4f65e73 100644
--- a/components/camel-cdi/src/test/java/org/apache/camel/cdi/test/InjectedTypeConverterMultipleContextsTest.java
+++ b/components/camel-cdi/src/test/java/org/apache/camel/cdi/test/InjectedTypeConverterMultipleContextsTest.java
@@ -59,7 +59,7 @@ public class InjectedTypeConverterMultipleContextsTest {
.addClass(FirstCamelContextConvertingRoute.class)
.addClass(SecondCamelContextConvertingRoute.class)
// Type converter
- .addClass(InjectedTypeConverter.class)
+ .addClass(InjectedTestTypeConverter.class)
// No need as Camel CDI automatically registers the type converter bean
//.addAsManifestResource(new StringAsset("org.apache.camel.cdi.se.converter"), ArchivePaths.create("services/org/apache/camel/TypeConverter"))
// Bean archive deployment descriptor
@@ -107,7 +107,7 @@ public class InjectedTypeConverterMultipleContextsTest {
}
@Converter
- public static final class InjectedTypeConverter {
+ public static final class InjectedTestTypeConverter {
@Converter
public TypeConverterOutput convert(TypeConverterInput input) throws Exception {
TypeConverterOutput output = new TypeConverterOutput();
diff --git a/components/camel-cdi/src/test/java/org/apache/camel/cdi/test/InjectedTypeConverterTest.java b/components/camel-cdi/src/test/java/org/apache/camel/cdi/test/InjectedTypeConverterTest.java
index 6e43984..4f9342f 100644
--- a/components/camel-cdi/src/test/java/org/apache/camel/cdi/test/InjectedTypeConverterTest.java
+++ b/components/camel-cdi/src/test/java/org/apache/camel/cdi/test/InjectedTypeConverterTest.java
@@ -28,7 +28,7 @@ import org.apache.camel.TypeConverter;
import org.apache.camel.cdi.CdiCamelExtension;
import org.apache.camel.cdi.Uri;
import org.apache.camel.cdi.bean.InjectedTypeConverterRoute;
-import org.apache.camel.cdi.converter.InjectedTypeConverter;
+import org.apache.camel.cdi.converter.InjectedTestTypeConverter;
import org.apache.camel.cdi.pojo.TypeConverterInput;
import org.apache.camel.cdi.pojo.TypeConverterOutput;
import org.apache.camel.component.mock.MockEndpoint;
@@ -58,7 +58,7 @@ public class InjectedTypeConverterTest {
// Test class
.addClass(InjectedTypeConverterRoute.class)
// Type converter
- .addClass(InjectedTypeConverter.class)
+ .addClass(InjectedTestTypeConverter.class)
// No need as Camel CDI automatically registers the type converter bean
//.addAsManifestResource(new StringAsset("org.apache.camel.cdi.se.converter"), ArchivePaths.create("services/org/apache/camel/TypeConverter"))
// Bean archive deployment descriptor
diff --git a/core/camel-api/src/main/java/org/apache/camel/Converter.java b/core/camel-api/src/main/java/org/apache/camel/Converter.java
index 79b2234..9f08426 100644
--- a/core/camel-api/src/main/java/org/apache/camel/Converter.java
+++ b/core/camel-api/src/main/java/org/apache/camel/Converter.java
@@ -50,4 +50,12 @@ public @interface Converter {
* Important this configuration must be set on the class-level, not on the method.
*/
boolean ignoreOnLoadError() default false;
+
+ /**
+ * Whether to let the Camel compiler plugin to generate java source code
+ * for fast loading of the type converters.
+ *
+ * This option should only be configured on the top-level class.
+ */
+ boolean loader() default false;
}
diff --git a/core/camel-api/src/main/java/org/apache/camel/FallbackConverter.java b/core/camel-api/src/main/java/org/apache/camel/FallbackConverter.java
index f3e4dae..6b3f4e7 100644
--- a/core/camel-api/src/main/java/org/apache/camel/FallbackConverter.java
+++ b/core/camel-api/src/main/java/org/apache/camel/FallbackConverter.java
@@ -51,4 +51,13 @@ public @interface FallbackConverter {
*/
boolean canPromote() default false;
+ /**
+ * Whether to let the Camel compiler plugin to generate java source code
+ * for fast loading of the type converters.
+ *
+ * This option should only be configured on the top-level class.
+ */
+ boolean loader() default false;
+
+
}
\ No newline at end of file
diff --git a/core/camel-base/src/main/java/org/apache/camel/impl/converter/BaseTypeConverterRegistry.java b/core/camel-base/src/main/java/org/apache/camel/impl/converter/BaseTypeConverterRegistry.java
index 5a808b1..6380da8 100644
--- a/core/camel-base/src/main/java/org/apache/camel/impl/converter/BaseTypeConverterRegistry.java
+++ b/core/camel-base/src/main/java/org/apache/camel/impl/converter/BaseTypeConverterRegistry.java
@@ -48,6 +48,7 @@ import org.apache.camel.spi.TypeConverterRegistry;
import org.apache.camel.support.MessageHelper;
import org.apache.camel.support.TypeConverterSupport;
import org.apache.camel.support.service.ServiceSupport;
+import org.apache.camel.util.DoubleMap;
import org.apache.camel.util.ObjectHelper;
/**
diff --git a/core/camel-base/src/main/java/org/apache/camel/impl/converter/DoubleMap.java b/core/camel-util/src/main/java/org/apache/camel/util/DoubleMap.java
similarity index 99%
rename from core/camel-base/src/main/java/org/apache/camel/impl/converter/DoubleMap.java
rename to core/camel-util/src/main/java/org/apache/camel/util/DoubleMap.java
index abeb236..9a8ff70 100644
--- a/core/camel-base/src/main/java/org/apache/camel/impl/converter/DoubleMap.java
+++ b/core/camel-util/src/main/java/org/apache/camel/util/DoubleMap.java
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.camel.impl.converter;
+package org.apache.camel.util;
import java.util.function.Predicate;
diff --git a/tooling/apt/src/main/java/org/apache/camel/tools/apt/AnnotationProcessorHelper.java b/tooling/apt/src/main/java/org/apache/camel/tools/apt/AnnotationProcessorHelper.java
index 66e4e86..09fd766 100644
--- a/tooling/apt/src/main/java/org/apache/camel/tools/apt/AnnotationProcessorHelper.java
+++ b/tooling/apt/src/main/java/org/apache/camel/tools/apt/AnnotationProcessorHelper.java
@@ -23,7 +23,9 @@ import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.nio.file.Files;
+import java.nio.file.OpenOption;
import java.nio.file.Paths;
+import java.nio.file.StandardOpenOption;
import java.util.Collections;
import java.util.List;
import java.util.Set;
@@ -379,7 +381,7 @@ public final class AnnotationProcessorHelper {
}
public static void dumpExceptionToErrorFile(String fileName, String message, Throwable e) {
- try (BufferedWriter w = Files.newBufferedWriter(Paths.get(fileName))) {
+ try (BufferedWriter w = Files.newBufferedWriter(Paths.get(fileName), StandardOpenOption.CREATE, StandardOpenOption.APPEND)) {
w.append(message);
w.append("\n\n");
PrintWriter pw = new PrintWriter(w);
diff --git a/tooling/apt/src/main/java/org/apache/camel/tools/apt/ConverterProcessor.java b/tooling/apt/src/main/java/org/apache/camel/tools/apt/ComponentConverterProcessor.java
similarity index 76%
copy from tooling/apt/src/main/java/org/apache/camel/tools/apt/ConverterProcessor.java
copy to tooling/apt/src/main/java/org/apache/camel/tools/apt/ComponentConverterProcessor.java
index 08e3322..19c9790 100644
--- a/tooling/apt/src/main/java/org/apache/camel/tools/apt/ConverterProcessor.java
+++ b/tooling/apt/src/main/java/org/apache/camel/tools/apt/ComponentConverterProcessor.java
@@ -24,7 +24,6 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
-
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.lang.model.element.AnnotationMirror;
@@ -39,27 +38,60 @@ import javax.tools.Diagnostic;
import javax.tools.JavaFileObject;
@SupportedAnnotationTypes({"org.apache.camel.Converter"})
-public class ConverterProcessor extends AbstractCamelAnnotationProcessor {
+public class ComponentConverterProcessor extends AbstractCamelAnnotationProcessor {
- @Override
- protected void doProcess(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) throws Exception {
- if (this.processingEnv.getElementUtils().getTypeElement("org.apache.camel.impl.converter.CoreStaticTypeConverterLoader") != null) {
- return;
+ private static final class ClassConverters {
+
+ private final Map<String, Map<TypeMirror, ExecutableElement>> converters = new TreeMap<>();
+ private final Comparator<TypeMirror> comparator;
+ private final List<ExecutableElement> fallbackConverters = new ArrayList<>();
+
+ ClassConverters(Comparator<TypeMirror> comparator) {
+ this.comparator = comparator;
+ }
+
+ void addTypeConverter(TypeMirror to, TypeMirror from, ExecutableElement ee) {
+ converters.computeIfAbsent(toString(to), c -> new TreeMap<>(comparator)).put(from, ee);
+ }
+
+ void addFallbackTypeConverter(ExecutableElement ee) {
+ fallbackConverters.add(ee);
+ }
+
+ Map<String, Map<TypeMirror, ExecutableElement>> getConverters() {
+ return converters;
+ }
+
+ List<ExecutableElement> getFallbackConverters() {
+ return fallbackConverters;
}
- // We're in tests, do not generate anything
- if (this.processingEnv.getElementUtils().getTypeElement("org.apache.camel.converter.ObjectConverter") == null) {
- return;
+ private static String toString(TypeMirror type) {
+ return type.toString().replaceAll("<.*>", "");
}
+ }
+
+ @Override
+ protected void doProcess(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) throws Exception {
+ Map<String, ClassConverters> converters = new TreeMap<>();
+
Comparator<TypeMirror> comparator = (o1, o2) -> processingEnv.getTypeUtils().isAssignable(o1, o2)
? -1 : processingEnv.getTypeUtils().isAssignable(o2, o1) ? +1 : o1.toString().compareTo(o2.toString());
- Map<String, Map<TypeMirror, ExecutableElement>> converters = new TreeMap<>();
TypeElement converterAnnotationType = this.processingEnv.getElementUtils().getTypeElement("org.apache.camel.Converter");
+ // the current class with type converters
+ String currentClass = null;
for (Element element : roundEnv.getElementsAnnotatedWith(converterAnnotationType)) {
- if (element.getKind() == ElementKind.METHOD) {
- ExecutableElement ee = (ExecutableElement)element;
+ // we need a top level class first
+ if (element.getKind() == ElementKind.CLASS) {
+ TypeElement te = (TypeElement) element;
+ if (!te.getNestingKind().isNested() && isLoaderEnabled(te)) {
+ // we only accept top-level classes and if loader is enabled
+ currentClass = te.getQualifiedName().toString();
+ }
+ } else if (currentClass != null && element.getKind() == ElementKind.METHOD) {
+ ExecutableElement ee = (ExecutableElement) element;
TypeMirror to = ee.getReturnType();
TypeMirror from = ee.getParameters().get(0).asType();
String fromStr = toString(from);
@@ -70,22 +102,53 @@ public class ConverterProcessor extends AbstractCamelAnnotationProcessor {
} else {
processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, "Could not retrieve type element for " + fromStr);
}
-
}
- converters.computeIfAbsent(toString(to), c -> new TreeMap<>(comparator)).put(from, ee);
+ converters.computeIfAbsent(currentClass, c -> new ClassConverters(comparator)).addTypeConverter(to, from, ee);
}
}
+
TypeElement fallbackAnnotationType = this.processingEnv.getElementUtils().getTypeElement("org.apache.camel.FallbackConverter");
- List<ExecutableElement> fallbackConverters = new ArrayList<>();
+ currentClass = null;
for (Element element : roundEnv.getElementsAnnotatedWith(fallbackAnnotationType)) {
- if (element.getKind() == ElementKind.METHOD) {
- ExecutableElement ee = (ExecutableElement)element;
- fallbackConverters.add(ee);
+ if (element.getKind() == ElementKind.CLASS) {
+ TypeElement te = (TypeElement) element;
+ if (!te.getNestingKind().isNested() && isLoaderEnabled(te)) {
+ // we only accept top-level classes and if loader is enabled
+ currentClass = te.getQualifiedName().toString();
+ }
+ } else if (currentClass != null && element.getKind() == ElementKind.METHOD) {
+ ExecutableElement ee = (ExecutableElement) element;
+ converters.computeIfAbsent(currentClass, c -> new ClassConverters(comparator)).addFallbackTypeConverter(ee);
+ }
+ }
+
+ // now write all the converters
+ for (Map.Entry<String, ClassConverters> entry : converters.entrySet()) {
+ String key = entry.getKey();
+ ClassConverters value = entry.getValue();
+ writeConverterLoader(key, value, converterAnnotationType, fallbackAnnotationType);
+ }
+ }
+
+ private static boolean isLoaderEnabled(Element element) {
+ for (AnnotationMirror ann : element.getAnnotationMirrors()) {
+ for (Map.Entry<? extends ExecutableElement, ? extends AnnotationValue> entry : ann.getElementValues().entrySet()) {
+ if ("loader".equals(entry.getKey().getSimpleName().toString())) {
+ return (Boolean) entry.getValue().getValue();
+ }
}
}
+ return false;
+ }
+
+ private void writeConverterLoader(String fqn, ClassConverters converters,
+ TypeElement converterAnnotationType,
+ TypeElement fallbackAnnotationType) throws Exception {
+
+ int pos = fqn.lastIndexOf('.');
+ String p = fqn.substring(0, pos);
+ String c = fqn.substring(pos + 1) + "Loader";
- String p = "org.apache.camel.impl.converter";
- String c = "CoreStaticTypeConverterLoader";
JavaFileObject jfo = processingEnv.getFiler().createSourceFile(p + "." + c);
Set<String> converterClasses = new LinkedHashSet<>();
try (Writer writer = jfo.openWriter()) {
@@ -98,11 +161,12 @@ public class ConverterProcessor extends AbstractCamelAnnotationProcessor {
writer.append("import org.apache.camel.spi.TypeConverterLoader;\n");
writer.append("import org.apache.camel.spi.TypeConverterRegistry;\n");
writer.append("import org.apache.camel.support.TypeConverterSupport;\n");
+ writer.append("import org.apache.camel.util.DoubleMap;\n");
writer.append("\n");
writer.append("@SuppressWarnings(\"unchecked\")\n");
writer.append("public class ").append(c).append(" implements TypeConverterLoader {\n");
writer.append("\n");
- writer.append(" public static final CoreStaticTypeConverterLoader INSTANCE = new CoreStaticTypeConverterLoader();\n");
+ writer.append(" public static final ").append(c).append(" INSTANCE = new ").append(c).append("();\n");
writer.append("\n");
writer.append(" static abstract class SimpleTypeConverter extends TypeConverterSupport {\n");
writer.append(" private final boolean allowNull;\n");
@@ -133,7 +197,7 @@ public class ConverterProcessor extends AbstractCamelAnnotationProcessor {
writer.append("\n");
writer.append(" private ").append(c).append("() {\n");
- for (Map.Entry<String, Map<TypeMirror, ExecutableElement>> to : converters.entrySet()) {
+ for (Map.Entry<String, Map<TypeMirror, ExecutableElement>> to : converters.getConverters().entrySet()) {
for (Map.Entry<TypeMirror, ExecutableElement> from : to.getValue().entrySet()) {
boolean allowNull = false;
for (AnnotationMirror ann : from.getValue().getAnnotationMirrors()) {
@@ -163,7 +227,7 @@ public class ConverterProcessor extends AbstractCamelAnnotationProcessor {
writer.append(" @Override\n");
writer.append(" public void load(TypeConverterRegistry registry) throws TypeConverterLoaderException {\n");
writer.append(" converters.forEach((k, v, c) -> registry.addTypeConverter(k, v, c));\n");
- for (ExecutableElement ee : fallbackConverters) {
+ for (ExecutableElement ee : converters.getFallbackConverters()) {
boolean allowNull = false;
boolean canPromote = false;
for (AnnotationMirror ann : ee.getAnnotationMirrors()) {
diff --git a/tooling/apt/src/main/java/org/apache/camel/tools/apt/ConverterProcessor.java b/tooling/apt/src/main/java/org/apache/camel/tools/apt/CoreConverterProcessor.java
similarity index 98%
rename from tooling/apt/src/main/java/org/apache/camel/tools/apt/ConverterProcessor.java
rename to tooling/apt/src/main/java/org/apache/camel/tools/apt/CoreConverterProcessor.java
index 08e3322..dfa0c29 100644
--- a/tooling/apt/src/main/java/org/apache/camel/tools/apt/ConverterProcessor.java
+++ b/tooling/apt/src/main/java/org/apache/camel/tools/apt/CoreConverterProcessor.java
@@ -39,7 +39,7 @@ import javax.tools.Diagnostic;
import javax.tools.JavaFileObject;
@SupportedAnnotationTypes({"org.apache.camel.Converter"})
-public class ConverterProcessor extends AbstractCamelAnnotationProcessor {
+public class CoreConverterProcessor extends AbstractCamelAnnotationProcessor {
@Override
protected void doProcess(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) throws Exception {
@@ -98,6 +98,7 @@ public class ConverterProcessor extends AbstractCamelAnnotationProcessor {
writer.append("import org.apache.camel.spi.TypeConverterLoader;\n");
writer.append("import org.apache.camel.spi.TypeConverterRegistry;\n");
writer.append("import org.apache.camel.support.TypeConverterSupport;\n");
+ writer.append("import org.apache.camel.util.DoubleMap;\n");
writer.append("\n");
writer.append("@SuppressWarnings(\"unchecked\")\n");
writer.append("public class ").append(c).append(" implements TypeConverterLoader {\n");
diff --git a/tooling/apt/src/main/resources/META-INF/services/javax.annotation.processing.Processor b/tooling/apt/src/main/resources/META-INF/services/javax.annotation.processing.Processor
index 264838a..790ceb0 100644
--- a/tooling/apt/src/main/resources/META-INF/services/javax.annotation.processing.Processor
+++ b/tooling/apt/src/main/resources/META-INF/services/javax.annotation.processing.Processor
@@ -18,6 +18,8 @@
### only specify ModelAnnotationProcessor as it delegates to CoreEip or Spring accordingly
org.apache.camel.tools.apt.ModelAnnotationProcessor
org.apache.camel.tools.apt.EndpointAnnotationProcessor
-org.apache.camel.tools.apt.ConverterProcessor
-org.apache.camel.tools.apt.TypeConverterProcessor
org.apache.camel.tools.apt.SpiProcessor
+org.apache.camel.tools.apt.TypeConverterProcessor
+org.apache.camel.tools.apt.CoreConverterProcessor
+org.apache.camel.tools.apt.ComponentConverterProcessor
+