Skip to content
This repository was archived by the owner on Sep 14, 2022. It is now read-only.

Commit 9edcd11

Browse files
committed
merged from develop
2 parents b9ab6b1 + 6c51e88 commit 9edcd11

File tree

6 files changed

+81
-49
lines changed

6 files changed

+81
-49
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ Which will include the proper cross-publish version of swagger-scala-module.
2727
## How does it work?
2828
Including the library in your project allows the swagger extension module to discover this module, bringing in the appropriate jackson library in the process. You can then use scala classes and objects in your swagger project.
2929

30+
## Treatment of `Option` and `required`
31+
All properties, besides those wrapped in `Option` or explicitly set via annotations `@ApiModelProperty(required = false)`, default to `required = true` in the generated swagger model. See [#7](https://github.com/swagger-api/swagger-scala-module/issues/7)
32+
3033
## Support
3134
The following methods are available to obtain support for Swagger:
3235

build.sbt

Lines changed: 24 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,9 @@ organization := "io.swagger"
88

99
version := "1.0.3"
1010

11-
// scala 2.12 requires jdk8. JDK8 cannot be used with 2.10 so crossbuilding won't work
12-
scalaVersion := "2.10.4"
11+
scalaVersion := "2.11.8"
1312

14-
crossScalaVersions := Seq("2.10.0", "2.10.1", "2.10.2", "2.10.3", "2.10.4", "2.10.6", "2.11.0", "2.11.1", "2.11.4", "2.11.7")
15-
16-
//scalaVersion := "2.12.0"
17-
18-
//crossScalaVersions := Seq(/*"2.10.0", "2.10.1", "2.10.2", "2.10.3", "2.10.4", "2.10.6", "2.11.0", "2.11.1", "2.11.4", "2.11.7",*/ "2.12.0")
13+
crossScalaVersions := Seq("2.10.6", scalaVersion.value, "2.12.1")
1914

2015
organizationHomepage in ThisBuild := Some(url("http://swagger.io"))
2116

@@ -34,8 +29,8 @@ libraryDependencies ++= Seq(
3429
"junit" % "junit" % "4.12" % "test"
3530
)
3631

37-
publishTo <<= (version) { version: String =>
38-
if (version.trim.endsWith("SNAPSHOT"))
32+
publishTo := {
33+
if (version.value.trim.endsWith("SNAPSHOT"))
3934
Some("Sonatype Nexus Snapshots" at "https://oss.sonatype.org/content/repositories/snapshots")
4035
else
4136
Some("Sonatype Nexus Releases" at "https://oss.sonatype.org/service/local/staging/deploy/maven2")
@@ -70,21 +65,23 @@ startYear := Some(2014)
7065

7166
licenses := Seq(("Apache License 2.0", new URL("http://www.apache.org/licenses/LICENSE-2.0.html")))
7267

73-
pomExtra <<= (pomExtra, name, description) {(pom, name, desc) => pom ++ Group(
74-
<scm>
75-
<connection>scm:git:git@github.com:swagger-api/swagger-scala-module.git</connection>
76-
<developerConnection>scm:git:git@github.com:swagger-api/swagger-scala-module.git</developerConnection>
77-
<url>https://github.com/swagger-api/swagger-scala-module</url>
78-
</scm>
79-
<issueManagement>
80-
<system>github</system>
81-
<url>https://github.com/swagger-api/swagger-scala-module/issues</url>
82-
</issueManagement>
83-
<developers>
84-
<developer>
85-
<id>fehguy</id>
86-
<name>Tony Tam</name>
87-
<email>fehguy@gmail.com</email>
88-
</developer>
89-
</developers>
90-
)}
68+
pomExtra := {
69+
pomExtra.value ++ Group(
70+
<scm>
71+
<connection>scm:git:git@github.com:swagger-api/swagger-scala-module.git</connection>
72+
<developerConnection>scm:git:git@github.com:swagger-api/swagger-scala-module.git</developerConnection>
73+
<url>https://github.com/swagger-api/swagger-scala-module</url>
74+
</scm>
75+
<issueManagement>
76+
<system>github</system>
77+
<url>https://github.com/swagger-api/swagger-scala-module/issues</url>
78+
</issueManagement>
79+
<developers>
80+
<developer>
81+
<id>fehguy</id>
82+
<name>Tony Tam</name>
83+
<email>fehguy@gmail.com</email>
84+
</developer>
85+
</developers>
86+
)
87+
}

project/build.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
sbt.version=0.13.5
1+
sbt.version=0.13.13

src/main/scala/io/swagger/scala/converter/SwaggerScalaModelConverter.scala

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import java.lang.annotation.Annotation
44
import java.lang.reflect.Type
55
import java.util.Iterator
66

7-
import com.fasterxml.jackson.databind.`type`.CollectionLikeType
7+
import com.fasterxml.jackson.databind.`type`.ReferenceType
88
import com.fasterxml.jackson.module.scala.DefaultScalaModule
99
import io.swagger.converter._
1010
import io.swagger.models.Model
@@ -32,26 +32,33 @@ class SwaggerScalaModelConverter extends ModelConverter {
3232
val sp = new StringProperty()
3333
for (v <- enumInstance.values)
3434
sp._enum(v.toString)
35+
sp.setRequired(true)
3536
return sp
3637
}
3738
case None =>
3839
if (cls.isAssignableFrom(classOf[BigDecimal])) {
39-
return PrimitiveType.DECIMAL.createProperty()
40+
val dp = PrimitiveType.DECIMAL.createProperty()
41+
dp.setRequired(true)
42+
return dp
4043
}
4144
}
4245
}
4346

4447
// Unbox scala options
45-
val nextType = `type` match {
46-
case clt: CollectionLikeType if isOption(cls) => clt.getContentType
47-
case _ => `type`
48-
}
49-
50-
if (chain.hasNext())
51-
chain.next().resolveProperty(nextType, context, annotations, chain)
52-
else
53-
null
48+
`type` match {
49+
case rt: ReferenceType if isOption(cls) && chain.hasNext => rt.getContentType
50+
val nextType = rt.getContentType
51+
val nextResolved = chain.next().resolveProperty(nextType, context, annotations, chain)
52+
nextResolved.setRequired(false)
53+
nextResolved
54+
case t if chain.hasNext =>
55+
val nextResolved = chain.next().resolveProperty(t, context, annotations, chain)
56+
nextResolved.setRequired(true)
57+
nextResolved
58+
case _ =>
59+
null
5460
}
61+
}
5562

5663
override
5764
def resolve(`type`: Type, context: ModelConverterContext, chain: Iterator[ModelConverter]): Model = {

src/test/scala/ModelPropertyParserTest.scala

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,12 @@
11
import io.swagger.converter._
22
import io.swagger.models.properties
3-
4-
import models._
5-
6-
import io.swagger.util.Json
73
import io.swagger.models.properties._
8-
9-
import scala.collection.JavaConverters._
10-
4+
import models._
115
import org.junit.runner.RunWith
126
import org.scalatest.junit.JUnitRunner
13-
import org.scalatest.FlatSpec
14-
import org.scalatest.Matchers
7+
import org.scalatest.{FlatSpec, Matchers}
8+
9+
import scala.collection.JavaConverters._
1510

1611
@RunWith(classOf[JUnitRunner])
1712
class ModelPropertyParserTest extends FlatSpec with Matchers {
@@ -59,5 +54,28 @@ class ModelPropertyParserTest extends FlatSpec with Matchers {
5954
model should be ('defined)
6055
val modelOpt = model.get.getProperties().get("field")
6156
modelOpt shouldBe a [properties.DecimalProperty]
57+
modelOpt.getRequired should be (true)
58+
}
59+
60+
it should "process all properties as required barring Option[_] or if overridden in annotation" in {
61+
val schemas = ModelConverters
62+
.getInstance()
63+
.readAll(classOf[ModelWithOptionAndNonOption])
64+
.asScala
65+
66+
val model = schemas("ModelWithOptionAndNonOption")
67+
model should not be (null)
68+
69+
val optional = model.getProperties().get("optional")
70+
optional.getRequired should be (false)
71+
72+
val required = model.getProperties().get("required")
73+
required.getRequired should be (true)
74+
75+
val forcedRequired = model.getProperties().get("forcedRequired")
76+
forcedRequired.getRequired should be (true)
77+
78+
val forcedOptional = model.getProperties().get("forcedOptional")
79+
forcedOptional.getRequired should be (false)
6280
}
6381
}

src/test/scala/models/ModelWOptionString.scala

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,11 @@ case class ModelWOptionString (
1414
@ApiModel(description = "An Option[Model] is not an array")
1515
case class ModelWOptionModel (
1616
@(ApiModelProperty @field)(value="this is an Option[Model] attribute") modelOpt: Option[ModelWOptionString]
17-
)
17+
)
18+
19+
case class ModelWithOptionAndNonOption(
20+
required: String,
21+
optional: Option[String],
22+
@ApiModelProperty(required = false) forcedOptional: String,
23+
@ApiModelProperty(required = true) forcedRequired: Option[String]
24+
)

0 commit comments

Comments
 (0)