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 2018/02/21 10:34:06 UTC

[camel] 01/03: CAMEL-12266: Maven plugin for restdsl can now generate xml.

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 4656f0f52a2e0dad1d11c56d861a8d8b0a90a089
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Wed Feb 21 09:46:47 2018 +0100

    CAMEL-12266: Maven plugin for restdsl can now generate xml.
---
 .../src/it/simple-xml/pom.xml                      | 53 ++++++++++++
 .../src/it/simple-xml/src/spec/swagger.json        |  1 +
 .../src/it/simple-xml/verify.groovy                | 20 +++++
 .../src/main/docs/camel-package-maven-plugin.adoc  | 24 ++++++
 ...GenerateMojo.java => AbstractGenerateMojo.java} | 85 ++-----------------
 .../maven/generator/swagger/GenerateMojo.java      | 61 +------------
 .../maven/generator/swagger/GenerateXmlMojo.java   | 89 +++++++++++++++++++
 .../camel/generator/swagger/RestDslGenerator.java  |  6 +-
 .../swagger/RestDslSourceCodeGenerator.java        |  3 +
 .../generator/swagger/RestDslXmlGenerator.java     | 44 ++++++++++
 .../generator/swagger/RestDslXmlGeneratorTest.java | 57 +++++++++++++
 .../src/test/resources/SwaggerPetstoreXml.txt      | 99 ++++++++++++++++++++++
 12 files changed, 403 insertions(+), 139 deletions(-)

diff --git a/tooling/maven/camel-restdsl-swagger-plugin/src/it/simple-xml/pom.xml b/tooling/maven/camel-restdsl-swagger-plugin/src/it/simple-xml/pom.xml
new file mode 100644
index 0000000..19b22f4
--- /dev/null
+++ b/tooling/maven/camel-restdsl-swagger-plugin/src/it/simple-xml/pom.xml
@@ -0,0 +1,53 @@
+<?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.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <groupId>org.apache.camel.maven.generator.swagger.it</groupId>
+  <artifactId>simple</artifactId>
+  <version>1-SNAPSHOT</version>
+
+  <description>A simple IT verifying the basic use case.</description>
+
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    <maven.compiler.source>1.8</maven.compiler.source>
+    <maven.compiler.target>1.8</maven.compiler.target>
+  </properties>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>@project.groupId@</groupId>
+        <artifactId>@project.artifactId@</artifactId>
+        <version>@project.version@</version>
+        <executions>
+          <execution>
+            <id>simple</id>
+            <goals>
+              <goal>generate-xml</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+</project>
diff --git a/tooling/maven/camel-restdsl-swagger-plugin/src/it/simple-xml/src/spec/swagger.json b/tooling/maven/camel-restdsl-swagger-plugin/src/it/simple-xml/src/spec/swagger.json
new file mode 100644
index 0000000..816847f
--- /dev/null
+++ b/tooling/maven/camel-restdsl-swagger-plugin/src/it/simple-xml/src/spec/swagger.json
@@ -0,0 +1 @@
+{"swagger":"2.0","info":{"description":"This is a sample server Petstore server.  You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/).  For this sample, you can use the api key `special-key` to test the authorization filters.","version":"1.0.0","title":"Swagger Petstore","termsOfService":"http://swagger.io/terms/","contact":{"email":"apiteam@swagger.io"},"license":{"name":"Apache 2.0","url":"http://www.a [...]
\ No newline at end of file
diff --git a/tooling/maven/camel-restdsl-swagger-plugin/src/it/simple-xml/verify.groovy b/tooling/maven/camel-restdsl-swagger-plugin/src/it/simple-xml/verify.groovy
new file mode 100644
index 0000000..c7575d7
--- /dev/null
+++ b/tooling/maven/camel-restdsl-swagger-plugin/src/it/simple-xml/verify.groovy
@@ -0,0 +1,20 @@
+/**
+ * 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.
+ */
+
+def File restdsl = new File(basedir, "target/generated-sources/restdsl-swagger/camel-rest.xml")
+
+assert restdsl.exists()
diff --git a/tooling/maven/camel-restdsl-swagger-plugin/src/main/docs/camel-package-maven-plugin.adoc b/tooling/maven/camel-restdsl-swagger-plugin/src/main/docs/camel-package-maven-plugin.adoc
index 1e800b7..10bd474 100644
--- a/tooling/maven/camel-restdsl-swagger-plugin/src/main/docs/camel-package-maven-plugin.adoc
+++ b/tooling/maven/camel-restdsl-swagger-plugin/src/main/docs/camel-package-maven-plugin.adoc
@@ -5,6 +5,9 @@ The Camel REST DSL Swagger Maven Plugin supports the following goals
  - camel-restdsl-swagger:generate - To generate consumer REST DSL
  RouteBuilder source code from Swagger specification
 
+ - camel-restdsl-swagger:generate-xml - To generate consumer REST DSL
+ XML source code from Swagger specification
+
 == camel-restdsl-swagger:generate
 
 The `camel-restdsl-swagger:generate` goal of the Camel REST DSL
@@ -28,3 +31,24 @@ in the `<configuration>` tag.
 | `destinationGenerator` | | Fully qualified class name of the class that implements `org.apache.camel.generator.swagger.DestinationGenerator` interface for customizing destination endpoint
 |========================================
 
+== camel-restdsl-swagger:generate-xml
+
+The `camel-restdsl-swagger:generate-xml` goal of the Camel REST DSL
+Swagger Maven Plugin is used to generate REST DSL XML
+implementation source code from Maven.
+
+=== Options
+
+The plugin supports the following options which can be configured from
+the command line (use `-D` syntax), or defined in the `pom.xml` file
+in the `<configuration>` tag.
+
+|========================================
+| Parameter | Default Value | Description
+| `skip` | `false` | Set to `true` to skip code generation.
+| `specificationUri` | `src/spec/swagger.json` | URI of the Swagger specification, loaded using Swagger's resource loading mechanism, supports filesystem paths, HTTP and classpath resources, by default `src/spec/swagger.json` within the project directory
+| `outputDirectory` | `generated-sources/restdsl-swagger` | Where to place the generated source file, by default `generated-sources/restdsl-swagger` within the project directory
+| `fileName` | `camel-rest.xml` | The name of the XML file as output.
+| `destinationGenerator` | | Fully qualified class name of the class that implements `org.apache.camel.generator.swagger.DestinationGenerator` interface for customizing destination endpoint
+|========================================
+
diff --git a/tooling/maven/camel-restdsl-swagger-plugin/src/main/java/org/apache/camel/maven/generator/swagger/GenerateMojo.java b/tooling/maven/camel-restdsl-swagger-plugin/src/main/java/org/apache/camel/maven/generator/swagger/AbstractGenerateMojo.java
similarity index 56%
copy from tooling/maven/camel-restdsl-swagger-plugin/src/main/java/org/apache/camel/maven/generator/swagger/GenerateMojo.java
copy to tooling/maven/camel-restdsl-swagger-plugin/src/main/java/org/apache/camel/maven/generator/swagger/AbstractGenerateMojo.java
index d47649a..213b0e7 100644
--- a/tooling/maven/camel-restdsl-swagger-plugin/src/main/java/org/apache/camel/maven/generator/swagger/GenerateMojo.java
+++ b/tooling/maven/camel-restdsl-swagger-plugin/src/main/java/org/apache/camel/maven/generator/swagger/AbstractGenerateMojo.java
@@ -5,9 +5,9 @@
  * 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
- *
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
  * 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.
@@ -21,95 +21,26 @@ import java.io.IOException;
 import java.net.MalformedURLException;
 import java.net.URL;
 import java.net.URLClassLoader;
-import java.nio.file.Path;
-
-import io.swagger.models.Swagger;
-import io.swagger.parser.SwaggerParser;
 
 import org.apache.camel.generator.swagger.DestinationGenerator;
-import org.apache.camel.generator.swagger.RestDslGenerator;
-import org.apache.camel.generator.swagger.RestDslSourceCodeGenerator;
-import org.apache.camel.util.ObjectHelper;
 import org.apache.maven.plugin.AbstractMojo;
 import org.apache.maven.plugin.MojoExecutionException;
-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.apache.maven.project.MavenProject;
 
-@Mojo(name = "generate", inheritByDefault = false, defaultPhase = LifecyclePhase.GENERATE_SOURCES,
-    requiresDependencyResolution = ResolutionScope.COMPILE, threadSafe = true)
-public class GenerateMojo extends AbstractMojo {
-
-    @Parameter
-    private String className;
-
-    @Parameter
-    private String destinationGenerator;
-
-    @Parameter
-    private String indent;
-
-    @Parameter(defaultValue = "${project.build.directory}/generated-sources/restdsl-swagger", required = true)
-    private String outputDirectory;
+abstract class AbstractGenerateMojo extends AbstractMojo {
 
     @Parameter
-    private String packageName;
+    String destinationGenerator;
 
     @Parameter(defaultValue = "${project}")
-    private MavenProject project;
+    MavenProject project;
 
     @Parameter(defaultValue = "false")
-    private boolean skip;
+    boolean skip;
 
     @Parameter(defaultValue = "${project.basedir}/src/spec/swagger.json", required = true)
-    private String specificationUri;
-
-    @Override
-    public void execute() throws MojoExecutionException {
-        if (skip) {
-            return;
-        }
-
-        final SwaggerParser swaggerParser = new SwaggerParser();
-
-        final Swagger swagger = swaggerParser.read(specificationUri);
-
-        if (swagger == null) {
-            throw new MojoExecutionException("Unable to generate REST DSL Swagger sources from specification: "
-                + specificationUri + ", make sure that the specification is available at the given URI");
-        }
-
-        final RestDslSourceCodeGenerator<Path> generator = RestDslGenerator.toPath(swagger);
-
-        if (ObjectHelper.isNotEmpty(className)) {
-            generator.withClassName(className);
-        }
-
-        if (indent != null) {
-            generator.withIndent(indent.replace("\\t", "\t"));
-        }
-
-        if (ObjectHelper.isNotEmpty(packageName)) {
-            generator.withPackageName(packageName);
-        }
-
-        if (ObjectHelper.isNotEmpty(destinationGenerator)) {
-            final DestinationGenerator destinationGeneratorObject = createDestinationGenerator();
-
-            generator.withDestinationGenerator(destinationGeneratorObject);
-        }
-
-        final Path outputPath = new File(outputDirectory).toPath();
-
-        try {
-            generator.generate(outputPath);
-        } catch (final IOException e) {
-            throw new MojoExecutionException(
-                "Unable to generate REST DSL Swagger sources from specification: " + specificationUri, e);
-        }
-    }
+    String specificationUri;
 
     DestinationGenerator createDestinationGenerator() throws MojoExecutionException {
         final Class<DestinationGenerator> destinationGeneratorClass;
diff --git a/tooling/maven/camel-restdsl-swagger-plugin/src/main/java/org/apache/camel/maven/generator/swagger/GenerateMojo.java b/tooling/maven/camel-restdsl-swagger-plugin/src/main/java/org/apache/camel/maven/generator/swagger/GenerateMojo.java
index d47649a..997aca0 100644
--- a/tooling/maven/camel-restdsl-swagger-plugin/src/main/java/org/apache/camel/maven/generator/swagger/GenerateMojo.java
+++ b/tooling/maven/camel-restdsl-swagger-plugin/src/main/java/org/apache/camel/maven/generator/swagger/GenerateMojo.java
@@ -18,37 +18,28 @@ package org.apache.camel.maven.generator.swagger;
 
 import java.io.File;
 import java.io.IOException;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.net.URLClassLoader;
 import java.nio.file.Path;
 
 import io.swagger.models.Swagger;
 import io.swagger.parser.SwaggerParser;
-
 import org.apache.camel.generator.swagger.DestinationGenerator;
 import org.apache.camel.generator.swagger.RestDslGenerator;
 import org.apache.camel.generator.swagger.RestDslSourceCodeGenerator;
 import org.apache.camel.util.ObjectHelper;
-import org.apache.maven.plugin.AbstractMojo;
 import org.apache.maven.plugin.MojoExecutionException;
 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.apache.maven.project.MavenProject;
 
 @Mojo(name = "generate", inheritByDefault = false, defaultPhase = LifecyclePhase.GENERATE_SOURCES,
     requiresDependencyResolution = ResolutionScope.COMPILE, threadSafe = true)
-public class GenerateMojo extends AbstractMojo {
+public class GenerateMojo extends AbstractGenerateMojo {
 
     @Parameter
     private String className;
 
     @Parameter
-    private String destinationGenerator;
-
-    @Parameter
     private String indent;
 
     @Parameter(defaultValue = "${project.build.directory}/generated-sources/restdsl-swagger", required = true)
@@ -57,15 +48,6 @@ public class GenerateMojo extends AbstractMojo {
     @Parameter
     private String packageName;
 
-    @Parameter(defaultValue = "${project}")
-    private MavenProject project;
-
-    @Parameter(defaultValue = "false")
-    private boolean skip;
-
-    @Parameter(defaultValue = "${project.basedir}/src/spec/swagger.json", required = true)
-    private String specificationUri;
-
     @Override
     public void execute() throws MojoExecutionException {
         if (skip) {
@@ -111,45 +93,4 @@ public class GenerateMojo extends AbstractMojo {
         }
     }
 
-    DestinationGenerator createDestinationGenerator() throws MojoExecutionException {
-        final Class<DestinationGenerator> destinationGeneratorClass;
-
-        final ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
-        final URL outputDirectory;
-        try {
-            outputDirectory = new File(project.getBuild().getOutputDirectory()).toURI().toURL();
-        } catch (final MalformedURLException e) {
-            throw new IllegalStateException(e);
-        }
-        final URL[] withOutput = new URL[] {outputDirectory};
-
-        try (URLClassLoader classLoader = new URLClassLoader(withOutput, contextClassLoader)) {
-            @SuppressWarnings("unchecked")
-            final Class<DestinationGenerator> tmp = (Class) classLoader.loadClass(destinationGenerator);
-
-            if (!DestinationGenerator.class.isAssignableFrom(tmp)) {
-                throw new MojoExecutionException("The given destinationGenerator class (" + destinationGenerator
-                    + ") does not implement " + DestinationGenerator.class.getName() + " interface.");
-            }
-
-            destinationGeneratorClass = tmp;
-        } catch (final ClassNotFoundException | IOException e) {
-            throw new MojoExecutionException(
-                "The given destinationGenerator class (" + destinationGenerator
-                    + ") cannot be loaded, make sure that it is present in the COMPILE classpath scope of the project",
-                e);
-        }
-
-        final DestinationGenerator destinationGeneratorObject;
-        try {
-            destinationGeneratorObject = destinationGeneratorClass.newInstance();
-        } catch (InstantiationException | IllegalAccessException e) {
-            throw new MojoExecutionException(
-                "The given destinationGenerator class (" + destinationGenerator
-                    + ") cannot be instantiated, make sure that it is declared as public and that all dependencies are present on the COMPILE classpath scope of the project",
-                e);
-        }
-        return destinationGeneratorObject;
-    }
-
 }
diff --git a/tooling/maven/camel-restdsl-swagger-plugin/src/main/java/org/apache/camel/maven/generator/swagger/GenerateXmlMojo.java b/tooling/maven/camel-restdsl-swagger-plugin/src/main/java/org/apache/camel/maven/generator/swagger/GenerateXmlMojo.java
new file mode 100644
index 0000000..82e0582
--- /dev/null
+++ b/tooling/maven/camel-restdsl-swagger-plugin/src/main/java/org/apache/camel/maven/generator/swagger/GenerateXmlMojo.java
@@ -0,0 +1,89 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.generator.swagger;
+
+import java.io.File;
+import java.io.FileOutputStream;
+
+import io.swagger.models.Swagger;
+import io.swagger.parser.SwaggerParser;
+import org.apache.camel.CamelContext;
+import org.apache.camel.generator.swagger.DestinationGenerator;
+import org.apache.camel.generator.swagger.RestDslGenerator;
+import org.apache.camel.generator.swagger.RestDslXmlGenerator;
+import org.apache.camel.impl.DefaultCamelContext;
+import org.apache.camel.util.IOHelper;
+import org.apache.camel.util.ObjectHelper;
+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;
+
+@Mojo(name = "generate-xml", inheritByDefault = false, defaultPhase = LifecyclePhase.GENERATE_SOURCES,
+    requiresDependencyResolution = ResolutionScope.COMPILE, threadSafe = true)
+public class GenerateXmlMojo extends AbstractGenerateMojo {
+
+    @Parameter(defaultValue = "${project.build.directory}/generated-sources/restdsl-swagger", required = true)
+    private String outputDirectory;
+
+    @Parameter(defaultValue = "camel-rest.xml", required = true)
+    private String fileName;
+
+    @Override
+    public void execute() throws MojoExecutionException, MojoFailureException {
+        if (skip) {
+            return;
+        }
+
+        final SwaggerParser swaggerParser = new SwaggerParser();
+
+        final Swagger swagger = swaggerParser.read(specificationUri);
+
+        if (swagger == null) {
+            throw new MojoExecutionException("Unable to generate REST DSL Swagger sources from specification: "
+                + specificationUri + ", make sure that the specification is available at the given URI");
+        }
+
+        final RestDslXmlGenerator generator = RestDslGenerator.toXml(swagger);
+
+        if (ObjectHelper.isNotEmpty(destinationGenerator)) {
+            final DestinationGenerator destinationGeneratorObject = createDestinationGenerator();
+
+            generator.withDestinationGenerator(destinationGeneratorObject);
+        }
+
+        try {
+            CamelContext camel = new DefaultCamelContext();
+            String xml = generator.generate(camel);
+
+            // ensure output folder is created
+            new File(outputDirectory).mkdirs();
+            File out = new File(outputDirectory, fileName);
+
+            FileOutputStream fos = new FileOutputStream(out);
+            fos.write(xml.getBytes());
+            fos.close();
+
+        } catch (final Exception e) {
+            throw new MojoExecutionException(
+                "Unable to generate REST DSL Swagger sources from specification: " + specificationUri, e);
+        }
+    }
+
+}
diff --git a/tooling/swagger-rest-dsl-generator/src/main/java/org/apache/camel/generator/swagger/RestDslGenerator.java b/tooling/swagger-rest-dsl-generator/src/main/java/org/apache/camel/generator/swagger/RestDslGenerator.java
index 237a506..b6d144c 100644
--- a/tooling/swagger-rest-dsl-generator/src/main/java/org/apache/camel/generator/swagger/RestDslGenerator.java
+++ b/tooling/swagger-rest-dsl-generator/src/main/java/org/apache/camel/generator/swagger/RestDslGenerator.java
@@ -17,11 +17,9 @@
 package org.apache.camel.generator.swagger;
 
 import java.nio.file.Path;
-
 import javax.annotation.processing.Filer;
 
 import io.swagger.models.Swagger;
-
 import org.apache.camel.model.rest.RestsDefinition;
 
 import static org.apache.camel.util.ObjectHelper.notNull;
@@ -62,6 +60,10 @@ public abstract class RestDslGenerator<G> {
         return new RestDslDefinitionGenerator(swagger);
     }
 
+    public static RestDslXmlGenerator toXml(final Swagger swagger) {
+        return new RestDslXmlGenerator(swagger);
+    }
+
     public static RestDslSourceCodeGenerator<Filer> toFiler(final Swagger swagger) {
         return new FilerGenerator(swagger);
     }
diff --git a/tooling/swagger-rest-dsl-generator/src/main/java/org/apache/camel/generator/swagger/RestDslSourceCodeGenerator.java b/tooling/swagger-rest-dsl-generator/src/main/java/org/apache/camel/generator/swagger/RestDslSourceCodeGenerator.java
index 62c8f70..a630b17 100644
--- a/tooling/swagger-rest-dsl-generator/src/main/java/org/apache/camel/generator/swagger/RestDslSourceCodeGenerator.java
+++ b/tooling/swagger-rest-dsl-generator/src/main/java/org/apache/camel/generator/swagger/RestDslSourceCodeGenerator.java
@@ -37,6 +37,9 @@ import org.apache.camel.util.ObjectHelper;
 
 import static org.apache.camel.util.StringHelper.notEmpty;
 
+/**
+ * Generates Java source code
+ */
 public abstract class RestDslSourceCodeGenerator<T> extends RestDslGenerator<RestDslSourceCodeGenerator<T>> {
     static final String DEFAULT_CLASS_NAME = "RestDslRoute";
 
diff --git a/tooling/swagger-rest-dsl-generator/src/main/java/org/apache/camel/generator/swagger/RestDslXmlGenerator.java b/tooling/swagger-rest-dsl-generator/src/main/java/org/apache/camel/generator/swagger/RestDslXmlGenerator.java
new file mode 100644
index 0000000..1260f50
--- /dev/null
+++ b/tooling/swagger-rest-dsl-generator/src/main/java/org/apache/camel/generator/swagger/RestDslXmlGenerator.java
@@ -0,0 +1,44 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.generator.swagger;
+
+import io.swagger.models.Swagger;
+import org.apache.camel.CamelContext;
+import org.apache.camel.model.ModelHelper;
+import org.apache.camel.model.rest.RestsDefinition;
+
+public class RestDslXmlGenerator extends RestDslGenerator<RestDslXmlGenerator> {
+
+    // TODO: remove root namespace
+    // TODO: re-order attributes so id/url is first
+
+    RestDslXmlGenerator(final Swagger swagger) {
+        super(swagger);
+    }
+
+    public String generate(final CamelContext context) throws Exception {
+        final RestDefinitionEmitter emitter = new RestDefinitionEmitter(context);
+
+        final PathVisitor<RestsDefinition> restDslStatement = new PathVisitor<>(emitter, destinationGenerator());
+
+        swagger.getPaths().forEach(restDslStatement::visit);
+
+        RestsDefinition rests = emitter.result();
+        String xml = ModelHelper.dumpModelAsXml(context, rests);
+        return xml;
+    }
+}
diff --git a/tooling/swagger-rest-dsl-generator/src/test/java/org/apache/camel/generator/swagger/RestDslXmlGeneratorTest.java b/tooling/swagger-rest-dsl-generator/src/test/java/org/apache/camel/generator/swagger/RestDslXmlGeneratorTest.java
new file mode 100644
index 0000000..0610b56
--- /dev/null
+++ b/tooling/swagger-rest-dsl-generator/src/test/java/org/apache/camel/generator/swagger/RestDslXmlGeneratorTest.java
@@ -0,0 +1,57 @@
+/**
+ * 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.generator.swagger;
+
+import java.net.URI;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+
+import io.swagger.models.Swagger;
+import io.swagger.parser.SwaggerParser;
+import org.apache.camel.CamelContext;
+import org.apache.camel.impl.DefaultCamelContext;
+import org.junit.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class RestDslXmlGeneratorTest {
+
+    final Swagger swagger = new SwaggerParser().read("petstore.json");
+
+    @Test
+    public void shouldGenerateXml() throws Exception {
+        final CamelContext context = new DefaultCamelContext();
+
+        final String xml = RestDslGenerator.toXml(swagger).generate(context);
+        assertThat(xml).isNotEmpty();
+    }
+
+    @Test
+    public void shouldGenerateXmlWithDefaults() throws Exception {
+        final CamelContext context = new DefaultCamelContext();
+
+        final String xml = RestDslGenerator.toXml(swagger).generate(context);
+
+        final URI file = RestDslGeneratorTest.class.getResource("/SwaggerPetstoreXml.txt").toURI();
+        final String expectedContent = new String(Files.readAllBytes(Paths.get(file)), StandardCharsets.UTF_8);
+
+        assertThat(xml).isEqualTo(expectedContent);
+    }
+
+
+}
diff --git a/tooling/swagger-rest-dsl-generator/src/test/resources/SwaggerPetstoreXml.txt b/tooling/swagger-rest-dsl-generator/src/test/resources/SwaggerPetstoreXml.txt
new file mode 100644
index 0000000..e592be7
--- /dev/null
+++ b/tooling/swagger-rest-dsl-generator/src/test/resources/SwaggerPetstoreXml.txt
@@ -0,0 +1,99 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<rests xmlns="http://camel.apache.org/schema/spring">
+    <rest>
+        <put consumes="application/json,application/xml" customId="true" id="updatePet" produces="application/xml,application/json" uri="/pet">
+            <param description="Pet object that needs to be added to the store" name="body" required="true" type="body"/>
+            <to uri="direct:updatePet"/>
+        </put>
+        <post consumes="application/json,application/xml" customId="true" id="addPet" produces="application/xml,application/json" uri="/pet">
+            <param description="Pet object that needs to be added to the store" name="body" required="true" type="body"/>
+            <to uri="direct:addPet"/>
+        </post>
+        <get customId="true" id="findPetsByStatus" produces="application/xml,application/json" uri="/pet/findByStatus">
+            <description>Multiple status values can be provided with comma separated strings</description>
+            <param arrayType="string" collectionFormat="multi" dataType="array" description="Status values that need to be considered for filter" name="status" required="true" type="query"/>
+            <to uri="direct:findPetsByStatus"/>
+        </get>
+        <get customId="true" id="findPetsByTags" produces="application/xml,application/json" uri="/pet/findByTags">
+            <description>Muliple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing.</description>
+            <param arrayType="string" collectionFormat="multi" dataType="array" description="Tags to filter by" name="tags" required="true" type="query"/>
+            <to uri="direct:findPetsByTags"/>
+        </get>
+        <get customId="true" id="getPetById" produces="application/xml,application/json" uri="/pet/{petId}">
+            <description>Returns a single pet</description>
+            <param dataType="integer" description="ID of pet to return" name="petId" required="true" type="path"/>
+            <to uri="direct:getPetById"/>
+        </get>
+        <post consumes="application/x-www-form-urlencoded" customId="true" id="updatePetWithForm" produces="application/xml,application/json" uri="/pet/{petId}">
+            <param dataType="integer" description="ID of pet that needs to be updated" name="petId" required="true" type="path"/>
+            <param dataType="string" description="Updated name of the pet" name="name" required="false" type="formData"/>
+            <param dataType="string" description="Updated status of the pet" name="status" required="false" type="formData"/>
+            <to uri="direct:updatePetWithForm"/>
+        </post>
+        <delete customId="true" id="deletePet" produces="application/xml,application/json" uri="/pet/{petId}">
+            <param dataType="string" name="api_key" required="false" type="header"/>
+            <param dataType="integer" description="Pet id to delete" name="petId" required="true" type="path"/>
+            <to uri="direct:deletePet"/>
+        </delete>
+        <post consumes="multipart/form-data" customId="true" id="uploadFile" produces="application/json" uri="/pet/{petId}/uploadImage">
+            <param dataType="integer" description="ID of pet to update" name="petId" required="true" type="path"/>
+            <param dataType="string" description="Additional data to pass to server" name="additionalMetadata" required="false" type="formData"/>
+            <param dataType="file" description="file to upload" name="file" required="false" type="formData"/>
+            <to uri="direct:uploadFile"/>
+        </post>
+        <get customId="true" id="getInventory" produces="application/json" uri="/store/inventory">
+            <description>Returns a map of status codes to quantities</description>
+            <to uri="direct:getInventory"/>
+        </get>
+        <post customId="true" id="placeOrder" produces="application/xml,application/json" uri="/store/order">
+            <param description="order placed for purchasing the pet" name="body" required="true" type="body"/>
+            <to uri="direct:placeOrder"/>
+        </post>
+        <get customId="true" id="getOrderById" produces="application/xml,application/json" uri="/store/order/{orderId}">
+            <description>For valid response try integer IDs with value &gt;= 1 and &lt;= 10. Other values will generated exceptions</description>
+            <param dataType="integer" description="ID of pet that needs to be fetched" name="orderId" required="true" type="path"/>
+            <to uri="direct:getOrderById"/>
+        </get>
+        <delete customId="true" id="deleteOrder" produces="application/xml,application/json" uri="/store/order/{orderId}">
+            <description>For valid response try integer IDs with positive integer value. Negative or non-integer values will generate API errors</description>
+            <param dataType="integer" description="ID of the order that needs to be deleted" name="orderId" required="true" type="path"/>
+            <to uri="direct:deleteOrder"/>
+        </delete>
+        <post customId="true" id="createUser" produces="application/xml,application/json" uri="/user">
+            <description>This can only be done by the logged in user.</description>
+            <param description="Created user object" name="body" required="true" type="body"/>
+            <to uri="direct:createUser"/>
+        </post>
+        <post customId="true" id="createUsersWithArrayInput" produces="application/xml,application/json" uri="/user/createWithArray">
+            <param description="List of user object" name="body" required="true" type="body"/>
+            <to uri="direct:createUsersWithArrayInput"/>
+        </post>
+        <post customId="true" id="createUsersWithListInput" produces="application/xml,application/json" uri="/user/createWithList">
+            <param description="List of user object" name="body" required="true" type="body"/>
+            <to uri="direct:createUsersWithListInput"/>
+        </post>
+        <get customId="true" id="loginUser" produces="application/xml,application/json" uri="/user/login">
+            <param dataType="string" description="The user name for login" name="username" required="true" type="query"/>
+            <param dataType="string" description="The password for login in clear text" name="password" required="true" type="query"/>
+            <to uri="direct:loginUser"/>
+        </get>
+        <get customId="true" id="logoutUser" produces="application/xml,application/json" uri="/user/logout">
+            <to uri="direct:logoutUser"/>
+        </get>
+        <get customId="true" id="getUserByName" produces="application/xml,application/json" uri="/user/{username}">
+            <param dataType="string" description="The name that needs to be fetched. Use user1 for testing. " name="username" required="true" type="path"/>
+            <to uri="direct:getUserByName"/>
+        </get>
+        <put customId="true" id="updateUser" produces="application/xml,application/json" uri="/user/{username}">
+            <description>This can only be done by the logged in user.</description>
+            <param dataType="string" description="name that need to be updated" name="username" required="true" type="path"/>
+            <param description="Updated user object" name="body" required="true" type="body"/>
+            <to uri="direct:updateUser"/>
+        </put>
+        <delete customId="true" id="deleteUser" produces="application/xml,application/json" uri="/user/{username}">
+            <description>This can only be done by the logged in user.</description>
+            <param dataType="string" description="The name that needs to be deleted" name="username" required="true" type="path"/>
+            <to uri="direct:deleteUser"/>
+        </delete>
+    </rest>
+</rests>

-- 
To stop receiving notification emails like this one, please contact
davsclaus@apache.org.