Bug-915: Adding static document generation.
[controller.git] / opendaylight / md-sal / sal-rest-docgen / src / main / java / org / opendaylight / controller / sal / rest / doc / impl / StaticDocGenerator.java
1 /*
2  * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.controller.sal.rest.doc.impl;
9
10 import com.fasterxml.jackson.databind.ObjectMapper;
11 import com.fasterxml.jackson.databind.SerializationFeature;
12
13 import org.apache.maven.plugin.logging.Log;
14 import org.apache.maven.project.MavenProject;
15 import org.opendaylight.controller.sal.rest.doc.swagger.ApiDeclaration;
16 import org.opendaylight.controller.sal.rest.doc.swagger.Resource;
17 import org.opendaylight.controller.sal.rest.doc.swagger.ResourceList;
18 import org.opendaylight.yangtools.yang.model.api.Module;
19 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
20 import org.slf4j.Logger;
21 import org.slf4j.LoggerFactory;
22 import org.opendaylight.yangtools.yang2sources.spi.CodeGenerator;
23
24 import javax.ws.rs.core.UriInfo;
25 import java.io.BufferedWriter;
26 import java.io.File;
27 import java.io.FileWriter;
28 import java.io.IOException;
29 import java.text.SimpleDateFormat;
30 import java.util.ArrayList;
31 import java.util.Collection;
32 import java.util.List;
33 import java.util.Map;
34 import java.util.Set;
35
36 /**
37  * This class gathers all yang defined {@link Module}s and generates Swagger compliant documentation.
38  */
39 public class StaticDocGenerator extends ApiDocGenerator implements CodeGenerator {
40
41     private static final String DEFAULT_OUTPUT_BASE_DIR_PATH = "target" + File.separator + "generated-resources"
42         + File.separator + "swagger-api-documentation";
43
44     private static Logger _logger = LoggerFactory.getLogger(ApiDocGenerator.class);
45
46     private MavenProject mavenProject;
47     private File projectBaseDir;
48     private Map<String, String> additionalConfig;
49     private File resourceBaseDir;
50     private static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
51
52     /**
53      *
54      * @param context
55      * @param outputDir
56      * @param yangModules
57      * @return
58      * @throws IOException
59      */
60     @Override
61     public Collection<File> generateSources(SchemaContext context, File outputDir, Set<Module> yangModules) throws IOException {
62         List<File> result = new ArrayList<>();
63
64         // Create Base Directory
65         final File outputBaseDir;
66         if (outputDir == null) {
67             outputBaseDir = new File(DEFAULT_OUTPUT_BASE_DIR_PATH);
68         }
69         else outputBaseDir = outputDir;
70         outputBaseDir.mkdirs();
71
72         // Create Resources directory
73         File resourcesDir = new File(outputBaseDir, "resources");
74         resourcesDir.mkdirs();
75
76         // Create JS file
77         File resourcesJsFile = new File(outputBaseDir, "resources.js");
78         resourcesJsFile.createNewFile();
79         BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(resourcesJsFile));
80         ObjectMapper mapper = new ObjectMapper();
81         mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
82
83         // Write resource listing to JS file
84         ResourceList resourceList = super.getResourceListing(null, context, "");
85         String resourceListJson = mapper.writeValueAsString(resourceList);
86         resourceListJson = resourceListJson.replace("\'", "\\\'").replace("\\n", "\\\\n");
87         bufferedWriter.write("function getSpec() {\n\treturn \'" + resourceListJson + "\';\n}\n\n");
88
89         // Write resources/APIs to JS file and to disk
90         bufferedWriter.write("function jsonFor(resource) {\n\tswitch(resource) {\n");
91         for (Resource resource : resourceList.getApis()) {
92             int revisionIndex = resource.getPath().indexOf('(');
93             String name = resource.getPath().substring(0, revisionIndex);
94             String revision = resource.getPath().substring(revisionIndex + 1, resource.getPath().length() - 1);
95             ApiDeclaration apiDeclaration = super.getApiDeclaration(name, revision, null, context, "");
96             String json = mapper.writeValueAsString(apiDeclaration);
97             // Manually insert models because org.json.JSONObject cannot be serialized by ObjectMapper
98             json = json.replace("\"models\":{}", "\"models\":" + apiDeclaration.getModels().toString().replace("\\\"", "\""));
99             // Escape single quotes and new lines
100             json = json.replace("\'", "\\\'").replace("\\n", "\\\\n");
101             bufferedWriter.write("\t\tcase \"" + name + "(" + revision + ")\": return \'" + json + "\';\n");
102
103             File resourceFile = new File(resourcesDir, name + "(" + revision + ").json");
104             BufferedWriter resourceFileWriter = new BufferedWriter(new FileWriter(resourceFile));
105             resourceFileWriter.write(json);
106             resourceFileWriter.close();
107             result.add(resourceFile);
108         }
109         bufferedWriter.write("\t}\n\treturn \"\";\n}");
110         bufferedWriter.close();
111
112         result.add(resourcesJsFile);
113         return result;
114     }
115
116     @Override
117     protected String generatePath(UriInfo uriInfo, String name, String revision) {
118         if (uriInfo == null) {
119             return name + "(" + revision + ")";
120         }
121         return super.generatePath(uriInfo, name, revision);
122     }
123
124     @Override
125     protected String createBasePathFromUriInfo(UriInfo uriInfo) {
126         if (uriInfo == null) {
127             return RESTCONF_CONTEXT_ROOT;
128         }
129         return super.createBasePathFromUriInfo(uriInfo);
130     }
131
132     @Override
133     public void setLog(Log log) {
134     }
135
136     @Override
137     public void setAdditionalConfig(Map<String, String> additionalConfig) {
138         this.additionalConfig = additionalConfig;
139     }
140
141     @Override
142     public void setResourceBaseDir(File resourceBaseDir) {
143         this.resourceBaseDir = resourceBaseDir;
144     }
145
146     @Override
147     public void setMavenProject(MavenProject mavenProject) {
148         this.mavenProject = mavenProject;
149         this.projectBaseDir = mavenProject.getBasedir();
150     }
151 }

©2013 OpenDaylight, A Linux Foundation Collaborative Project. All Rights Reserved.
OpenDaylight is a registered trademark of The OpenDaylight Project, Inc.
Linux Foundation and OpenDaylight are registered trademarks of the Linux Foundation.
Linux is a registered trademark of Linus Torvalds.