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

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

commit 354d210e9b126887919d259c44bc6ed42925d73e
Author: lburgazzoli <lburgazz...@gmail.com>
AuthorDate: Fri Jun 19 15:05:27 2020 +0200

    Re-apply commit 9f425b3d14e1831f06cbe246110de670fef9cd3b
---
 .../quarkus/core/deployment/CamelProcessor.java    | 342 +++++++++++++++++++++
 1 file changed, 342 insertions(+)

diff --git 
a/extensions-core/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/CamelProcessor.java
 
b/extensions-core/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/CamelProcessor.java
new file mode 100644
index 0000000..db563f5
--- /dev/null
+++ 
b/extensions-core/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/CamelProcessor.java
@@ -0,0 +1,342 @@
+/*
+ * 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.quarkus.core.deployment;
+
+import java.io.IOException;
+import java.lang.reflect.Modifier;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import io.quarkus.arc.deployment.AdditionalBeanBuildItem;
+import io.quarkus.arc.deployment.BeanRegistrationPhaseBuildItem;
+import io.quarkus.arc.deployment.UnremovableBeanBuildItem;
+import io.quarkus.arc.processor.BuildExtension;
+import io.quarkus.deployment.ApplicationArchive;
+import io.quarkus.deployment.Capabilities;
+import io.quarkus.deployment.annotations.BuildProducer;
+import io.quarkus.deployment.annotations.BuildStep;
+import io.quarkus.deployment.annotations.ExecutionTime;
+import io.quarkus.deployment.annotations.Overridable;
+import io.quarkus.deployment.annotations.Record;
+import io.quarkus.deployment.builditem.ApplicationArchivesBuildItem;
+import io.quarkus.deployment.builditem.CombinedIndexBuildItem;
+import io.quarkus.deployment.recording.RecorderContext;
+import io.quarkus.runtime.RuntimeValue;
+import org.apache.camel.impl.converter.BaseTypeConverterRegistry;
+import org.apache.camel.quarkus.core.CamelConfig;
+import org.apache.camel.quarkus.core.CamelConfigFlags;
+import org.apache.camel.quarkus.core.CamelProducers;
+import org.apache.camel.quarkus.core.CamelRecorder;
+import org.apache.camel.quarkus.core.FastFactoryFinderResolver.Builder;
+import 
org.apache.camel.quarkus.core.deployment.spi.CamelFactoryFinderResolverBuildItem;
+import 
org.apache.camel.quarkus.core.deployment.spi.CamelModelJAXBContextFactoryBuildItem;
+import 
org.apache.camel.quarkus.core.deployment.spi.CamelModelToXMLDumperBuildItem;
+import 
org.apache.camel.quarkus.core.deployment.spi.CamelRoutesBuilderClassBuildItem;
+import 
org.apache.camel.quarkus.core.deployment.spi.CamelRoutesLoaderBuildItems;
+import org.apache.camel.quarkus.core.deployment.spi.CamelServiceBuildItem;
+import org.apache.camel.quarkus.core.deployment.spi.CamelServiceDestination;
+import org.apache.camel.quarkus.core.deployment.spi.CamelServiceFilter;
+import 
org.apache.camel.quarkus.core.deployment.spi.CamelServiceFilterBuildItem;
+import 
org.apache.camel.quarkus.core.deployment.spi.CamelServicePatternBuildItem;
+import 
org.apache.camel.quarkus.core.deployment.spi.CamelTypeConverterLoaderBuildItem;
+import 
org.apache.camel.quarkus.core.deployment.spi.CamelTypeConverterRegistryBuildItem;
+import org.apache.camel.quarkus.core.deployment.spi.ContainerBeansBuildItem;
+import org.apache.camel.quarkus.core.deployment.util.CamelSupport;
+import org.apache.camel.quarkus.core.deployment.util.PathFilter;
+import org.apache.camel.quarkus.support.common.CamelCapabilities;
+import org.apache.camel.spi.TypeConverterLoader;
+import org.apache.camel.spi.TypeConverterRegistry;
+import org.jboss.jandex.ClassInfo;
+import org.jboss.jandex.DotName;
+import org.jboss.jandex.IndexView;
+import org.jboss.jandex.Type;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+class CamelProcessor {
+    private static final Logger LOGGER = 
LoggerFactory.getLogger(CamelProcessor.class);
+
+    private static final DotName ROUTES_BUILDER_TYPE = DotName.createSimple(
+            "org.apache.camel.RoutesBuilder");
+    private static final DotName ROUTE_BUILDER_TYPE = DotName.createSimple(
+            "org.apache.camel.builder.RouteBuilder");
+    private static final DotName ADVICE_WITH_ROUTE_BUILDER_TYPE = 
DotName.createSimple(
+            "org.apache.camel.builder.AdviceWithRouteBuilder");
+    private static final DotName DATA_FORMAT_TYPE = DotName.createSimple(
+            "org.apache.camel.spi.DataFormat");
+    private static final DotName LANGUAGE_TYPE = DotName.createSimple(
+            "org.apache.camel.spi.Language");
+    private static final DotName COMPONENT_TYPE = DotName.createSimple(
+            "org.apache.camel.Component");
+    private static final DotName PRODUCER_TYPE = DotName.createSimple(
+            "org.apache.camel.Producer");
+    private static final DotName PREDICATE_TYPE = DotName.createSimple(
+            "org.apache.camel.Predicate");
+
+    private static final Set<DotName> UNREMOVABLE_BEANS_TYPES = 
CamelSupport.setOf(
+            ROUTES_BUILDER_TYPE,
+            DATA_FORMAT_TYPE,
+            LANGUAGE_TYPE,
+            COMPONENT_TYPE,
+            PRODUCER_TYPE,
+            PREDICATE_TYPE);
+
+    @BuildStep
+    BeanRegistrationPhaseBuildItem.BeanConfiguratorBuildItem containerBeans(
+            BeanRegistrationPhaseBuildItem beanRegistrationPhase,
+            BuildProducer<ContainerBeansBuildItem> containerBeans) {
+
+        containerBeans.produce(
+                new 
ContainerBeansBuildItem(beanRegistrationPhase.getContext().get(BuildExtension.Key.BEANS)));
+
+        // method using BeanRegistrationPhaseBuildItem should return a 
BeanConfiguratorBuildItem
+        // otherwise the build step may be processed at the wrong time.
+        return new BeanRegistrationPhaseBuildItem.BeanConfiguratorBuildItem();
+    }
+
+    /*
+     * Configure filters for core services.
+     */
+    @BuildStep
+    void coreServiceFilter(BuildProducer<CamelServiceFilterBuildItem> 
filterBuildItems) {
+        filterBuildItems.produce(
+                new 
CamelServiceFilterBuildItem(CamelServiceFilter.forService("properties-component-factory")));
+
+        // The reactive executor is programmatically configured by an 
extension or
+        // a default implementation is provided by this processor thus we can 
safely
+        // prevent loading of this service.
+        filterBuildItems.produce(
+                new 
CamelServiceFilterBuildItem(CamelServiceFilter.forService("reactive-executor")));
+    }
+
+    @BuildStep
+    void coreServicePatterns(BuildProducer<CamelServicePatternBuildItem> 
services) {
+        services.produce(new CamelServicePatternBuildItem(
+                CamelServiceDestination.REGISTRY,
+                true,
+                "META-INF/services/org/apache/camel/component/*",
+                "META-INF/services/org/apache/camel/language/constant",
+                "META-INF/services/org/apache/camel/language/file",
+                "META-INF/services/org/apache/camel/language/header",
+                "META-INF/services/org/apache/camel/language/ref",
+                "META-INF/services/org/apache/camel/language/simple"));
+
+        services.produce(new CamelServicePatternBuildItem(
+                CamelServiceDestination.DISCOVERY,
+                true,
+                "META-INF/services/org/apache/camel/*",
+                "META-INF/services/org/apache/camel/management/*",
+                "META-INF/services/org/apache/camel/model/*",
+                "META-INF/services/org/apache/camel/configurer/*",
+                "META-INF/services/org/apache/camel/language/*",
+                "META-INF/services/org/apache/camel/dataformat/*",
+                "META-INF/services/org/apache/camel/send-dynamic/*"));
+
+        services.produce(new CamelServicePatternBuildItem(
+                CamelServiceDestination.DISCOVERY,
+                false,
+                "META-INF/services/org/apache/camel/configurer/avro-component",
+                
"META-INF/services/org/apache/camel/configurer/avro-endpoint"));
+    }
+
+    @BuildStep
+    void userServicePatterns(
+            CamelConfig camelConfig,
+            BuildProducer<CamelServicePatternBuildItem> services) {
+
+        camelConfig.service.discovery.includePatterns.ifPresent(list -> 
services.produce(new CamelServicePatternBuildItem(
+                CamelServiceDestination.DISCOVERY,
+                true,
+                list)));
+
+        camelConfig.service.discovery.excludePatterns.ifPresent(list -> 
services.produce(new CamelServicePatternBuildItem(
+                CamelServiceDestination.DISCOVERY,
+                false,
+                list)));
+
+        camelConfig.service.registry.includePatterns.ifPresent(list -> 
services.produce(new CamelServicePatternBuildItem(
+                CamelServiceDestination.REGISTRY,
+                true,
+                list)));
+
+        camelConfig.service.registry.excludePatterns.ifPresent(list -> 
services.produce(new CamelServicePatternBuildItem(
+                CamelServiceDestination.REGISTRY,
+                false,
+                list)));
+    }
+
+    @BuildStep
+    void camelServices(
+            ApplicationArchivesBuildItem applicationArchives,
+            List<CamelServicePatternBuildItem> servicePatterns,
+            BuildProducer<CamelServiceBuildItem> camelServices) {
+
+        final PathFilter pathFilter = servicePatterns.stream()
+                .filter(patterns -> patterns.getDestination() == 
CamelServiceDestination.DISCOVERY)
+                .collect(
+                        PathFilter.Builder::new,
+                        (builder, patterns) -> 
builder.patterns(patterns.isInclude(), patterns.getPatterns()),
+                        PathFilter.Builder::combine)
+                .build();
+        CamelSupport.services(applicationArchives, pathFilter)
+                .forEach(camelServices::produce);
+    }
+
+    /*
+     * Discover {@link TypeConverterLoader}.
+     */
+    @SuppressWarnings("unchecked")
+    @Record(ExecutionTime.STATIC_INIT)
+    @BuildStep
+    CamelTypeConverterRegistryBuildItem typeConverterRegistry(
+            CamelRecorder recorder,
+            RecorderContext recorderContext,
+            ApplicationArchivesBuildItem applicationArchives,
+            List<CamelTypeConverterLoaderBuildItem> additionalLoaders) {
+
+        RuntimeValue<TypeConverterRegistry> typeConverterRegistry = 
recorder.createTypeConverterRegistry();
+
+        //
+        // This should be simplified by searching for classes implementing 
TypeConverterLoader but that
+        // would lead to have 
org.apache.camel.impl.converter.AnnotationTypeConverterLoader taken into
+        // account even if it should not.
+        //
+        // TODO: we could add a filter to discard 
AnnotationTypeConverterLoader but maybe we should introduce
+        //       a marker interface like StaticTypeConverterLoader for loaders 
that do not require to perform
+        //       any discovery at runtime.
+        //
+        for (ApplicationArchive archive : 
applicationArchives.getAllApplicationArchives()) {
+            for (Path root : archive.getRootDirs()) {
+                Path path = 
root.resolve(BaseTypeConverterRegistry.META_INF_SERVICES_TYPE_CONVERTER_LOADER);
+                if (!Files.isRegularFile(path)) {
+                    continue;
+                }
+
+                try {
+                    Files.readAllLines(path, StandardCharsets.UTF_8).stream()
+                            .map(String::trim)
+                            .filter(l -> !l.isEmpty())
+                            .filter(l -> !l.startsWith("#"))
+                            .map(l -> (Class<? extends TypeConverterLoader>) 
recorderContext.classProxy(l))
+                            .forEach(loader -> 
recorder.addTypeConverterLoader(typeConverterRegistry, loader));
+                } catch (IOException e) {
+                    throw new RuntimeException("Error discovering 
TypeConverterLoader", e);
+                }
+            }
+        }
+
+        //
+        // User can register loaders by providing a 
CamelTypeConverterLoaderBuildItem that can be used to
+        // provide additional TypeConverter or override default converters 
discovered by the previous step.
+        //
+        for (CamelTypeConverterLoaderBuildItem item : additionalLoaders) {
+            recorder.addTypeConverterLoader(typeConverterRegistry, 
item.getValue());
+        }
+
+        return new CamelTypeConverterRegistryBuildItem(typeConverterRegistry);
+    }
+
+    @Overridable
+    @BuildStep
+    @Record(value = ExecutionTime.STATIC_INIT, optional = true)
+    public CamelModelJAXBContextFactoryBuildItem 
createJaxbContextFactory(CamelRecorder recorder) {
+        return new 
CamelModelJAXBContextFactoryBuildItem(recorder.newDisabledModelJAXBContextFactory());
+    }
+
+    @Overridable
+    @BuildStep
+    @Record(value = ExecutionTime.STATIC_INIT, optional = true)
+    public CamelRoutesLoaderBuildItems.Xml createXMLRoutesLoader(CamelRecorder 
recorder) {
+        return new 
CamelRoutesLoaderBuildItems.Xml(recorder.newDisabledXMLRoutesDefinitionLoader());
+    }
+
+    @Overridable
+    @BuildStep
+    @Record(value = ExecutionTime.STATIC_INIT, optional = true)
+    public CamelModelToXMLDumperBuildItem createModelToXMLDumper(CamelRecorder 
recorder) {
+        return new 
CamelModelToXMLDumperBuildItem(recorder.newDisabledModelToXMLDumper());
+    }
+
+    @BuildStep
+    @Record(ExecutionTime.STATIC_INIT)
+    void disableXmlReifiers(CamelRecorder recorder, Capabilities capabilities) 
{
+        if (!capabilities.isCapabilityPresent(CamelCapabilities.XML)) {
+            LOGGER.debug("Camel XML capability not detected, disable XML 
reifiers");
+            recorder.disableXmlReifiers();
+        }
+    }
+
+    @Record(ExecutionTime.STATIC_INIT)
+    @BuildStep
+    CamelFactoryFinderResolverBuildItem factoryFinderResolver(
+            RecorderContext recorderContext,
+            CamelRecorder recorder,
+            List<CamelServiceBuildItem> camelServices) {
+
+        RuntimeValue<Builder> builder = 
recorder.factoryFinderResolverBuilder();
+
+        camelServices.forEach(service -> {
+            recorder.factoryFinderResolverEntry(
+                    builder,
+                    service.path.toString(),
+                    recorderContext.classProxy(service.type));
+        });
+
+        return new 
CamelFactoryFinderResolverBuildItem(recorder.factoryFinderResolver(builder));
+    }
+
+    @BuildStep
+    UnremovableBeanBuildItem unremovableRoutesBuilders() {
+        return new UnremovableBeanBuildItem(
+                b -> 
b.getTypes().stream().map(Type::name).anyMatch(UNREMOVABLE_BEANS_TYPES::contains));
+    }
+
+    @BuildStep
+    void unremovableBeans(BuildProducer<AdditionalBeanBuildItem> beanProducer) 
{
+        
beanProducer.produce(AdditionalBeanBuildItem.unremovableOf(CamelProducers.class));
+    }
+
+    @BuildStep(onlyIf = { CamelConfigFlags.RoutesDiscoveryEnabled.class })
+    public List<CamelRoutesBuilderClassBuildItem> 
discoverRoutesBuilderClassNames(
+            CombinedIndexBuildItem combinedIndex,
+            CamelConfig config) {
+
+        final IndexView index = combinedIndex.getIndex();
+
+        Set<ClassInfo> allKnownImplementors = new HashSet<>();
+        
allKnownImplementors.addAll(index.getAllKnownImplementors(ROUTES_BUILDER_TYPE));
+        
allKnownImplementors.addAll(index.getAllKnownSubclasses(ROUTE_BUILDER_TYPE));
+        
allKnownImplementors.addAll(index.getAllKnownSubclasses(ADVICE_WITH_ROUTE_BUILDER_TYPE));
+
+        return allKnownImplementors
+                .stream()
+                // public and non-abstract
+                .filter(ci -> ((ci.flags() & (Modifier.ABSTRACT | 
Modifier.PUBLIC)) == Modifier.PUBLIC))
+                .map(ClassInfo::name)
+                .filter(new PathFilter.Builder()
+                        .exclude(config.routesDiscovery.excludePatterns)
+                        .include(config.routesDiscovery.includePatterns)
+                        .build().asDotNamePredicate())
+                .map(CamelRoutesBuilderClassBuildItem::new)
+                .collect(Collectors.toList());
+    }
+}

Reply via email to