net.wasdev.maven.plugins.swaggerdocgen.SwaggerProcessor.java Source code

Java tutorial

Introduction

Here is the source code for net.wasdev.maven.plugins.swaggerdocgen.SwaggerProcessor.java

Source

/**
* (C) Copyright IBM Corporation 2016.
*
* Licensed 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 net.wasdev.maven.plugins.swaggerdocgen;

import java.io.Closeable;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.logging.Logger;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;

import io.swagger.jaxrs.Reader;
import io.swagger.models.Path;
import io.swagger.models.Swagger;
import io.swagger.parser.SwaggerParser;
import io.swagger.util.Json;
import io.swagger.util.Yaml;

public class SwaggerProcessor {
    // Location of Swagger JSON doc in module
    private static final String DEFAULT_SWAGGER_JSON_LOCATION = "META-INF/swagger.json";

    // Location of Swagger JSON stub doc in module
    private static final String DEFAULT_SWAGGER_JSON_STUB_LOCATION = "META-INF/stub/swagger.json";

    // Location of Swagger YAML doc in module
    private static final String DEFAULT_SWAGGER_YAML_LOCATION = "META-INF/swagger.yaml";

    // Location of Swagger YAML stub doc in module
    private static final String DEFAULT_SWAGGER_YAML_STUB_LOCATION = "META-INF/stub/swagger.yaml";

    private final ClassLoader classLoader;
    private final File warFile;
    private final File outputFile;

    private static final Logger logger = Logger.getLogger(SwaggerProcessor.class.getName());

    public SwaggerProcessor(ClassLoader classLoader, File warFile, File outputFile) {
        this.classLoader = classLoader;
        this.warFile = warFile;
        this.outputFile = outputFile;
    }

    public void process() {
        final String document = getDocument();
        if (document != null) {
            OutputStreamWriter writer = null;
            try {
                writer = new OutputStreamWriter(new FileOutputStream(outputFile), "UTF-8");
                writer.write(document);
                writer.flush();
            } catch (IOException ioe) {
                logger.severe("Failed to write to the output document " + outputFile.getAbsolutePath());
            } finally {
                tryToClose(writer);
            }
        }
    }

    public String getDocument() {
        ZipFile warZipFile = null;
        try {
            warZipFile = new ZipFile(warFile);

            // Search for META-INF/swagger.json or META-INF/swagger.yaml in the
            // WAR
            ZipEntry entry = warZipFile.getEntry(DEFAULT_SWAGGER_JSON_LOCATION);
            if (entry == null) {
                entry = warZipFile.getEntry(DEFAULT_SWAGGER_YAML_LOCATION);
            }
            if (entry != null) {
                InputStream swaggerStream = warZipFile.getInputStream(entry);
                String swaggerDoc = getSwaggerDocFromStream(swaggerStream);
                // Swagger swaggerModel = new SwaggerParser().parse(swaggerDoc,
                // null, false);
                Swagger swaggerModel = new SwaggerParser().parse(swaggerDoc, null);

                return createYAMLfromPojo(swaggerModel);
            }

            // Search for META-INF/stub/swagger.json or
            // META-INF/stub/swagger.yaml in the WAR
            Swagger swaggerStubModel = null;
            entry = warZipFile.getEntry(DEFAULT_SWAGGER_JSON_STUB_LOCATION);
            if (entry == null) {
                entry = warZipFile.getEntry(DEFAULT_SWAGGER_YAML_STUB_LOCATION);
            }
            if (entry != null) {
                InputStream swaggerStream = warZipFile.getInputStream(entry);
                String swaggerDoc = getSwaggerDocFromStream(swaggerStream);
                swaggerStubModel = new SwaggerParser().parse(swaggerDoc, null);
            }
            // Scan the WAR for annotations and merge with the stub document.
            return getSwaggerDocFromAnnotatedClasses(warZipFile, swaggerStubModel);
        } catch (IOException ioe) {
            logger.severe("Failed to generate the Swagger document.");
        } finally {
            tryToClose(warZipFile);
        }
        return null;
    }

    private String getSwaggerDocFromStream(InputStream is) {
        try {
            return IOUtils.toString(is, "UTF-8"); // YAML document's format has
            // to be preserved
        } catch (IOException ioe) {
            logger.severe("Cannot read the Swagger document inside the application.");
        } finally {
            tryToClose(is);
        }
        return null;
    }

    private String getSwaggerDocFromAnnotatedClasses(ZipFile warZipFile, Swagger swaggerStubModel)
            throws IOException {
        SwaggerAnnotationsScanner annScan = new SwaggerAnnotationsScanner(classLoader, warZipFile);
        Set<Class<?>> classes = annScan.getScannedClasses();
        Reader reader = new Reader(swaggerStubModel);
        Set<String> stubPaths = null;
        if (swaggerStubModel != null && swaggerStubModel.getPaths() != null) {
            stubPaths = swaggerStubModel.getPaths().keySet();
        }
        Swagger swresult = reader.read(classes);
        swresult = addUrlMapping(swresult, stubPaths, annScan.getUrlMapping());
        String ext = FilenameUtils.getExtension(this.outputFile.getName());
        if (ext.equalsIgnoreCase("json")) {
            return createJSONfromPojo(swresult);
        } else if (ext.equalsIgnoreCase("yaml")) {
            return createYAMLfromPojo(swresult);
        }

        throw new IllegalArgumentException("Unsupported document type: " + ext);
    }

    private Swagger addUrlMapping(Swagger result, Set<String> ignorePaths, String urlMapping) {
        if (urlMapping == null || urlMapping == "") {
            return result;
        }

        Map<String, Path> paths = result.getPaths();
        Map<String, Path> newPaths = new HashMap<String, Path>();
        for (Entry<String, Path> pathEntry : paths.entrySet()) {
            if (ignorePaths != null && ignorePaths.contains(pathEntry.getKey())) {
                newPaths.put(pathEntry.getKey(), pathEntry.getValue());
                continue;
            }
            newPaths.put(urlMapping + pathEntry.getKey(), pathEntry.getValue());
        }
        result.setPaths(newPaths);
        return result;
    }

    private String createYAMLfromPojo(Object pojo) throws IOException {
        return Yaml.mapper().writeValueAsString(pojo);
    }

    private void tryToClose(Closeable c) {
        if (c != null) {
            try {
                c.close();
            } catch (IOException ioe) {
                logger.severe("Failed to successfully close the file.");
            }
        }
    }

    private String createJSONfromPojo(Object pojo) throws IOException {
        return Json.mapper().writeValueAsString(pojo);
    }
}