Merge pull request #580 from jamesnetherton/dozer-jaxb

Dozer extension should use JaxbFileRootBuildItem
diff --git a/extensions/core-xml/deployment/pom.xml b/extensions/core-xml/deployment/pom.xml
index c49ad79..c398dd9 100644
--- a/extensions/core-xml/deployment/pom.xml
+++ b/extensions/core-xml/deployment/pom.xml
@@ -58,6 +58,52 @@
             <groupId>io.quarkus</groupId>
             <artifactId>quarkus-jaxb-deployment</artifactId>
         </dependency>
+
+        <!-- test dependencies -->
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-direct</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>io.quarkus</groupId>
+            <artifactId>quarkus-resteasy-deployment</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>io.quarkus</groupId>
+            <artifactId>quarkus-resteasy-jsonb-deployment</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>io.quarkus</groupId>
+            <artifactId>quarkus-junit5-internal</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>io.rest-assured</groupId>
+            <artifactId>rest-assured</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.assertj</groupId>
+            <artifactId>assertj-core</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.awaitility</groupId>
+            <artifactId>awaitility</artifactId>
+            <scope>test</scope>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.hamcrest</groupId>
+                    <artifactId>hamcrest-core</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
     </dependencies>
 
     <build>
diff --git a/extensions/core-xml/deployment/src/test/java/org/apache/camel/quarkus/component/xml/deployment/CamelDevModeTest.java b/extensions/core-xml/deployment/src/test/java/org/apache/camel/quarkus/component/xml/deployment/CamelDevModeTest.java
new file mode 100644
index 0000000..abf5333
--- /dev/null
+++ b/extensions/core-xml/deployment/src/test/java/org/apache/camel/quarkus/component/xml/deployment/CamelDevModeTest.java
@@ -0,0 +1,117 @@
+/*
+ * 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.component.xml.deployment;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.StandardCopyOption;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Properties;
+import java.util.concurrent.TimeUnit;
+
+import io.quarkus.test.QuarkusDevModeTest;
+import io.restassured.RestAssured;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.asset.Asset;
+import org.jboss.shrinkwrap.api.asset.StringAsset;
+import org.jboss.shrinkwrap.api.spec.JavaArchive;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
+
+import static org.awaitility.Awaitility.await;
+
+public class CamelDevModeTest {
+    static Path BASE;
+
+    @RegisterExtension
+    static final QuarkusDevModeTest TEST = new QuarkusDevModeTest()
+            .setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class)
+                    .addClass(CamelSupportServlet.class)
+                    .addAsResource(applicationProperties(), "application.properties"));
+
+    @BeforeAll
+    public static void setUp() {
+        try {
+            BASE = Files.createTempDirectory("camel-devmode-");
+            copy("routes.1", "routes.xml");
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    @AfterAll
+    public static void cleanUp() throws IOException {
+        Files.walk(BASE)
+                .sorted(Comparator.reverseOrder())
+                .map(Path::toFile)
+                .forEach(File::delete);
+    }
+
+    public static Asset applicationProperties() {
+        Writer writer = new StringWriter();
+
+        Properties props = new Properties();
+        props.setProperty("camel.main.xml-routes", "file:" + BASE.toAbsolutePath().toString() + "/routes.xml");
+
+        try {
+            props.store(writer, "");
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+
+        return new StringAsset(writer.toString());
+    }
+
+    public static void copy(String source, String target) throws IOException {
+        Files.copy(
+                CamelDevModeTest.class.getResourceAsStream("/" + source),
+                BASE.resolve(target),
+                StandardCopyOption.REPLACE_EXISTING);
+    }
+
+    public static List<String> routes() {
+        return RestAssured.when()
+                .get("/test/describe")
+                .then()
+                .statusCode(200)
+                .extract()
+                .body()
+                .jsonPath().getList("routes", String.class);
+    }
+
+    @Test
+    public void testRoutesDiscovery() throws IOException {
+        await().atMost(10, TimeUnit.SECONDS).until(() -> {
+            List<String> routes = routes();
+            return routes.size() == 1 && routes.contains("r1");
+        });
+
+        copy("routes.2", "routes.xml");
+
+        await().atMost(10, TimeUnit.SECONDS).until(() -> {
+            List<String> routes = routes();
+            return routes.size() == 1 && routes.contains("r2");
+        });
+    }
+}
diff --git a/extensions/core-xml/deployment/src/test/java/org/apache/camel/quarkus/component/xml/deployment/CamelSupportServlet.java b/extensions/core-xml/deployment/src/test/java/org/apache/camel/quarkus/component/xml/deployment/CamelSupportServlet.java
new file mode 100644
index 0000000..92aac18
--- /dev/null
+++ b/extensions/core-xml/deployment/src/test/java/org/apache/camel/quarkus/component/xml/deployment/CamelSupportServlet.java
@@ -0,0 +1,48 @@
+/*
+ * 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.component.xml.deployment;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.inject.Inject;
+import javax.json.Json;
+import javax.json.JsonArrayBuilder;
+import javax.json.JsonObject;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+
+import org.apache.camel.CamelContext;
+
+@Path("/test")
+@ApplicationScoped
+public class CamelSupportServlet {
+    @Inject
+    CamelContext context;
+
+    @Path("/describe")
+    @GET
+    @Produces(MediaType.APPLICATION_JSON)
+    public JsonObject describeMain() {
+        JsonArrayBuilder routes = Json.createArrayBuilder();
+        context.getRoutes().forEach(route -> routes.add(route.getId()));
+
+        return Json.createObjectBuilder()
+                .add("routes", routes)
+                .build();
+    }
+}
diff --git a/extensions/core-xml/deployment/src/test/resources/routes.1 b/extensions/core-xml/deployment/src/test/resources/routes.1
new file mode 100644
index 0000000..9150f91
--- /dev/null
+++ b/extensions/core-xml/deployment/src/test/resources/routes.1
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    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.
+
+-->
+<routes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+        xmlns="http://camel.apache.org/schema/spring"
+        xsi:schemaLocation="
+            http://camel.apache.org/schema/spring
+            http://camel.apache.org/schema/spring/camel-spring.xsd">
+
+    <route id="r1">
+        <from uri="direct:start"/>
+        <to uri="direct:end"/>
+    </route>
+
+</routes>
\ No newline at end of file
diff --git a/extensions/core-xml/deployment/src/test/resources/routes.2 b/extensions/core-xml/deployment/src/test/resources/routes.2
new file mode 100644
index 0000000..1e177f2
--- /dev/null
+++ b/extensions/core-xml/deployment/src/test/resources/routes.2
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    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.
+
+-->
+<routes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+        xmlns="http://camel.apache.org/schema/spring"
+        xsi:schemaLocation="
+            http://camel.apache.org/schema/spring
+            http://camel.apache.org/schema/spring/camel-spring.xsd">
+
+    <route id="r2">
+        <from uri="direct:start"/>
+        <to uri="direct:end"/>
+    </route>
+
+</routes>
\ No newline at end of file
diff --git a/extensions/core/runtime/src/main/java/org/apache/camel/quarkus/core/FastCamelContext.java b/extensions/core/runtime/src/main/java/org/apache/camel/quarkus/core/FastCamelContext.java
index fa2a9de..e864c84 100644
--- a/extensions/core/runtime/src/main/java/org/apache/camel/quarkus/core/FastCamelContext.java
+++ b/extensions/core/runtime/src/main/java/org/apache/camel/quarkus/core/FastCamelContext.java
@@ -24,6 +24,7 @@
 import org.apache.camel.CamelContext;
 import org.apache.camel.Component;
 import org.apache.camel.Endpoint;
+import org.apache.camel.NoSuchLanguageException;
 import org.apache.camel.PollingConsumer;
 import org.apache.camel.Processor;
 import org.apache.camel.Producer;
@@ -177,7 +178,14 @@
         // languages are automatically discovered by build steps so we can reduce the
         // operations done by the standard resolver by looking them up directly from the
         // registry
-        return (name, context) -> context.getRegistry().lookupByNameAndType(name, Language.class);
+        return (name, context) -> {
+            Language answer = context.getRegistry().lookupByNameAndType(name, Language.class);
+            if (answer == null) {
+                throw new NoSuchLanguageException(name);
+            }
+
+            return answer;
+        };
     }
 
     @Override
diff --git a/integration-tests/core/src/main/java/org/apache/camel/quarkus/core/CamelServlet.java b/integration-tests/core/src/main/java/org/apache/camel/quarkus/core/CamelServlet.java
index 25e64fd..9aa932d 100644
--- a/integration-tests/core/src/main/java/org/apache/camel/quarkus/core/CamelServlet.java
+++ b/integration-tests/core/src/main/java/org/apache/camel/quarkus/core/CamelServlet.java
@@ -16,18 +16,18 @@
  */
 package org.apache.camel.quarkus.core;
 
-import java.util.Set;
-
 import javax.enterprise.context.ApplicationScoped;
 import javax.inject.Inject;
 import javax.json.Json;
 import javax.json.JsonObject;
 import javax.ws.rs.GET;
 import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
 import javax.ws.rs.core.MediaType;
 
 import org.apache.camel.CamelContext;
+import org.apache.camel.NoSuchLanguageException;
 import org.apache.camel.component.log.LogComponent;
 import org.apache.camel.spi.Registry;
 import org.apache.camel.support.processor.DefaultExchangeFormatter;
@@ -37,6 +37,8 @@
 public class CamelServlet {
     @Inject
     Registry registry;
+    @Inject
+    CamelContext context;
 
     @Path("/registry/log/exchange-formatter")
     @GET
@@ -78,7 +80,19 @@
     @GET
     @Produces(MediaType.TEXT_PLAIN)
     public String contextVersion() {
-        Set<CamelContext> camelContexts = registry.findByType(CamelContext.class);
-        return camelContexts.isEmpty() ? "" : camelContexts.iterator().next().getVersion();
+        return context.getVersion();
+    }
+
+    @Path("/language/{name}")
+    @GET
+    @Produces(MediaType.TEXT_PLAIN)
+    public boolean resolveLanguage(@PathParam("name") String name) {
+        try {
+            context.resolveLanguage(name);
+        } catch (NoSuchLanguageException e) {
+            return false;
+        }
+
+        return true;
     }
 }
diff --git a/integration-tests/core/src/test/java/org/apache/camel/quarkus/core/CamelTest.java b/integration-tests/core/src/test/java/org/apache/camel/quarkus/core/CamelTest.java
index e5a9abd..a46c52c 100644
--- a/integration-tests/core/src/test/java/org/apache/camel/quarkus/core/CamelTest.java
+++ b/integration-tests/core/src/test/java/org/apache/camel/quarkus/core/CamelTest.java
@@ -50,4 +50,10 @@
     public void testCamelContextVersion() {
         RestAssured.when().get("/test/context/version").then().body(not(""));
     }
+
+    @Test
+    public void testResolveLanguages() {
+        RestAssured.when().get("/test/language/simple").then().body(is("true"));
+        RestAssured.when().get("/test/language/undefined").then().body(is("false"));
+    }
 }
diff --git a/pom.xml b/pom.xml
index a7e6ba7..e847141 100644
--- a/pom.xml
+++ b/pom.xml
@@ -301,6 +301,8 @@
                             <exclude>ide-config/**</exclude>
                             <exclude>mvnw*</exclude>
                             <exclude>node/**</exclude>
+                            <exclude>**/resources/routes.1</exclude>
+                            <exclude>**/resources/routes.2</exclude>
                         </excludes>
                         <mapping>
                             <groovy>SLASHSTAR_STYLE</groovy>