Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions modules/swagger-codegen/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,9 @@
<relativePath>../..</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>com.wordnik</groupId>
<artifactId>swagger-codegen</artifactId>
<packaging>jar</packaging>
<name>swagger-codegen (core library)</name>
<version>2.1.1-M2-SNAPSHOT</version>
<build>
<sourceDirectory>src/main/java</sourceDirectory>
<defaultGoal>install</defaultGoal>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package com.wordnik.swagger.codegen;

import java.util.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class CodegenResponse {
public String code, message;
public Boolean hasMore;
public List<Map<String, String>> examples;
public List<Map<String, Object>> examples;
public final List<CodegenProperty> headers = new ArrayList<CodegenProperty>();
public String dataType, baseType, containerType;
public Boolean simpleType;
Expand All @@ -14,4 +16,4 @@ public class CodegenResponse {
public Boolean isListContainer;
public Object schema;
public String jsonSchema;
}
}
Original file line number Diff line number Diff line change
@@ -1,26 +1,58 @@
package com.wordnik.swagger.codegen;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.wordnik.swagger.codegen.examples.ExampleGenerator;
import com.wordnik.swagger.models.*;
import com.wordnik.swagger.models.ArrayModel;
import com.wordnik.swagger.models.Model;
import com.wordnik.swagger.models.ModelImpl;
import com.wordnik.swagger.models.Operation;
import com.wordnik.swagger.models.RefModel;
import com.wordnik.swagger.models.Response;
import com.wordnik.swagger.models.Swagger;
import com.wordnik.swagger.models.auth.ApiKeyAuthDefinition;
import com.wordnik.swagger.models.auth.BasicAuthDefinition;
import com.wordnik.swagger.models.auth.In;
import com.wordnik.swagger.models.auth.SecuritySchemeDefinition;
import com.wordnik.swagger.models.parameters.*;
import com.wordnik.swagger.models.properties.*;
import com.wordnik.swagger.models.parameters.BodyParameter;
import com.wordnik.swagger.models.parameters.CookieParameter;
import com.wordnik.swagger.models.parameters.FormParameter;
import com.wordnik.swagger.models.parameters.HeaderParameter;
import com.wordnik.swagger.models.parameters.Parameter;
import com.wordnik.swagger.models.parameters.PathParameter;
import com.wordnik.swagger.models.parameters.QueryParameter;
import com.wordnik.swagger.models.parameters.SerializableParameter;
import com.wordnik.swagger.models.properties.AbstractNumericProperty;
import com.wordnik.swagger.models.properties.ArrayProperty;
import com.wordnik.swagger.models.properties.BooleanProperty;
import com.wordnik.swagger.models.properties.DateProperty;
import com.wordnik.swagger.models.properties.DateTimeProperty;
import com.wordnik.swagger.models.properties.DecimalProperty;
import com.wordnik.swagger.models.properties.DoubleProperty;
import com.wordnik.swagger.models.properties.FloatProperty;
import com.wordnik.swagger.models.properties.IntegerProperty;
import com.wordnik.swagger.models.properties.LongProperty;
import com.wordnik.swagger.models.properties.MapProperty;
import com.wordnik.swagger.models.properties.Property;
import com.wordnik.swagger.models.properties.PropertyBuilder;
import com.wordnik.swagger.models.properties.RefProperty;
import com.wordnik.swagger.models.properties.StringProperty;
import com.wordnik.swagger.util.Json;

import org.apache.commons.lang.StringUtils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.util.*;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class DefaultCodegen {
Logger LOGGER = LoggerFactory.getLogger(DefaultCodegen.class);

Expand Down Expand Up @@ -996,9 +1028,9 @@ public List<CodegenSecurity> fromSecurity(Map<String, SecuritySchemeDefinition>
if(schemes == null)
return null;

List<CodegenSecurity> secs = new ArrayList<CodegenSecurity>();
for(Iterator entries = schemes.entrySet().iterator(); entries.hasNext(); ) {
Map.Entry<String, SecuritySchemeDefinition> entry = (Map.Entry<String, SecuritySchemeDefinition>) entries.next();
List<CodegenSecurity> secs = new ArrayList<CodegenSecurity>(schemes.size());
for (Iterator<Map.Entry<String, SecuritySchemeDefinition>> it = schemes.entrySet().iterator(); it.hasNext();) {
final Map.Entry<String, SecuritySchemeDefinition> entry = it.next();
final SecuritySchemeDefinition schemeDefinition = entry.getValue();

CodegenSecurity sec = CodegenModelFactory.newInstance(CodegenModelType.SECURITY);
Expand All @@ -1018,23 +1050,22 @@ public List<CodegenSecurity> fromSecurity(Map<String, SecuritySchemeDefinition>
sec.isOAuth = !sec.isBasic;
}

sec.hasMore = entries.hasNext();
sec.hasMore = it.hasNext();
secs.add(sec);
}
return secs;
}

protected List<Map<String, String>> toExamples(Map<String, String> examples) {
protected List<Map<String, Object>> toExamples(Map<String, Object> examples) {
if(examples == null)
return null;

List<Map<String, String>> output = new ArrayList<Map<String, String>>();
for(String key: examples.keySet()) {
String value = examples.get(key);
final List<Map<String, Object>> output = new ArrayList<Map<String, Object>>(examples.size());
for(Map.Entry<String, Object> entry : examples.entrySet()) {

Map<String, String> kv = new HashMap<String, String>();
kv.put("contentType", key);
kv.put("example", value);
final Map<String, Object> kv = new HashMap<String, Object>();
kv.put("contentType", entry.getKey());
kv.put("example", entry.getValue());
output.add(kv);
}
return output;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,33 @@
package com.wordnik.swagger.codegen.examples;

import com.wordnik.swagger.models.*;
import com.wordnik.swagger.models.properties.*;
import com.wordnik.swagger.util.Json;

import java.text.SimpleDateFormat;


import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;


import java.math.BigDecimal;
import java.util.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.wordnik.swagger.models.Model;
import com.wordnik.swagger.models.ModelImpl;
import com.wordnik.swagger.models.properties.ArrayProperty;
import com.wordnik.swagger.models.properties.BooleanProperty;
import com.wordnik.swagger.models.properties.DateProperty;
import com.wordnik.swagger.models.properties.DateTimeProperty;
import com.wordnik.swagger.models.properties.DecimalProperty;
import com.wordnik.swagger.models.properties.DoubleProperty;
import com.wordnik.swagger.models.properties.FileProperty;
import com.wordnik.swagger.models.properties.FloatProperty;
import com.wordnik.swagger.models.properties.IntegerProperty;
import com.wordnik.swagger.models.properties.LongProperty;
import com.wordnik.swagger.models.properties.MapProperty;
import com.wordnik.swagger.models.properties.ObjectProperty;
import com.wordnik.swagger.models.properties.Property;
import com.wordnik.swagger.models.properties.RefProperty;
import com.wordnik.swagger.models.properties.StringProperty;
import com.wordnik.swagger.models.properties.UUIDProperty;
import com.wordnik.swagger.util.Json;

public class ExampleGenerator {
protected Map<String, Model> examples;
Expand All @@ -22,7 +36,7 @@ public ExampleGenerator(Map<String, Model> examples) {
this.examples = examples;
}

public List<Map<String, String>> generate(Map<String, String> examples, List<String> mediaTypes, Property property) {
public List<Map<String, String>> generate(Map<String, Object> examples, List<String> mediaTypes, Property property) {
List<Map<String, String>> output = new ArrayList<Map<String, String>>();
Set<String> processedModels = new HashSet<String>();
if(examples == null ) {
Expand All @@ -37,28 +51,24 @@ public List<Map<String, String>> generate(Map<String, String> examples, List<Str
String example = Json.pretty(resolvePropertyToExample(mediaType, property, processedModels));

if(example != null) {
example = example.replaceAll("\n", "\\\\n");
kv.put("example", example);
output.add(kv);
}
}
else if(property != null && mediaType.startsWith("application/xml")) {
String example = new XmlExampleGenerator(this.examples).toXml(property);
if(example != null) {
example = example.replaceAll("\n", "\\\\n");
kv.put("example", example);
output.add(kv);
}
}
}
}
else {
for(String key: examples.keySet()) {
String value = examples.get(key);

Map<String, String> kv = new HashMap<String, String>();
kv.put("contentType", key);
kv.put("example", value);
for(Map.Entry<String, Object> entry: examples.entrySet()) {
final Map<String, String> kv = new HashMap<String, String>();
kv.put("contentType", entry.getKey());
kv.put("example", Json.pretty(entry.getValue()));
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This piece has to be reworked as it renders examples into JSON view regardless of the contentType value.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tomtit I would recommend you to leave a comment (TODO) in the code so that someone can find out what needs to be done and potentially file a PR for that.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@wing328, I would like to rework this piece as a part of this PR. I realized the problem with contentType after the PR had been created. Perhaps @fehguy or @webron could provide some additional comments here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here is the note from discussion with @webron:

If the user provided:
"application/xml": {
"name": "Puma",
"type": "Dog",
"color": "Black",
"gender": "Female",
"breed": "Mixed"
}
we are going to show it just like that. A JSON.
If they want an XML there, let them put an XML inside a string.

So, the proposed changes provide exactly this functionality.

output.add(kv);
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
package com.wordnik.swagger.codegen.languages;

import com.wordnik.swagger.codegen.*;
import com.wordnik.swagger.util.Json;
import com.wordnik.swagger.models.properties.*;

import java.util.*;
import java.io.File;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import com.wordnik.swagger.codegen.CodegenConfig;
import com.wordnik.swagger.codegen.CodegenOperation;
import com.wordnik.swagger.codegen.CodegenParameter;
import com.wordnik.swagger.codegen.CodegenResponse;
import com.wordnik.swagger.codegen.CodegenType;
import com.wordnik.swagger.codegen.DefaultCodegen;
import com.wordnik.swagger.codegen.SupportingFile;

public class NodeJSServerCodegen extends DefaultCodegen implements CodegenConfig {
protected String apiVersion = "1.0.0";
Expand Down Expand Up @@ -156,8 +164,10 @@ public String apiFileFolder() {

@Override
public Map<String, Object> postProcessOperations(Map<String, Object> objs) {
Map<String, Object> objectMap = (Map<String, Object>)objs.get("operations");
List<CodegenOperation> operations = (List<CodegenOperation>)objectMap.get("operation");
@SuppressWarnings("unchecked")
Map<String, Object> objectMap = (Map<String, Object>) objs.get("operations");
@SuppressWarnings("unchecked")
List<CodegenOperation> operations = (List<CodegenOperation>) objectMap.get("operation");
for(CodegenOperation operation : operations) {
operation.httpMethod = operation.httpMethod.toLowerCase();
List<CodegenParameter> params = operation.allParams;
Expand All @@ -170,20 +180,14 @@ public Map<String, Object> postProcessOperations(Map<String, Object> objs) {
resp.code = "default";
}
}
if(operation.examples != null && operation.examples.size() > 0) {
List<Map<String, String>> examples = operation.examples;
for(int i = examples.size() - 1; i >= 0; i--) {
Map<String, String> example = examples.get(i);
String contentType = example.get("contentType");
if(contentType != null && contentType.indexOf("application/json") == 0) {
String jsonExample = example.get("example");
if(jsonExample != null) {
jsonExample = jsonExample.replaceAll("\\\\n", "\n");
example.put("example", jsonExample);
}
if(operation.examples != null && !operation.examples.isEmpty()) {
// Leave application/json* items only
for (Iterator<Map<String, String>> it = operation.examples.iterator(); it.hasNext();) {
final Map<String, String> example = it.next();
final String contentType = example.get("contentType");
if (contentType == null || !contentType.startsWith("application/json")) {
it.remove();
}
else
examples.remove(i);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
{{#examples}}
<h3 class="field-label">Example data</h3>
<div class="example-data-content-type">Content-Type: {{{contentType}}}</div>
<pre class="example"><code>{{{example}}}</code></pre>
<pre class="example"><code>{{example}}</code></pre>
{{/examples}}
</div> <!-- method -->
<hr>
Expand Down
12 changes: 12 additions & 0 deletions modules/swagger-codegen/src/test/resources/2_0/petstore.json
Original file line number Diff line number Diff line change
Expand Up @@ -720,6 +720,18 @@
"description": "successful operation",
"schema": {
"$ref": "#/definitions/User"
},
"examples": {
"application/json": {
"id": 1,
"username": "johnp",
"firstName": "John",
"lastName": "Public",
"email": "johnp@swagger.io",
"password": "-secret-",
"phone": "0123456789",
"userStatus": 0
}
}
},
"400": {
Expand Down
2 changes: 0 additions & 2 deletions modules/swagger-generator/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,9 @@
<version>2.1.1-M2-SNAPSHOT</version>
<relativePath>../..</relativePath>
</parent>
<groupId>com.wordnik</groupId>
<artifactId>swagger-generator</artifactId>
<packaging>war</packaging>
<name>swagger-generator</name>
<version>2.1.1-M2-SNAPSHOT</version>
<build>
<sourceDirectory>src/main/java</sourceDirectory>
<plugins>
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -440,7 +440,7 @@
<swagger-parser-version>1.0.6-SNAPSHOT</swagger-parser-version>
<scala-version>2.10.4</scala-version>
<felix-version>2.3.4</felix-version>
<swagger-core-version>1.5.1-M2</swagger-core-version>
<swagger-core-version>1.5.2-M2-SNAPSHOT</swagger-core-version>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tomtit - notice that this broke the build

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@webron, that is why I've referenced the swagger-api/swagger-core/pull/1002 pull request. The com.wordnik.swagger.models.Response from that change is required. Just don't know how to reference the develop_2.0 branch properly.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apologies, I had missed that comment. We can't depend on a SNAPSHOT here though. That means we'll have to wait until swagger-core is released and then modify this PR accordingly. Still not sure what version that's going to end up being.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tomtit There is a Java generator that uses examples but the code cannot be merged back to the official repo as the generated code is in Java 8 but swagger-codegen has to be built in Java 7 container.
Here is the repo
https://github.com/networknt/swagger-codegen
And here is the petstore generated
https://github.com/networknt/light-java-example/tree/master/petstore

<scala-test-version>2.1.4</scala-test-version>
<commons-io-version>2.3</commons-io-version>
<commons-cli-version>1.2</commons-cli-version>
Expand Down