Skip to content
This repository has been archived by the owner on Apr 10, 2019. It is now read-only.

Commit

Permalink
#114, feature: Explicit model generation of cross-referenced parts in…
Browse files Browse the repository at this point in the history
…to each namespace using it
  • Loading branch information
slavaschmidt committed May 9, 2016
1 parent f9d0ca7 commit f661d83
Show file tree
Hide file tree
Showing 14 changed files with 710 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ trait CommonData {
case TypeRef(ref) =>
app.findType(ref) match {
case p: PrimitiveType => useType(p.name, suffix, "")
case d: TypeDef => useType(d.name, suffix, "")
case _ => useType(ref, suffix, "")
}
case p: PrimitiveType => useType(t.name, suffix, "")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ trait ClassesStep extends EnrichmentStep[Type] {
"fields" -> typeFields(table, k).map { f =>
Map(
"name" -> escape(f.name.simple),
"type_name" -> typeNameDenotation(table, f.tpe.name)
TYPE_NAME -> typeNameDenotation(table, f.tpe.name)
)
},
"imports" -> t.imports
Expand Down
22 changes: 22 additions & 0 deletions compiler/src/test/resources/examples/cross_spec_references.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
swagger: '2.0'
info:
version: "1.0.0"
title: An Example of cross - specification references
host: localhost:9000
schemes:
- http
paths:
/:
post:
parameters:
- name: root
in: body
required: true
schema:
$ref: "hackweek.yaml#/definitions/ModelSchemaRoot"
responses:
200:
description: Must have correct imports for cross-references specifications
schema:
$ref: "parts/split.petstore.definitions.yaml#/definitions/Pet"

Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package cross_spec_references.yaml

import play.api.mvc.{Action, Controller, Results}
import play.api.http._
import Results.Status
import de.zalando.play.controllers.{PlayBodyParsing, ParsingError, ResponseWriters}
import PlayBodyParsing._
import scala.util._
import de.zalando.play.controllers.ArrayWrapper




trait Cross_spec_referencesYamlBase extends Controller with PlayBodyParsing {
private type postActionRequestType = (ModelSchemaRoot)
private type postActionType = postActionRequestType => Try[(Int, Any)]

private val errorToStatuspost: PartialFunction[Throwable, Status] = PartialFunction.empty[Throwable, Status]

private def postParser(acceptedTypes: Seq[String], maxLength: Int = parse.DefaultMaxTextLength) = {
def bodyMimeType: Option[MediaType] => String = mediaType => {
val requestType = mediaType.toSeq.map {
case m: MediaRange => m
case MediaType(a,b,c) => new MediaRange(a,b,c,None,Nil)
}
negotiateContent(requestType, acceptedTypes).orElse(acceptedTypes.headOption).getOrElse("application/json")
}

import de.zalando.play.controllers.WrappedBodyParsers

val customParsers = WrappedBodyParsers.anyParser[ModelSchemaRoot]
anyParser[ModelSchemaRoot](bodyMimeType, customParsers, "Invalid ModelSchemaRoot", maxLength)
}

val postActionConstructor = Action
def postAction = (f: postActionType) => postActionConstructor(postParser(Seq[String]())) { request =>
val providedTypes = Seq[String]()

negotiateContent(request.acceptedTypes, providedTypes).map { postResponseMimeType =>
val possibleWriters = Map(
200 -> anyToWritable[Pet]
)
val root = request.body



val result =
new PostValidator(root).errors match {
case e if e.isEmpty => processValidpostRequest(f)((root))(possibleWriters, postResponseMimeType)
case l =>
implicit val marshaller: Writeable[Seq[ParsingError]] = parsingErrors2Writable(postResponseMimeType)
BadRequest(l)
}
result

}.getOrElse(Status(415)("The server doesn't support any of the requested mime types"))
}

private def processValidpostRequest[T <: Any](f: postActionType)(request: postActionRequestType)
(writers: Map[Int, String => Writeable[T]], mimeType: String)(implicit m: Manifest[T]) = {
import de.zalando.play.controllers.ResponseWriters

val callerResult = f(request)
val status = callerResult match {
case Failure(error) => (errorToStatuspost orElse defaultErrorMapping)(error)
case Success((code: Int, result: T @ unchecked)) =>
val writerOpt = ResponseWriters.choose(mimeType)[T]().orElse(writers.get(code).map(_.apply(mimeType)))
writerOpt.map { implicit writer =>
Status(code)(result)
}.getOrElse {
implicit val errorWriter = anyToWritable[IllegalStateException](mimeType)
Status(500)(new IllegalStateException(s"Response code was not defined in specification: $code"))
}
case Success(other) =>
implicit val errorWriter = anyToWritable[IllegalStateException](mimeType)
Status(500)(new IllegalStateException(s"Expected pair (responseCode, response) from the controller, but was: other"))
}
status
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@

import play.api.mvc.{Action, Controller}

import play.api.data.validation.Constraint

import de.zalando.play.controllers._

import PlayBodyParsing._

import PlayValidations._

import scala.util._


/**
* This controller is re-generated after each change in the specification.
* Please only place your hand-written code between appropriate comments in the body of the controller.
*/

package cross_spec_references.yaml {

class Cross_spec_referencesYaml extends Cross_spec_referencesYamlBase {
val post = postAction { (root: ModelSchemaRoot) =>
// ----- Start of unmanaged code area for action Cross_spec_referencesYaml.post
Failure(???)
// ----- End of unmanaged code area for action Cross_spec_referencesYaml.post
}

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
⌿definitions⌿Meta⌿copyright ->
Opt(Str)
⌿definitions⌿ModelSchema⌿keywords ->
Opt(Str)
⌿definitions⌿ModelSchema⌿specialDescriptions ->
Opt(TypeRef(⌿definitions⌿ModelSchema⌿specialDescriptions⌿Opt))
⌿definitions⌿ModelSchemaRoot⌿data ->
Opt(TypeRef(⌿definitions⌿ModelSchemaRoot⌿data⌿Opt))
⌿definitions⌿Pet⌿id ->
Opt(Lng)
⌿definitions⌿ModelSchemaRoot⌿links ->
Opt(TypeRef(⌿definitions⌿ModelSchemaRoot⌿links⌿Opt))
⌿definitions⌿Pet⌿tags ->
Opt(TypeRef(⌿definitions⌿Pet⌿tags⌿Opt))
⌿definitions⌿Pet⌿photoUrls ->
ArrResult(Str)
⌿definitions⌿ModelSchema⌿lengthRegister ->
Opt(Str)
⌿definitions⌿ModelSchema⌿ageGroups ->
Arr(Str)
⌿definitions⌿Pet⌿category ->
Opt(TypeRef(⌿definitions⌿Pet⌿category⌿Opt))
⌿definitions⌿ModelSchemaRoot⌿meta ->
Opt(TypeRef(⌿definitions⌿ModelSchemaRoot⌿meta⌿Opt))
⌿definitions⌿ModelSchema⌿specialDescriptions⌿Opt ->
Arr(Str)
⌿definitions⌿Pet⌿category⌿Opt ->
TypeDef(⌿definitions⌿Category, Seq(
Field(⌿definitions⌿Category⌿id, TypeRef(⌿definitions⌿Pet⌿id)),
Field(⌿definitions⌿Category⌿name, TypeRef(⌿definitions⌿Meta⌿copyright))))
⌿definitions⌿ModelSchemaRoot⌿data⌿Opt ->
TypeDef(⌿definitions⌿ModelSchema, Seq(
Field(⌿definitions⌿ModelSchema⌿name, Str),
Field(⌿definitions⌿ModelSchema⌿sizeRegister, Str),
Field(⌿definitions⌿ModelSchema⌿brand, Str),
Field(⌿definitions⌿ModelSchema⌿partnerArticleModelId, Intgr),
Field(⌿definitions⌿ModelSchema⌿silhouetteId, Str),
Field(⌿definitions⌿ModelSchema⌿description, TypeRef(⌿definitions⌿Meta⌿copyright)),
Field(⌿definitions⌿ModelSchema⌿ageGroups, TypeRef(⌿definitions⌿ModelSchema⌿ageGroups)),
Field(⌿definitions⌿ModelSchema⌿keywords, TypeRef(⌿definitions⌿ModelSchema⌿keywords)),
Field(⌿definitions⌿ModelSchema⌿lengthRegister, TypeRef(⌿definitions⌿ModelSchema⌿lengthRegister)),
Field(⌿definitions⌿ModelSchema⌿specialDescriptions, TypeRef(⌿definitions⌿ModelSchema⌿specialDescriptions)),
Field(⌿definitions⌿ModelSchema⌿articleModelAttributes, TypeRef(⌿definitions⌿ModelSchema⌿specialDescriptions))))
⌿definitions⌿ModelSchemaRoot⌿meta⌿Opt ->
TypeDef(⌿definitions⌿Meta, Seq(
Field(⌿definitions⌿Meta⌿copyright, TypeRef(⌿definitions⌿Meta⌿copyright))))
⌿paths⌿/⌿post⌿root ->
TypeDef(⌿definitions⌿ModelSchemaRoot, Seq(
Field(⌿definitions⌿ModelSchemaRoot⌿data, TypeRef(⌿definitions⌿ModelSchemaRoot⌿data)),
Field(⌿definitions⌿ModelSchemaRoot⌿meta, TypeRef(⌿definitions⌿ModelSchemaRoot⌿meta)),
Field(⌿definitions⌿ModelSchemaRoot⌿links, TypeRef(⌿definitions⌿ModelSchemaRoot⌿links))))
⌿definitions⌿ModelSchemaRoot⌿links⌿Opt ->
TypeDef(⌿definitions⌿Links, Seq(
Field(⌿definitions⌿Links⌿self, TypeRef(⌿definitions⌿Meta⌿copyright)),
Field(⌿definitions⌿Links⌿related, TypeRef(⌿definitions⌿Meta⌿copyright))))
⌿definitions⌿Pet⌿tags⌿Opt ->
ArrResult(TypeRef(⌿definitions⌿Pet⌿category⌿Opt))
⌿paths⌿/⌿post⌿responses⌿200 ->
TypeDef(⌿definitions⌿Pet, Seq(
Field(⌿definitions⌿Pet⌿name, Str),
Field(⌿definitions⌿Pet⌿tags, TypeRef(⌿definitions⌿Pet⌿tags)),
Field(⌿definitions⌿Pet⌿photoUrls, TypeRef(⌿definitions⌿Pet⌿photoUrls)),
Field(⌿definitions⌿Pet⌿id, TypeRef(⌿definitions⌿Pet⌿id)),
Field(⌿definitions⌿Pet⌿status, TypeRef(⌿definitions⌿Meta⌿copyright)),
Field(⌿definitions⌿Pet⌿category, TypeRef(⌿definitions⌿Pet⌿category))))
-- params --

⌿paths⌿/⌿post⌿root -> Parameter(root,TypeRef(⌿paths⌿/⌿post⌿root),None,None,.+,false,body)
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@



Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package cross_spec_references

package object yaml {

import de.zalando.play.controllers.ArrayWrapper



type ModelSchemaSpecialDescriptionsOpt = ArrayWrapper[String]
type MetaCopyright = Option[String]
type ModelSchemaKeywords = Option[String]
type ModelSchemaSpecialDescriptions = Option[ModelSchemaSpecialDescriptionsOpt]
type ModelSchemaRootData = Option[ModelSchemaRootDataOpt]
type PetId = Option[Long]
type ModelSchemaRootLinks = Option[ModelSchemaRootLinksOpt]
type PetTags = Option[PetTagsOpt]
type PetPhotoUrls = Seq[String]
type ModelSchemaLengthRegister = Option[String]
type ModelSchemaAgeGroups = ArrayWrapper[String]
type PetCategory = Option[PetCategoryOpt]
type PetTagsOpt = Seq[PetCategoryOpt]
type ModelSchemaRootMeta = Option[ModelSchemaRootMetaOpt]


case class PetCategoryOpt(id: PetId, name: MetaCopyright)
case class ModelSchemaRootDataOpt(name: String, sizeRegister: String, brand: String, partnerArticleModelId: Int, silhouetteId: String, description: MetaCopyright, ageGroups: ModelSchemaAgeGroups, keywords: ModelSchemaKeywords, lengthRegister: ModelSchemaLengthRegister, specialDescriptions: ModelSchemaSpecialDescriptions, articleModelAttributes: ModelSchemaSpecialDescriptions)
case class ModelSchemaRootMetaOpt(copyright: MetaCopyright)
case class ModelSchemaRoot(data: ModelSchemaRootData, meta: ModelSchemaRootMeta, links: ModelSchemaRootLinks)
case class Pet(name: String, tags: PetTags, photoUrls: PetPhotoUrls, id: PetId, status: MetaCopyright, category: PetCategory)
case class ModelSchemaRootLinksOpt(self: MetaCopyright, related: MetaCopyright)


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
package cross_spec_references.yaml

import org.scalacheck.Gen
import org.scalacheck.Arbitrary
import Arbitrary._
import de.zalando.play.controllers.ArrayWrapper

object Generators {



def createModelSchemaSpecialDescriptionsOptGenerator = _generate(ModelSchemaSpecialDescriptionsOptGenerator)
def createMetaCopyrightGenerator = _generate(MetaCopyrightGenerator)
def createModelSchemaKeywordsGenerator = _generate(ModelSchemaKeywordsGenerator)
def createModelSchemaSpecialDescriptionsGenerator = _generate(ModelSchemaSpecialDescriptionsGenerator)
def createModelSchemaRootDataGenerator = _generate(ModelSchemaRootDataGenerator)
def createPetIdGenerator = _generate(PetIdGenerator)
def createModelSchemaRootLinksGenerator = _generate(ModelSchemaRootLinksGenerator)
def createPetTagsGenerator = _generate(PetTagsGenerator)
def createPetPhotoUrlsGenerator = _generate(PetPhotoUrlsGenerator)
def createModelSchemaLengthRegisterGenerator = _generate(ModelSchemaLengthRegisterGenerator)
def createModelSchemaAgeGroupsGenerator = _generate(ModelSchemaAgeGroupsGenerator)
def createPetCategoryGenerator = _generate(PetCategoryGenerator)
def createPetTagsOptGenerator = _generate(PetTagsOptGenerator)
def createModelSchemaRootMetaGenerator = _generate(ModelSchemaRootMetaGenerator)



def ModelSchemaSpecialDescriptionsOptGenerator = _genList(arbitrary[String], "csv")
def MetaCopyrightGenerator = Gen.option(arbitrary[String])
def ModelSchemaKeywordsGenerator = Gen.option(arbitrary[String])
def ModelSchemaSpecialDescriptionsGenerator = Gen.option(ModelSchemaSpecialDescriptionsOptGenerator)
def ModelSchemaRootDataGenerator = Gen.option(ModelSchemaRootDataOptGenerator)
def PetIdGenerator = Gen.option(arbitrary[Long])
def ModelSchemaRootLinksGenerator = Gen.option(ModelSchemaRootLinksOptGenerator)
def PetTagsGenerator = Gen.option(PetTagsOptGenerator)
def PetPhotoUrlsGenerator = Gen.containerOf[List,String](arbitrary[String])
def ModelSchemaLengthRegisterGenerator = Gen.option(arbitrary[String])
def ModelSchemaAgeGroupsGenerator = _genList(arbitrary[String], "csv")
def PetCategoryGenerator = Gen.option(PetCategoryOptGenerator)
def PetTagsOptGenerator = Gen.containerOf[List,PetCategoryOpt](PetCategoryOptGenerator)
def ModelSchemaRootMetaGenerator = Gen.option(ModelSchemaRootMetaOptGenerator)


def createPetCategoryOptGenerator = _generate(PetCategoryOptGenerator)
def createModelSchemaRootDataOptGenerator = _generate(ModelSchemaRootDataOptGenerator)
def createModelSchemaRootMetaOptGenerator = _generate(ModelSchemaRootMetaOptGenerator)
def createModelSchemaRootGenerator = _generate(ModelSchemaRootGenerator)
def createPetGenerator = _generate(PetGenerator)
def createModelSchemaRootLinksOptGenerator = _generate(ModelSchemaRootLinksOptGenerator)


def PetCategoryOptGenerator = for {
id <- PetIdGenerator
name <- MetaCopyrightGenerator
} yield PetCategoryOpt(id, name)
def ModelSchemaRootDataOptGenerator = for {
name <- arbitrary[String]
sizeRegister <- arbitrary[String]
brand <- arbitrary[String]
partnerArticleModelId <- arbitrary[Int]
silhouetteId <- arbitrary[String]
description <- MetaCopyrightGenerator
ageGroups <- ModelSchemaAgeGroupsGenerator
keywords <- ModelSchemaKeywordsGenerator
lengthRegister <- ModelSchemaLengthRegisterGenerator
specialDescriptions <- ModelSchemaSpecialDescriptionsGenerator
articleModelAttributes <- ModelSchemaSpecialDescriptionsGenerator
} yield ModelSchemaRootDataOpt(name, sizeRegister, brand, partnerArticleModelId, silhouetteId, description, ageGroups, keywords, lengthRegister, specialDescriptions, articleModelAttributes)
def ModelSchemaRootMetaOptGenerator = for {
copyright <- MetaCopyrightGenerator
} yield ModelSchemaRootMetaOpt(copyright)
def ModelSchemaRootGenerator = for {
data <- ModelSchemaRootDataGenerator
meta <- ModelSchemaRootMetaGenerator
links <- ModelSchemaRootLinksGenerator
} yield ModelSchemaRoot(data, meta, links)
def PetGenerator = for {
name <- arbitrary[String]
tags <- PetTagsGenerator
photoUrls <- PetPhotoUrlsGenerator
id <- PetIdGenerator
status <- MetaCopyrightGenerator
category <- PetCategoryGenerator
} yield Pet(name, tags, photoUrls, id, status, category)
def ModelSchemaRootLinksOptGenerator = for {
self <- MetaCopyrightGenerator
related <- MetaCopyrightGenerator
} yield ModelSchemaRootLinksOpt(self, related)

def _generate[T](gen: Gen[T]) = (count: Int) => for (i <- 1 to count) yield gen.sample

def _genList[T](gen: Gen[T], format: String): Gen[ArrayWrapper[T]] = for {
items <- Gen.containerOf[List,T](gen)
} yield ArrayWrapper(format)(items)



}
Loading

0 comments on commit f661d83

Please sign in to comment.