Repository: cxf Updated Branches: refs/heads/master 5e2d2a1a6 -> 3b08b6301
[CXF-7464]add java2swagger maven plugin so that can generate swagger(json/yaml) during build time Project: http://git-wip-us.apache.org/repos/asf/cxf/repo Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/3b08b630 Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/3b08b630 Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/3b08b630 Branch: refs/heads/master Commit: 3b08b6301343406f5f312fd4d0f385a6227775a2 Parents: 5e2d2a1 Author: Freeman Fang <[email protected]> Authored: Wed Aug 2 15:49:18 2017 +0800 Committer: Freeman Fang <[email protected]> Committed: Wed Aug 2 15:49:18 2017 +0800 ---------------------------------------------------------------------- maven-plugins/java2swagger-plugin/pom.xml | 214 +++++++++++++ .../java2swagger/Java2SwaggerMojo.java | 317 +++++++++++++++++++ maven-plugins/pom.xml | 1 + 3 files changed, 532 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cxf/blob/3b08b630/maven-plugins/java2swagger-plugin/pom.xml ---------------------------------------------------------------------- diff --git a/maven-plugins/java2swagger-plugin/pom.xml b/maven-plugins/java2swagger-plugin/pom.xml new file mode 100644 index 0000000..455b4ff --- /dev/null +++ b/maven-plugins/java2swagger-plugin/pom.xml @@ -0,0 +1,214 @@ +<?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/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + <groupId>org.apache.cxf</groupId> + <artifactId>cxf-java2swagger-plugin</artifactId> + <packaging>maven-plugin</packaging> + <version>3.2.0-SNAPSHOT</version> + <name>Apache CXF Java2Swagger Maven2 Plugin</name> + <description>Apache CXF Java2Swagger Maven2 Plugin</description> + <url>http://cxf.apache.org</url> + + <parent> + <groupId>org.apache.cxf</groupId> + <artifactId>cxf-maven-plugins</artifactId> + <version>3.2.0-SNAPSHOT</version> + </parent> + <properties> + <cxf.manifest.location /> + </properties> + + <dependencies> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.maven.shared</groupId> + <artifactId>maven-artifact-resolver</artifactId> + <version>1.0</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-core</artifactId> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-compat</artifactId> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-artifact</artifactId> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-plugin-api</artifactId> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.codehaus.plexus</groupId> + <artifactId>plexus-utils</artifactId> + <version>2.0.5</version> + </dependency> + <dependency> + <groupId>org.codehaus.plexus</groupId> + <artifactId>plexus-archiver</artifactId> + <version>1.2</version> + </dependency> + + <dependency> + <groupId>org.apache.cxf</groupId> + <artifactId>cxf-tools-common</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.apache.cxf</groupId> + <artifactId>cxf-tools-wadlto-jaxrs</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-core</artifactId> + <optional>true</optional> + </dependency> + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-beans</artifactId> + <optional>true</optional> + </dependency> + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-context</artifactId> + <optional>true</optional> + </dependency> + + <dependency> + <groupId>org.apache.ant</groupId> + <artifactId>ant</artifactId> + </dependency> + <dependency> + <groupId>org.apache.ant</groupId> + <artifactId>ant-nodeps</artifactId> + </dependency> + + <dependency> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-javadoc-plugin</artifactId> + <version>2.10.3</version> + <exclusions> + <exclusion> + <groupId>org.apache.maven</groupId> + <artifactId>maven-project</artifactId> + </exclusion> + <exclusion> + <groupId>org.apache.maven</groupId> + <artifactId>maven-artifact-manager</artifactId> + </exclusion> + <exclusion> + <groupId>org.apache.maven</groupId> + <artifactId>maven-toolchain</artifactId> + </exclusion> + </exclusions> + </dependency> + + <dependency> + <groupId>com.sun</groupId> + <artifactId>tools</artifactId> + <version>1.7.0</version> + <scope>system</scope> + <systemPath>${java.home}/../lib/tools.jar</systemPath> + </dependency> + <dependency> + <groupId>org.apache.cxf</groupId> + <artifactId>cxf-rt-rs-service-description-swagger</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> + + + <profiles> + <profile> + <id>ibmjdk</id> + <activation> + <property> + <name>java.vendor</name> + <value>IBM Corporation</value> + </property> + </activation> + <dependencies> + <dependency> + <groupId>xerces</groupId> + <artifactId>xercesImpl</artifactId> + </dependency> + </dependencies> + </profile> + <profile> + <id>mac-jdk16</id> + <activation> + <file> + <exists>${java.home}/../Classes/classes.jar</exists> + </file> + </activation> + <dependencies> + <dependency> + <groupId>com.sun</groupId> + <artifactId>tools</artifactId> + <version>1.6.0</version> + <scope>system</scope> + <systemPath>${java.home}/../Classes/classes.jar</systemPath> + </dependency> + </dependencies> + </profile> + <profile> + <id>setup.eclipse</id> + <build> + <defaultGoal>process-test-sources</defaultGoal> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-antrun-plugin</artifactId> + <executions> + <execution> + <id>setup.eclipse.project.wadl2java</id> + <phase>process-test-sources</phase> + <configuration> + <target> + <!-- The javadoc dumping capability requires com.sun classes from with rt/classes.jar --> + <propertyfile file="${basedir}/.settings/org.eclipse.jdt.core.prefs"> + <entry key="org.eclipse.jdt.core.compiler.problem.forbiddenReference" value="ignore" /> + </propertyfile> + </target> + </configuration> + <goals> + <goal>run</goal> + </goals> + </execution> + </executions> + </plugin> + </plugins> + </build> + </profile> + </profiles> +</project> http://git-wip-us.apache.org/repos/asf/cxf/blob/3b08b630/maven-plugins/java2swagger-plugin/src/main/java/org/apache/cxf/maven_plugin/java2swagger/Java2SwaggerMojo.java ---------------------------------------------------------------------- diff --git a/maven-plugins/java2swagger-plugin/src/main/java/org/apache/cxf/maven_plugin/java2swagger/Java2SwaggerMojo.java b/maven-plugins/java2swagger-plugin/src/main/java/org/apache/cxf/maven_plugin/java2swagger/Java2SwaggerMojo.java new file mode 100644 index 0000000..ec31e28 --- /dev/null +++ b/maven-plugins/java2swagger-plugin/src/main/java/org/apache/cxf/maven_plugin/java2swagger/Java2SwaggerMojo.java @@ -0,0 +1,317 @@ +/** + * 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.cxf.maven_plugin.java2swagger; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.lang.annotation.Annotation; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.ArrayList; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.core.util.DefaultPrettyPrinter; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.ObjectWriter; +import com.fasterxml.jackson.databind.SerializationFeature; + +import org.apache.cxf.helpers.FileUtils; +import org.apache.maven.plugin.AbstractMojo; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.project.MavenProject; +import org.apache.maven.project.MavenProjectHelper; +import org.reflections.Reflections; + +import io.swagger.annotations.Api; +import io.swagger.jaxrs.Reader; +import io.swagger.models.Contact; +import io.swagger.models.Info; +import io.swagger.models.License; +import io.swagger.models.Scheme; +import io.swagger.models.Swagger; +import io.swagger.util.Yaml; + + + +/** + * @goal java2swagger + * @description CXF Java To swagger payload Tool + * @requiresDependencyResolution test + * @threadSafe + */ +public class Java2SwaggerMojo extends AbstractMojo { + + /** + * @parameter + * @required + */ + private List<String> resourcePackages; + + /** + * @parameter default-value="1.0.0" + */ + private String version; + + + /** + * @parameter default-value="/api" + */ + private String basePath; + + /** + * @parameter default-value="Sample REST Application" + */ + private String title; + + + /** + * @parameter default-value="The Application" + */ + private String description; + + + /** + * @parameter default-value="[email protected]" + */ + private String contact; + + + /** + * @parameter default-value="Apache 2.0 License" + */ + private String license; + + /** + * @parameter default-value="http://www.apache.org/licenses/LICENSE-2.0.html" + */ + private String licenseUrl; + + /** + * @parameter default-value="example.cxf.apache.org:8181" + */ + private String host; + + /** + * @parameter + */ + private List<String> schemes; + + + /** + * @parameter default-value="json" + */ + private String payload; + + + /** + * @parameter + */ + private String outputFile; + + + /** + * Attach the generated swagger file to the list of files to be deployed + * on install. This means the swagger file will be copied to the repository + * with groupId, artifactId and version of the project and type "json" or "yaml". + * <p/> + * With this option you can use the maven repository as a Service Repository. + * + * @parameter default-value="false" + */ + private Boolean attachSwagger; + + + /** + * @parameter + */ + private String classifier; + + + /** + * @parameter expression="${project}" + * @required + */ + private MavenProject project; + + + /** + * Maven ProjectHelper. + * + * @component + * @readonly + */ + private MavenProjectHelper projectHelper; + + + /** + * @parameter + */ + private String outputFileName; + + + private ClassLoader resourceClassLoader; + + private Swagger swagger; + + private ObjectMapper mapper = new ObjectMapper(); + + private Set<Class<?>> resourceClasses; + + + public void execute() throws MojoExecutionException { + try { + configureSwagger(); + loadSwaggerAnnotation(); + generateSwaggerPayLoad(); + } catch (Exception ex) { + ex.printStackTrace(); + } + } + + + private void generateSwaggerPayLoad() throws MojoExecutionException { + + if (outputFile == null && project != null) { + // Put the json in target/generated/json + // put the yaml in target/generated/yaml + + String name = null; + if (outputFileName != null) { + name = outputFileName; + } else if (resourceClasses.size() == 1) { + name = resourceClasses.iterator().next().getSimpleName(); + } else { + name = "swagger"; + } + outputFile = (project.getBuild().getDirectory() + "/generated/" + payload.toLowerCase() + "/" + name + "." + + payload.toLowerCase()).replace("/", File.separator); + } + + BufferedWriter writer = null; + try { + FileUtils.mkDir(new File(outputFile).getParentFile()); + writer = new BufferedWriter(new FileWriter(outputFile)); + if ("json".equals(this.payload)) { + ObjectWriter jsonWriter = mapper.writer(new DefaultPrettyPrinter()); + writer.write(jsonWriter.writeValueAsString(swagger)); + } else if ("yaml".equals(this.payload)) { + writer.write(Yaml.pretty().writeValueAsString(swagger)); + } + + } catch (IOException e) { + throw new MojoExecutionException(e.getMessage(), e); + } finally { + try { + if (writer != null) { + writer.close(); + } + } catch (IOException e) { + throw new MojoExecutionException(e.getMessage(), e); + } + } + // Attach the generated swagger file to the artifacts that get deployed + // with the enclosing project + if (attachSwagger && outputFile != null) { + File jsonFile = new File(outputFile); + if (jsonFile.exists()) { + if (classifier != null) { + projectHelper.attachArtifact(project, payload.toLowerCase(), classifier, jsonFile); + } else { + projectHelper.attachArtifact(project, payload.toLowerCase(), jsonFile); + } + + } + } + } + + + private ClassLoader getClassLoader() throws MojoExecutionException { + if (resourceClassLoader == null) { + try { + List<?> runtimeClasspathElements = project.getRuntimeClasspathElements(); + URL[] runtimeUrls = new URL[runtimeClasspathElements.size()]; + for (int i = 0; i < runtimeClasspathElements.size(); i++) { + String element = (String) runtimeClasspathElements.get(i); + runtimeUrls[i] = new File(element).toURI().toURL(); + } + resourceClassLoader = new URLClassLoader(runtimeUrls, Thread.currentThread() + .getContextClassLoader()); + } catch (Exception e) { + throw new MojoExecutionException(e.getMessage(), e); + } + } + return resourceClassLoader; + } + + private Set<Class<?>> loadResourceClasses(Class<? extends Annotation> clazz) throws MojoExecutionException { + resourceClasses = new LinkedHashSet<Class<?>>(this.resourcePackages.size()); + Thread.currentThread().setContextClassLoader(getClassLoader()); + for (String resourcePackage : resourcePackages) { + Set<Class<?>> c = new Reflections(resourcePackage).getTypesAnnotatedWith(clazz, true); + resourceClasses.addAll(c); + Set<Class<?>> inherited = new Reflections(resourcePackage).getTypesAnnotatedWith(clazz); + resourceClasses.addAll(inherited); + } + + return resourceClasses; + } + + + + private void loadSwaggerAnnotation() throws MojoExecutionException { + Reader reader = new Reader(swagger); + swagger = reader.read(loadResourceClasses(Api.class)); + } + + private void configureSwagger() { + swagger = new Swagger(); + mapper.configure(SerializationFeature.WRITE_EMPTY_JSON_ARRAYS, false); + mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); + Info info = new Info(); + Contact swaggerContact = new Contact(); + License swaggerLicense = new License(); + swaggerLicense.name(this.license) + .url(this.licenseUrl); + swaggerContact.email(this.contact) + .name("Apache CXF") + .url("http://cxf.apache.org/"); + info.version(this.version) + .description(this.description) + .contact(swaggerContact) + .license(swaggerLicense) + .title(this.title); + swagger.setInfo(info); + if (this.schemes == null || this.schemes.size() == 0) { + this.schemes = new ArrayList<String>(); + this.schemes.add("http"); + this.schemes.add("https"); + } + for (String scheme : this.schemes) { + swagger.scheme(Scheme.forValue(scheme)); + } + swagger.setHost(this.host); + swagger.setBasePath(this.basePath); + } +} http://git-wip-us.apache.org/repos/asf/cxf/blob/3b08b630/maven-plugins/pom.xml ---------------------------------------------------------------------- diff --git a/maven-plugins/pom.xml b/maven-plugins/pom.xml index 6ce0ae4..598f893 100644 --- a/maven-plugins/pom.xml +++ b/maven-plugins/pom.xml @@ -37,6 +37,7 @@ <module>codegen-plugin</module> <module>java2ws-plugin</module> <module>java2wadl-plugin</module> + <module>java2swagger-plugin</module> <module>wsdl-validator-plugin</module> <module>wadl2java-plugin</module> <module>corba</module>
