Skip to content

Commit 5d581c3

Browse files
committed
Fixes #429: Handling of composed models has been added.
1 parent 087c28d commit 5d581c3

File tree

4 files changed

+126
-112
lines changed

4 files changed

+126
-112
lines changed

modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/DefaultCodegen.java

Lines changed: 90 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,30 @@
11
package com.wordnik.swagger.codegen;
22

3+
import java.io.File;
4+
import java.util.ArrayList;
5+
import java.util.Arrays;
6+
import java.util.Collection;
7+
import java.util.Collections;
8+
import java.util.HashMap;
9+
import java.util.HashSet;
10+
import java.util.Iterator;
11+
import java.util.List;
12+
import java.util.Map;
13+
import java.util.Set;
14+
import java.util.regex.Matcher;
15+
import java.util.regex.Pattern;
16+
17+
import javax.annotation.Nullable;
18+
19+
import org.apache.commons.lang.StringUtils;
20+
import org.slf4j.Logger;
21+
import org.slf4j.LoggerFactory;
22+
323
import com.google.common.base.Function;
424
import com.google.common.collect.Lists;
5-
625
import com.wordnik.swagger.codegen.examples.ExampleGenerator;
726
import com.wordnik.swagger.models.ArrayModel;
27+
import com.wordnik.swagger.models.ComposedModel;
828
import com.wordnik.swagger.models.Model;
929
import com.wordnik.swagger.models.ModelImpl;
1030
import com.wordnik.swagger.models.Operation;
@@ -40,27 +60,9 @@
4060
import com.wordnik.swagger.models.properties.StringProperty;
4161
import com.wordnik.swagger.util.Json;
4262

43-
import javax.annotation.Nullable;
44-
import java.io.File;
45-
import java.util.ArrayList;
46-
import java.util.Arrays;
47-
import java.util.HashMap;
48-
import java.util.HashSet;
49-
import java.util.Iterator;
50-
import java.util.List;
51-
import java.util.Map;
52-
import java.util.Set;
53-
import java.util.regex.Matcher;
54-
import java.util.regex.Pattern;
55-
56-
import org.apache.commons.lang.StringUtils;
57-
58-
import org.slf4j.Logger;
59-
import org.slf4j.LoggerFactory;
60-
6163

6264
public class DefaultCodegen {
63-
Logger LOGGER = LoggerFactory.getLogger(DefaultCodegen.class);
65+
private static final Logger LOGGER = LoggerFactory.getLogger(DefaultCodegen.class);
6466

6567
protected String outputFolder = "";
6668
protected Set<String> defaultIncludes = new HashSet<String>();
@@ -473,100 +475,28 @@ public CodegenModel fromModel(String name, Model model) {
473475
m.classVarName = toVarName(name);
474476
m.modelJson = Json.pretty(model);
475477
m.externalDocs = model.getExternalDocs();
476-
int count = 0;
477478
if(model instanceof ArrayModel) {
478479
ArrayModel am = (ArrayModel) model;
479480
ArrayProperty arrayProperty = new ArrayProperty(am.getItems());
480-
CodegenProperty cp = fromProperty(name, arrayProperty);
481-
if(cp.complexType != null && !defaultIncludes.contains(cp.complexType))
482-
m.imports.add(cp.complexType);
483-
m.parent = toInstantiationType(arrayProperty);
484-
String containerType = cp.containerType;
485-
if(instantiationTypes.containsKey(containerType))
486-
m.imports.add(instantiationTypes.get(containerType));
487-
if(typeMapping.containsKey(containerType)) {
488-
containerType = typeMapping.get(containerType);
489-
cp.containerType = containerType;
490-
m.imports.add(containerType);
491-
}
481+
addParentContainer(m, name, arrayProperty);
492482
}
493483
else if (model instanceof RefModel) {
494484
// TODO
495-
}
496-
else {
485+
} else if (model instanceof ComposedModel) {
486+
final ComposedModel composed = (ComposedModel) model;
487+
final RefModel parent = (RefModel) composed.getParent();
488+
final String parentModel = toModelName(parent.getSimpleRef());
489+
m.parent = parentModel;
490+
addImport(m, parentModel);
491+
final ModelImpl child = (ModelImpl) composed.getChild();
492+
addVars(m, child.getProperties(), child.getRequired());
493+
} else {
497494
ModelImpl impl = (ModelImpl) model;
498495
if(impl.getAdditionalProperties() != null) {
499496
MapProperty mapProperty = new MapProperty(impl.getAdditionalProperties());
500-
CodegenProperty cp = fromProperty(name, mapProperty);
501-
if(cp.complexType != null && !defaultIncludes.contains(cp.complexType))
502-
m.imports.add(cp.complexType);
503-
m.parent = toInstantiationType(mapProperty);
504-
String containerType = cp.containerType;
505-
if(instantiationTypes.containsKey(containerType))
506-
m.imports.add(instantiationTypes.get(containerType));
507-
if(typeMapping.containsKey(containerType)) {
508-
containerType = typeMapping.get(containerType);
509-
cp.containerType = containerType;
510-
m.imports.add(containerType);
511-
}
512-
}
513-
if(impl.getProperties() != null && impl.getProperties().size() > 0) {
514-
m.hasVars = true;
515-
m.hasEnums = false;
516-
for(String key: impl.getProperties().keySet()) {
517-
Property prop = impl.getProperties().get(key);
518-
519-
if(prop == null) {
520-
LOGGER.warn("null property for " + key);
521-
}
522-
else {
523-
CodegenProperty cp;
524-
try{
525-
cp = fromProperty(key, prop);
526-
}
527-
catch(Exception e) {
528-
System.out.println("failed to process model " + name);
529-
throw new RuntimeException(e);
530-
}
531-
cp.required = null;
532-
if(impl.getRequired() != null) {
533-
for(String req : impl.getRequired()) {
534-
if(key.equals(req))
535-
cp.required = true;
536-
}
537-
}
538-
if(cp.complexType != null && !defaultIncludes.contains(cp.complexType)) {
539-
m.imports.add(cp.complexType);
540-
}
541-
m.vars.add(cp);
542-
count += 1;
543-
if (cp.isEnum)
544-
m.hasEnums = true;
545-
if(count != impl.getProperties().keySet().size())
546-
cp.hasMore = new Boolean(true);
547-
if(cp.isContainer != null) {
548-
String arrayImport = typeMapping.get("array");
549-
if(arrayImport != null &&
550-
!languageSpecificPrimitives.contains(arrayImport) &&
551-
!defaultIncludes.contains(arrayImport))
552-
m.imports.add(arrayImport);
553-
}
554-
555-
if(cp.complexType != null &&
556-
!languageSpecificPrimitives.contains(cp.complexType) &&
557-
!defaultIncludes.contains(cp.complexType))
558-
m.imports.add(cp.complexType);
559-
560-
if(cp.baseType != null &&
561-
!languageSpecificPrimitives.contains(cp.baseType) &&
562-
!defaultIncludes.contains(cp.baseType))
563-
m.imports.add(cp.baseType);
564-
}
565-
}
566-
}
567-
else {
568-
m.emptyVars = true;
497+
addParentContainer(m, name, mapProperty);
569498
}
499+
addVars(m, impl.getProperties(), impl.getRequired());
570500
}
571501
return m;
572502
}
@@ -1149,6 +1079,62 @@ public void addOperationToGroup(String tag, String resourcePath, Operation opera
11491079
co.baseName = tag;
11501080
}
11511081

1082+
private void addParentContainer(CodegenModel m, String name, Property property) {
1083+
final CodegenProperty tmp = fromProperty(name, property);
1084+
addImport(m, tmp.complexType);
1085+
m.parent = toInstantiationType(property);
1086+
final String containerType = tmp.containerType;
1087+
final String instantiationType = instantiationTypes.get(containerType);
1088+
if (instantiationType != null) {
1089+
addImport(m, instantiationType);
1090+
}
1091+
final String mappedType = typeMapping.get(containerType);
1092+
if (mappedType != null) {
1093+
addImport(m, mappedType);
1094+
}
1095+
}
1096+
1097+
private void addImport(CodegenModel m, String type) {
1098+
if (type != null && !languageSpecificPrimitives.contains(type) && !defaultIncludes.contains(type)) {
1099+
m.imports.add(type);
1100+
}
1101+
}
1102+
1103+
private void addVars(CodegenModel m, Map<String, Property> properties, Collection<String> required) {
1104+
if (properties != null && properties.size() > 0) {
1105+
m.hasVars = true;
1106+
m.hasEnums = false;
1107+
final int totalCount = properties.size();
1108+
final Set<String> mandatory = required == null ? Collections.<String> emptySet() : new HashSet<String>(required);
1109+
int count = 0;
1110+
for (Map.Entry<String, Property> entry : properties.entrySet()) {
1111+
final String key = entry.getKey();
1112+
final Property prop = entry.getValue();
1113+
1114+
if (prop == null) {
1115+
LOGGER.warn("null property for " + key);
1116+
} else {
1117+
final CodegenProperty cp = fromProperty(key, prop);
1118+
cp.required = mandatory.contains(key) ? true : null;
1119+
if (cp.isEnum) {
1120+
m.hasEnums = true;
1121+
}
1122+
count += 1;
1123+
if (count != totalCount)
1124+
cp.hasMore = true;
1125+
if (cp.isContainer != null) {
1126+
addImport(m, typeMapping.get("array"));
1127+
}
1128+
addImport(m, cp.baseType);
1129+
addImport(m, cp.complexType);
1130+
m.vars.add(cp);
1131+
}
1132+
}
1133+
} else {
1134+
m.emptyVars = true;
1135+
}
1136+
}
1137+
11521138
/* underscore and camelize are copied from Twitter elephant bird
11531139
* https://github.com/twitter/elephant-bird/blob/master/core/src/main/java/com/twitter/elephantbird/util/Strings.java
11541140
*/
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package Java
2+
3+
import scala.collection.JavaConverters._
4+
5+
import org.junit.runner.RunWith
6+
import org.scalatest.FlatSpec
7+
import org.scalatest.Matchers
8+
import org.scalatest.junit.JUnitRunner
9+
import com.wordnik.swagger.codegen.languages.JavaClientCodegen
10+
import com.wordnik.swagger.models.ComposedModel
11+
import com.wordnik.swagger.models.ModelImpl
12+
import com.wordnik.swagger.models.RefModel
13+
import com.wordnik.swagger.models.properties.StringProperty
14+
15+
@RunWith(classOf[JUnitRunner])
16+
class JavaInheritanceTest extends FlatSpec with Matchers {
17+
it should "convert a composed model" in {
18+
val model = new ComposedModel().parent(new RefModel("Base")).child(new ModelImpl().additionalProperties(new StringProperty()))
19+
20+
val codegen = new JavaClientCodegen()
21+
val cm = codegen.fromModel("sample", model)
22+
23+
cm.name should be("sample")
24+
cm.classname should be("Sample")
25+
cm.parent should be("Base")
26+
cm.imports.asScala should be (Set("Base"))
27+
}
28+
}

modules/swagger-codegen/src/test/scala/Objc/ObjcModelTest.scala

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package objc
1+
package Objc
22

33
import com.wordnik.swagger.codegen.languages.ObjcClientCodegen
44
import com.wordnik.swagger.util.Json
@@ -217,8 +217,8 @@ class ObjcModelTest extends FlatSpec with Matchers {
217217
cm.description should be ("an array model")
218218
cm.vars.size should be (0)
219219
cm.parent should be ("NSMutableArray")
220-
cm.imports.size should be (3)
221-
(cm.imports.asScala.toSet & Set("SWGChildren", "NSArray", "NSMutableArray")).size should be (3)
220+
cm.imports.size should be (1)
221+
(cm.imports.asScala.toSet & Set("SWGChildren")).size should be (1)
222222
}
223223

224224
it should "convert an map model" in {
@@ -234,8 +234,8 @@ class ObjcModelTest extends FlatSpec with Matchers {
234234
cm.description should be ("an map model")
235235
cm.vars.size should be (0)
236236
cm.parent should be ("NSMutableDictionary")
237-
cm.imports.size should be (3)
238-
(cm.imports.asScala.toSet & Set("SWGChildren", "NSDictionary", "NSMutableDictionary")).size should be (3)
237+
cm.imports.size should be (1)
238+
(cm.imports.asScala.toSet & Set("SWGChildren")).size should be (1)
239239
}
240240

241241
it should "create proper imports per #316" in {

modules/swagger-codegen/src/test/scala/scala/ScalaModelTest.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package Java
1+
package scala
22

33
import com.wordnik.swagger.codegen.languages.ScalaClientCodegen
44
import com.wordnik.swagger.util.Json
@@ -218,8 +218,8 @@ class ScalaModelTest extends FlatSpec with Matchers {
218218
cm.description should be ("an array model")
219219
cm.vars.size should be (0)
220220
cm.parent should be ("ListBuffer[Children]")
221-
cm.imports.size should be (3)
222-
(cm.imports.asScala.toSet & Set("List", "ListBuffer", "Children")).size should be (3)
221+
cm.imports.size should be (2)
222+
(cm.imports.asScala.toSet & Set("ListBuffer", "Children")).size should be (2)
223223
}
224224

225225
it should "convert an map model" in {

0 commit comments

Comments
 (0)